Skip to content

A wrapper allowing Numpy arrays to be accessed in C++ as boost::multi_array objects

Notifications You must be signed in to change notification settings

mdboom/numpy-boost

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This code provides a very thin wrapper around Numpy arrays to make them accessible in C++ as boost::multi_array objects. Wherever possible, the data itself is not copied, even when the data is noncontiguous.

Advantages over using the raw Numpy/C API are:

  • Cleaner syntax without using macros, e.g. indexing, iterators
  • Automatic integration with Python reference counting, for easier memory management
  • Any C++ algorithm written to the boost::multi_array interface can easily be recompiled to work with Numpy arrays.

Known shortcomings:

  • Due to the design of boost::multi_array, the datatype and number of dimensions of the array is fixed at compile time (though this is often not an important limitation in practice).
  • Some features in Numpy arrays are not supported by boost::multi_array, and therefore require an implicit data copy on conversion. These include:
    • Values in non-native endianess
    • Object arrays and recarrays are not supported.

Note

This code is currently experimental and lacks adequate documentation and unit tests.

Prerequisites

  • Boost 1.34 or later
  • Numpy 1.1 or later
  • Python 2.3 or later

Compilation

The setup.py script included in the source tree is for testing and demonstration purposes only. You do not need to build or install it to start using this library.

The entirety of this project exists in a two header files include/numpy-boost.hpp, which handles the bridge between Numpy and boost::multi_array, and the optional include/numpy-boost-python.hpp which is helpful if you are wrapping your library with boost::python. These need to be on your C++ include path, as well as Numpy's headers. Since everything is implemented in header files, you do not need to link to any additional libraries.

If using distutils to build your Python extension module, this can be achieved with the following:

from distutils.core import setup, Extension

import numpy
try:
    numpy_include = numpy.get_include()
except AttributeError:
    numpy_include = numpy.get_numpy_include()

setup(name="my_project",
      version="0.1",
      description = "My project that uses numpy-boost",
      packages=['my_project'],
      ext_modules=[
              Extension('my_project.extension_module',
                ['src/my_project_source.cpp'],
                include_dirs=[PATH_TO_NUMPY_BOOST_HPP, numpy_include]
                )
      ]
      )

Beyond that, your extension module should do all of the things required of a Numpy-using extension module. See the Numpy documentation for more information.

Usage

To create a numpy_boost array based on an existing Numpy array:

PyArrayObject* numpy_array; // passed into function

...

numpy_boost<double, 3> array(numpy_array);

where the template arguments to numpy_boost are the data type and the number of dimensions.

To create a new empty numpy_boost array:

int dims[] = { 32, 64 };
numpy_boost<int, 2> array(dims);

To return a Numpy array back to the caller, use the py_ptr() method. Note this returns a borrowed reference:

PyObject* result = array.py_ptr();
Py_INCREF(result);
return result;

About

A wrapper allowing Numpy arrays to be accessed in C++ as boost::multi_array objects

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published