In [ ]:
%%file demo.cpp
#include <numeric> // Standard library import for std::accumulate
#include <xtensor/xmath.hpp> // xtensor import for the C++ universal functions
template <class E>
double sum_of_sines(E m)
{
auto sines = xt::sin(m);
// return xt::sum(sines)();
return std::accumulate(sines.begin(), sines.end(), 0.0);
}
In [ ]:
>xcpp14
#include <iostream>
#include "demo.cpp"
std::cout << "HELLO C++ 14! " << sum_of_sines(xt::arange<double>(10000.0));
We can expose the sum_of_sines
to Python with pybind11
and xtensor-python
.
#ifdef XPYTHON
#include "pybind11/pybind11.h" // Pybind11 import to define Python bindings
#define FORCE_IMPORT_ARRAY
#include "xtensor-python/pyarray.hpp" // Numpy bindings
PYBIND11_MODULE(xpython, m)
{
xt::import_numpy();
m.doc() = "Test module for xtensor python bindings";
m.def("sum_of_sines", sum_of_sines<xt::pyarray<double, xt::layout_type::row_major>>,
"Sum the sines of the input values");
}
#endif
In [ ]:
%%bash
rm -f xpython.cpp
cp demo.cpp xpython.cpp
cat << EOF >> xpython.cpp
#include "pybind11/pybind11.h" // Pybind11 import to define Python bindings
#define FORCE_IMPORT_ARRAY
#include "xtensor-python/pyarray.hpp" // Numpy bindings
PYBIND11_MODULE(xpython, m)
{
xt::import_numpy();
m.doc() = "Test module for xtensor python bindings";
m.def("sum_of_sines", sum_of_sines<xt::pyarray<double, xt::layout_type::row_major>>,
"Sum the sines of the input values");
}
EOF
In [ ]:
%%bash
export PYTHON_INCLUDES=`python3-config --includes`
export NUMPY_INCLUDES=`python -c "import numpy; print(numpy.get_include())"`
$CXX -w -shared -fPIC \
-I${CONDA_PREFIX}/include \
-L${CONDA_PREFIX}/lib/ \
-I${NUMPY_INCLUDES} \
${PYTHON_INCLUDES} \
xpython.cpp -o xpython.so
In [ ]:
>python3
import numpy as np
from xpython import sum_of_sines
x = np.arange(10000.0)
print("NumPy : ", np.sum(np.sin(x)))
print("xtensor: ", sum_of_sines(x))
In [ ]:
%%bash
rm -f xr.cpp
cp demo.cpp xr.cpp
cat << EOF >> xr.cpp
#include <xtensor-r/rarray.hpp> // R bindings
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins(cpp14)]]
// [[Rcpp::export]]
double rsum_of_sines(const xt::rarray<double>& e) {
return sum_of_sines(e);
}
EOF
In [ ]:
>ir
conda_prefix <- Sys.getenv("CONDA_PREFIX")
Sys.setenv(PKG_CXXFLAGS=paste("-I", conda_prefix, "/include/", sep=""))
Rcpp::sourceCpp("xr.cpp");
arr <- seq(0., 10000.0 - 1.0, 1.0)
rsum_of_sines(arr)