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...