bast / python-cffi-demo

Python CFFI demo: interfacing C++, Fortran, and Python.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build Status License

python-cffi-demo

Inspired by Armin Ronacher's "Beautiful Native Libraries".

Example

In this example we imagine we are on a desert island and wish to compute pi by throwing darts:

This example is implemented in 3 different languages (C++, Fortran, Python) and we demonstrate how to call this functionality across languages.

These 3 implementations are combined in an example Python package that we call pi. At the same time we demonstrate how to automatically test the interface and the 3 implementations.

Limitations

We do not discuss memory allocation strategies. For this have a look at this demo.

Lower-level learning goals

  • Approximate pi using the Monte Carlo method
  • Calling Fortran libraries from C(++)
  • Calling C(++) libraries from Fortran
  • Calling Fortran/C(++) libraries from Python using Python CFFI
  • Automatically testing Fortran/C(++) libraries on Linux and Mac OS X using pytest and Travis CI
  • Hiding CMake infrastructure behind a simple pip install

Higher-level learning goals

  • Automatically test dynamic Fortran/C(++) libraries
  • Write tests without recompiling the code
  • Speed up your Python code
  • Provide a Python API to your compiled library and leverage Python tools

Requirements

Installing Python dependencies

In this example using Virtual Environments but also Anaconda or Miniconda will do the job:

virtualenv venv
source venv/bin/activate
pip install -r requirements.txt

How to configure and build the compiled libraries

mkdir build
cd build
cmake ..
make

How to test this demo

PI_LIBRARY_DIR=build/lib PI_INCLUDE_DIR=island pytest -vv test.py

Installing with pip

This example comes with a full-fledged setup script which configures and builds the code under the hood and makes it possible to install the demo with pip:

virtualenv venv
source venv/bin/activate
pip install git+https://github.com/bast/python-cffi-demo.git
python -c 'import island; print(island.approximate_pi_c(100))'

C(++) calling Fortran and vice versa

$ cd build

$ ./bin/pi_cpp.x
pi computed by c = 3.141664
pi computed by fortran = 3.141636

$ ./bin/pi_fortran.x
pi computed by fortran =    3.1416358947753906
pi computed by c =    3.1416640000000000

Timing the libraries through a Python interface

Default is 2M points but feel free to experiment by increasing the number of points in test.py.

$ PI_LIBRARY_DIR=build/lib PI_INCLUDE_DIR=island python test.py

num points: 2000000
python  pi=3.14163 time spent: 1.749 sec
c       pi=3.14190 time spent: 0.041 sec
fortran pi=3.14225 time spent: 0.126 sec

How you can contribute

Feel free to improve the C++, Fortran, and Python codes.

If you know intuitive examples that we can use to demonstrate memory allocation strategies, please suggest these.

About

Python CFFI demo: interfacing C++, Fortran, and Python.

License:Mozilla Public License 2.0


Languages

Language:Python 51.2%Language:CMake 19.3%Language:Fortran 17.1%Language:C++ 8.8%Language:C 3.6%