python-igraph icon indicating copy to clipboard operation
python-igraph copied to clipboard

wasm wheel

Open flange-ipb opened this issue 2 years ago • 10 comments

#560

  • [x] patch setup.py
  • [x] Actions workflow

Current showstoppers: During configuration of the igraph build:

CMake Error at etc/cmake/ieee754_endianness.cmake:50 (message): igraph only supports platforms where IEEE754 doubles have the same endianness as uint64_t Call Stack (most recent call first): CMakeLists.txt:107 (include)

due to igraph commit efa91da.

flange-ipb avatar Aug 17 '22 13:08 flange-ipb

You can pass -DIEEE754_DOUBLE_ENDIANNESS_MATCHES:BOOL=ON to cmake to skip the check that throws this error. On the other hand, I wonder why this test fails and whether we can do something about it. The igraph RNG assumes that the endianness of an IEEE754 double and an uint64_t is the same, and it has been so on all platforms we've tested so far. Is this not the case with WebAssembly?

The reason why we need this is that in igraph_rng_get_unif01(), we generate uniformly distributed real numbers from the [0, 1) interval by extracting 52 bits from a random 64-bit uint, and fill that directly into the mantissa of an IEEE754 double. The trick needs to work on the bit level, so we need to ensure that the endianness is the same for both types (i.e. both are little-endian or both are big-endian):

uint64_t r = (igraph_i_rng_get_random_bits_uint64(rng, 52) & 0xFFFFFFFFFFFFFull) | 0x3FF0000000000000ull;
return *(double *)(&r) - 1.0;

ntamas avatar Aug 17 '22 14:08 ntamas

Also, note that before igraph commit efa91da, this did not cause problems because this pre-test was not run at all - it was skipped for all cross-compilation builds. In that commit, we changed this so that the pre-test is still run if a valid CMake cross-compiling emulator is provided. So, in this case it should be checked what the cross-compiling emulator does with the code of the test and whether we need to adjust the test.

This is the source of the test in igraph's repo.

ntamas avatar Aug 17 '22 14:08 ntamas

You could investigate with the WasmFiddle.

flange-ipb avatar Aug 17 '22 14:08 flange-ipb

Well, I'm getting this as the output and I don't know whether this is what I should get or not:

NYI: printf null
0

I guess that the zero at the end is the return code of the main() function, and the NYI: printf null part before it is what came out of printf("OK"). But I also get this when simply printf-ing a string from a main() function unconditionally, so I guess printf is not supported in this environment?

ntamas avatar Aug 17 '22 15:08 ntamas

How is ieee754_endianness_check built and executed? I'd expect to see a wasm and js file somewhere, which needs to be called by node.js.

I guess that the zero at the end is the return code of the main() function, and the NYI: printf null part before it is what came out of printf("OK"). But I also get this when simply printf-ing a string from a main() function unconditionally, so I guess printf is not supported in this environment?

Let me compile and run the file separately ...

flange-ipb avatar Aug 17 '22 15:08 flange-ipb

root@af3fc1b32e84:/igraph/etc/cmake# node a.out.js stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc. (this may also be due to not including full filesystem support - try building with -sFORCE_FILESYSTEM)

printf needs a newline ...

flange-ipb avatar Aug 17 '22 15:08 flange-ipb

Ok, figured it out: IEEE754_DOUBLE_ENDIANNESS_TEST_EXIT_CODE is 0 and IEEE754_DOUBLE_ENDIANNESS_TEST_RESULT is "OK\n" (the test in ieee754_endianness.cmake:29 needs to be corrected).

flange-ipb avatar Aug 17 '22 15:08 flange-ipb

Ok, I added an action to build the wheel. This comes from the Pyodide example. It does not use the cibuildwheel action because it doesn't support WASM yet.

I'm not sure about running pytest, which would have to be invoked inside a Pyodide environment. Here is an example with a lot of JavaScript glue code.

flange-ipb avatar Aug 29 '22 11:08 flange-ipb

I'm not sure about running pytest, which would have to be invoked inside a Pyodide environment.

This should become possible with pyodide#2976. I'll wait until this is released, probably in a few weeks.

flange-ipb avatar Sep 02 '22 07:09 flange-ipb

Looks good to me so far! Please mark this as "ready for review" if you'd like us to merge this as-is, without running the unit tests.

As for the built wheels, right now they will be published as build artifacts, but I'm not sure whether PyPI can handle them. Are wasm wheels routinely published on PyPI?

ntamas avatar Sep 04 '22 21:09 ntamas

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 12 '22 06:11 stale[bot]

@flange-ipb Is this ready for review?

ntamas avatar Nov 12 '22 08:11 ntamas

Looks good to me so far! Please mark this as "ready for review" if you'd like us to merge this as-is, without running the unit tests.

As for the built wheels, right now they will be published as build artifacts, but I'm not sure whether PyPI can handle them. Are wasm wheels routinely published on PyPI?

Not yet, however Python is heading towards full wasm support in the future, even official documentation is mentioning wasm function compatibility and it seems they have started implementing build support for it. For the time being pyodide framework is the top framework for making Python running on wasm.
I'm injecting myself to this thread as I'm the person who asked @flange-ipb is he could help me bringing igraph to wasm as it is my goto package to handle my graphing needs :)

skelsec avatar Jan 23 '23 19:01 skelsec

Updated PR for the current state of the main branch; it still seems to work. I have tweaked the detection of Emscripten a bit. Is this ready to be merged?

ntamas avatar Jan 31 '23 13:01 ntamas