Skip to content

Instantly share code, notes, and snippets.

@jjlin18
Created June 1, 2012 06:50
Show Gist options
  • Save jjlin18/2849675 to your computer and use it in GitHub Desktop.
Save jjlin18/2849675 to your computer and use it in GitHub Desktop.
sample code for get and return numpy in C++
// From http://stackoverflow.com/questions/9128519/reading-many-values-from-numpy-c-api
/*
Make
g++ -o matrix_multiply.o -c matrix_multiply.cpp -I{python include file for numpy/noprefix.h} -I{python include} -fPIC -O2 -Wno-deprecated -Wno-write-strings
g++ -o matrix_multiply.so -shared matrix_multiply.o -L{boost lib path} -lz -lm -ldl -lpthread -boost_python
Python code:
import numpy
import matrix_multiply
a = numpy.arange(1.0, 13.0,1.0)
b = a.reshape(3,4)
x = matrix_multiply.multiply( b, 4.0)
*/
#include <boost/python.hpp>
#include <exception>
#include <numpy/arrayobject.h>
using namespace boost::python;
struct WrongSizeError : public std::exception {
const char* what() const throw() { return "Unsupported array size."; }
};
struct WrongTypeError : public std::exception {
const char* what() const throw() { return "Unsupported array type."; }
};
// Boost::Python needs the translators
void translate_sz(const WrongSizeError& e)
{
PyErr_SetString(PyExc_RuntimeError, e.what());
}
void translate_ty(const WrongTypeError& e)
{
PyErr_SetString(PyExc_RuntimeError, e.what());
}
// multiply matrix of double (m) by f
object multiply(numeric::array m, double f)
{
PyObject* m_obj = PyArray_FROM_OTF(m.ptr(), NPY_DOUBLE, NPY_IN_ARRAY);
if (!m_obj)
throw WrongTypeError();
// to avoid memory leaks, let a Boost::Python object manage the array
object temp(handle<>(m_obj));
// check that m is a matrix of doubles
int k = PyArray_NDIM(m_obj);
if (k != 2)
throw WrongSizeError();
// get direct access to the array data
const double* data = static_cast<const double*>(PyArray_DATA(m_obj));
// make the output array, and get access to its data
PyObject* res = PyArray_SimpleNew(2, PyArray_DIMS(m_obj), NPY_DOUBLE);
double* res_data = static_cast<double*>(PyArray_DATA(res));
const unsigned size = PyArray_SIZE(m_obj); // number of elements in array
for (unsigned i = 0; i < size; ++i)
res_data[i] = f*data[i];
return object(handle<>(res)); // go back to using Boost::Python constructs
}
BOOST_PYTHON_MODULE(test)
{
// register exception translators
register_exception_translator<WrongSizeError>(&translate_sz);
register_exception_translator<WrongTypeError>(&translate_ty);
// tell Boost::Python under what name the array is known
numeric::array::set_module_and_type("numpy", "ndarray");
def("multiply", multiply);
// initialize the Numpy C API
import_array();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment