From 50a43b8d848995da73795d93976834898a368735 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Thu, 3 Jun 2021 12:51:19 +0200 Subject: [PATCH 1/2] Adding possibility to 'cast' or copy to `xt::xarray` etc --- .azure-pipelines/unix-build.yml | 8 +++++++ docs/source/examples/copy_cast/example.py | 7 ++++++ docs/source/examples/copy_cast/main.cpp | 23 ++++++++++++++++++ .../xtensor_type_caster_base.hpp | 24 +++++++++++++++---- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 docs/source/examples/copy_cast/example.py create mode 100644 docs/source/examples/copy_cast/main.cpp diff --git a/.azure-pipelines/unix-build.yml b/.azure-pipelines/unix-build.yml index d01651c..0008e13 100644 --- a/.azure-pipelines/unix-build.yml +++ b/.azure-pipelines/unix-build.yml @@ -42,6 +42,14 @@ steps: displayName: Example - readme 1 workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/readme_example_1 + - script: | + source activate xtensor-python + cmake . -DPYTHON_EXECUTABLE=`which python` + cmake --build . + python example.py + displayName: Example - Copy 'cast' + workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/copy_cast + - script: | source activate xtensor-python cmake . -DPYTHON_EXECUTABLE=`which python` diff --git a/docs/source/examples/copy_cast/example.py b/docs/source/examples/copy_cast/example.py new file mode 100644 index 0000000..5accee9 --- /dev/null +++ b/docs/source/examples/copy_cast/example.py @@ -0,0 +1,7 @@ +import mymodule +import numpy as np + +a = np.array([1, 2, 3]) +assert np.isclose(np.sum(np.sin(a)), mymodule.sum_of_sines(a)) +assert np.isclose(np.sum(np.cos(a)), mymodule.sum_of_cosines(a)) + diff --git a/docs/source/examples/copy_cast/main.cpp b/docs/source/examples/copy_cast/main.cpp new file mode 100644 index 0000000..9045465 --- /dev/null +++ b/docs/source/examples/copy_cast/main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#define FORCE_IMPORT_ARRAY +#include + +double sum_of_sines(xt::pyarray& m) +{ + auto xt::sum(xt::sin(m))(); +} + +double sum_of_cosines(const xt::xtensor& m) +{ + auto xt::sum(xt::cos(m))(); +} + +PYBIND11_MODULE(mymodule, m) +{ + xt::import_numpy(); + m.doc() = "Test module for xtensor python bindings"; + m.def("sum_of_sines", sum_of_sines, "Sum the sines of the input values"); + m.def("sum_of_cosines", sum_of_cosines, "Sum the cosines of the input values"); +} diff --git a/include/xtensor-python/xtensor_type_caster_base.hpp b/include/xtensor-python/xtensor_type_caster_base.hpp index 3c8a015..f5d49ec 100644 --- a/include/xtensor-python/xtensor_type_caster_base.hpp +++ b/include/xtensor-python/xtensor_type_caster_base.hpp @@ -74,10 +74,6 @@ namespace pybind11 template struct xtensor_type_caster_base { - bool load(handle /*src*/, bool) - { - return false; - } private: @@ -106,6 +102,26 @@ namespace pybind11 public: + bool load(handle src, bool convert) + { + using T = typename Type::value_type; + + if (!convert && !array_t::check_(src)) { + return false; + } + + auto buf = array_t::ensure(src); + + if (!buf) { + return false; + } + + type_caster::value = Type::from_shape(buf.shape()); + std::copy(buf.data(), buf.data() + buf.size(), type_caster::value.begin()); + + return true; + } + // Normal returned non-reference, non-const value: static handle cast(Type&& src, return_value_policy /* policy */, handle parent) { From 7962c61c60047907cc2e68bacf6ff1ccbb1b8449 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Thu, 3 Jun 2021 17:18:04 +0200 Subject: [PATCH 2/2] Fixing example --- docs/source/examples/copy_cast/CMakeLists.txt | 13 +++++++++++++ docs/source/examples/copy_cast/main.cpp | 8 +++++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 docs/source/examples/copy_cast/CMakeLists.txt diff --git a/docs/source/examples/copy_cast/CMakeLists.txt b/docs/source/examples/copy_cast/CMakeLists.txt new file mode 100644 index 0000000..e17611c --- /dev/null +++ b/docs/source/examples/copy_cast/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.1..3.19) + +project(mymodule) + +find_package(pybind11 CONFIG REQUIRED) +find_package(xtensor REQUIRED) +find_package(xtensor-python REQUIRED) +find_package(Python REQUIRED COMPONENTS NumPy) + +pybind11_add_module(mymodule main.cpp) +target_link_libraries(mymodule PUBLIC pybind11::module xtensor-python Python::NumPy) + +target_compile_definitions(mymodule PRIVATE VERSION_INFO=0.1.0) diff --git a/docs/source/examples/copy_cast/main.cpp b/docs/source/examples/copy_cast/main.cpp index 9045465..cb3e65c 100644 --- a/docs/source/examples/copy_cast/main.cpp +++ b/docs/source/examples/copy_cast/main.cpp @@ -6,12 +6,14 @@ double sum_of_sines(xt::pyarray& m) { - auto xt::sum(xt::sin(m))(); + auto sines = xt::sin(m); // sines does not actually hold values. + return std::accumulate(sines.begin(), sines.end(), 0.0); } -double sum_of_cosines(const xt::xtensor& m) +double sum_of_cosines(const xt::xarray& m) { - auto xt::sum(xt::cos(m))(); + auto cosines = xt::cos(m); // cosines does not actually hold values. + return std::accumulate(cosines.begin(), cosines.end(), 0.0); } PYBIND11_MODULE(mymodule, m)