mkkellogg / GaussianSplats3D

Three.js-based implementation of 3D Gaussian splatting
MIT License
1.45k stars 183 forks source link

Modernize emscripten usage ("env" "pthread_self": function import requires a callable) #293

Open PeterZhizhin opened 3 months ago

PeterZhizhin commented 3 months ago

If I recompile with a new emscripten compiler version (3.1.64), I get the following error on importing the WebAssembly module:

LinkError: WebAssembly.instantiate(): Import #0 "env" "pthread_self": function import requires a callable
    at 0026ddb4-d116-4418-b697-5ee71eb6c206:157:36
(anonymous) @ 0026ddb4-d116-4418-b697-5ee71eb6c206:157
Promise.then
self.onmessage @ 0026ddb4-d116-4418-b697-5ee71eb6c206:159

The reason for this is that a more recent emscripten (less than ~3 years old) compiler exports additional symbols that we are not defining when calling instantiate.

When compiling as a regular module, emscripten will generate additional JS output file that actually loads all functions:

em++ -std=c++11 sorter.cpp -o sorter.js -s WASM=1 -s USE_PTHREADS=1 -msimd128

This generates the following files:

sorter.js
sorter.wasm

The sorter.js file will actually load the sorter.wasm file into a Module variable. This variable can then be used to access defined C++ functions.

This approach will be more future-proof, since the generated .js file will be different depending on the compiler version.

I'd like to know if something like this was considered. And if it wasn't used, then why.

mkkellogg commented 3 months ago

I admit that I don't have a great reason for the way it is currently implemented other than it's simple and it works :) When I originally implemented it, I basically got a quick & dirty solution working and never bothered to change how the web worker or WASM module were set up after that. For what it's worth, I can compile and import just fine using emscripten 3.1.6, which was release in May of this year. I'm using the following command:

em++ -std=c++11 sorter.cpp -Os -s WASM=1 -s SIDE_MODULE=2 -o sorter.wasm -s IMPORTED_MEMORY=1 -s USE_PTHREADS=1 -msimd128
JiamingSuen commented 2 months ago

I'm having the same problem. I cannot reproduce the compiled sorter.wasm file in the repo with emscripten version 3.1.60 (on both macOS and Linux). The compiled wasm also produces Import #0 "env" "pthread_self": function import requires a callable error, same as 3.1.64. @mkkellogg Could you tell me which version of emscripten should be used to compile a usable wasm file? Thanks very much!

mkkellogg commented 2 months ago

@JiamingSuen I am also using version 3.1.6, and I am using the command below to compile it:

em++ -std=c++11 sorter.cpp -Os -s WASM=1 -s SIDE_MODULE=2 -o sorter.wasm -s IMPORTED_MEMORY=1 -s USE_PTHREADS=1 -msimd128

Can you try that command on your machine?

JiamingSuen commented 2 months ago

@JiamingSuen I am also using version 3.1.6, and I am using the command below to compile it:

em++ -std=c++11 sorter.cpp -Os -s WASM=1 -s SIDE_MODULE=2 -o sorter.wasm -s IMPORTED_MEMORY=1 -s USE_PTHREADS=1 -msimd128

Can you try that command on your machine?

I tried this command with Emscripten 3.1.60 on the current HEAD, and although I didn't modify sorter.cpp, the sorter.wasm file was updated. As a result, the webpage fails to load properly, showing the error "env" "pthread_self": function import requires a callable as the title suggests. This issue occurred after running another npm run build, which was necessary to update the JavaScript code in the build/demo folder.

If our Emscripten version matches, is it possible that the current sorter.wasm in the repo does not match the content of sorter.cpp?

$ em++ --version
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.60 (42a6ea2052f19f70d7d994e8c324bcad2f1f8939)
JiamingSuen commented 2 months ago

I just realized that you are using Emscripten 3.1.6, which is different from 3.1.60😂 3.1.6 was released two years ago.

By switching to 3.1.6, the compiled sorter.wasm is working again.

mkkellogg commented 2 months ago

Ha, good catch! I will look into how I can make it work with a more current version, like 3.1.60.