This is an archive of the discontinued LLVM Phabricator instance.

[OpenMP] Support for wasm32 architecture
Needs ReviewPublic

Authored by arsnyder16 on Jan 25 2023, 5:59 PM.

Details

Summary

These are changes i made to build a static library of libomp to run on wasm32

using the emscripten tool chain

export CFLAGS="-pthread"
export CXXFLAGS="-pthread"
emcmake cmake \
  -DOPENMP_STANDALONE_BUILD=ON \
  -DOPENMP_ENABLE_OMPT_TOOLS=OFF \
  -DOPENMP_ENABLE_LIBOMPTARGET=OFF \
  -DLIBOMP_HAVE_OMPT_SUPPORT=OFF \
  -DLIBOMP_OMPT_SUPPORT=OFF \
  -DLIBOMP_OMPD_SUPPORT=OFF \
  -DLIBOMP_USE_DEBUGGER=OFF \
  -DLIBOMP_FORTRAN_MODULES=OFF \
  -DLIBOMP_ENABLE_SHARED=OFF \
  -DLIBOMP_ARCH=wasm32 \
  -DOPENMP_ENABLE_LIBOMPTARGET_PROFILING=OFF \
  .

emmake make -j

downstream libaries need to compile with
-pthread -fopenmp=libomp`
then link to libomp.a that was built above

Diff Detail

Event Timeline

arsnyder16 created this revision.Jan 25 2023, 5:59 PM
arsnyder16 requested review of this revision.Jan 25 2023, 5:59 PM
arsnyder16 edited the summary of this revision. (Show Details)Jan 25 2023, 6:03 PM
arsnyder16 edited the summary of this revision. (Show Details)
tianshilei1992 retitled this revision from Support for wasm32 architecture to [OpenMP] Support for wasm32 architecture.Jan 25 2023, 6:04 PM
miwelc added a subscriber: miwelc.Jan 25 2023, 6:19 PM
penzn added a comment.Jan 25 2023, 7:12 PM

This was first shared as a patch here: https://github.com/llvm/llvm-project/issues/52714

For those who were added as reviewers, but were not part of the prior conversation, the patch wasn't presented as "it already works", though it should compile.

This was first shared as a patch here: https://github.com/llvm/llvm-project/issues/52714

For those who were added as reviewers, but were not part of the prior conversation, the patch wasn't presented as "it already works", though it should compile.

This does work for my application, we don’t fully exhaust all of the omp feature so I doubt its a full solution, but does support the basics.

-U999999 patch

arsnyder16 edited the summary of this revision. (Show Details)Jan 26 2023, 5:20 AM
arsnyder16 edited the summary of this revision. (Show Details)

update patch for main

penzn added inline comments.Jan 27 2023, 6:05 PM
openmp/runtime/src/kmp_os.h
1289–1290

Emscripten has dlopen and dlsym emulation under a flag, though other ways to use Clang won't provide that.

openmp/runtime/src/kmp_platform.h
42

Maybe it should be __wasm32__ instead of __EMSCRIPTEN__, so that it is possible to build with non-Emscripten Clang (WASI-SDK, or even bare).

openmp/runtime/src/z_Linux_util.cpp
2450

Do you have to add those definitions because of how Wasm handles varargs?

arsnyder16 added inline comments.Feb 1 2023, 5:35 AM
openmp/runtime/src/kmp_os.h
1289–1290

Emulation is only supported if you are also compiling with dynamic linking, which isn't always the case. I am not sure how critical these code paths are to keep.

https://github.com/emscripten-core/emscripten/blob/33a9cf1bceaaf52229285b6e77bf7f5747b18dba/src/library_dylink.js#L9

openmp/runtime/src/kmp_platform.h
42

Possibly, but the Emscripten tool chain is the one supplying LINUX/POSIX (via musl). Using just the clang compiler or other tool chains does not guarantee it will mimic a POSIX compatible system.

Another option that could be explored is getting this working without setting KMP_OS_LINUX at all. My guess would the main sticking point the code expecting to use pthreads if KMP_OS_LINUX is defined. I didn't actually try that i was looking for the path of least resistance, To make an official patch it might make sense to explore this further.

openmp/runtime/src/z_Linux_util.cpp
2450

Yea so this was the main runtime problem i encountered. I am little blurry on the exact details at it was about a year ago that i got this working.

For starters function pointer can be problematic with emscripten https://emscripten.org/docs/porting/guidelines/function_pointer_issues.html

What i do recall is that when the address of the function was looked up in the function table it was always the same signature, so my assumption would be similar to yours its related to using a function pointer to function using varargs.

We do have vargs in other areas of the the code base using libomp and i have yet to see any problem with those function. So it must be a combination of the function pointer and vargs.

Another interesting thing is that even recently i had to add even more microtasks signatures with more arguments (20-25). I wonder if the binaryen optimizer is adjusting call signatures in ways that causes these extra overloads. When I hit that problem it worked fine when using a debug build which would not have run through the optimizer.

As a side, i find it interesting that the limit is 15 arguments. Is that a documented restriction or are there other things at a play that should never allow it beyond 15?

Is it feasible to test it somehow? I doubt the regular way to invoke tests can work with WASM.

Is it feasible to test it somehow? I doubt the regular way to invoke tests can work with WASM.

Yes, the compiled wasm can be run through node. In our product we use gtest and we only ship our wasm in the browser so we build the gtest projects using emrun so we test within a headless chrome browser.

I think node would make sense here. Which tests specifically would you like to get working? runtime/test? Can you point me to any docs or examples of running the tests. As i get time i can poke at working through that.

Is it feasible to test it somehow? I doubt the regular way to invoke tests can work with WASM.

Yes, the compiled wasm can be run through node. In our product we use gtest and we only ship our wasm in the browser so we build the gtest projects using emrun so we test within a headless chrome browser.

I think node would make sense here. Which tests specifically would you like to get working? runtime/test? Can you point me to any docs or examples of running the tests. As i get time i can poke at working through that.

The whole LLVM project depends on LIT test (https://llvm.org/docs/CommandGuide/lit.html). The LIT configuration for libomp is in openmp/runtime/test/lit.cfg and openmp/runtime/test/lit.site.cfg.in.

I think for the testing infrastructure, you might need CMake to check the existence of node (silently), and then replace those RUN lines accordingly (by those LIT configuration).