This is personal note.
About installation of boost.numpy, I used this page*1 as reference.
0. Environment
1. Installation
sudo su - cd /opt/ wget https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.gz tar zxvf boost_1_67_0.tar.gz cd boost_1_67_0 ./bootstrap.sh --with-python-version=3.6 ./b2 --prefix=/opt/boost_1_67_0 install
For installation check
find / -name *boost_numpy*
2. Sample program
sample.cpp
#include "boost/python/numpy.hpp" #include <stdexcept> #include <algorithm> namespace p = boost::python; namespace np = boost::python::numpy; using namespace std; np::ndarray multiply_matrix(np::ndarray a, np::ndarray b, int size) { int nd = a.get_nd(); if (nd != 1) { throw std::runtime_error("a must be 1-dimensional"); } if (a.get_dtype() != np::dtype::get_builtin<double>()) { throw std::runtime_error("a must be float64 array"); } double *A = reinterpret_cast<double *>(a.get_data()); nd = b.get_nd(); if (nd != 1) { throw std::runtime_error("b must be 1-dimensional"); } if (b.get_dtype() != np::dtype::get_builtin<double>()) throw std::runtime_error("b must be float64 array"); double *B = reinterpret_cast<double *>(b.get_data()); vector<double> ma; for(int i = 0; i < size; i++) { for(int j = 0; j < size; j++) { double tmp = 0.0; for(int k = 0; k < size; k++) { tmp += A[i*size + k]*B[k*size + j]; } ma.push_back(tmp); } } Py_intptr_t shape[2] = {size, size}; np::ndarray result = np::zeros(2, shape, np::dtype::get_builtin<double>()); std::copy(ma.begin(), ma.end(), reinterpret_cast<double*>(result.get_data())); return result; } BOOST_PYTHON_MODULE(libsample) { Py_Initialize(); np::initialize(); p::def("multiply_matrix", multiply_matrix); }
CMakeList.txt
project(sample) cmake_minimum_required(VERSION 3.0) set(BOOST_ROOT /opt/boost_1_67_0) ### C++11 add_compile_options(-std=c++11) ### pkgconfig (for pkg_check_modules) find_package(PkgConfig REQUIRED) ### Python includes pkg_check_modules(PYTHON3 python3 REQUIRED) include_directories(${PYTHON3_INCLUDE_DIRS}) ### Boost includes include_directories(${BOOST_ROOT}/include) link_directories(${BOOST_ROOT}/lib) ### Build add_library(sample SHARED sample.cpp) set_target_properties(sample PROPERTIES SUFFIX ".so") target_link_libraries(sample boost_numpy36 boost_python36)
sample.py
import numpy as np import libsample as s import random if __name__ == "__main__": a = np.zeros([5, 5]) b = np.zeros([5, 5]) for i in range(5): for j in range(5): a[i, j] = random.uniform(-10.0, 10.0) b[i, j] = random.uniform(-10.0, 10.0) print(np.matmul(a, b)) result = s.multiply_matrix(a.reshape([5*5]), b.reshape(5*5), 5) print(result)
Note that input must be 1-dimentilnal, but output is OK for multi-dementional
3. Operation
mkdir build cd build cmake .. make cd .. cp build/*.so ./ python3 sample.py
4. Afterword
Next step is debugging...