TVM web build error, and unrecognised target

I’m exploring what TVM can do for wasm and webgpu, however I am having some issues running it. I’ve made as much progress as I can, with one or two ugly hacks.

According to the web README, building is straightforward, just ensure that Emscripten is set up properly, and run make then npm install.

However, for me (on TVM v0.10.0), make fails with:

/tvm/include/tvm/runtime/ndarray.h:51:45: error: integer value -1 is outside the valid range of values [0, 15] for this enumeration type [-Wenum-constexpr-conversion]
constexpr DLDeviceType kInvalidDeviceType = static_cast<DLDeviceType>(-1);
                                            ^
1 error generated.
emcc: error: '/root/emsdk/upstream/bin/clang++ -target wasm32-unknown-emscripten -fignore-exceptions -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -DEMSCRIPTEN --sysroot=/root/emsdk/upstream/emscripten/cache/sysroot -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -I/tvm -I/tvm/include -I/tvm/3rdparty/dlpack/include -I/tvm/3rdparty/dmlc-core/include -I/tvm/3rdparty/compiler-rt -O3 -std=c++17 -Wno-ignored-attributes -c emcc/wasm_runtime.cc -o dist/wasm/wasm_runtime.bc' failed (returned 1)

Looking at the line that causes the error, it was committed around 2 years ago, which makes me think that it’s not the responsible party. I am able to build regular TVM with this line intact.

There is a TVM web CI test here, so I can feel somewhat confident that the feature has not fallen to bitrot. Not sure what is causing it, perhaps my environment, but I am in a freshly pulled Ubuntu 20.04 docker container.

I can fix the web build by changing the invalid device type to some other valid value, e.g. 10. And I can then run npm install without an issue.

Now, trying to get an example running, I am following the webgpu-example from @tqchen. It is is a few years old, so I’ve had to make a few changes, as you can see in this git diff. Most importantly, it does not seem like the file tvmjs.bundle.js is generated any more, so I am assuming that tvmjs_runtime.js does the same thing.

However, now the part I am stuck on is I fail with the error:

ValueError: Error when parsing target["target"]: Cannot recognize 'target'. Candidates are: cl-opt, opt-level, fast-math-contract, fast-math-nsz, fast-math-nnan, fast-math-arcp, fast-math, keys, device, tag, model, host, mcpu, num-cores, mattr, fast-math-ninf, mtriple, libs, mfloat-abi, fast-math-reassoc, from_device, mabi. Target creation from string failed: llvm -target=wasm32-unknown-unknown-wasm -system-lib

Basically it doesn’t seem like my target is valid. It is possible that the target definition for wasm has changed, but I haven’t found a more up-to-date tutorial.

Likely this is due to the fact of latest clang compiler rejecting enum outside range.

This is a valid error from the compiler.

The particular case we should fix this line by changing it back to int constant, and in places where they are used, compare with device_type_int instead.

Many thanks, the first level issue has been fixed, in #13967.

The 2nd level issue I have is doing the code-gen for WASM. It seems that the previous syntax of putting -system-lib in the target string is no longer valid.

I have ammended the target string in the old webgpu example to replace -target with -mtriple. However I’m not sure what the new syntax for --system-lib is.

What I’m working with right now is: llvm -mtriple=wasm32-unknown-unknown --system-lib

Which generates the error:

Error when parsing target["system-lib"]: Cannot recognize 'system-lib'. Candidates are: cl-opt, opt-level, fast-math-contract, fast-math-nsz, fast-math-nnan, fast-math-arcp, fast-math, keys, target_device_type, device, tag, model, num-cores, mcpu, host, mattr, fast-math-ninf, mtriple, libs, mfloat-abi, fast-math-reassoc, from_device, mabi. Target creation from string failed: llvm -mtriple=wasm32-unknown-unknown --system-lib

The last post I’ve found mentioning -system-lib is this unanswered question from 2021. I’m not entirely sure what the flag was meant to do, or how it is invoked in newer versions of TVM.

system-lib is an attribute of tvm.relay.backend.Runtime, not target.

System lib is a Module that is always around (its lifetime is the lifetime of the application that contains it). If you have some functions that you want to make available at runtime, you can follow certain steps to add them to the system lib (you have to link them statically into your app for that to work). Then your application can get the address of the system lib from the registry via “runtime.SystemLib”, and call these functions in the same way as it would any other function from a TVM module.

Thanks, I think that older versions of TVM had system-lib in the target, but not anymore. I have removed it for now.

I’ve put my current code for a spruced up based TVM-Web example here, along with a pretty well automated Dockerfile for setting everything up.

My JS know-how is currently slim-to-none, so the current issue I’m trying to solve is that the index.html file I am taking from the 2020 example is trying to use a library called tvmjs. This failure occurs when I try and run a Python web-server and load the page.

I believe the source of the error is that for newer versions of TVM, the generated JS files are different now. I’ve had to adapt my version of the index.html, so that tvmjs_runtime.js and tvmjs_runtime.wasi.js are imported, which I am assuming are the correct replacements for tvmjs.bundle.js. It seems neither of these files include a definition of tvmjs.

You can see the versions of those files I have generated at this gist.

Perhaps tvmjs_runtime.js is not a drop-in replacement for tvmjs.bundle.js, or the semantics have changed or something.

in case you are interested in some of the latest works along this line, checkout https://github.com/apache/tvm/pull/14131

1 Like