emscripten
emscripten copied to clipboard
Enabling openmp
Is there a way to enable/compile with openmp support ? For this task, I was thinking more specifically about execution in the nodejs environment and not the browser.
It seems that you can builde libiomp out of tree, but will it work ? https://openmp.llvm.org/README.txt
I have tried to build with the following flags, but no luck/love : source /usr/local/emsdk/emsdk_env.sh export EMSCRIPTEN=$EMSDK/upstream/emscripten emcmake cmake -DCMAKE_INSTALL_PREFIX:PATH=$EMSCRIPTEN/system -DCMAKE_DISABLE_FIND_PACKAGE_CUDA=TRUE ..
In ncnn project, we implement a minimal openmp runtime for webassembly target https://github.com/Tencent/ncnn/blob/master/src/simpleomp.cpp
It only works for
#pragma omp parallel for num_threads(N)
@nihui Impressive! How does this integrate with the OpenMP pragma? Currently, I'm guessing that __kmpc_fork_call() is the central component
@nihui are there any documents about how to use simpleomp in emscripten?
add simpleomp source to your project and compile with -fopenmp
Hi @nihui, I am trying to use simpleomp in my project with emscripten. But problem is that the simpleomp.cpp is dependent on platform.h but actually platform.h.in exists there instead of the platform.h. Can you please guide me about how to add the source of simpleomp correctly to my project?
hey @Smithangshu and others
I successfully used ncnn's simpleomp.cpp!
I had to copy some parts of code. see:
- https://github.com/bottle2/raytracing/blob/master/cpu.h
- https://github.com/bottle2/raytracing/blob/master/platform.h
I also created this header to solve more linker errors:
- https://github.com/bottle2/raytracing/blob/master/simpleomp.h
in my particular case, my application is written in C and I just have a Makefile (I don't know CMake). hence
https://github.com/bottle2/raytracing/blob/master/Makefile https://emscripten.org/docs/porting/pthreads.html
as seen in my Makefile, some caveats:
- flag
-pthreadmust be used to compile every single translation unit - when linking, specify e.g.
-sPTHREAD_POOL_SIZE=navigator.hardwareConcurrency, otherwise if you use OpenMP in the main thread, it will deadlock or something - I compile
simpleomp.cppseparately withemcc -DNCNN_SIMPLEOMP=1 -c simpleomp.cpp, which will generate an objectsimpleomp.o, which can then be linked in the final application.
that's it. works like a charm
Based on @bottle2's answer, I created this repo SimpleOMP that includes prebuilt static library and an usage example.
Wow, thats very cool. Thanks for working on that.
Is there anything we need to change on the emscripten side or can this issue be closed now?
I think the issue should remain open. Emscripten itself doesn't seem to impose any limitation itself, but:
- Emscripten should provide an OpenMP runtime itself, without requiring linking a third-party
- A more fully-featured runtime is highly desirable, some very basic features are missing
- e.g.
ifclause that enables/disables parallelism dynamically
- e.g.
- flag
-fopenmpshould imply-pthread
one way is to advance ncnn's implementation. however, as mentioned, the way to go would be to patch and use LLVM's existing runtime
I will make some personal effort in less than a year
I think the issue should remain open. Emscripten itself doesn't seem to impose any limitation itself, but:
- Emscripten should provide an OpenMP runtime itself, without requiring linking a third-party
Is this something that other compilers/toolchain do? In general I would prefer to keep stuff in third-party rather than comlicating emscripten itself, whenever this possible anyway.
A more fully-featured runtime is highly desirable, some very basic features are missing
- e.g.
ifclause that enables/disables parallelism dynamicallyflag
-fopenmpshould imply-pthread
Is -fopenmp an existing clang flag or something you are adding somehow>
one way is to advance
ncnn's implementation. however, as mentioned, the way to go would be to patch and use LLVM's existing runtime
Yes, anything you can upstream in LLVM would be great, and will then be in inherited by emscripten automatically.
I will make some personal effort in less than a year
Thanks! I'll leave this open then
I think the issue should remain open. Emscripten itself doesn't seem to impose any limitation itself, but:
- Emscripten should provide an OpenMP runtime itself, without requiring linking a third-party
Is this something that other compilers/toolchain do? In general I would prefer to keep stuff in third-party rather than comlicating emscripten itself, whenever this possible anyway.
yeah. GCC does, Clang does, and MSVC does. not only they provide the runtime, but because OpenMP is an extension to C, C++ and Fortran, compilers also perform code transformation to realize the parallelism. Emscripten transforms the code correctly when -fopenmp is passed. this transformed code calls certain functions, this is where the runtime comes into play
A more fully-featured runtime is highly desirable, some very basic features are missing
- e.g.
ifclause that enables/disables parallelism dynamicallyflag
-fopenmpshould imply-pthreadIs
-fopenmpan existing clang flag or something you are adding somehow>
yes. it is -fopenmp on GCC and Clang, and it is /openmp on MSVC. it is already present in Emscripten
yeah. GCC does, Clang does, and MSVC does. not only they provide the runtime, but because OpenMP is an extension to C, C++ and Fortran, compilers also perform code transformation to realize the parallelism. Emscripten transforms the code correctly when
-fopenmpis passed. this transformed code calls certain functions, this is where the runtime comes into play
I see, in that case yes we should provide the same support that clang and gcc do.
Also, my current solution doesn't work on all projects. In some projects I encountered this error
Fatal: memory.copy lowering should only be run on modules with no passive segments
during wasm-opt, and I have no idea why nor how to solve it.
Update:
Ah I see now, it's memcpy that is causing this. I either not use it or add the -mbulk-memory option.
Also I just added support for the if() clause to SimpleOMP, as that looks quite desirable to me. I might add more soon.