Skip to content

Commit 7f96473

Browse files
yungyucJohanMabille
authored andcommitted
Add an example for sharing the memory buffer of the xarray between C++ and Python (numpy) (#175)
Demonstrate how to return an array and share the buffer to Python (numpy).
1 parent d11799f commit 7f96473

File tree

5 files changed

+43
-3
lines changed

5 files changed

+43
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ test/CMakeCache.txt
3939
test/Makefile
4040
test/CMakeFiles/
4141
test/cmake_install.cmake
42+
.pytest_cache/
4243

4344
# Documentation build artefacts
4445
docs/CMakeCache.txt

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ project(xtensor-python)
1212
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
1313
set(XTENSOR_PYTHON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
1414

15-
# Versionning
16-
# ===========
15+
# Versioning
16+
# ==========
1717

1818
set(XTENSOR_PYTHON_CONFIG_FILE
1919
"${XTENSOR_PYTHON_INCLUDE_DIR}/xtensor-python/xtensor_python_config.hpp")

include/xtensor-python/xtensor_type_caster_base.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace pybind11
3939
std::transform(src.strides().begin(), src.strides().end(),
4040
python_strides.begin(), [](auto v) {
4141
return sizeof(typename Type::value_type) * v;
42-
});
42+
});
4343

4444
std::vector<std::size_t> python_shape(src.shape().size());
4545
std::copy(src.shape().begin(), src.shape().end(), python_shape.begin());
@@ -162,6 +162,8 @@ namespace pybind11
162162
{
163163
return _("xt::xtensor");
164164
}
165+
#else
166+
static constexpr auto name = _("xt::xtensor");
165167
#endif
166168

167169
template <typename T>

test_python/main.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,16 @@ struct B
122122
int b;
123123
};
124124

125+
class C
126+
{
127+
public:
128+
using array_type = xt::xarray<double, xt::layout_type::row_major>;
129+
C() : m_array{0, 0, 0, 0} {}
130+
array_type & array() { return m_array; }
131+
private:
132+
array_type m_array;
133+
};
134+
125135
xt::pyarray<A> dtype_to_python()
126136
{
127137
A a1{123, 321, 'a', {1, 2, 3}};
@@ -217,4 +227,16 @@ PYBIND11_MODULE(xtensor_python_test, m)
217227

218228
m.def("col_major_array", col_major_array);
219229
m.def("row_major_tensor", row_major_tensor);
230+
231+
py::class_<C>(m, "C")
232+
.def(py::init<>())
233+
.def_property_readonly(
234+
"copy",
235+
[](C & self) { return self.array(); }
236+
)
237+
.def_property_readonly(
238+
"ref",
239+
[](C & self) -> C::array_type & { return self.array(); }
240+
)
241+
;
220242
}

test_python/test_pyarray.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,18 @@ def test_col_row_major(self):
146146
varF = np.arange(50, dtype=float).reshape(2, 5, 5, order='F')
147147
xt.col_major_array(varF)
148148
xt.col_major_array(varF[:, :, 0]) # still col major!
149+
150+
class AttributeTest(TestCase):
151+
152+
def setUp(self):
153+
self.c = xt.C()
154+
155+
def test_copy(self):
156+
arr = self.c.copy
157+
arr[0] = 1
158+
self.assertEqual([0.]*4, self.c.copy.tolist())
159+
160+
def test_reference(self):
161+
arr = self.c.ref
162+
arr[0] = 1
163+
self.assertEqual([1.] + [0.]*3, self.c.ref.tolist())

0 commit comments

Comments
 (0)