26 py::module_
np = py::module_::import(
"numpy");
29 check.pybind11 = py::dtype::of<T>();
35 get_dtype_check<std::int8_t>(
"int8"),
36 get_dtype_check<std::uint8_t>(
"uint8"),
37 get_dtype_check<std::int16_t>(
"int16"),
38 get_dtype_check<std::uint16_t>(
"uint16"),
39 get_dtype_check<std::int32_t>(
"int32"),
40 get_dtype_check<std::uint32_t>(
"uint32"),
41 get_dtype_check<std::int64_t>(
"int64"),
42 get_dtype_check<std::uint64_t>(
"uint64")};
56 check.name = py::type_id<T>();
57 check.size_cpp =
sizeof(
T);
58 check.dtype = py::dtype::of<T>();
59 check.size_numpy =
check.dtype.attr(
"itemsize").template cast<int>();
65 get_dtype_size_check<short>(),
66 get_dtype_size_check<unsigned short>(),
67 get_dtype_size_check<int>(),
68 get_dtype_size_check<unsigned int>(),
69 get_dtype_size_check<long>(),
70 get_dtype_size_check<unsigned long>(),
71 get_dtype_size_check<long long>(),
72 get_dtype_size_check<unsigned long long>(),
78 using arr_t = py::array_t<uint16_t, 0>;
81 template <
typename... Ix>
83 return arr(
a.nbytes() -
a.offset_at(index...), (
const uint8_t *)
a.data(index...));
86 template <
typename... Ix>
88 return arr(
a.size() -
a.index_at(index...),
a.data(index...));
91 template <
typename... Ix>
93 auto *ptr = (
uint8_t *)
a.mutable_data(index...);
100 template <
typename... Ix>
102 auto ptr =
a.mutable_data(index...);
109 template <
typename... Ix>
111 return a.index_at(idx...);
113 template <
typename... Ix>
115 return a.index_at(idx...);
117 template <
typename... Ix>
119 return a.offset_at(idx...);
121 template <
typename... Ix>
123 return a.offset_at(idx...);
125 template <
typename... Ix>
129 template <
typename... Ix>
131 a.mutable_at(idx...)++;
135 #define def_index_fn(name, type) \
136 sm.def(#name, [](type a) { return name(a); }); \
137 sm.def(#name, [](type a, int i) { return name(a, i); }); \
138 sm.def(#name, [](type a, int i, int j) { return name(a, i, j); }); \
139 sm.def(#name, [](type a, int i, int j, int k) { return name(a, i, j, k); });
141 template <
typename T,
typename T2>
144 throw std::domain_error(
"error: ndim != 2");
147 l.append(*r.data(0, 0));
148 l.append(*
r2.mutable_data(0, 0));
149 l.append(r.data(0, 1) ==
r2.mutable_data(0, 1));
151 l.append(r.itemsize());
152 l.append(r.shape(0));
153 l.append(r.shape(1));
155 l.append(r.nbytes());
164 py::module_::import(
"numpy");
165 }
catch (
const py::error_already_set &) {
170 py::class_<DtypeCheck>(sm,
"DtypeCheck")
174 return py::str(
"<DtypeCheck numpy={} pybind11={}>").format(
self.numpy,
self.
pybind11);
178 py::class_<DtypeSizeCheck>(sm,
"DtypeSizeCheck")
183 return py::str(
"<DtypeSizeCheck name='{}' size_cpp={} size_numpy={} dtype={}>")
184 .format(
self.
name,
self.size_cpp,
self.size_numpy,
self.
dtype);
189 sm.def(
"ndim", [](
const arr &
a) {
return a.ndim(); });
190 sm.def(
"shape", [](
const arr &
a) {
return arr(
a.ndim(),
a.shape()); });
191 sm.def(
"shape", [](
const arr &
a,
py::ssize_t dim) {
return a.shape(dim); });
192 sm.def(
"strides", [](
const arr &
a) {
return arr(
a.ndim(),
a.strides()); });
193 sm.def(
"strides", [](
const arr &
a,
py::ssize_t dim) {
return a.strides(dim); });
194 sm.def(
"writeable", [](
const arr &
a) {
return a.writeable(); });
195 sm.def(
"size", [](
const arr &
a) {
return a.size(); });
196 sm.def(
"itemsize", [](
const arr &
a) {
return a.itemsize(); });
197 sm.def(
"nbytes", [](
const arr &
a) {
return a.nbytes(); });
198 sm.def(
"owndata", [](
const arr &
a) {
return a.owndata(); });
215 sm.def(
"make_f_array", [] {
return py::array_t<float>({2, 2}, {4, 8}); });
216 sm.def(
"make_c_array", [] {
return py::array_t<float>({2, 2}, {8, 4}); });
226 {a.shape(), a.shape() + a.ndim()},
227 {a.strides(), a.strides() + a.ndim()},
234 int data[2] = {1, 2};
235 ArrayClass() {
py::print(
"ArrayClass()"); }
236 ~ArrayClass() {
py::print(
"~ArrayClass()"); }
238 py::class_<ArrayClass>(sm,
"ArrayClass")
240 .def(
"numpy_view", [](py::object &obj) {
242 auto &
a = obj.cast<ArrayClass &>();
243 return py::array_t<int>({2}, {4},
a.data, obj);
247 sm.def(
"function_taking_uint64", [](
uint64_t) {});
250 sm.def(
"isinstance_untyped", [](py::object yes, py::object no) {
251 return py::isinstance<py::array>(std::move(yes))
252 && !py::isinstance<py::array>(std::move(no));
254 sm.def(
"isinstance_typed", [](
const py::object &o) {
255 return py::isinstance<py::array_t<double>>(o) && !
py::isinstance<py::array_t<int>>(o);
259 sm.def(
"default_constructors", []() {
261 "array_t<int32>"_a = py::array_t<std::int32_t>(),
262 "array_t<double>"_a = py::array_t<double>());
264 sm.def(
"converting_constructors", [](
const py::object &o) {
265 return py::dict(
"array"_a =
py::array(o),
266 "array_t<int32>"_a = py::array_t<std::int32_t>(o),
267 "array_t<double>"_a = py::array_t<double>(o));
271 sm.def(
"overloaded", [](
const py::array_t<double> &) {
return "double"; });
272 sm.def(
"overloaded", [](
const py::array_t<float> &) {
return "float"; });
273 sm.def(
"overloaded", [](
const py::array_t<int> &) {
return "int"; });
274 sm.def(
"overloaded", [](
const py::array_t<unsigned short> &) {
return "unsigned short"; });
275 sm.def(
"overloaded", [](
const py::array_t<long long> &) {
return "long long"; });
277 [](
const py::array_t<std::complex<double>> &) {
return "double complex"; });
278 sm.def(
"overloaded", [](
const py::array_t<std::complex<float>> &) {
return "float complex"; });
280 sm.def(
"overloaded2",
281 [](
const py::array_t<std::complex<double>> &) {
return "double complex"; });
282 sm.def(
"overloaded2", [](
const py::array_t<double> &) {
return "double"; });
283 sm.def(
"overloaded2",
284 [](
const py::array_t<std::complex<float>> &) {
return "float complex"; });
285 sm.def(
"overloaded2", [](
const py::array_t<float> &) {
return "float"; });
290 sm.def(
"overloaded3", [](
const py::array_t<int> &) {
return "int"; },
py::arg{}.noconvert());
293 [](
const py::array_t<double> &) {
return "double"; },
298 sm.def(
"overloaded4", [](
const py::array_t<long long, 0> &) {
return "long long"; });
299 sm.def(
"overloaded4", [](
const py::array_t<double, 0> &) {
return "double"; });
303 sm.def(
"overloaded5", [](
const py::array_t<unsigned int> &) {
return "unsigned int"; });
304 sm.def(
"overloaded5", [](
const py::array_t<double> &) {
return "double"; });
308 sm.def(
"issue685", [](
const std::string &) {
return "string"; });
309 sm.def(
"issue685", [](
const py::array &) {
return "array"; });
310 sm.def(
"issue685", [](
const py::object &) {
return "other"; });
315 [](py::array_t<double>
a,
double v) {
316 auto r =
a.mutable_unchecked<2>();
326 sm.def(
"proxy_init3", [](
double start) {
327 py::array_t<double, py::array::c_style>
a({3, 3, 3});
328 auto r =
a.mutable_unchecked<3>();
332 r(
i,
j, k) = start++;
338 sm.def(
"proxy_init3F", [](
double start) {
339 py::array_t<double, py::array::f_style>
a({3, 3, 3});
340 auto r =
a.mutable_unchecked<3>();
344 r(
i,
j, k) = start++;
350 sm.def(
"proxy_squared_L2_norm", [](
const py::array_t<double> &
a) {
351 auto r =
a.unchecked<1>();
354 sumsq += r[
i] * r(
i);
359 sm.def(
"proxy_auxiliaries2", [](py::array_t<double>
a) {
360 auto r =
a.unchecked<2>();
361 auto r2 =
a.mutable_unchecked<2>();
365 sm.def(
"proxy_auxiliaries1_const_ref", [](py::array_t<double>
a) {
366 const auto &r =
a.unchecked<1>();
367 const auto &
r2 =
a.mutable_unchecked<1>();
368 return r(0) ==
r2(0) && r[0] ==
r2[0];
371 sm.def(
"proxy_auxiliaries2_const_ref", [](py::array_t<double>
a) {
372 const auto &r =
a.unchecked<2>();
373 const auto &
r2 =
a.mutable_unchecked<2>();
374 return r(0, 0) ==
r2(0, 0);
381 [](py::array_t<double>
a,
double v) {
382 auto r =
a.mutable_unchecked();
384 throw std::domain_error(
"error: ndim != 2");
394 sm.def(
"proxy_init3_dyn", [](
double start) {
395 py::array_t<double, py::array::c_style>
a({3, 3, 3});
396 auto r =
a.mutable_unchecked();
398 throw std::domain_error(
"error: ndim != 3");
403 r(
i,
j, k) = start++;
409 sm.def(
"proxy_auxiliaries2_dyn", [](py::array_t<double>
a) {
413 sm.def(
"array_auxiliaries2", [](py::array_t<double>
a) {
return auxiliaries(
a,
a); });
418 sm.def(
"array_fail_test", []() {
return py::array(py::object()); });
419 sm.def(
"array_t_fail_test", []() {
return py::array_t<double>(py::object()); });
421 sm.def(
"array_fail_test_negative_size", []() {
428 sm.def(
"array_initializer_list1", []() {
return py::array_t<float>(1); });
430 sm.def(
"array_initializer_list2", []() {
return py::array_t<float>({1, 2}); });
431 sm.def(
"array_initializer_list3", []() {
return py::array_t<float>({1, 2, 3}); });
432 sm.def(
"array_initializer_list4", []() {
return py::array_t<float>({1, 2, 3, 4}); });
436 sm.def(
"array_reshape2", [](py::array_t<double>
a) {
438 if (dim_sz * dim_sz !=
a.size()) {
439 throw std::domain_error(
440 "array_reshape2: input array total size is not a squared integer");
442 a.resize({dim_sz, dim_sz});
446 sm.def(
"array_resize3",
447 [](py::array_t<double>
a,
size_t N,
bool refcheck) {
a.resize({
N,
N,
N}, refcheck); });
451 sm.def(
"create_and_resize", [](
size_t N) {
452 py::array_t<double>
a;
454 std::fill(
a.mutable_data(),
a.mutable_data() +
a.size(), 42.);
459 [](py::array_t<uint8_t>
a,
const std::string &
dtype) {
return a.view(
dtype); });
461 sm.def(
"reshape_initializer_list",
462 [](py::array_t<int>
a,
size_t N,
size_t M,
size_t O) {
return a.reshape({
N,
M,
O}); });
463 sm.def(
"reshape_tuple", [](py::array_t<int>
a,
const std::vector<int> &new_shape) {
464 return a.reshape(new_shape);
467 sm.def(
"index_using_ellipsis",
471 sm.def(
"accept_double", [](
const py::array_t<double, 0> &) {},
py::arg(
"a"));
473 "accept_double_forcecast",
474 [](
const py::array_t<double, py::array::forcecast> &) {},
477 "accept_double_c_style",
478 [](
const py::array_t<double, py::array::c_style> &) {},
481 "accept_double_c_style_forcecast",
482 [](
const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},
485 "accept_double_f_style",
486 [](
const py::array_t<double, py::array::f_style> &) {},
489 "accept_double_f_style_forcecast",
490 [](
const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},
492 sm.def(
"accept_double_noconvert", [](
const py::array_t<double, 0> &) {},
"a"_a.noconvert());
494 "accept_double_forcecast_noconvert",
495 [](
const py::array_t<double, py::array::forcecast> &) {},
498 "accept_double_c_style_noconvert",
499 [](
const py::array_t<double, py::array::c_style> &) {},
502 "accept_double_c_style_forcecast_noconvert",
503 [](
const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},
506 "accept_double_f_style_noconvert",
507 [](
const py::array_t<double, py::array::f_style> &) {},
510 "accept_double_f_style_forcecast_noconvert",
511 [](
const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},
515 sm.def(
"test_fmt_desc_float", [](
const py::array_t<float> &) {});
516 sm.def(
"test_fmt_desc_double", [](
const py::array_t<double> &) {});
517 sm.def(
"test_fmt_desc_const_float", [](
const py::array_t<const float> &) {});
518 sm.def(
"test_fmt_desc_const_double", [](
const py::array_t<const double> &) {});
520 sm.def(
"round_trip_float", [](
double d) {
return d; });
522 sm.def(
"pass_array_pyobject_ptr_return_sum_str_values",
523 [](
const py::array_t<PyObject *> &objs) {
524 std::string sum_str_values;
525 for (
const auto &obj : objs) {
526 sum_str_values +=
py::str(obj.attr(
"value"));
528 return sum_str_values;
531 sm.def(
"pass_array_pyobject_ptr_return_as_list",
532 [](
const py::array_t<PyObject *> &objs) -> py::list {
return objs; });
534 sm.def(
"return_array_pyobject_ptr_cpp_loop", [](
const py::list &objs) {
536 py::array_t<PyObject *> arr_from_list(
static_cast<py::ssize_t>(arr_size));
537 PyObject **
data = arr_from_list.mutable_data();
539 assert(
data[
i] ==
nullptr);
540 data[
i] = py::cast<PyObject *>(objs[
i].attr(
"value"));
542 return arr_from_list;
545 sm.def(
"return_array_pyobject_ptr_from_list",
546 [](
const py::list &objs) -> py::array_t<PyObject *> {
return objs; });