| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1c2f638 commit 1e6d3ac
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,6 +17,7 @@ Example 1: Use an algorithm of the C++ library on a numpy array inplace | |||
| 17 | 17 | #include <numeric> // Standard library import for std::accumulate | |
| 18 | 18 | #include "pybind11/pybind11.h" // Pybind11 import to define Python bindings | |
| 19 | 19 | #include "xtensor/xmath.hpp" // xtensor import for the C++ universal functions | |
| 20 | + #define FORCE_IMPORT_ARRAY // numpy C api loading | ||
| 20 | 21 | #include "xtensor-python/pyarray.hpp" // Numpy bindings | |
| 21 | 22 | ||
| 22 | 23 | double sum_of_sines(xt::pyarray<double> &m) | |
@@ -28,6 +29,7 @@ Example 1: Use an algorithm of the C++ library on a numpy array inplace | |||
| 28 | 29 | ||
| 29 | 30 | PYBIND11_PLUGIN(xtensor_python_test) | |
| 30 | 31 | { | |
| 32 | + import_array() //this is actually a macro | ||
| 31 | 33 | pybind11::module m("xtensor_python_test", "Test module for xtensor python bindings"); | |
| 32 | 34 | ||
| 33 | 35 | m.def("sum_of_sines", sum_of_sines, | |
@@ -64,6 +66,7 @@ Example 2: Create a universal function from a C++ scalar function | |||
| 64 | 66 | .. code:: | |
| 65 | 67 | ||
| 66 | 68 | #include "pybind11/pybind11.h" | |
| 69 | + #define FORCE_IMPORT_ARRAY | ||
| 67 | 70 | #include "xtensor-python/pyvectorize.hpp" | |
| 68 | 71 | #include <numeric> | |
| 69 | 72 | #include <cmath> | |
@@ -77,6 +80,7 @@ Example 2: Create a universal function from a C++ scalar function | |||
| 77 | 80 | ||
| 78 | 81 | PYBIND11_PLUGIN(xtensor_python_test) | |
| 79 | 82 | { | |
| 83 | + import_array() | ||
| 80 | 84 | py::module m("xtensor_python_test", "Test module for xtensor python bindings"); | |
| 81 | 85 | ||
| 82 | 86 | m.def("vectorized_func", xt::pyvectorize(scalar_func), ""); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -61,6 +61,7 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f | |||
| 61 | 61 | ||
| 62 | 62 | basic_usage | |
| 63 | 63 | array_tensor | |
| 64 | + numpy_capi | ||
| 64 | 65 | cookie_cutter | |
| 65 | 66 | ||
| 66 | 67 | .. toctree:: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,62 @@ | |||
| 1 | + .. Copyright (c) 2016, Johan Mabille and Sylvain Corlay | ||
| 2 | + | ||
| 3 | + Distributed under the terms of the BSD 3-Clause License. | ||
| 4 | + | ||
| 5 | + The full license is in the file LICENSE, distributed with this software. | ||
| 6 | + | ||
| 7 | + Importing numpy C API | ||
| 8 | + ===================== | ||
| 9 | + | ||
| 10 | + Importing the C API module of numpy requires more code than just including a header. ``xtensor-python`` simplifies a lot | ||
| 11 | + this import, however some actions are still required in the user code. | ||
| 12 | + | ||
| 13 | + Extension module with a single file | ||
| 14 | + ----------------------------------- | ||
| 15 | + | ||
| 16 | + When writing an extension module that is self-contained in a single file, its author should pay attention to the following | ||
| 17 | + points: | ||
| 18 | + | ||
| 19 | + - ``FORCE_IMPORT_ARRAY`` must be defined before including any header of ``xtensor-python``. | ||
| 20 | + - ``import_array()`` must be called in the function initializing the module. | ||
| 21 | + | ||
| 22 | + Thus the basic skeleton of the module looks like: | ||
| 23 | + | ||
| 24 | + .. code:: | ||
| 25 | + | ||
| 26 | + #include "pybind11/pybind11.h" | ||
| 27 | + #define FORCE_IMPORT_ARRAY | ||
| 28 | + #include "xgtensor-python/pyarray.hpp" | ||
| 29 | + | ||
| 30 | + PYBIND11_PLUGIN(plugin_name) | ||
| 31 | + { | ||
| 32 | + import_array() | ||
| 33 | + pybind11::module m(//... | ||
| 34 | + //... | ||
| 35 | + return m.ptr(); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + Extension module with multiple files | ||
| 40 | + ------------------------------------ | ||
| 41 | + | ||
| 42 | + If the extension module contain many source files that include ``xtensor-python`` header files, the previous points are still | ||
| 43 | + required. However, the source files that don't contain the initializing code of the module can directly include ``xtensor-python`` | ||
| 44 | + header files. | ||
| 45 | + | ||
| 46 | + | ||
| 47 | + Using other extension modules | ||
| 48 | + ----------------------------- | ||
| 49 | + | ||
| 50 | + Including an header of ``xtensor-python`` actually defines ``PY_ARRAY_UNIQUE_SYMBOL`` to ``xtensor_python_ARRAY_API``. This might | ||
| 51 | + be problematic if you import another library that defines its own ``PY_ARRAY_UNIQUE_SYMBOL``, or if you define yours. If so, | ||
| 52 | + you can override the behavior of ``xtensor-python`` by explicitly defining ``PY_ARRAY_UNIQUE_SYMBOL`` prior to including any | ||
| 53 | + ``stenxor-python`` header: | ||
| 54 | + | ||
| 55 | + .. code:: | ||
| 56 | + | ||
| 57 | + // in every source file | ||
| 58 | + #define PY_ARRAY_UNIQUE_SYMBOL my_uniqe_array_api | ||
| 59 | + #include "xtensor-python/pyarray.hpp" | ||
| 60 | + | ||
| 61 | + | ||
| 62 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,38 +17,23 @@ | |||
| 17 | 17 | #include "pybind11/common.h" | |
| 18 | 18 | #include "pybind11/complex.h" | |
| 19 | 19 | ||
| 20 | + #ifndef FORCE_IMPORT_ARRAY | ||
| 21 | + #define NO_IMPORT_ARRAY | ||
| 22 | + #endif | ||
| 23 | + #ifndef PY_ARRAY_UNIQUE_SYMBOL | ||
| 24 | + #define PY_ARRAY_UNIQUE_SYMBOL xtensor_python_ARRAY_API | ||
| 25 | + #endif | ||
| 20 | 26 | #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION | |
| 21 | 27 | #include "numpy/arrayobject.h" | |
| 22 | 28 | ||
| 23 | 29 | #include "xtensor/xcontainer.hpp" | |
| 24 | 30 | ||
| 25 | 31 | namespace xt | |
| 26 | 32 | { | |
| 27 | - static bool is_numpy_imported = false; | ||
| 28 | - | ||
| 29 | - class numpy_import | ||
| 30 | - { | ||
| 31 | - protected: | ||
| 32 | - | ||
| 33 | - inline numpy_import() | ||
| 34 | - { | ||
| 35 | - if (!is_numpy_imported) | ||
| 36 | - { | ||
| 37 | - _import_array(); | ||
| 38 | - is_numpy_imported = true; | ||
| 39 | - } | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | - numpy_import(const numpy_import&) = default; | ||
| 43 | - numpy_import(numpy_import&&) = default; | ||
| 44 | - numpy_import& operator=(const numpy_import&) = default; | ||
| 45 | - numpy_import& operator=(numpy_import&&) = default; | ||
| 46 | - }; | ||
| 47 | 33 | ||
| 48 | 34 | template <class D> | |
| 49 | 35 | class pycontainer : public pybind11::object, | |
| 50 | - public xcontainer<D>, | ||
| 51 | - private numpy_import | ||
| 36 | + public xcontainer<D> | ||
| 52 | 37 | { | |
| 53 | 38 | public: | |
| 54 | 39 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,12 +8,19 @@ | |||
| 8 | 8 | ||
| 9 | 9 | #include <Python.h> | |
| 10 | 10 | ||
| 11 | + #include "pybind11/numpy.h" | ||
| 12 | + | ||
| 13 | + #define FORCE_IMPORT_ARRAY | ||
| 14 | + #include "xtensor-python/pyarray.hpp" | ||
| 15 | + | ||
| 11 | 16 | #include "gtest/gtest.h" | |
| 17 | + #include <iostream> | ||
| 12 | 18 | ||
| 13 | 19 | int main(int argc, char* argv[]) | |
| 14 | 20 | { | |
| 15 | 21 | // Initialize all the things (google-test and Python interpreter) | |
| 16 | 22 | Py_Initialize(); | |
| 23 | + import_array() | ||
| 17 | 24 | ::testing::InitGoogleTest(&argc, argv); | |
| 18 | 25 | ||
| 19 | 26 | // Run test suite | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,9 +7,7 @@ | |||
| 7 | 7 | ****************************************************************************/ | |
| 8 | 8 | ||
| 9 | 9 | #include "gtest/gtest.h" | |
| 10 | - | ||
| 11 | 10 | #include "test_common.hpp" | |
| 12 | - | ||
| 13 | 11 | #include "xtensor-python/pyarray.hpp" | |
| 14 | 12 | ||
| 15 | 13 | namespace xt | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,9 +7,7 @@ | |||
| 7 | 7 | ****************************************************************************/ | |
| 8 | 8 | ||
| 9 | 9 | #include "gtest/gtest.h" | |
| 10 | - | ||
| 11 | 10 | #include "test_common.hpp" | |
| 12 | - | ||
| 13 | 11 | #include "xtensor-python/pytensor.hpp" | |
| 14 | 12 | ||
| 15 | 13 | namespace xt | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,7 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | 11 | #include "xtensor/xmath.hpp" | |
| 12 | 12 | #include "xtensor/xarray.hpp" | |
| 13 | - | ||
| 13 | + #define FORCE_IMPORT_ARRAY | ||
| 14 | 14 | #include "xtensor-python/pyarray.hpp" | |
| 15 | 15 | #include "xtensor-python/pyvectorize.hpp" | |
| 16 | 16 | ||
@@ -51,6 +51,7 @@ int add(int i, int j) | |||
| 51 | 51 | ||
| 52 | 52 | PYBIND11_PLUGIN(xtensor_python_test) | |
| 53 | 53 | { | |
| 54 | + import_array() | ||
| 54 | 55 | py::module m("xtensor_python_test", "Test module for xtensor python bindings"); | |
| 55 | 56 | ||
| 56 | 57 | m.def("example1", example1); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments