mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
array-unchecked: add runtime dimension support and array-compatible methods
The extends the previous unchecked support with the ability to determine the dimensions at runtime. This incurs a small performance hit when used (versus the compile-time fixed alternative), but is still considerably faster than the full checks on every call that happen with `.at()`/`.mutable_at()`.
This commit is contained in:
@@ -68,6 +68,21 @@ template<typename... Ix> arr_t& mutate_at_t(arr_t& a, Ix... idx) { a.mutable_at(
|
||||
sm.def(#name, [](type a, int i, int j) { return name(a, i, j); }); \
|
||||
sm.def(#name, [](type a, int i, int j, int k) { return name(a, i, j, k); });
|
||||
|
||||
template <typename T, typename T2> py::handle auxiliaries(T &&r, T2 &&r2) {
|
||||
if (r.ndim() != 2) throw std::domain_error("error: ndim != 2");
|
||||
py::list l;
|
||||
l.append(*r.data(0, 0));
|
||||
l.append(*r2.mutable_data(0, 0));
|
||||
l.append(r.data(0, 1) == r2.mutable_data(0, 1));
|
||||
l.append(r.ndim());
|
||||
l.append(r.itemsize());
|
||||
l.append(r.shape(0));
|
||||
l.append(r.shape(1));
|
||||
l.append(r.size());
|
||||
l.append(r.nbytes());
|
||||
return l.release();
|
||||
}
|
||||
|
||||
test_initializer numpy_array([](py::module &m) {
|
||||
auto sm = m.def_submodule("array");
|
||||
|
||||
@@ -191,6 +206,7 @@ test_initializer numpy_array([](py::module &m) {
|
||||
for (size_t j = 0; j < r.shape(1); j++)
|
||||
r(i, j) += v;
|
||||
}, py::arg().noconvert(), py::arg());
|
||||
|
||||
sm.def("proxy_init3", [](double start) {
|
||||
py::array_t<double, py::array::c_style> a({ 3, 3, 3 });
|
||||
auto r = a.mutable_unchecked<3>();
|
||||
@@ -216,4 +232,36 @@ test_initializer numpy_array([](py::module &m) {
|
||||
sumsq += r[i] * r(i); // Either notation works for a 1D array
|
||||
return sumsq;
|
||||
});
|
||||
|
||||
sm.def("proxy_auxiliaries2", [](py::array_t<double> a) {
|
||||
auto r = a.unchecked<2>();
|
||||
auto r2 = a.mutable_unchecked<2>();
|
||||
return auxiliaries(r, r2);
|
||||
});
|
||||
|
||||
// Same as the above, but without a compile-time dimensions specification:
|
||||
sm.def("proxy_add2_dyn", [](py::array_t<double> a, double v) {
|
||||
auto r = a.mutable_unchecked();
|
||||
if (r.ndim() != 2) throw std::domain_error("error: ndim != 2");
|
||||
for (size_t i = 0; i < r.shape(0); i++)
|
||||
for (size_t j = 0; j < r.shape(1); j++)
|
||||
r(i, j) += v;
|
||||
}, py::arg().noconvert(), py::arg());
|
||||
sm.def("proxy_init3_dyn", [](double start) {
|
||||
py::array_t<double, py::array::c_style> a({ 3, 3, 3 });
|
||||
auto r = a.mutable_unchecked();
|
||||
if (r.ndim() != 3) throw std::domain_error("error: ndim != 3");
|
||||
for (size_t i = 0; i < r.shape(0); i++)
|
||||
for (size_t j = 0; j < r.shape(1); j++)
|
||||
for (size_t k = 0; k < r.shape(2); k++)
|
||||
r(i, j, k) = start++;
|
||||
return a;
|
||||
});
|
||||
sm.def("proxy_auxiliaries2_dyn", [](py::array_t<double> a) {
|
||||
return auxiliaries(a.unchecked(), a.mutable_unchecked());
|
||||
});
|
||||
|
||||
sm.def("array_auxiliaries2", [](py::array_t<double> a) {
|
||||
return auxiliaries(a, a);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user