Compiling PYTHIA to WebAssembly
During the community bonding period, I’ll be compiling some physics simulation libraries using Emscripten, and running examples provided in their source code. I’ll be focusing on examples that need access to data files containing various physical parameters. This will be useful later on to test the CernVM-FS Emscripten backend I’ll be implementing.
I’ll be starting off with PYTHIA, which is a C++ library used for the simulation of high-energy physics events. You can download its source code from here. I used version 8.235.
This is the simplest part. From the PYTHIA source code directory, run
$ emconfigure ./configure
$ emmake make
and you’re done!
This will fill up the
tmp directory with
*.o files. But these aren’t your usual ELF files.
$ file tmp/Analysis.o
tmp/Analysis.o: LLVM IR bitcode
The Emscripten compiler produced LLVM IR bitcode files, and packaged them up into a
lib/libpythia8.a archive file.
Running an example
Let’s run example 3, which is
main03.cc in the
examples directory. This program expects to find a
main03.cmnd input command file in it’s current directory when run, and also the directory of data files at
<pythia-dir>/share/Pythia8/xmldoc in the same location.
So from the
examples directory, run
$ emmake make main03
em++ main03.cc -o main03 -I../include -O2 -pedantic -W -Wall -Wshadow -fPIC -L../lib -Wl,-rpath,../lib -lpythia8 -ldl
$ file main03
main03: LLVM IR bitcode
We generated LLVM IR bitcode again. To produce the final target for the browser, run
$ mv main03 main03.bc
$ em++ main03.bc -o main03.html -O2 \
-s WASM=1 \
--preload-file main03.cmnd \
--preload-file ../share/Pythia8/xmldoc@<pythia-dir>/share/Pythia8/xmldoc \
Let’s break this down
- We had to rename
em++won’t recognise what type of file it is.
-s WASM=1will produce WASM instead of asm.js, which is the default.
--preload-file main03.cmndwill load this file into memory when it is accessed by the C++ program, and it will appear to be stored in the root directory for the program (which is also its current directory when it starts executing).
--preload-file ../share/Pythia8/xmldoc@<pythia-dir>/share/Pythia8/xmldocis similar to the above, it loads the entire
xmldocdirectory, but instead of it appearing at the root it will appear at the path specified after the
@, which is where the program expects to find it.
-s TOTAL_MEMORY=50MBsets the highest memory limit for the program, which is an increase from the default. I got this value by starting with the size of
xmldocdirectory, and doing a bit of trial and error. It can probably be reduced further.
By default, Emscripten uses 64-bit doubles for all floating point values, which can cause different rounding errors in WASM code compared to native code. If this is an issue, you can pass
-s PRECISE_F32=1, which instructs Emscripten to use 32-bit floating point values wherever
float is used in C/C++ code.
The final output files will now be:
main03.data (the preloaded files).
To run this program on a browser, execute
$ emrun main03.html
The benefit of using
emrun instead of just opening
main03.html is that
emrun will serve all the output files through a local web server, which avoids some CORS issues related to serving them from the filesystem.
The program won’t show any output until it finishes executing, which could take several seconds, depending on your browser/computer.
I’ve also hosted the example here, if you want to see a demo right away.