24 #include <type_traits> 33 static_assert(
sizeof(::
pybind11::ssize_t) ==
sizeof(Py_intptr_t),
"ssize_t != Py_intptr_t");
48 template <
typename type,
typename SFINAE =
void>
93 auto it = registered_dtypes.find(std::type_index(tinfo));
94 if (it != registered_dtypes.end()) {
97 if (throw_if_missing) {
98 pybind11_fail(std::string(
"NumPy type info missing for ") + tinfo.name());
103 template <
typename T>
110 ptr = &get_or_create_shared_data<numpy_internals>(
"_numpy_internals");
121 template <
typename T>
123 template <
typename U>
127 template <
typename Concrete>
133 template <
typename Concrete,
typename T,
typename... Ts,
typename... Ints>
135 return sizeof(Concrete) ==
sizeof(T) ?
I :
platform_lookup<Concrete, Ts...>(Is...);
140 NPY_ARRAY_C_CONTIGUOUS_ = 0x0001,
141 NPY_ARRAY_F_CONTIGUOUS_ = 0x0002,
142 NPY_ARRAY_OWNDATA_ = 0x0004,
143 NPY_ARRAY_FORCECAST_ = 0x0010,
144 NPY_ARRAY_ENSUREARRAY_ = 0x0040,
145 NPY_ARRAY_ALIGNED_ = 0x0100,
146 NPY_ARRAY_WRITEABLE_ = 0x0400,
169 NPY_INT8_ = NPY_BYTE_,
170 NPY_UINT8_ = NPY_UBYTE_,
171 NPY_INT16_ = NPY_SHORT_,
172 NPY_UINT16_ = NPY_USHORT_,
177 = platform_lookup<std::int32_t, long, int, short>(NPY_LONG_, NPY_INT_, NPY_SHORT_),
178 NPY_UINT32_ = platform_lookup<std::uint32_t, unsigned long, unsigned int, unsigned short>(
179 NPY_ULONG_, NPY_UINT_, NPY_USHORT_),
181 = platform_lookup<std::int64_t, long, long long, int>(NPY_LONG_, NPY_LONGLONG_, NPY_INT_),
183 = platform_lookup<std::uint64_t, unsigned long, unsigned long long, unsigned int>(
184 NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),
198 return PyObject_TypeCheck(obj, PyArray_Type_) != 0;
201 return PyObject_TypeCheck(obj, PyArrayDescr_Type_) != 0;
204 unsigned int (*PyArray_GetNDArrayCFeatureVersion_)();
205 PyObject *(*PyArray_DescrFromType_)(
int);
206 PyObject *(*PyArray_NewFromDescr_)(PyTypeObject *,
215 PyObject *(*PyArray_DescrNewFromType_)(
int);
216 int (*PyArray_CopyInto_)(PyObject *, PyObject *);
217 PyObject *(*PyArray_NewCopy_)(PyObject *,
int);
221 PyObject *(*PyArray_DescrFromScalar_)(PyObject *);
222 PyObject *(*PyArray_FromAny_)(PyObject *, PyObject *,
int,
int,
int, PyObject *);
223 int (*PyArray_DescrConverter_)(PyObject *, PyObject **);
224 bool (*PyArray_EquivTypes_)(PyObject *, PyObject *);
225 int (*PyArray_GetArrayParamsFromObject_)(PyObject *,
233 PyObject *(*PyArray_Squeeze_)(PyObject *);
235 int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);
237 PyObject *(*PyArray_Newshape_)(PyObject *, PyArray_Dims *,
int);
238 PyObject *(*PyArray_View_)(PyObject *, PyObject *, PyObject *);
242 API_PyArray_GetNDArrayCFeatureVersion = 211,
243 API_PyArray_Type = 2,
244 API_PyArrayDescr_Type = 3,
245 API_PyVoidArrType_Type = 39,
246 API_PyArray_DescrFromType = 45,
247 API_PyArray_DescrFromScalar = 57,
248 API_PyArray_FromAny = 69,
249 API_PyArray_Resize = 80,
250 API_PyArray_CopyInto = 82,
251 API_PyArray_NewCopy = 85,
252 API_PyArray_NewFromDescr = 94,
253 API_PyArray_DescrNewFromType = 96,
254 API_PyArray_Newshape = 135,
255 API_PyArray_Squeeze = 136,
256 API_PyArray_View = 137,
257 API_PyArray_DescrConverter = 174,
258 API_PyArray_EquivTypes = 182,
259 API_PyArray_GetArrayParamsFromObject = 278,
260 API_PyArray_SetBaseObject = 282
265 auto c = m.attr(
"_ARRAY_API");
266 void **api_ptr = (
void **) PyCapsule_GetPointer(
c.ptr(),
nullptr);
268 #define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func]; 271 pybind11_fail(
"pybind11 numpy support requires numpy >= 1.7.0");
315 template <
typename T>
317 template <
typename T,
size_t N>
319 template <
typename T>
321 template <
typename T>
324 template <
typename T>
327 static constexpr
bool is_array =
false;
328 static constexpr
bool is_empty =
false;
335 template <
typename T>
337 template <
typename T,
size_t N>
340 static constexpr
bool is_array =
true;
342 static constexpr
size_t extent =
N;
350 static constexpr
auto extents = const_name<array_info<T>::is_array>(
359 template <
typename T,
size_t N>
361 template <
typename T>
364 template <
typename T>
368 #if defined(__GLIBCXX__) \ 369 && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150426 || __GLIBCXX__ == 20150623 \ 370 || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803) 373 std::is_trivially_destructible<T>,
376 std::is_trivially_copyable<T>,
387 template <
typename T>
390 template <s
size_t Dim = 0,
typename Str
ides>
394 template <
ssize_t Dim = 0,
typename Strides,
typename... Ix>
396 return i * strides[Dim] + byte_offset_unsafe<Dim + 1>(
strides, index...);
404 template <
typename T, s
size_t Dims>
416 template <
bool Dyn = Dynamic>
421 : data_{
reinterpret_cast<const unsigned char *
>(
data)}, dims_{
Dims} {
422 for (
size_t i = 0;
i < (
size_t) dims_;
i++) {
423 shape_[
i] = shape[
i];
428 template <
bool Dyn = Dynamic>
433 : data_{
reinterpret_cast<const unsigned char *
>(
data)}, shape_{shape}, strides_{
strides},
442 template <
typename... Ix>
444 static_assert(
ssize_t{
sizeof...(Ix)} ==
Dims || Dynamic,
445 "Invalid number of indices for unchecked array reference");
446 return *
reinterpret_cast<const T *
>(data_
453 template <s
size_t D = Dims,
typename = enable_if_t<D == 1 || Dynamic>>
459 template <
typename... Ix>
460 const T *
data(Ix... ix)
const {
475 template <
bool Dyn = Dynamic>
477 return std::accumulate(
478 shape_.begin(), shape_.end(), (
ssize_t) 1, std::multiplies<ssize_t>());
480 template <
bool Dyn = Dynamic>
482 return std::accumulate(shape_, shape_ + ndim(), (
ssize_t) 1, std::multiplies<ssize_t>());
491 template <
typename T, s
size_t Dims>
495 using ConstBase::ConstBase;
500 using ConstBase::operator();
501 using ConstBase::operator[];
504 template <
typename... Ix>
507 "Invalid number of indices for unchecked array reference");
515 template <s
size_t D = Dims,
typename = enable_if_t<D == 1 || Dynamic>>
521 template <
typename... Ix>
527 template <
typename T, s
size_t Dim>
529 static_assert(Dim == 0 && Dim > 0 ,
530 "unchecked array proxy object is not castable");
532 template <
typename T, s
size_t Dim>
558 args[
"names"] = std::move(names);
559 args[
"formats"] = std::move(formats);
560 args[
"offsets"] = std::move(offsets);
561 args[
"itemsize"] = pybind11::int_(itemsize);
562 m_ptr = from_args(args).release().ptr();
567 if (m_ptr ==
nullptr) {
574 PyObject *ptr =
nullptr;
578 return reinterpret_steal<dtype>(ptr);
582 template <
typename T>
626 .attr(
"_dtype_from_pep3118")
630 return reinterpret_borrow<object>(obj);
644 field_descr(
pybind11::str &&name,
object &&format, pybind11::int_ &&offset)
645 : name{std::move(name)}, format{std::move(format)}, offset{std::move(offset)} {};
647 auto field_dict = attr(
"fields").
cast<
dict>();
648 std::vector<field_descr> field_descriptors;
649 field_descriptors.reserve(field_dict.size());
651 for (
auto field : field_dict.attr(
"items")()) {
654 auto spec_fo = spec[1].cast<
tuple>();
656 auto offset = spec_fo[1].
cast<pybind11::int_>();
657 if ((
len(name) == 0u) && format.kind() ==
'V') {
660 field_descriptors.emplace_back(
661 std::move(name), format.strip_padding(format.itemsize()), std::move(offset));
664 std::sort(field_descriptors.begin(),
665 field_descriptors.end(),
666 [](
const field_descr &
a,
const field_descr &
b) {
667 return a.offset.cast<
int>() <
b.offset.cast<
int>();
671 for (
auto &
descr : field_descriptors) {
672 names.append(std::move(
descr.name));
673 formats.append(std::move(
descr.format));
674 offsets.append(std::move(
descr.offset));
676 return dtype(std::move(names), std::move(formats), std::move(offsets), itemsize);
685 c_style = detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_,
686 f_style = detail::npy_api::NPY_ARRAY_F_CONTIGUOUS_,
687 forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_
699 const void *ptr =
nullptr,
702 if (strides->empty()) {
706 auto ndim = shape->size();
707 if (ndim != strides->size()) {
708 pybind11_fail(
"NumPy: shape ndim doesn't match strides ndim");
714 if (isinstance<array>(
base)) {
716 flags = reinterpret_borrow<array>(
base).flags()
720 flags = detail::npy_api::NPY_ARRAY_WRITEABLE_;
725 auto tmp = reinterpret_steal<object>(
api.PyArray_NewFromDescr_(
727 descr.release().ptr(),
730 reinterpret_cast<Py_intptr_t *>(shape->data()),
731 reinterpret_cast<Py_intptr_t *>(strides->data()),
732 const_cast<void *>(ptr),
740 api.PyArray_SetBaseObject_(tmp.ptr(),
base.inc_ref().ptr());
742 tmp = reinterpret_steal<object>(
743 api.PyArray_NewCopy_(tmp.ptr(), -1 ));
746 m_ptr = tmp.release().ptr();
751 const void *ptr =
nullptr,
755 template <
typename T,
761 template <
typename T>
765 template <
typename T>
769 template <
typename T>
783 return std::accumulate(shape(), shape() + ndim(), (
ssize_t) 1, std::multiplies<ssize_t>());
806 fail_dim_check(dim,
"invalid axis");
817 fail_dim_check(dim,
"invalid axis");
837 template <
typename... Ix>
838 const void *
data(Ix... index)
const {
845 template <
typename... Ix>
853 template <
typename... Ix>
855 if ((
ssize_t)
sizeof...(index) > ndim()) {
856 fail_dim_check(
sizeof...(index),
"too many indices for an array");
858 return byte_offset(
ssize_t(index)...);
865 template <
typename... Ix>
879 throw std::domain_error(
"array has incorrect number of dimensions: " 880 + std::to_string(ndim()) +
"; expected " 881 + std::to_string(Dims));
883 return detail::unchecked_mutable_reference<T, Dims>(
884 mutable_data(), shape(),
strides(), ndim());
894 template <
typename T,
ssize_t Dims = -1>
895 detail::unchecked_reference<T, Dims>
unchecked() const & {
897 throw std::domain_error(
"array has incorrect number of dimensions: " 898 + std::to_string(ndim()) +
"; expected " 899 + std::to_string(Dims));
901 return detail::unchecked_reference<T, Dims>(
data(), shape(),
strides(), ndim());
907 return reinterpret_steal<array>(
api.PyArray_Squeeze_(m_ptr));
914 detail::npy_api::PyArray_Dims
d 916 reinterpret_cast<Py_intptr_t *
>(new_shape->data()),
917 int(new_shape->size())};
919 auto new_array = reinterpret_steal<object>(
924 if (isinstance<array>(new_array)) {
925 *
this = std::move(new_array);
931 detail::npy_api::PyArray_Dims
d 932 = {
reinterpret_cast<Py_intptr_t *
>(new_shape->data()),
int(new_shape->size())};
948 auto new_view = reinterpret_steal<array>(
api.PyArray_View_(
959 auto result = reinterpret_steal<array>(raw_array(h.
ptr(), ExtraFlags));
967 template <
typename,
typename>
968 friend struct detail::npy_format_descriptor;
971 throw index_error(msg +
": " + std::to_string(dim) +
" (ndim = " + std::to_string(ndim())
975 template <
typename... Ix>
977 check_dimensions(index...);
983 throw std::domain_error(
"array is not writeable");
987 template <
typename... Ix>
994 template <
typename... Ix>
997 throw index_error(std::string(
"index ") + std::to_string(i)
998 +
" is out of bounds for axis " + std::to_string(axis)
999 +
" with size " + std::to_string(*shape));
1001 check_dimensions_impl(axis + 1, shape + 1, index...);
1005 static PyObject *
raw_array(PyObject *ptr,
int ExtraFlags = 0) {
1006 if (ptr ==
nullptr) {
1007 PyErr_SetString(PyExc_ValueError,
"cannot create a pybind11::array from a nullptr");
1011 ptr,
nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags,
nullptr);
1015 template <
typename T,
int ExtraFlags = array::forcecast>
1028 static_assert(!detail::array_info<T>::is_array,
"Array types cannot be used with array_t");
1042 Py_XDECREF(
h.ptr());
1057 const T *ptr =
nullptr,
1074 template <
typename... Ix>
1076 return offset_at(index...) / itemsize();
1079 template <
typename... Ix>
1081 return static_cast<const T *
>(
array::data(index...));
1084 template <
typename... Ix>
1090 template <
typename... Ix>
1091 const T &
at(Ix... index)
const {
1092 if ((
ssize_t)
sizeof...(index) != ndim()) {
1093 fail_dim_check(
sizeof...(index),
"index dimension mismatch");
1096 + byte_offset(
ssize_t(index)...) / itemsize());
1100 template <
typename... Ix>
1102 if ((
ssize_t)
sizeof...(index) != ndim()) {
1103 fail_dim_check(
sizeof...(index),
"index dimension mismatch");
1106 + byte_offset(
ssize_t(index)...) / itemsize());
1117 return array::mutable_unchecked<T, Dims>();
1129 return array::unchecked<T, Dims>();
1135 auto result = reinterpret_steal<array_t>(raw_array_t(h.
ptr()));
1144 return api.PyArray_Check_(h.
ptr())
1146 dtype::of<T>().ptr())
1153 if (ptr ==
nullptr) {
1154 PyErr_SetString(PyExc_ValueError,
"cannot create a pybind11::array_t from a nullptr");
1158 dtype::of<T>().
release().ptr(),
1161 detail::npy_api::NPY_ARRAY_ENSUREARRAY_
1167 template <
typename T>
1176 static std::string
format() {
return std::to_string(
N) +
's'; }
1180 static std::string
format() {
return std::to_string(
N) +
's'; }
1183 template <
typename T>
1191 template <
typename T>
1201 template <
typename T,
int ExtraFlags>
1206 if (!convert && !type::check_(src)) {
1209 value = type::ensure(src);
1210 return static_cast<bool>(
value);
1219 template <
typename T>
1226 template <
typename T,
typename =
void>
1229 template <
typename T>
1237 template <
typename T>
1243 > (
const_name(
"numpy.float") + const_name<sizeof(T) * 8>(),
1247 template <
typename T>
1254 + const_name<sizeof(typename T::value_type) * 16>(),
1258 template <
typename T>
1282 static constexpr
int value = values[detail::is_fmt_numeric<T>::index];
1285 if (
auto *ptr =
npy_api::get().PyArray_DescrFromType_(value)) {
1286 return reinterpret_steal<pybind11::dtype>(ptr);
1292 #define PYBIND11_DECL_CHAR_FMT \ 1293 static constexpr auto name = const_name("S") + const_name<N>(); \ 1294 static pybind11::dtype dtype() { \ 1295 return pybind11::dtype(std::string("S") + std::to_string(N)); \ 1303 PYBIND11_DECL_CHAR_FMT
1305 #undef PYBIND11_DECL_CHAR_FMT 1307 template <
typename T>
1315 static constexpr
auto name 1320 return pybind11::dtype::from_args(
1325 template <
typename T>
1332 static pybind11::dtype
dtype() {
return base_descr::dtype(); }
1344 const std::type_info &tinfo,
1346 bool (*direct_converter)(PyObject *,
void *&)) {
1355 std::vector<field_descriptor> ordered_fields(std::move(fields));
1357 ordered_fields.begin(),
1358 ordered_fields.end(),
1362 for (
auto &field : ordered_fields) {
1364 pybind11_fail(std::string(
"NumPy: unsupported field dtype: `") + field.name +
"` @ " 1368 formats.append(field.descr);
1369 offsets.append(pybind11::int_(field.offset));
1372 = pybind11::dtype(std::move(names), std::move(formats), std::move(offsets), itemsize)
1384 std::ostringstream oss;
1391 for (
auto &field : ordered_fields) {
1392 if (field.offset > offset) {
1393 oss << (field.offset -
offset) <<
'x';
1395 oss << field.format <<
':' << field.name <<
':';
1396 offset = field.offset + field.size;
1398 if (itemsize > offset) {
1399 oss << (itemsize -
offset) <<
'x';
1402 auto format_str = oss.str();
1407 if (!
api.PyArray_EquivTypes_(dtype_ptr,
arr.dtype().ptr())) {
1411 auto tindex = std::type_index(tinfo);
1416 template <
typename T,
typename SFINAE>
1419 "Attempt to use a non-POD or unimplemented POD type as a numpy dtype");
1423 static pybind11::dtype
dtype() {
return reinterpret_borrow<pybind11::dtype>(dtype_ptr()); }
1445 if (!PyObject_TypeCheck(obj,
api.PyVoidArrType_Type_)) {
1448 if (
auto descr = reinterpret_steal<object>(
api.PyArray_DescrFromScalar_(obj))) {
1449 if (
api.PyArray_EquivTypes_(dtype_ptr(),
descr.ptr())) {
1458 #ifdef __CLION_IDE__ // replace heavy macro with dummy code for the IDE (doesn't affect code) 1459 # define PYBIND11_NUMPY_DTYPE(Type, ...) ((void) 0) 1460 # define PYBIND11_NUMPY_DTYPE_EX(Type, ...) ((void) 0) 1463 # define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \ 1464 ::pybind11::detail::field_descriptor { \ 1465 Name, offsetof(T, Field), sizeof(decltype(std::declval<T>().Field)), \ 1466 ::pybind11::format_descriptor<decltype(std::declval<T>().Field)>::format(), \ 1467 ::pybind11::detail::npy_format_descriptor< \ 1468 decltype(std::declval<T>().Field)>::dtype() \ 1472 # define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, # Field) 1476 # define PYBIND11_EVAL0(...) __VA_ARGS__ 1477 # define PYBIND11_EVAL1(...) PYBIND11_EVAL0(PYBIND11_EVAL0(PYBIND11_EVAL0(__VA_ARGS__))) 1478 # define PYBIND11_EVAL2(...) PYBIND11_EVAL1(PYBIND11_EVAL1(PYBIND11_EVAL1(__VA_ARGS__))) 1479 # define PYBIND11_EVAL3(...) PYBIND11_EVAL2(PYBIND11_EVAL2(PYBIND11_EVAL2(__VA_ARGS__))) 1480 # define PYBIND11_EVAL4(...) PYBIND11_EVAL3(PYBIND11_EVAL3(PYBIND11_EVAL3(__VA_ARGS__))) 1481 # define PYBIND11_EVAL(...) PYBIND11_EVAL4(PYBIND11_EVAL4(PYBIND11_EVAL4(__VA_ARGS__))) 1482 # define PYBIND11_MAP_END(...) 1483 # define PYBIND11_MAP_OUT 1484 # define PYBIND11_MAP_COMMA , 1485 # define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END 1486 # define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT 1487 # define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0(test, next, 0) 1488 # define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1(PYBIND11_MAP_GET_END test, next) 1489 # if defined(_MSC_VER) \ 1490 && !defined(__clang__) // MSVC is not as eager to expand macros, hence this workaround 1491 # define PYBIND11_MAP_LIST_NEXT1(test, next) \ 1492 PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)) 1494 # define PYBIND11_MAP_LIST_NEXT1(test, next) \ 1495 PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0) 1497 # define PYBIND11_MAP_LIST_NEXT(test, next) \ 1498 PYBIND11_MAP_LIST_NEXT1(PYBIND11_MAP_GET_END test, next) 1499 # define PYBIND11_MAP_LIST0(f, t, x, peek, ...) \ 1500 f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST1)(f, t, peek, __VA_ARGS__) 1501 # define PYBIND11_MAP_LIST1(f, t, x, peek, ...) \ 1502 f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST0)(f, t, peek, __VA_ARGS__) 1504 # define PYBIND11_MAP_LIST(f, t, ...) \ 1505 PYBIND11_EVAL(PYBIND11_MAP_LIST1(f, t, __VA_ARGS__, (), 0)) 1507 # define PYBIND11_NUMPY_DTYPE(Type, ...) \ 1508 ::pybind11::detail::npy_format_descriptor<Type>::register_dtype( \ 1509 ::std::vector<::pybind11::detail::field_descriptor>{ \ 1510 PYBIND11_MAP_LIST(PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)}) 1512 # if defined(_MSC_VER) && !defined(__clang__) 1513 # define PYBIND11_MAP2_LIST_NEXT1(test, next) \ 1514 PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)) 1516 # define PYBIND11_MAP2_LIST_NEXT1(test, next) \ 1517 PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0) 1519 # define PYBIND11_MAP2_LIST_NEXT(test, next) \ 1520 PYBIND11_MAP2_LIST_NEXT1(PYBIND11_MAP_GET_END test, next) 1521 # define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...) \ 1522 f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST1)(f, t, peek, __VA_ARGS__) 1523 # define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...) \ 1524 f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST0)(f, t, peek, __VA_ARGS__) 1526 # define PYBIND11_MAP2_LIST(f, t, ...) \ 1527 PYBIND11_EVAL(PYBIND11_MAP2_LIST1(f, t, __VA_ARGS__, (), 0)) 1529 # define PYBIND11_NUMPY_DTYPE_EX(Type, ...) \ 1530 ::pybind11::detail::npy_format_descriptor<Type>::register_dtype( \ 1531 ::std::vector<::pybind11::detail::field_descriptor>{ \ 1532 PYBIND11_MAP2_LIST(PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)}) 1534 #endif // __CLION_IDE__ 1545 : p_ptr(reinterpret_cast<char *>(ptr)), m_strides(strides.
size()) {
1546 m_strides.back() =
static_cast<value_type>(strides.back());
1547 for (
size_type i = m_strides.size() - 1;
i != 0; --
i) {
1550 m_strides[
j] = strides[
j] + m_strides[
i] - strides[
i] *
s;
1556 void *
data()
const {
return p_ptr; }
1559 char *p_ptr{
nullptr};
1569 : m_shape(shape.
size()), m_index(shape.
size(), 0), m_common_iterator() {
1572 for (
size_t i = 0;
i < shape.size(); ++
i) {
1573 m_shape[
i] = shape[
i];
1577 for (
size_t i = 0;
i <
N; ++
i) {
1578 init_common_iterator(buffers[
i], shape, m_common_iterator[i], strides);
1583 for (
size_t j = m_index.size();
j != 0; --
j) {
1585 if (++m_index[i] != m_shape[i]) {
1586 increment_common_iterator(i);
1594 template <
size_t K,
class T =
void>
1596 return reinterpret_cast<T *
>(m_common_iterator[
K].data());
1606 auto buffer_shape_iter = buffer.
shape.rbegin();
1607 auto buffer_strides_iter = buffer.
strides.rbegin();
1608 auto shape_iter = shape.rbegin();
1609 auto strides_iter = strides.rbegin();
1611 while (buffer_shape_iter != buffer.
shape.rend()) {
1612 if (*shape_iter == *buffer_shape_iter) {
1613 *strides_iter = *buffer_strides_iter;
1618 ++buffer_shape_iter;
1619 ++buffer_strides_iter;
1624 std::fill(strides_iter, strides.rend(), 0);
1629 for (
auto &
iter : m_common_iterator) {
1630 iter.increment(dim);
1647 broadcast(
const std::array<buffer_info, N> &buffers,
ssize_t &ndim, std::vector<ssize_t> &shape) {
1648 ndim = std::accumulate(
1654 shape.resize((
size_t) ndim, 1);
1658 for (
size_t i = 0;
i <
N; ++
i) {
1659 auto res_iter = shape.rbegin();
1660 auto end = buffers[
i].shape.rend();
1661 for (
auto shape_iter = buffers[
i].shape.rbegin(); shape_iter !=
end;
1662 ++shape_iter, ++res_iter) {
1663 const auto &dim_size_in = *shape_iter;
1664 auto &dim_size_out = *res_iter;
1668 if (dim_size_out == 1) {
1669 dim_size_out = dim_size_in;
1670 }
else if (dim_size_in != 1 && dim_size_in != dim_size_out) {
1671 pybind11_fail(
"pybind11::vectorize: incompatible size/dimension of inputs!");
1676 bool trivial_broadcast_c =
true;
1677 bool trivial_broadcast_f =
true;
1678 for (
size_t i = 0;
i < N && (trivial_broadcast_c || trivial_broadcast_f); ++
i) {
1679 if (buffers[
i].
size == 1) {
1684 if (buffers[
i].ndim != ndim) {
1689 if (!
std::equal(buffers[
i].shape.cbegin(), buffers[
i].shape.cend(), shape.cbegin())) {
1694 if (trivial_broadcast_c) {
1695 ssize_t expect_stride = buffers[
i].itemsize;
1696 auto end = buffers[
i].shape.crend();
1697 for (
auto shape_iter = buffers[
i].shape.crbegin(),
1698 stride_iter = buffers[
i].strides.crbegin();
1699 trivial_broadcast_c && shape_iter !=
end;
1700 ++shape_iter, ++stride_iter) {
1701 if (expect_stride == *stride_iter) {
1702 expect_stride *= *shape_iter;
1704 trivial_broadcast_c =
false;
1710 if (trivial_broadcast_f) {
1711 ssize_t expect_stride = buffers[
i].itemsize;
1712 auto end = buffers[
i].shape.cend();
1713 for (
auto shape_iter = buffers[
i].shape.cbegin(),
1714 stride_iter = buffers[
i].strides.cbegin();
1715 trivial_broadcast_f && shape_iter !=
end;
1716 ++shape_iter, ++stride_iter) {
1717 if (expect_stride == *stride_iter) {
1718 expect_stride *= *shape_iter;
1720 trivial_broadcast_f =
false;
1731 template <
typename T>
1734 "Functions with rvalue reference arguments cannot be vectorized");
1752 template <
typename Func,
typename Return,
typename... Args>
1765 static Return
call(Func &
f, Args &...
args) {
return f(args...); }
1771 template <
typename Func,
typename... Args>
1784 static void call(
void *,
size_t, Func &
f, Args &...
args) {
f(args...); }
1787 template <
typename Func,
typename Return,
typename... Args>
1797 static constexpr
size_t N =
sizeof...(Args);
1801 "pybind11::vectorize(...) requires a function with at least one vectorizable argument");
1804 template <
typename T,
1823 template <
size_t Index>
1835 template <
size_t...
Index,
size_t... VIndex,
size_t... BIndex>
1844 std::array<void *, N>
params{{&args...}};
1847 std::array<buffer_info, NVectorized> buffers{
1848 {
reinterpret_cast<array *
>(
params[VIndex])->request()...}};
1852 std::vector<ssize_t> shape(0);
1853 auto trivial =
broadcast(buffers, nd, shape);
1857 = std::accumulate(shape.begin(), shape.end(), (
size_t) 1, std::multiplies<size_t>());
1861 if (size == 1 && ndim == 0) {
1870 return std::move(
result);
1874 auto *mutable_data = returned_array::mutable_data(
result);
1876 apply_broadcast(buffers,
params, mutable_data, size, shape, i_seq, vi_seq, bi_seq);
1878 apply_trivial(buffers,
params, mutable_data, size, i_seq, vi_seq, bi_seq);
1881 return std::move(
result);
1884 template <
size_t...
Index,
size_t... VIndex,
size_t... BIndex>
1886 std::array<void *, N> &
params,
1896 std::array<std::pair<unsigned char *&, const size_t>, NVectorized> vecparams{
1897 {std::pair<unsigned char *&, const size_t>(
1898 reinterpret_cast<unsigned char *&
>(params[VIndex] = buffers[BIndex].ptr),
1901 for (
size_t i = 0;
i <
size; ++
i) {
1902 returned_array::call(
1904 for (
auto &
x : vecparams) {
1905 x.first +=
x.second;
1910 template <
size_t...
Index,
size_t... VIndex,
size_t... BIndex>
1912 std::array<void *, N> &
params,
1915 const std::vector<ssize_t> &output_shape,
1922 for (
size_t i = 0;
i <
size; ++
i, ++input_iter) {
1924 returned_array::call(
1930 template <
typename Func,
typename Return,
typename... Args>
1932 return detail::vectorize_helper<Func, Return, Args...>(
f);
1935 template <
typename T,
int Flags>
1937 static constexpr
auto name 1944 template <
typename Return,
typename... Args>
1945 detail::vectorize_helper<Return (*)(Args...), Return, Args...>
vectorize(Return (*f)(Args...)) {
1946 return detail::vectorize_helper<Return (*)(Args...), Return, Args...>(
f);
1953 (detail::function_signature_t<Func> *)
nullptr)) {
1955 (detail::function_signature_t<Func> *)
nullptr);
1959 template <
typename Return,
1962 typename Helper = detail::vectorize_helper<
1963 decltype(std::mem_fn(std::declval<Return (Class::*)(Args...)>())),
1968 return Helper(std::mem_fn(f));
1972 template <
typename Return,
1975 typename Helper = detail::vectorize_helper<
1976 decltype(std::mem_fn(std::declval<Return (Class::*)(Args...)
const>())),
1980 Helper
vectorize(Return (Class::*f)(Args...)
const) {
1981 return Helper(std::mem_fn(f));
typename std::conditional< B, T, F >::type conditional_t
PYBIND11_NOINLINE detail::type_info * get_type_info(PyTypeObject *type)
detail::unchecked_reference< T, Dims > unchecked() const &
void apply_broadcast(std::array< buffer_info, NVectorized > &buffers, std::array< void *, N > ¶ms, Return *out, size_t size, const std::vector< ssize_t > &output_shape, index_sequence< Index... >, index_sequence< VIndex... >, index_sequence< BIndex... >)
array(ssize_t count, const T *ptr, handle base=handle())
ssize_t ndim() const
Number of dimensions.
array view(const std::string &dtype)
std::vector< Eigen::Index > Dims
enable_if_t<!Dyn, ssize_t > size() const
all_of< std::is_standard_layout< T >, std::is_trivially_copyable< T >, satisfies_none_of< T, std::is_reference, std::is_array, is_std_array, std::is_arithmetic, is_complex, std::is_enum > > is_pod_struct
void * mutable_data(Ix... index)
static Type create(broadcast_trivial, const std::vector< ssize_t > &)
detail::any_container< ssize_t > ShapeContainer
int flags() const
Return the NumPy array flags.
static void call(void *, size_t, Func &f, Args &...args)
static dtype from_args(const object &args)
This is essentially the same as calling numpy.dtype(args) in Python.
std::vector< ssize_t > strides
ssize_t offset_at(Ix... index) const
const ssize_t * strides() const
Strides of the array.
vectorize_helper< Func, Return, Args... > vectorize_extractor(const Func &f, Return(*)(Args...))
ssize_t index_at(Ix... index) const
PYBIND11_NOINLINE void register_structured_dtype(any_container< field_descriptor > fields, const std::type_info &tinfo, ssize_t itemsize, bool(*direct_converter)(PyObject *, void *&))
ssize_t itemsize() const
Byte size of a single element.
PYBIND11_NOINLINE void load_numpy_internals(numpy_internals *&ptr)
array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base=handle())
PYBIND11_DEPRECATED("make_simple_namespace should be replaced with " "py::module_::import(\ypes\.attr(\impleNamespace\ ") object make_simple_namespace(Args &&...args_)
constexpr int platform_lookup()
std::ofstream out("Result.txt")
const T & at(Ix... index) const
const ssize_t * shape() const
Dimensions of the array.
std::array< common_iter, N > m_common_iterator
PyTypeObject * PyArray_Type_
#define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN)
#define PYBIND11_SILENCE_MSVC_C4127(...)
std::tuple< typename vectorize_arg< Args >::call_type... > arg_call_types
static Return call(Func &f, Args &...args)
static object _dtype_from_pep3118()
PYBIND11_NOINLINE internals & get_internals()
Return a reference to the current internals data.
array(const pybind11::dtype &dt, ShapeContainer shape, StridesContainer strides, const void *ptr=nullptr, handle base=handle())
#define DECL_NPY_API(Func)
PyArrayDescr_Proxy * descr
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate offset
Wrapper for Python extension modules.
array_t(ShapeContainer shape, StridesContainer strides, const T *ptr=nullptr, handle base=handle())
static Cal3_S2 K(500, 500, 0.1, 640/2, 480/2)
void check_dimensions(Ix... index) const
iterator iter(handle obj)
dtype strip_padding(ssize_t itemsize)
bool owndata() const
If set, the array owns the data (will be freed when the array is deleted)
static void append_extents(list &shape)
PyObject_HEAD char * data
array_t(handle h, borrowed_t)
remove_reference_t< T > call_type
#define PYBIND11_NAMESPACE
T * mutable_data(Ix... ix)
Mutable pointer access to the data at the given indices.
multi_array_iterator & operator++()
static Type create(broadcast_trivial trivial, const std::vector< ssize_t > &shape)
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun)
PyObject_HEAD PyObject * typeobj
constexpr size_t constexpr_sum()
Compile-time integer sum.
void increment(size_type dim)
unsigned int(* PyArray_GetNDArrayCFeatureVersion_)()
static const SmartProjectionParams params
static bool compare(const buffer_info &b)
static Return * mutable_data(Type &array)
PyExc_RuntimeError [[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
bool has_fields() const
Returns true for structured data types.
bool PyArray_Check_(PyObject *obj) const
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
const handle & inc_ref() const &
constexpr ssize_t itemsize() const
dtype(const pybind11::str &format)
static void call(Return *out, size_t i, Func &f, Args &...args)
PyArrayDescr_Proxy * array_descriptor_proxy(PyObject *ptr)
typename select_indices_impl< index_sequence<>, 0, Bs... >::type select_indices
void init_common_iterator(const buffer_info &buffer, const container_type &shape, common_iter &iterator, container_type &strides)
detail::vectorize_helper< Return(*)(Args...), Return, Args... > vectorize(Return(*f)(Args...))
typename std::tuple_element< Index, arg_call_types >::type param_n_t
std::vector< ssize_t > c_strides(const std::vector< ssize_t > &shape, ssize_t itemsize)
ssize_t nbytes() const
Total number of bytes.
numpy_type_info * get_type_info(bool throw_if_missing=true)
PyObject_VAR_HEAD char * obval
detail::unchecked_reference< T, Dims > unchecked() const &
std::vector< ssize_t > container_type
multi_array_iterator(const std::array< buffer_info, N > &buffers, const container_type &shape)
static detail::void_type call(Func &f, Args &...args)
array(ShapeContainer shape, const T *ptr, handle base=handle())
array_t(const buffer_info &info, handle base=handle())
EIGEN_ALWAYS_INLINE DSizes< IndexType, NumDims > strides(const DSizes< IndexType, NumDims > &dimensions)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
ssize_t offset_at() const
object run(typename vectorize_arg< Args >::type &...args, index_sequence< Index... > i_seq, index_sequence< VIndex... > vi_seq, index_sequence< BIndex... > bi_seq)
type_map< std::vector< bool(*)(PyObject *, void *&)> > direct_conversions
unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t< Dyn, ssize_t > dims)
std::integral_constant< bool, B > bool_constant
Backports of std::bool_constant and std::negation to accommodate older compilers. ...
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
Eigen::Triplet< double > T
enable_if_t< Dyn, ssize_t > size() const
#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun)
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
#define PYBIND11_DECL_CHAR_FMT
container_type::value_type value_type
std::unordered_map< std::type_index, numpy_type_info > registered_dtypes
dtype(const std::string &format)
typename std::remove_reference< T >::type remove_reference_t
std::vector< ssize_t > container_type
ssize_t byte_offset_unsafe(const Strides &)
constexpr descr< 0 > concat()
detail::any_container< ssize_t > StridesContainer
array(const buffer_info &info, handle base=handle())
static void append_extents(list &)
int num() const
type number of dtype.
static dtype of()
Return dtype associated with a C++ type.
static array_t ensure(handle h)
array(const pybind11::dtype &dt, ShapeContainer shape, const void *ptr=nullptr, handle base=handle())
std::vector< ssize_t > f_strides(const std::vector< ssize_t > &shape, ssize_t itemsize)
conditional_t< Dynamic, const ssize_t *, std::array< ssize_t,(size_t) Dims > > strides_
const unsigned char * data_
array(const pybind11::dtype &dt, T count, const void *ptr=nullptr, handle base=handle())
T & operator[](ssize_t index)
std::vector< ssize_t > shape
static constexpr ssize_t itemsize()
Returns the item size, i.e. sizeof(T)
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set offsets
unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t<!Dyn, ssize_t >)
void apply_trivial(std::array< buffer_info, NVectorized > &buffers, std::array< void *, N > ¶ms, Return *out, size_t size, index_sequence< Index... >, index_sequence< VIndex... >, index_sequence< BIndex... >)
T & operator()(Ix... index)
Mutable, unchecked access to data at the given indices.
void increment_common_iterator(size_t dim)
PyTypeObject * PyArrayDescr_Type_
static PyObject * raw_array(PyObject *ptr, int ExtraFlags=0)
Create array from any object – always returns a new reference.
std::is_same< bools< Ts::value..., true >, bools< true, Ts::value... > > all_of
const T * data(Ix... index) const
T * mutable_data(Ix... index)
pybind11::dtype dtype() const
Array descriptor (dtype)
const T & operator[](ssize_t index) const
remove_reference_t< Func > f
static void * mutable_data(Type &)
ssize_t byte_offset(Ix... index) const
object operator()(typename vectorize_arg< Args >::type... args)
static array ensure(handle h, int ExtraFlags=0)
ssize_t size() const
Total number of elements.
const T & operator()(Ix... index) const
ADT create(const Signature &signature)
static module_ import(const char *name)
Import and return a module or throws error_already_set.
array_t(handle h, stolen_t)
static bool check_(handle h)
int alignment() const
Alignment of the data type.
static EIGEN_DEPRECATED const end_t end
detail::unchecked_mutable_reference< T, Dims > mutable_unchecked() &
std::string format(const std::string &str, const std::vector< std::string > &find, const std::vector< std::string > &replace)
dtype(const buffer_info &info)
array reshape(ShapeContainer new_shape)
Optional order parameter omitted, to be added as needed.
bool PyArrayDescr_Check_(PyObject *obj) const
void check_dimensions_impl(ssize_t, const ssize_t *) const
detail::unchecked_mutable_reference< T, Dims > mutable_unchecked() &
void check_writeable() const
T & mutable_at(Ix... index)
conditional_t< vectorize, array_t< remove_cv_t< call_type >, array::forcecast >, T > type
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
dtype(const char *format)
numpy_type_info * get_type_info(const std::type_info &tinfo, bool throw_if_missing=true)
void check_dimensions_impl(ssize_t axis, const ssize_t *shape, ssize_t i, Ix... index) const
ssize_t index_at(Ix... index) const
array_t(private_ctor, ShapeContainer &&shape, StridesContainer &&strides, const T *ptr, handle base)
array squeeze()
Return a new view with all of the dimensions of length 1 removed.
Annotation for function names.
array_t(ssize_t count, const T *ptr=nullptr, handle base=handle())
Annotation indicating that a class derives from another given type.
const void * data(Ix... index) const
Information record describing a Python buffer object.
common_iterator(void *ptr, const container_type &strides, const container_type &shape)
PyObject * ptr() const
Return the underlying PyObject * pointer.
char byteorder() const
Single character for byteorder.
py::ssize_t offset_at(const arr &a, Ix... idx)
ssize_t ndim() const
Returns the number of dimensions of the array.
Container::iterator get(Container &c, Position position)
all_of< std::is_standard_layout< T >, std::is_trivial< T > > is_pod
bool check_flags(const void *ptr, int flag)
PyTypeObject * PyVoidArrType_Type_
bool_constant< sizeof(T)==sizeof(U)> as
static PyObject * raw_array_t(PyObject *ptr)
Create array from any object – always returns a new reference.
numpy_internals & get_numpy_internals()
bool equal(const T &obj1, const T &obj2, double tol)
size_t len(handle h)
Get the length of a Python object.
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
ssize_t itemsize() const
Size of the data type in bytes.
const T * data(Ix... ix) const
Pointer access to the data at the given indices.
container_type::size_type size_type
internal::enable_if< internal::valid_indexed_view_overload< RowIndices, ColIndices >::value &&internal::traits< typename EIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::ReturnAsIndexedView, typename EIGEN_INDEXED_VIEW_METHOD_TYPE< RowIndices, ColIndices >::type >::type operator()(const RowIndices &rowIndices, const ColIndices &colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
constexpr descr< N - 1 > const_name(char const (&text)[N])
void fail_dim_check(ssize_t dim, const std::string &msg) const
typename make_index_sequence_impl< N >::type make_index_sequence
#define PYBIND11_NOINLINE
array_t(ShapeContainer shape, const T *ptr=nullptr, handle base=handle())
static constexpr auto name
void resize(ShapeContainer new_shape, bool refcheck=true)
return_value_policy
Approach used to cast a previously unknown C++ instance into a Python object.
dtype(list names, list formats, list offsets, ssize_t itemsize)
#define PYBIND11_TYPE_CASTER(type, py_name)
char flags() const
Flags for the array descriptor.
#define PYBIND11_NAMESPACE_END(name)
static BinaryMeasurement< Rot3 > convert(const BetweenFactor< Pose3 >::shared_ptr &f)
broadcast_trivial broadcast(const std::array< buffer_info, N > &buffers, ssize_t &ndim, std::vector< ssize_t > &shape)
#define PYBIND11_NAMESPACE_BEGIN(name)
ssize_t shape(ssize_t dim) const
Dimension along a given axis.
PyArray_Proxy * array_proxy(void *ptr)
object base() const
Base object.
typename array_info< T >::type remove_all_extents_t
ssize_t shape(ssize_t dim) const
Returns the shape (i.e. size) of dimension dim
bool(* PyArray_EquivTypes_)(PyObject *, PyObject *)
ssize_t strides(ssize_t dim) const
Stride along a given axis.
bool writeable() const
If set, the array is writeable (otherwise the buffer is read-only)