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

built OpenCV.js fails to load wasm in node.js #19243

Open
3 of 4 tasks
peteruhnak opened this issue Jan 1, 2021 · 8 comments
Open
3 of 4 tasks

built OpenCV.js fails to load wasm in node.js #19243

peteruhnak opened this issue Jan 1, 2021 · 8 comments

Comments

@peteruhnak
Copy link

System information (version)
  • OpenCV => 4.5.1 & master
  • Operating System / Platform => node 8/10/14 (built on ubuntu 20)
  • Compiler => emscripten
Detailed description

Expected behavior:

  1. Running opencv.js via node built using the documented instructions correctly loads, passes all tests and runs test_async.js (see further).
  2. Pre-built opencv.js passes all tests and test_async.js

Note that running the tests.html via browser works correctly, the failures are specific to running via node.js.

Actual behavior:

  1. Self-built opencv.js
    • node tests.js fails to even fail properly and instead just reports 0 failed, 0 passed
    • node test_async.js fails to load wasm due to needing experimental wasm threads & shared memory
      • RuntimeError: abort(RuntimeError: abort(CompileError: WebAssembly.instantiate(): Compiling function #73 failed: Invalid opcode (enable with --experimental-wasm-threads) @+39429)
      • (with threads enabled) RuntimeError: abort(RuntimeError: abort(CompileError: WebAssembly.instantiate(): Compiling function #73 failed: Atomic opcodes used without shared memory @+39428)
  2. Pre-built opencv.js
    • node tests.js fails most tests (34 failed, 10 passed), due to improper loading
    • node test_async.js works as expected (and generally using the pre-built library works as expected when loaded properly)
      **

Running node tests.js simply outputs:

Testing  /home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js ... 
0 failed, 0 passed

If I modify tests.js and only allow a single file (e.g. tests: [ 'test_mat.js']) I instead get the following error:

You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js
RuntimeError: abort(You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js) at Error
    at jsStackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381549)
    at stackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381725)
    at abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33457)
    at Promise.get (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7202)
    at Object.<anonymous> (/home/ubuntu/prog/docker-opencv/js_wasm/bin/test_mat.js:756:26)
    at runTest (/home/ubuntu/prog/docker-opencv/js_wasm/bin/node_modules/node-qunit/node_modules/qunit/qunit/qunit.js:3044:32)
    at Test.run (/home/ubuntu/prog/docker-opencv/js_wasm/bin/node_modules/node-qunit/node_modules/qunit/qunit/qunit.js:3032:8)
    at /home/ubuntu/prog/docker-opencv/js_wasm/bin/node_modules/node-qunit/node_modules/qunit/qunit/qunit.js:3255:15
    at processTaskQueue (/home/ubuntu/prog/docker-opencv/js_wasm/bin/node_modules/node-qunit/node_modules/qunit/qunit/qunit.js:2640:26)
    at /home/ubuntu/prog/docker-opencv/js_wasm/bin/node_modules/node-qunit/node_modules/qunit/qunit/qunit.js:2644:12
0 failed, 0 passed

This is presumably due to the tests not loading the library correctly.

**

Running node test_async.js (code see further) produces the following error:

Node 8/Node 10 -- generic decoding error:

failed to asynchronously prepare wasm: CompileError: WasmCompile: Wasm decoding failed: unexpected section: Code @+37433
CompileError: WasmCompile: Wasm decoding failed: unexpected section: Code @+37433
RuntimeError: abort(CompileError: WasmCompile: Wasm decoding failed: unexpected section: Code @+37433) at Error
    at jsStackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381549)
    at stackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381725)
    at abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33457)
    at /home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7358365
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:189:7)
    at Function.Module.runMain (module.js:696:11)
    at startup (bootstrap_node.js:204:16)
    at bootstrap_node.js:625:3

Node 14 -- invalid threads opcode

RuntimeError: abort(RuntimeError: abort(CompileError: WebAssembly.instantiate(): Compiling function #73 failed: Invalid opcode (enable with --experimental-wasm-threads) @+39429) at Error
    at jsStackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381549)
    at stackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381725)
    at abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33457)
    at /home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7358365) at Error
    at jsStackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381549)
    at stackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381725)
    at process.abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33457)
    at process.emit (events.js:315:20)
    at processPromiseRejections (internal/process/promises.js:245:33)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)
    at process.abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33488)
    at process.emit (events.js:315:20)
    at processPromiseRejections (internal/process/promises.js:245:33)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)

Rerunning with --experimental-wasm-threads produces invalid shared memory opcode instead

RuntimeError: abort(RuntimeError: abort(CompileError: WebAssembly.instantiate(): Compiling function #73 failed: Atomic opcodes used without shared memory @+39428) at Error
    at jsStackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381549)
    at stackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381725)
    at abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33457)
    at /home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7358365) at Error
    at jsStackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381549)
    at stackTrace (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:7381725)
    at process.abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33457)
    at process.emit (events.js:315:20)
    at processPromiseRejections (internal/process/promises.js:245:33)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)
    at process.abort (/home/ubuntu/prog/docker-opencv/js_wasm/bin/opencv.js:31:33488)
    at process.emit (events.js:315:20)
    at processPromiseRejections (internal/process/promises.js:245:33)
    at processTicksAndRejections (internal/process/task_queues.js:94:32)
Steps to reproduce
  1. Follow instructions here except for extra flags (see 2) https://docs.opencv.org/4.5.1/d4/da1/tutorial_js_setup.html
  • using emsdk or docker didn't make any difference, nor the latest emsdk vs 2.0.10
  • using --build_wasm or not also doesn't seem to matter (it always produces wasm)
  1. Build with --build_test and --build_flags '-s ASSERTIONS=1'
sudo docker run --rm -v $(pwd):/src -u 1000:1000 emscripten/emsdk:2.0.10 emcmake python3 ./opencv/platforms/js/build_js.py js_assertions --build_test --build_flags '-s ASSERTIONS=1'
  1. install node dependencies & run tests
  2. change tests.js to run only for a single file (tests: [ 'test_mat.js' ]) & run tests
  3. run node test_async.js
let cv

function loadOpenCv() {
    return new Promise(resolve => {
        global.Module = {
            onRuntimeInitialized: () => {
                console.log('opencv ready')
                resolve()
            }
        }
        cv = require('./opencv.js')
    })
}

loadOpenCv().then(() => {
    const mat = new cv.Mat(10, 20, cv.CV_8UC3)
    console.log(mat.cols)
    mat.delete()
})
Issue submission checklist
  • I report the issue, it's not a question
  • I checked the problem with documentation, FAQ, open issues,
    answers.opencv.org, Stack Overflow, etc and have not found solution
  • I updated to latest OpenCV version and the issue is still there
  • There is reproducer code and related data files: videos, images, onnx, etc
@alalek
Copy link
Member

alalek commented Jan 1, 2021

Perhaps you want to have something like "test_js" step from here.

I can confirm that specific versions of used software are required. Configuration of testing infrastructure is here.
Migration on newer node versions were failed, some extra build options are required.

@peteruhnak
Copy link
Author

peteruhnak commented Jan 1, 2021

Thanks!

I can confirm that using emscripten 1.39.0-upstream I managed to build it and successfully run the test_async.js.


I can close this issue (as my main problem is solved), however I think these points still stand (so feel free to close the issue or keep it open):

  • the docs should also mention emscripten 1.39.0-upstream for node (the recommended 2.0.10 is only ok for browser)
  • node tests.js still fails due to the non-async loading

For the tests.js, I really don't understand why it works on the OpenCV build server. Digging through qunit/qunit-node source code, I didn't really see anything that would guarantee correct loading (which is also why it always fails for me); so I guess the CI server is getting a lucky race condition every time 🤷 (which is also weird).

@alalek
Copy link
Member

alalek commented Jan 1, 2021

Lets keep this open.
Hopefully some JS / Emscripten experts can suggest solutions / workarounds for mentioned issues.

@boulabiar
Copy link

I am having this issue with chrome mobile and firefox and many other browsers.
This is related to sharedarraybuffer or atomics that got activated after OpenCV 4.2. (4.2 works fine, but 4.4 doesn't work).

It seems like some work with optimisations and threads requested a still experimental feature in browsers and in node.
https://caniuse.com/sharedarraybuffer

When I force compiling a file using opencv wasm without threads in Emscripten (USE_PTHREADS=0), compilation fails because opencv wasm requested threads (and sharedarraybuffer) when it was compiled.
error message:
wasm-ld: error: 'atomics' feature is usedy alloc.cpp.o, so --shared-memory must be used.

There should be an option to compile without it.

@ValYouW
Copy link

ValYouW commented Feb 16, 2021

Also trying to build opencv.js with --disable_wasm using latest emsdk (2.0.14) fails in the wasm2js command:

.../emsdk/upstream/bin/wasm2js --emscripten -O ../../bin/opencv_js.wasm --mvp-features --enable-threads --enable-mutable-globals --enable-bulk-memory --enable-sign-ext' failed (-6)

@exist2disappear
Copy link

i'm on 4.3.0 2021.4.21:
build with --disable_wasm.
err is :
em++: error: '/root/gitwork/emsdk/upstream/bin/wasm2js --emscripten -O ../../bin/opencv_js.wasm --mvp-features --enable-threads --enable-mutable-globals --enable-bulk-memory --enable-sign-ext' failed (-6)

what opt should use?

@rubuslab
Copy link

I think the key point is how to install build tool emscripten.
I installed emscripten-1.39.12 and build opencv.js success.
the steps as below:

  1. install emscripten-1.39.12 and refine configuration
    (my main folder /data/develop-003/)
    rm /root/.emscripten* -rf
    git clone -b 1.39.12 https://github.com/emscripten-core/emsdk.git
    cd emsdk
    ./emsdk install 1.39.12
    ./emsdk activate 1.39.12
    cp /root/.emscripten ./
    source ./emsdk_env.sh

// test command
./upstream/emscripten/emcc -v

  1. clone opencv and build wasm js
    git clone https://github.com/opencv/opencv.git
    cd opencv
    python3 ./platforms/js/build_js.py build_wasm_out --build_wasm --emscripten_dir=/data/develop-003/emsdk/upstream/emscripten/

May this can help you.

@dosgo
Copy link

dosgo commented Nov 3, 2021

Is this related to wasi?

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

No branches or pull requests

7 participants