-
Notifications
You must be signed in to change notification settings - Fork 0
Interfacing with Cpp
First, install cython
using conda (from within the project's virtual environment):
$ conda install cython
To build cython
extensions for a python project, we must add the extension to setup.py
and call
$ python setup.py build_ext --inplace # build cpp extension
This compiles and builds the cpp
code and returns a dynamic library that can be linked to from python
.
Most of the work is done in the .pyx
cython wrapper files.
To link a C++ library to python using cython, a wrapper .pyx
file is necessary.
The Cython wrapper is very similar to python, except objects can be statically typed using the cdef
command (as oppose to python's dynamically duck-typed at runtime).
See cython userguide for more details.
Import notes:
- The first two lines of a
.pyx
file are important and must specify the language and.cpp
source files. For example
# distutils: language = c++
# distutils: sources = cython/src/<name>.cpp
- The
setup.py
file includes the Cython extensions using thesetuptools.Extension
class. To get the dynamically linked libraries (.so
files) to be in the appropriate folder use a dot.
in the name. For example
extensions = [
Extension(name = "path.to.output.name", ... ), # Creates 'path/to/output/name.so'
... ]
The C++ code is stored in the cython
folder.
The header and source files are in cython/src
.
The unit tests are in cython/test
.
To build (stand-alone) C++ files/executables, we use CMake
.
Recall CMake
is a structured language that helps organize and generate Makefiles
.
Then by calling make
, the Makefiles
compile the code.
Because CMake
generates a lot of junk, the workflow is to build the project in a build
directory
$ cd [...]/cython
$ mkdir build
$ cd build
$ cmake .. # Setups up the Makefiles in the `build` directory
$ make # Compiles the code in the `build` directory
To clean up the project, just remove the build folder.
Adding new C++ sources, headers, and tests, requires modifying the appropriate CMakeLists.txt
files.
The unit tests are written using the CXX_TEST framework and are added to the CMakeLists
within the build directory (read up on CMake's FindCxxTest module for additional details). Don't forget to link the relevant libraries from the src
directory.
To run the tests, build the project and call make test
or use the command ctest
(both from the build folder).
I prefer to call ctest --verbose
from the build
folder.
Don't forget you can run tests individually via the cxx_test executables (compiled in the build\test
folder).
To debug Cpp code we must build our libraries in 'debug' mode.
$ cd [...]/cython
$ mkdir debug # folder to build in 'debug' mode.
$ cd debug
$ cmake -D CMAKE_BUILD_TYPE=Debug .. # Setups up the Makefiles in the `build` directory
$ make # Compiles the code in the `debug` directory
By selecting the CMAKE_BUILD_TYPE=Debug
, we build the cpp files with the g++ -g -O0
flags, which allow for debugging with gdb
.
To debug an executable file (e.g. a CXXTest my_tester
) call $ gdb test/my_tester
.
This will begin a gdb
session.
We connect python's numpy
with C++ eigen
we use Eigency
.
First install eigen
by downloading the most recent copy and using cmake
to install it to /usr/local/include/eigen3
.
Read the Install
guide in the archived tar file.
For convenience, add syslinks from eigen3
to include
$ cd /usr/local/include
$ sudo ln -sf eigen3/Eigen Eigen
For more documentation on how to use eigen
, read the docs link
and quickreference guide link
First install eigency
by cloning the repo and calling python setup.py install
(make sure cython
is installed). Then read the README.md.
Be aware that Eigen follows column-major format and Python/C++ follows row-major format, so transpose appropriately link.
The simplest solution is to make sure np.ndarray
are in column-major format using the np.asfortranarray
or np.array(..., order = 'F')
options.
Don't forget to import eigency
in the .pyx
file by calling from eigency.core cimport *
. The cimport is important.