Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opir/Futhark fails to import code that uses __int128 #32

Open
beef331 opened this issue May 1, 2022 · 3 comments
Open

Opir/Futhark fails to import code that uses __int128 #32

beef331 opened this issue May 1, 2022 · 3 comments

Comments

@beef331
Copy link
Contributor

beef331 commented May 1, 2022

Attempting to wrap wasmedge for instance fails due to hitting __int128. The following is what I'm using if it helps. In this API one does not directly touch the data at __int128 so any allocation that matches the size should result in usable code.

import futhark
import std/strutils

proc removeWasmEdge(name, kind, partof: string): string =
  const prefix = "WasmEdge_"
  result =
    if name.startsWith(prefix):
      name[prefix.len..name.high]
    else:
      name
  case kind
  of "const", "typedef":
    discard
  else:
    result[0] = result[0].toLowerAscii

importc:
  sysPath "/usr/lib/clang/13.0.1/include"
  path "/home/jason/.wasmedge/include/"
  renameCallback removeWasmEdge
  "wasmedge/wasmedge.h"
@beef331
Copy link
Contributor Author

beef331 commented May 2, 2022

Well importing int128 now works but there is another related issue

typedef struct WasmEdge_Value {
  uint128_t Value;                              
  enum WasmEdge_ValType Type;                              
} WasmEdge_Value;

sizeof(WasmEdge_Value) on C is 32 but inside Nim it's 24.

The following type definitions resolve the issue.

type
  uInt128t* {.importc: "unsigned __int128".} = object
    do_not_use1, do_not_use2: uint64
  int128t* {.importc: "__int128".} = object
    do_not_use1, do_not_use2: uint64

@PMunch
Copy link
Owner

PMunch commented May 3, 2022

Hmm, this is a bit weird. So the uint128t and uint128t should be the same size as what Futhark spits out for those, 16 bytes. I believe the issue might be with alignment and padding. Probably the C-compiler does something different for int128t than for a struct of the same size.

@PMunch
Copy link
Owner

PMunch commented May 3, 2022

That does indeed seem to be the issue. The following test C code:

#include <stdint.h>
#include <stdio.h>

typedef struct {
    int64_t a;
    int64_t b;
} fake;

typedef struct {
    __int128 f1;
    int64_t f2;
} withreal;

typedef struct {
    fake f1;
    int64_t f2;
} withfake;

int main() {
    printf("__int128 %d\n", sizeof(__int128));
    printf("struct %d\n", sizeof(fake));
    printf("withreal %d\n", sizeof(withreal));
    printf("withfake %d\n", sizeof(withfake));
}

outputs this:

__int128 16
struct 16
withreal 32
withfake 24

Not entirely sure how to fix that, or if it is even fixable in a trivial way. But as you say Futhark allows you to define you own type definitions for edge cases like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants