Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb013cee

Browse files
authored
Merge pull request#256 from tdegeus/example
Add (CMake) example
2 parentsaa916ec +f4dc5e3 commitb013cee

File tree

12 files changed

+253
-13
lines changed

12 files changed

+253
-13
lines changed

‎.azure-pipelines/unix-build.yml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ steps:
1111
mkdir build
1212
cd build
1313
cmake -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DPYTHON_EXECUTABLE=`which python` -DDOWNLOAD_GTEST=ON $(Build.SourcesDirectory)
14+
make install
1415
displayName: Configure xtensor-python
1516
workingDirectory: $(Build.BinariesDirectory)
16-
17+
1718
-script:|
1819
source activate xtensor-python
1920
make -j2 test_xtensor_python
2021
displayName: Build xtensor-python
2122
workingDirectory: $(Build.BinariesDirectory)/build
22-
23+
2324
-script:|
2425
source activate xtensor-python
2526
cd test
@@ -32,3 +33,19 @@ steps:
3233
py.test -s
3334
displayName: Test xtensor-python (Python)
3435
workingDirectory: $(Build.SourcesDirectory)
36+
37+
-script:|
38+
source activate xtensor-python
39+
cmake . -DPYTHON_EXECUTABLE=`which python`
40+
cmake --build .
41+
python example.py
42+
displayName: Example - readme 1
43+
workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/readme_example_1
44+
45+
-script:|
46+
source activate xtensor-python
47+
cmake . -DPYTHON_EXECUTABLE=`which python`
48+
cmake --build .
49+
python example.py
50+
displayName: Example - SFINAE
51+
workingDirectory: $(Build.SourcesDirectory)/docs/source/examples/sfinae

‎README.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ Both containers enable the numpy-style APIs of xtensor (see [the numpy to xtenso
4949

5050
```cpp
5151
#include<numeric>// Standard library import for std::accumulate
52-
#include"pybind11/pybind11.h"// Pybind11 import to define Python bindings
53-
#include"xtensor/xmath.hpp"// xtensor import for the C++ universal functions
52+
#include<pybind11/pybind11.h>// Pybind11 import to define Python bindings
53+
#include<xtensor/xmath.hpp>// xtensor import for the C++ universal functions
5454
#defineFORCE_IMPORT_ARRAY
55-
#include"xtensor-python/pyarray.hpp"// Numpy bindings
55+
#include<xtensor-python/pyarray.hpp>// Numpy bindings
5656

5757
doublesum_of_sines(xt::pyarray<double>& m)
5858
{
@@ -77,7 +77,7 @@ import xtensor_python_test as xt
7777
7878
v = np.arange(15).reshape(3, 5)
7979
s = xt.sum_of_sines(v)
80-
s
80+
print(s)
8181
```
8282

8383
**Outputs**
@@ -86,14 +86,22 @@ s
8686
1.2853996391883833
8787
```
8888

89+
**Working example**
90+
91+
Get the working example here:
92+
93+
*[`CMakeLists.txt`](docs/source/examples/readme_example_1/CMakeLists.txt)
94+
*[`main.cpp`](docs/source/examples/readme_example_1/main.cpp)
95+
*[`example.py`](docs/source/examples/readme_example_1/example.py)
96+
8997
###Example 2: Create a universal function from a C++ scalar function
9098

9199
**C++ code**
92100

93101
```cpp
94-
#include"pybind11/pybind11.h"
102+
#include<pybind11/pybind11.h>
95103
#defineFORCE_IMPORT_ARRAY
96-
#include"xtensor-python/pyvectorize.hpp"
104+
#include<xtensor-python/pyvectorize.hpp>
97105
#include<numeric>
98106
#include<cmath>
99107

@@ -122,7 +130,7 @@ import xtensor_python_test as xt
122130
x = np.arange(15).reshape(3, 5)
123131
y = [1, 2, 3, 4, 5]
124132
z = xt.vectorized_func(x, y)
125-
z
133+
print(z)
126134
```
127135

128136
**Outputs**

‎docs/source/examples.rst

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
2+
****************
3+
(CMake) Examples
4+
****************
5+
6+
Basic example (from readme)
7+
===========================
8+
9+
Consider the following C++ code:
10+
11+
:download:`main.cpp<examples/readme_example_1/main.cpp>`
12+
13+
..literalinclude::examples/readme_example_1/main.cpp
14+
:language: cpp
15+
16+
There are several options to build the module,
17+
whereby we will CMake here with the following ``CMakeLists.txt``:
18+
19+
:download:`CMakeLists.txt<examples/readme_example_1/CMakeLists.txt>`
20+
21+
..literalinclude::examples/readme_example_1/CMakeLists.txt
22+
:language: cmake
23+
24+
Then we can test the module:
25+
26+
:download:`example.py<examples/readme_example_1/example.py>`
27+
28+
..literalinclude::examples/readme_example_1/example.py
29+
:language: cmake
30+
31+
..note::
32+
33+
Since we did not install the module,
34+
we should compile and run the example from the same folder.
35+
To install, please consult
36+
`this pybind11 / CMake example<https://github.com/pybind/cmake_example>`_.
37+
38+
39+
Type restriction with SFINAE
40+
============================
41+
42+
..seealso::
43+
44+
`Medium post by Johan Mabille<https://medium.com/@johan.mabille/designing-language-bindings-with-xtensor-f32aa0f20db>`__
45+
This example covers "Option 4".
46+
47+
In this example we will design a module with a function that accepts an ``xt::xtensor`` as argument,
48+
but in such a way that an ``xt::pyxtensor`` can be accepted in the Python module.
49+
This is done by having a templated function
50+
51+
..code-block::cpp
52+
53+
template <class T>
54+
void times_dimension(T& t);
55+
56+
As this might be a bit too permissive for your liking, we will show you how to limit the
57+
scope to *xtensor* types, and allow other overloads using the principle of SFINAE
58+
(Substitution Failure Is Not An Error).
59+
In particular:
60+
61+
:download:`mymodule.hpp<examples/sfinae/mymodule.hpp>`
62+
63+
..literalinclude::examples/sfinae/mymodule.hpp
64+
:language: cpp
65+
66+
Consequently from C++, the interaction with the module's function is trivial
67+
68+
:download:`main.cpp<examples/sfinae/main.cpp>`
69+
70+
..literalinclude::examples/sfinae/main.cpp
71+
:language: cpp
72+
73+
For the Python module we just have to specify the template to be
74+
``xt::pyarray`` or ``xt::pytensor``. E.g.
75+
76+
:download:`src/python.cpp<examples/sfinae/python.cpp>`
77+
78+
..literalinclude::examples/sfinae/python.cpp
79+
:language: cpp
80+
81+
We will again use CMake to compile, with the following ``CMakeLists.txt``:
82+
83+
:download:`CMakeLists.txt<examples/sfinae/CMakeLists.txt>`
84+
85+
..literalinclude::examples/sfinae/CMakeLists.txt
86+
:language: cmake
87+
88+
Then we can test the module:
89+
90+
:download:`example.py<examples/readme_example_1/example.py>`
91+
92+
..literalinclude::examples/readme_example_1/example.py
93+
:language: cmake
94+
95+
..note::
96+
97+
Since we did not install the module,
98+
we should compile and run the example from the same folder.
99+
To install, please consult
100+
`this pybind11 / CMake example<https://github.com/pybind/cmake_example>`_.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
cmake_minimum_required(VERSION 3.1..3.19)
2+
3+
project(mymodule)
4+
5+
find_package(pybind11 CONFIG REQUIRED)
6+
find_package(xtensor REQUIRED)
7+
find_package(xtensor-python REQUIRED)
8+
find_package(Python REQUIRED COMPONENTS NumPy)
9+
10+
pybind11_add_module(mymodule main.cpp)
11+
target_link_libraries(mymodulePUBLIC pybind11::module xtensor-python Python::NumPy)
12+
13+
target_compile_definitions(mymodulePRIVATE VERSION_INFO=0.1.0)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
importmymodule
2+
importnumpyasnp
3+
4+
a=np.array([1,2,3])
5+
assertnp.isclose(np.sum(np.sin(a)),mymodule.sum_of_sines(a))
6+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include<numeric>
2+
#include<xtensor.hpp>
3+
#include<pybind11/pybind11.h>
4+
#defineFORCE_IMPORT_ARRAY
5+
#include<xtensor-python/pyarray.hpp>
6+
7+
doublesum_of_sines(xt::pyarray<double>& m)
8+
{
9+
auto sines =xt::sin(m);// sines does not actually hold values.
10+
returnstd::accumulate(sines.begin(), sines.end(),0.0);
11+
}
12+
13+
PYBIND11_MODULE(mymodule, m)
14+
{
15+
xt::import_numpy();
16+
m.doc() ="Test module for xtensor python bindings";
17+
m.def("sum_of_sines", sum_of_sines,"Sum the sines of the input values");
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
cmake_minimum_required(VERSION 3.1..3.19)
2+
3+
project(mymodule)
4+
5+
find_package(pybind11 CONFIG REQUIRED)
6+
find_package(xtensor REQUIRED)
7+
find_package(xtensor-python REQUIRED)
8+
find_package(Python REQUIRED COMPONENTS NumPy)
9+
10+
pybind11_add_module(mymodule python.cpp)
11+
target_link_libraries(mymodulePUBLIC pybind11::module xtensor-python Python::NumPy)
12+
13+
target_compile_definitions(mymodulePRIVATE VERSION_INFO=0.1.0)
14+
15+
add_executable(myexec main.cpp)
16+
target_link_libraries(myexecPUBLIC xtensor)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
importmymodule
2+
importnumpyasnp
3+
4+
a=np.array([[1,2,3], [4,5,6]],dtype=np.float64)
5+
b=np.array(a,copy=True)
6+
mymodule.times_dimension(b)# changing in-place!
7+
assertnp.allclose(2*a,b)
8+

‎docs/source/examples/sfinae/main.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include"mymodule.hpp"
2+
#include<xtensor/xio.hpp>
3+
4+
intmain()
5+
{
6+
xt::xtensor<size_t,2> a = xt::arange<size_t>(2 *3).reshape({2,3});
7+
mymodule::times_dimension(a);
8+
std::cout << a << std::endl;
9+
return0;
10+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include<xtensor/xtensor.hpp>
2+
3+
namespacemymodule {
4+
5+
template<classT>
6+
structis_std_vector
7+
{
8+
staticconstbool value =false;
9+
};
10+
11+
template<classT>
12+
structis_std_vector<std::vector<T> >
13+
{
14+
staticconstbool value =true;
15+
};
16+
17+
// any xtensor object
18+
template<classT, std::enable_if_t<xt::is_xexpression<T>::value,bool> =true>
19+
voidtimes_dimension(T& t)
20+
{
21+
using value_type =typename T::value_type;
22+
t *= (value_type)(t.dimension());
23+
}
24+
25+
// an std::vector
26+
template<classT, std::enable_if_t<is_std_vector<T>::value,bool> =true>
27+
voidtimes_dimension(T& t)
28+
{
29+
// do nothing
30+
}
31+
32+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include"mymodule.hpp"
2+
#include<pybind11/pybind11.h>
3+
#defineFORCE_IMPORT_ARRAY
4+
#include<xtensor-python/pyarray.hpp>
5+
6+
PYBIND11_MODULE(mymodule, m)
7+
{
8+
xt::import_numpy();
9+
m.doc() ="Test module for xtensor python bindings";
10+
m.def("times_dimension", &mymodule::times_dimension<xt::pyarray<double>>);
11+
}

‎docs/source/index.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ What are ``xtensor`` and ``xtensor-python``?
1616
- ``xtensor`` is a C++ library for multi-dimensional arrays enabling numpy-style broadcasting and lazy computing.
1717
- ``xtensor-python`` enables inplace use of numpy arrays with all the benefits from ``xtensor``
1818

19-
- C++ universal functions and broadcasting
19+
- C++ universal functions and broadcasting
2020
- STL - compliant APIs.
2121

2222

@@ -62,6 +62,7 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f
6262
basic_usage
6363
array_tensor
6464
numpy_capi
65+
examples
6566
cookiecutter
6667

6768
..toctree::
@@ -79,7 +80,7 @@ This software is licensed under the BSD-3-Clause license. See the LICENSE file f
7980

8081
.. _NumPy:http://www.numpy.org
8182
.. _`Buffer Protocol`:https://docs.python.org/3/c-api/buffer.html
82-
.. _`numpy to xtensor cheat sheet`:http://xtensor.readthedocs.io/en/latest/numpy.html
83+
.. _`numpy to xtensor cheat sheet`:http://xtensor.readthedocs.io/en/latest/numpy.html
8384
.. _xtensor:https://github.com/xtensor-stack/xtensor
84-
.. _pybind11:https://github.com/pybind/pybind11
85-
.. _xtensor-python-cookiecutter:https://github.com/xtensor-stack/xtensor-python-cookiecutter
85+
.. _pybind11:https://github.com/pybind/pybind11
86+
.. _xtensor-python-cookiecutter:https://github.com/xtensor-stack/xtensor-python-cookiecutter

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp