Compile mcx/mcxlab on Debian Buster for Octave
Introduction
I would like to thank Dr. Fang for making his software [mcx/mcxlab] (http://mcx.space/) publicly available.
As a Debian user, I had to compile mcxlab from source myself. It took some time to make the necessary adjustments. So in the following I describe what I had to change to save some time for one or the other user.
I myself use Debian Buster and do not have a Matlab license, but use Octave, instead.
With Debian Buster, the CUDA libraries are located elsewhere in the system than in the current Makefile assumed. The Debian Buster repositories also contain a more recent version of the cuda tools (currently 9.2) than the nightly builds of mcx/mcxlab (7.5), which makes it necessary to build it on my system from source.
To run mcxlab with Octave under Debian Buster, the file mcx/src/Makefile must be modified. Also the file mcx/src/mcxlab.cpp has to be changed, because Octave does not accept int or size_t as dimension array. Instead mwSize should be used.
The following steps were necessary to compile mcxlab:
Compile mcxlab from source
I assume that you installed some requirements on your system, so that cuda is available, like the nvidia-driver and in addition:
sudo apt-get install nvidia-cuda-toolkit nvidia-profiler nvidia-opencl-dev
Get the most recent source code from github
git clone --recurse-submodules https://github.com/fangq/mcx.git
Modify the Makefile in mcx/src
Modify the paths of the include files and libraries to fit with Debian paths:
For those who are not “fluent” in reading the output of the program diff: the lines starting with < are replaced with the lines starting with >
diff /tmp/mcx-original/mcx/src/Makefile /tmp/mcx-modified/mcx/src/Makefile
4a5,6
> # 2019/12/17
> # modified to compile mcxlab on Debian Buster with Octave
30c32
< INCLUDEDIRS=-I/usr/local/cuda/include
—
> INCLUDEDIRS=-I/usr/include -I/usr/include/octave-4.4.1/octave
39c41
< LINKOPT=-L/usr/local/lib ‘OcelotConfig -l’ -ltinfo
—
> LINKOPT=-L/usr/lib/x86_64-linux-gnu ‘OcelotConfig -l’ -ltinfo
47c49
< LINKOPT=-L/usr/local/cuda/lib -lm $(CUDART)
—
> LINKOPT=-L/usr/lib/x86_64-linux-gnu -lm $(CUDART)
50c52
< LINKOPT=-L/usr/local/cuda/lib -lm $(CUDART)
—
> LINKOPT=-L/usr/lib/x86_64-linux-gnu -lm $(CUDART)
92c94
< ifeq $(wildcard /usr/local/cuda/lib64) /usr/local/cuda/lib64
—
> ifeq $(wildcard /usr/lib/x86_64-linux-gnu) /usr/lib/x86_64-linux-gnu
94c96
< LINKOPT=-L/usr/local/cuda/lib64 $(CUDART) -lm -lstdc++
—
> LINKOPT=-L/usr/lib/x86_64-linux-gnu $(CUDART) -lm -lstdc++
96c98
< LINKOPT=-L/usr/local/cuda/lib64 $(CUDART) -lm -static-libgcc -static-libstdc++
—
> LINKOPT=-L/usr/lib/x86_64-linux-gnu $(CUDART) -lm -static-libgcc -static-libstdc++
Change into the directory mcx and call “make oct”.
You will get a lot of errors like this one:
error: cannot convert ‘dimtype*’
To solve these errors you have to edit the file mcx/src/mcxlab.cpp:
Replace the following lines (lines 74–78):
#if (! defined MX_API_VER) || (MX_API_VER < 0x07300000)
typedef int dimtype; /*< MATLAB before 2017 uses int as the dimension array /
#else
typedef size_t dimtype; /< MATLAB after 2017 uses size_t as the dimension array */
#endif
with this line:
typedef mwSize dimtype; /**< Using mwSize in your code allows you to re-use the code on all platforms */
Now “make oct” should compile successfully. The newly compiled mcx.mex will reside in mcx/mcxlab. You can add this directory to your octave path.
Unfortunately, I never really learned how to program. For this reason I can’t make the changes in mcxlab.cpp generically, so that in the future the different Matlab versions as well as Octave will be supported. I also can’t change the Makefile so that it decides by itself which paths should be used to find the cuda libraries and octave include files.
I’m sure, however, that this implementation shouldn’t be too much trouble for thoses with a CS background.
Good luck with the Monte Carlo simulations.