Using C++ with OpenMP in jupyter notebooks

Many people might know jupyter notebooks as an interactive, web-based environment for python programming, often in the context of data analysis. However, if the cling kernel is used, it becomes possible to interactively work with C/C++ code. The so-called kernel is the interpreter used for the evaluation of code cells and cling is an interactive C++ interpreter. This could look like this:

C++ in jupyter notebook

In the IkapP project funded by the Stifterverband and state of North Rhine-Westphalia, one goal is to remove entry barriers faced by students using HPC systems in lectures. One step towards this goal is the creation of a virtual lab environment for parallel programming that can also be used for interactive experiments with different parallelization approaches. Users can, e.g., interactively experience performance results of code changes on real HPC systems. There are many parallel programming models in use and of relevance for our lectures, but we wanted to start with OpenMP and MPI. However, cling does not support OpenMP out of the box.

At the time of this writing, the current version of xeus-cling is 0.8.1, which is not based on a recent version of clang. So in principle, OpenMP Version 3.1 should be supported, which means tasking will be available, but offloading will not be available. OpenMP “in action” in a jupyter notebook could look like this:

C++ with OpenMP in jupyter notebook

In order for such notebooks to work correctly, we had to fix a few things in the xeus-cling code, in particular to ensure correct output from multiple threads. The corresponding patches were created and submitted by Jonas Hahnfeld, a student worker in the IkapP project at RWTH. They have been accepted to mainline (#314, #315, #320, #332, #319, #316, #324, #325 (also submitted to xeus-python) and #329), but since our submission there has been no new release.

Compiling and Installing xeus-cling on CentOS 7.7

The production environment on RWTH’s HPC systems is CentOS 7.7. The build instructions were compiled by Jonas. In order to build xeus-clang for a jupyter environment, do for each of the following projects (in this order):

https://github.com/jarro2783/cxxopts, https://github.com/nlohmann/json, https://github.com/zeux/pugixml, https://github.com/xtensor-stack/xtl, https://github.com/zeromq/libzmq, https://github.com/zeromq/cppzmq, https://github.com/jupyter-xeus/xeus, https://github.com/jupyter-xeus/xeus-cling

$ git clone https://github.com/org/repo src
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/path/to/install/xeus-cling/ \
-DCMAKE_C_COMPILER=/path/to/install/xeus-cling/bin/clang \
-DCMAKE_CXX_COMPILER=/path/to/install/xeus-cling/bin/clang++ \  ../src
$ make -j32
$ make install

After that, activate the kernels via

for k in xcpp11 xcpp14 xcpp17; do
cp -r ../../../../xeus-cling/share/jupyter/kernels/$k /path/to/install/jupyter/share/jupyter/kernels/;
done

and add -fopenmp to each kernel.json to enable OpenMP. Finally, let cling find the runtime libraries by adding to jupyterhub_config.py:

c.Spawner.environment = {
  'LD_LIBRARY_PATH': '/path/to/install/xeus-cling/lib/',
}