On the BioNano team at Autodesk Research, running molecular analysis in the cloud is something we already enable scientists to do with ease. Our Molecular Design Toolkit gives users access to this power in a web interface with a Python backend. But what if we wanted to scrap the network lag and run some analysis directly in the browser?
Molecular Design Toolkit calculating the orbitals of butene in an iPython notebook
With the Web Assembly browser preview recently landing in V8, I got curious about what it would take to use it to run some of these computations. Web Assembly is a new browser feature that runs a binary code format directly in the browser. It’s mainly being designed as a compilation target for C and C++ right now, which is the language of many of the open source chemical analysis tools we use. If an entire 3D Unity game can be compiled to run in the browser via web assembly, chemical analysis should be a piece of cake, right? This is my journey into the early days of web assembly.
In this article, we’re going to look at compiling a major C++ library into a format that can be built into a Web Assembly project, compiling that project itself to Web Assembly, and getting it all running in the browser. Here I’m using the OpenBabel library, which translates between various chemical data formats, but this should work just as well for most C++ libraries.
Assuming your computer is already set up to compile C++ programs (make sure you’ve got the Xcode command line tools installed if you’re on a Mac), the first thing you need to do is install Emscripten.
Emscripten is a Mozilla project that compiles C++ to asm.js or, more recently, Web Assembly. It basically works like a drop in replacement for tools like cmake, make, and g++. Follow the Emscripten installation instructions in webassembly.org’s developer guide for how to get set up.
See if you can get the provided Hello World example running as a test. You’ll need to make sure your browser supports Web Assembly, which you can do by enabling the WebAssembly flag in the latest version of Chrome Canary. Be sure to try including the -s WASM=1 flag which will compile to web assembly instead of asm.js.
At the time I tried this, it seemed there was a bug with binaryen on the Mac. If you run into this, check the issue in Github and keep in mind you might have to install binaryen yourself, which ended up being the solution in my case.
OpenBabel provides a nice set of instructions for compiling their project on your own, however, in order to use OpenBabel with an Emscripten project, we’ll need to compile it specially to LLVM bitcode. The steps we take will be very similar to those given in the instructions, but we’re going to use emcmake with cmake, and emmake with make, following Emscripten’s instructions on compiling with libraries.
Download the latest OpenBabel release from Github into your working directory, and then:
tar zxf openbabel-2.4.0.tar.gz
emcmake cmake ../openbabel-2.4.0 -DCMAKE_INSTALL_PREFIX=/my/openbabel/install/path -DENABLE_TESTS=OFF
emmake make install
Now that you have OpenBabel in LLVM bitcode, you can use it to build your C++ project that uses OpenBabel into Web Assembly with Emscripten. You might want to try one of the simple examples from OpenBabel’s C++ examples page copied locally into a .cpp file.
To compile, just use em++ instead of g++, and make sure to link your OpenBabel bitcode using the path that you passed to -DCMAKE_INSTALL_PREFIX when you compiled OpenBabel:
em++ -I/my/openbabel/install/path/include/openbabel-2.0 -L/my/openbabel/install/path/lib -lopenbabel myproject.cpp -s WASM=1 -o myproject.html
That should emit several myproject.* files, that when accessed through a web server, should run your project. Start up a server such as python -m SimpleHTTPServer 8080, and then open localhost:8080/myproject.html in your Web Assembly enabled browser. You will see a nice interface generated by Emscripten that should show you the output of your program.
Emscripten’s generated HTML page running a Web Assembly program
If you’re having trouble, you might want to try compiling your code with g++ as well as em++ in order to make sure your program works as a normal native binary. In addition to swapping the em++ command for g++ and dropping any Emscripten-specific flags, you’ll also have to point to a natively compiled version of OpenBabel. The -L and -I flags that point to the LLVM bitcode version of OpenBabel won’t work with g++. If you’re on a Mac, you can easily install a precompiled version of OpenBabel with homebrew. Once that’s installed, you can use pkg-config to tell you exactly what your new -L and -I flags should be: pkg-config –libs –cflags /usr/local/Cellar/open-babel/2.4.1/lib/pkgconfig/openbabel-2.0.pc
If you are diving deeper into writing a fully featured program with OpenBabel and Emscripten, take a look at this blog post from someone who successfully built OpenBabel to asm.js a few years back, which was incredibly valuable for me in writing this article.
With Web Assembly now in the bleeding edge of most major browsers, the pieces of this new web are mostly in place. What’s left is for developers to take advantage of it and come up with all the new and unexpected applications that are now possible.
Malte Tinnus is a Senior Principal UX Designer at Autodesk Life Sciences, collaborating with world leading researchers to envision the paradigms and tools needed to understand and exploit the intersection of design and life.