emscripten icon indicating copy to clipboard operation
emscripten copied to clipboard

Enabling openmp

Open flatmax opened this issue 4 years ago • 8 comments

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.

flatmax avatar Apr 14 '21 03:04 flatmax

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 ..

flatmax avatar Apr 14 '21 03:04 flatmax

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 avatar May 08 '21 09:05 nihui

@nihui Impressive! How does this integrate with the OpenMP pragma? Currently, I'm guessing that __kmpc_fork_call() is the central component

ted537 avatar Dec 01 '21 00:12 ted537

@nihui are there any documents about how to use simpleomp in emscripten?

nkbai avatar Mar 26 '22 05:03 nkbai

add simpleomp source to your project and compile with -fopenmp

nihui avatar Mar 26 '22 11:03 nihui

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?

Smithangshu avatar Jul 14 '23 11:07 Smithangshu

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 -pthread must 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.cpp separately with emcc -DNCNN_SIMPLEOMP=1 -c simpleomp.cpp, which will generate an object simpleomp.o, which can then be linked in the final application.

that's it. works like a charm

bottle2 avatar Jan 17 '25 20:01 bottle2

Based on @bottle2's answer, I created this repo SimpleOMP that includes prebuilt static library and an usage example.

MuTsunTsai avatar Nov 14 '25 03:11 MuTsunTsai

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?

sbc100 avatar Nov 14 '25 21:11 sbc100

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. if clause that enables/disables parallelism dynamically
  • flag -fopenmp should 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

bottle2 avatar Nov 15 '25 17:11 bottle2

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. if clause that enables/disables parallelism dynamically
  • flag -fopenmp should 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

sbc100 avatar Nov 15 '25 18:11 sbc100

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. if clause that enables/disables parallelism dynamically
  • flag -fopenmp should imply -pthread

Is -fopenmp an 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

bottle2 avatar Nov 15 '25 18:11 bottle2

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

I see, in that case yes we should provide the same support that clang and gcc do.

sbc100 avatar Nov 15 '25 18:11 sbc100

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.

MuTsunTsai avatar Nov 17 '25 05:11 MuTsunTsai

Also I just added support for the if() clause to SimpleOMP, as that looks quite desirable to me. I might add more soon.

MuTsunTsai avatar Nov 17 '25 10:11 MuTsunTsai