28 # pragma warning(push) 29 # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 36 static_assert(
sizeof(
ssize_t) ==
sizeof(Py_intptr_t),
"ssize_t != Py_intptr_t");
91 auto it = registered_dtypes.find(std::type_index(tinfo));
92 if (it != registered_dtypes.end())
95 pybind11_fail(std::string(
"NumPy type info missing for ") + tinfo.name());
105 ptr = &get_or_create_shared_data<numpy_internals>(
"_numpy_internals");
122 template <
typename Concrete,
typename T,
typename... Ts,
typename... Ints>
124 return sizeof(Concrete) ==
sizeof(T) ? I :
platform_lookup<Concrete, Ts...>(Is...);
129 NPY_ARRAY_C_CONTIGUOUS_ = 0x0001,
130 NPY_ARRAY_F_CONTIGUOUS_ = 0x0002,
131 NPY_ARRAY_OWNDATA_ = 0x0004,
132 NPY_ARRAY_FORCECAST_ = 0x0010,
133 NPY_ARRAY_ENSUREARRAY_ = 0x0040,
134 NPY_ARRAY_ALIGNED_ = 0x0100,
135 NPY_ARRAY_WRITEABLE_ = 0x0400,
147 NPY_INT8_ = NPY_BYTE_,
148 NPY_UINT8_ = NPY_UBYTE_,
149 NPY_INT16_ = NPY_SHORT_,
150 NPY_UINT16_ = NPY_USHORT_,
154 NPY_INT32_ = platform_lookup<std::int32_t, long, int, short>(
155 NPY_LONG_, NPY_INT_, NPY_SHORT_),
156 NPY_UINT32_ = platform_lookup<std::uint32_t, unsigned long, unsigned int, unsigned short>(
157 NPY_ULONG_, NPY_UINT_, NPY_USHORT_),
158 NPY_INT64_ = platform_lookup<std::int64_t, long, long long, int>(
159 NPY_LONG_, NPY_LONGLONG_, NPY_INT_),
160 NPY_UINT64_ = platform_lookup<std::uint64_t, unsigned long, unsigned long long, unsigned int>(
161 NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),
175 return (
bool) PyObject_TypeCheck(obj, PyArray_Type_);
178 return (
bool) PyObject_TypeCheck(obj, PyArrayDescr_Type_);
181 unsigned int (*PyArray_GetNDArrayCFeatureVersion_)();
182 PyObject *(*PyArray_DescrFromType_)(
int);
183 PyObject *(*PyArray_NewFromDescr_)
184 (PyTypeObject *, PyObject *,
int, Py_intptr_t
const *,
185 Py_intptr_t
const *,
void *,
int, PyObject *);
187 PyObject *(*PyArray_DescrNewFromType_)(
int);
188 int (*PyArray_CopyInto_)(PyObject *, PyObject *);
189 PyObject *(*PyArray_NewCopy_)(PyObject *,
int);
193 PyObject *(*PyArray_DescrFromScalar_)(PyObject *);
194 PyObject *(*PyArray_FromAny_) (PyObject *, PyObject *,
int,
int,
int, PyObject *);
195 int (*PyArray_DescrConverter_) (PyObject *, PyObject **);
196 bool (*PyArray_EquivTypes_) (PyObject *, PyObject *);
197 int (*PyArray_GetArrayParamsFromObject_)(PyObject *, PyObject *,
unsigned char, PyObject **,
int *,
198 Py_intptr_t *, PyObject **, PyObject *);
199 PyObject *(*PyArray_Squeeze_)(PyObject *);
201 int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);
205 API_PyArray_GetNDArrayCFeatureVersion = 211,
206 API_PyArray_Type = 2,
207 API_PyArrayDescr_Type = 3,
208 API_PyVoidArrType_Type = 39,
209 API_PyArray_DescrFromType = 45,
210 API_PyArray_DescrFromScalar = 57,
211 API_PyArray_FromAny = 69,
212 API_PyArray_Resize = 80,
213 API_PyArray_CopyInto = 82,
214 API_PyArray_NewCopy = 85,
215 API_PyArray_NewFromDescr = 94,
216 API_PyArray_DescrNewFromType = 96,
217 API_PyArray_DescrConverter = 174,
218 API_PyArray_EquivTypes = 182,
219 API_PyArray_GetArrayParamsFromObject = 278,
220 API_PyArray_Squeeze = 136,
221 API_PyArray_SetBaseObject = 282
226 auto c = m.attr(
"_ARRAY_API");
227 #if PY_MAJOR_VERSION >= 3 228 void **api_ptr = (
void **) PyCapsule_GetPointer(
c.ptr(),
NULL);
230 void **api_ptr = (
void **) PyCObject_AsVoidPtr(
c.ptr());
233 #define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func]; 236 pybind11_fail(
"pybind11 numpy support requires numpy >= 1.7.0");
280 template <
typename T>
struct is_complex : std::false_type { };
285 static constexpr
bool is_array =
false;
286 static constexpr
bool is_empty =
false;
287 static constexpr
auto extents =
_(
"");
296 static constexpr
bool is_array =
true;
298 static constexpr
size_t extent =
N;
306 static constexpr
auto extents = _<array_info<T>::is_array>(
318 std::is_standard_layout<T>,
319 #if !defined(__GNUG__) || defined(_LIBCPP_VERSION) || defined(_GLIBCXX_USE_CXX11_ABI) 322 std::is_trivially_copyable<T>,
325 std::is_trivially_destructible<T>,
332 template <
ssize_t Dim = 0,
typename Strides,
typename... Ix>
334 return i * strides[Dim] + byte_offset_unsafe<Dim + 1>(strides, index...);
342 template <
typename T, s
size_t Dims>
355 template <
bool Dyn = Dynamic>
357 : data_{
reinterpret_cast<const unsigned char *
>(
data)}, dims_{Dims} {
358 for (
size_t i = 0;
i < (
size_t) dims_;
i++) {
359 shape_[
i] = shape[
i];
360 strides_[
i] = strides[
i];
364 template <
bool Dyn = Dynamic>
366 : data_{
reinterpret_cast<const unsigned char *
>(
data)}, shape_{shape}, strides_{strides}, dims_{dims} {}
374 template <
typename... Ix>
const T &
operator()(Ix... index)
const {
375 static_assert(
ssize_t{
sizeof...(Ix)} == Dims || Dynamic,
376 "Invalid number of indices for unchecked array reference");
383 template <s
size_t D = Dims,
typename = enable_if_t<D == 1 || Dynamic>>
387 template <
typename... Ix>
const T *
data(Ix... ix)
const {
return &operator()(
ssize_t(ix)...); }
399 template <
bool Dyn = Dynamic>
401 return std::accumulate(shape_.begin(), shape_.end(), (
ssize_t) 1, std::multiplies<ssize_t>());
403 template <
bool Dyn = Dynamic>
405 return std::accumulate(shape_, shape_ + ndim(), (
ssize_t) 1, std::multiplies<ssize_t>());
411 return size() * itemsize();
415 template <
typename T, s
size_t Dims>
419 using ConstBase::ConstBase;
425 "Invalid number of indices for unchecked array reference");
426 return const_cast<T &
>(ConstBase::operator()(index...));
433 template <s
size_t D = Dims,
typename = enable_if_t<D == 1 || Dynamic>>
440 template <
typename T, s
size_t Dim>
442 static_assert(Dim == 0 && Dim > 0 ,
"unchecked array proxy object is not castable");
444 template <
typename T, s
size_t Dim>
459 explicit dtype(
const std::string &format) {
467 args[
"names"] =
names;
468 args[
"formats"] = formats;
470 args[
"itemsize"] = pybind11::int_(itemsize);
471 m_ptr = from_args(args).release().ptr();
476 PyObject *
ptr =
nullptr;
479 return reinterpret_steal<dtype>(
ptr);
505 .attr(
"_dtype_from_pep3118").
cast<
object>().
release().ptr();
506 return reinterpret_borrow<object>(obj);
516 std::vector<field_descr> field_descriptors;
518 for (
auto field : attr(
"fields").attr(
"items")()) {
521 auto format = spec[1].cast<
tuple>()[0].cast<dtype>();
523 if (!
len(name) && format.kind() ==
'V')
528 std::sort(field_descriptors.begin(), field_descriptors.end(),
529 [](
const field_descr&
a,
const field_descr&
b) {
530 return a.offset.cast<
int>() <
b.offset.cast<
int>();
534 for (
auto&
descr : field_descriptors) {
535 names.append(
descr.name);
536 formats.append(
descr.format);
537 offsets.append(
descr.offset);
539 return dtype(names, formats, offsets, itemsize);
548 c_style = detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_,
549 f_style = detail::npy_api::NPY_ARRAY_F_CONTIGUOUS_,
550 forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_
562 if (strides->empty())
563 *strides = c_strides(*shape, dt.itemsize());
565 auto ndim = shape->size();
566 if (ndim != strides->size())
567 pybind11_fail(
"NumPy: shape ndim doesn't match strides ndim");
572 if (isinstance<array>(
base))
577 flags = detail::npy_api::NPY_ARRAY_WRITEABLE_;
581 auto tmp = reinterpret_steal<object>(api.PyArray_NewFromDescr_(
582 api.PyArray_Type_,
descr.release().ptr(), (
int) ndim, shape->data(), strides->data(),
583 const_cast<void *
>(
ptr), flags,
nullptr));
588 api.PyArray_SetBaseObject_(tmp.ptr(),
base.inc_ref().ptr());
590 tmp = reinterpret_steal<object>(api.PyArray_NewCopy_(tmp.ptr(), -1 ));
593 m_ptr = tmp.release().ptr();
603 template <
typename T>
607 template <
typename T>
611 template <
typename T>
624 return std::accumulate(shape(), shape() + ndim(), (
ssize_t) 1, std::multiplies<ssize_t>());
634 return size() * itemsize();
655 fail_dim_check(dim,
"invalid axis");
667 fail_dim_check(dim,
"invalid axis");
668 return strides()[
dim];
688 template<
typename... Ix>
const void*
data(Ix... index)
const {
703 if ((
ssize_t)
sizeof...(index) > ndim())
704 fail_dim_check(
sizeof...(index),
"too many indices for an array");
705 return byte_offset(
ssize_t(index)...);
723 if (Dims >= 0 && ndim() != Dims)
724 throw std::domain_error(
"array has incorrect number of dimensions: " + std::to_string(ndim()) +
725 "; expected " + std::to_string(Dims));
726 return detail::unchecked_mutable_reference<T, Dims>(mutable_data(), shape(), strides(), ndim());
736 template <
typename T,
ssize_t Dims = -1> detail::unchecked_reference<T, Dims>
unchecked() const & {
737 if (Dims >= 0 && ndim() != Dims)
738 throw std::domain_error(
"array has incorrect number of dimensions: " + std::to_string(ndim()) +
739 "; expected " + std::to_string(Dims));
740 return detail::unchecked_reference<T, Dims>(
data(), shape(), strides(), ndim());
746 return reinterpret_steal<array>(api.PyArray_Squeeze_(m_ptr));
753 detail::npy_api::PyArray_Dims
d = {
754 new_shape->data(),
int(new_shape->size())
757 object new_array = reinterpret_steal<object>(
761 if (isinstance<array>(new_array)) { *
this = std::move(new_array); }
767 auto result = reinterpret_steal<array>(raw_array(h.
ptr(), ExtraFlags));
774 template<
typename,
typename>
friend struct detail::npy_format_descriptor;
777 throw index_error(msg +
": " + std::to_string(dim) +
778 " (ndim = " + std::to_string(ndim()) +
")");
782 check_dimensions(index...);
788 throw std::domain_error(
"array is not writeable");
792 static std::vector<ssize_t>
c_strides(
const std::vector<ssize_t> &shape,
ssize_t itemsize) {
793 auto ndim = shape.size();
794 std::vector<ssize_t> strides(ndim, itemsize);
796 for (
size_t i = ndim - 1;
i > 0; --
i)
797 strides[
i - 1] = strides[
i] * shape[
i];
802 static std::vector<ssize_t>
f_strides(
const std::vector<ssize_t> &shape,
ssize_t itemsize) {
803 auto ndim = shape.size();
804 std::vector<ssize_t> strides(ndim, itemsize);
805 for (
size_t i = 1;
i < ndim; ++
i)
806 strides[
i] = strides[
i - 1] * shape[
i - 1];
818 throw index_error(std::string(
"index ") + std::to_string(i) +
819 " is out of bounds for axis " + std::to_string(axis) +
820 " with size " + std::to_string(*shape));
822 check_dimensions_impl(axis + 1, shape + 1, index...);
826 static PyObject *
raw_array(PyObject *ptr,
int ExtraFlags = 0) {
827 if (ptr ==
nullptr) {
828 PyErr_SetString(PyExc_ValueError,
"cannot create a pybind11::array from a nullptr");
832 ptr,
nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags,
nullptr);
836 template <
typename T,
int ExtraFlags = array::forcecast>
class array_t :
public array {
843 static_assert(!detail::array_info<T>::is_array,
"Array types cannot be used with array_t");
853 if (!m_ptr) PyErr_Clear();
854 if (!is_borrowed) Py_XDECREF(
h.ptr());
867 :
array_t(private_ctor{}, std::move(shape),
868 ExtraFlags & f_style ? f_strides(*shape, itemsize()) : c_strides(*shape, itemsize()),
882 template<
typename... Ix>
const T*
data(Ix... index)
const {
883 return static_cast<const T*
>(
array::data(index...));
891 template<
typename... Ix>
const T&
at(Ix... index)
const {
892 if ((
ssize_t)
sizeof...(index) != ndim())
893 fail_dim_check(
sizeof...(index),
"index dimension mismatch");
894 return *(
static_cast<const T*
>(
array::data()) + byte_offset(
ssize_t(index)...) / itemsize());
899 if ((
ssize_t)
sizeof...(index) != ndim())
900 fail_dim_check(
sizeof...(index),
"index dimension mismatch");
911 return array::mutable_unchecked<T, Dims>();
922 return array::unchecked<T, Dims>();
928 auto result = reinterpret_steal<array_t>(raw_array_t(h.
ptr()));
936 return api.PyArray_Check_(h.
ptr())
944 if (ptr ==
nullptr) {
945 PyErr_SetString(PyExc_ValueError,
"cannot create a pybind11::array_t from a nullptr");
950 detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags,
nullptr);
954 template <
typename T>
962 static std::string
format() {
return std::to_string(
N) +
"s"; }
965 static std::string
format() {
return std::to_string(
N) +
"s"; }
968 template <
typename T>
976 template <
typename T>
986 template <
typename T,
int ExtraFlags>
991 if (!convert && !type::check_(src))
993 value = type::ensure(src);
994 return static_cast<bool>(
value);
1003 template <
typename T>
1010 template <
typename T,
typename =
void>
1013 template <
typename T>
1020 template <
typename T>
1023 _(
"numpy.float") + _<sizeof(T)*8>(),
_(
"numpy.longdouble")
1027 template <
typename T>
1031 _(
"numpy.complex") + _<sizeof(typename T::value_type)*16>(),
_(
"numpy.longcomplex")
1035 template <
typename T>
1049 static constexpr
int value = values[detail::is_fmt_numeric<T>::index];
1052 if (
auto ptr =
npy_api::get().PyArray_DescrFromType_(value))
1053 return reinterpret_steal<pybind11::dtype>(
ptr);
1058 #define PYBIND11_DECL_CHAR_FMT \ 1059 static constexpr auto name = _("S") + _<N>(); \ 1060 static pybind11::dtype dtype() { return pybind11::dtype(std::string("S") + std::to_string(N)); } 1063 #undef PYBIND11_DECL_CHAR_FMT 1084 static pybind11::dtype
dtype() {
return base_descr::dtype(); }
1097 const std::type_info& tinfo,
ssize_t itemsize,
1098 bool (*direct_converter)(PyObject *,
void *&)) {
1106 std::vector<field_descriptor> ordered_fields(std::move(fields));
1107 std::sort(ordered_fields.begin(), ordered_fields.end(),
1111 for (
auto& field : ordered_fields) {
1113 pybind11_fail(std::string(
"NumPy: unsupported field dtype: `") +
1114 field.name +
"` @ " + tinfo.name());
1116 formats.append(field.descr);
1117 offsets.append(pybind11::int_(field.offset));
1119 auto dtype_ptr = pybind11::dtype(names, formats, offsets, itemsize).release().ptr();
1129 std::ostringstream oss;
1136 for (
auto& field : ordered_fields) {
1137 if (field.offset > offset)
1138 oss << (field.offset -
offset) <<
'x';
1139 oss << field.format <<
':' << field.name <<
':';
1140 offset = field.offset + field.size;
1142 if (itemsize > offset)
1143 oss << (itemsize -
offset) <<
'x';
1145 auto format_str = oss.str();
1150 if (!api.PyArray_EquivTypes_(dtype_ptr,
arr.dtype().ptr()))
1153 auto tindex = std::type_index(tinfo);
1159 static_assert(
is_pod_struct<T>::value,
"Attempt to use a non-POD or unimplemented POD type as a numpy dtype");
1164 return reinterpret_borrow<pybind11::dtype>(dtype_ptr());
1174 sizeof(T), &direct_converter);
1185 if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_))
1187 if (
auto descr = reinterpret_steal<object>(api.PyArray_DescrFromScalar_(obj))) {
1188 if (api.PyArray_EquivTypes_(dtype_ptr(),
descr.ptr())) {
1197 #ifdef __CLION_IDE__ // replace heavy macro with dummy code for the IDE (doesn't affect code) 1198 # define PYBIND11_NUMPY_DTYPE(Type, ...) ((void)0) 1199 # define PYBIND11_NUMPY_DTYPE_EX(Type, ...) ((void)0) 1202 #define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \ 1203 ::pybind11::detail::field_descriptor { \ 1204 Name, offsetof(T, Field), sizeof(decltype(std::declval<T>().Field)), \ 1205 ::pybind11::format_descriptor<decltype(std::declval<T>().Field)>::format(), \ 1206 ::pybind11::detail::npy_format_descriptor<decltype(std::declval<T>().Field)>::dtype() \ 1210 #define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #Field) 1214 #define PYBIND11_EVAL0(...) __VA_ARGS__ 1215 #define PYBIND11_EVAL1(...) PYBIND11_EVAL0 (PYBIND11_EVAL0 (PYBIND11_EVAL0 (__VA_ARGS__))) 1216 #define PYBIND11_EVAL2(...) PYBIND11_EVAL1 (PYBIND11_EVAL1 (PYBIND11_EVAL1 (__VA_ARGS__))) 1217 #define PYBIND11_EVAL3(...) PYBIND11_EVAL2 (PYBIND11_EVAL2 (PYBIND11_EVAL2 (__VA_ARGS__))) 1218 #define PYBIND11_EVAL4(...) PYBIND11_EVAL3 (PYBIND11_EVAL3 (PYBIND11_EVAL3 (__VA_ARGS__))) 1219 #define PYBIND11_EVAL(...) PYBIND11_EVAL4 (PYBIND11_EVAL4 (PYBIND11_EVAL4 (__VA_ARGS__))) 1220 #define PYBIND11_MAP_END(...) 1221 #define PYBIND11_MAP_OUT 1222 #define PYBIND11_MAP_COMMA , 1223 #define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END 1224 #define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT 1225 #define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0 (test, next, 0) 1226 #define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1 (PYBIND11_MAP_GET_END test, next) 1227 #if defined(_MSC_VER) && !defined(__clang__) // MSVC is not as eager to expand macros, hence this workaround 1228 #define PYBIND11_MAP_LIST_NEXT1(test, next) \ 1229 PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) 1231 #define PYBIND11_MAP_LIST_NEXT1(test, next) \ 1232 PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) 1234 #define PYBIND11_MAP_LIST_NEXT(test, next) \ 1235 PYBIND11_MAP_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) 1236 #define PYBIND11_MAP_LIST0(f, t, x, peek, ...) \ 1237 f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST1) (f, t, peek, __VA_ARGS__) 1238 #define PYBIND11_MAP_LIST1(f, t, x, peek, ...) \ 1239 f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST0) (f, t, peek, __VA_ARGS__) 1241 #define PYBIND11_MAP_LIST(f, t, ...) \ 1242 PYBIND11_EVAL (PYBIND11_MAP_LIST1 (f, t, __VA_ARGS__, (), 0)) 1244 #define PYBIND11_NUMPY_DTYPE(Type, ...) \ 1245 ::pybind11::detail::npy_format_descriptor<Type>::register_dtype \ 1246 (::std::vector<::pybind11::detail::field_descriptor> \ 1247 {PYBIND11_MAP_LIST (PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)}) 1249 #if defined(_MSC_VER) && !defined(__clang__) 1250 #define PYBIND11_MAP2_LIST_NEXT1(test, next) \ 1251 PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) 1253 #define PYBIND11_MAP2_LIST_NEXT1(test, next) \ 1254 PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) 1256 #define PYBIND11_MAP2_LIST_NEXT(test, next) \ 1257 PYBIND11_MAP2_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) 1258 #define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...) \ 1259 f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST1) (f, t, peek, __VA_ARGS__) 1260 #define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...) \ 1261 f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST0) (f, t, peek, __VA_ARGS__) 1263 #define PYBIND11_MAP2_LIST(f, t, ...) \ 1264 PYBIND11_EVAL (PYBIND11_MAP2_LIST1 (f, t, __VA_ARGS__, (), 0)) 1266 #define PYBIND11_NUMPY_DTYPE_EX(Type, ...) \ 1267 ::pybind11::detail::npy_format_descriptor<Type>::register_dtype \ 1268 (::std::vector<::pybind11::detail::field_descriptor> \ 1269 {PYBIND11_MAP2_LIST (PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)}) 1271 #endif // __CLION_IDE__ 1295 : p_ptr(reinterpret_cast<char*>(ptr)), m_strides(strides.
size()) {
1296 m_strides.back() =
static_cast<value_type>(strides.back());
1297 for (
size_type i = m_strides.size() - 1;
i != 0; --
i) {
1300 m_strides[
j] = strides[
j] + m_strides[
i] - strides[
i] *
s;
1305 p_ptr += m_strides[
dim];
1323 : m_shape(shape.
size()), m_index(shape.
size(), 0),
1324 m_common_iterator() {
1327 for (
size_t i = 0;
i < shape.size(); ++
i)
1328 m_shape[
i] = shape[
i];
1331 for (
size_t i = 0;
i <
N; ++
i)
1332 init_common_iterator(buffers[
i], shape, m_common_iterator[i], strides);
1336 for (
size_t j = m_index.size();
j != 0; --
j) {
1338 if (++m_index[i] != m_shape[i]) {
1339 increment_common_iterator(i);
1348 template <
size_t K,
class T =
void> T*
data()
const {
1349 return reinterpret_cast<T*
>(m_common_iterator[
K].data());
1360 auto buffer_shape_iter = buffer.
shape.rbegin();
1361 auto buffer_strides_iter = buffer.
strides.rbegin();
1362 auto shape_iter = shape.rbegin();
1363 auto strides_iter = strides.rbegin();
1365 while (buffer_shape_iter != buffer.
shape.rend()) {
1366 if (*shape_iter == *buffer_shape_iter)
1367 *strides_iter = *buffer_strides_iter;
1371 ++buffer_shape_iter;
1372 ++buffer_strides_iter;
1377 std::fill(strides_iter, strides.rend(), 0);
1382 for (
auto &
iter : m_common_iterator)
1383 iter.increment(dim);
1404 shape.resize((
size_t) ndim, 1);
1408 for (
size_t i = 0;
i <
N; ++
i) {
1409 auto res_iter = shape.rbegin();
1410 auto end = buffers[
i].shape.rend();
1411 for (
auto shape_iter = buffers[
i].shape.rbegin(); shape_iter !=
end; ++shape_iter, ++res_iter) {
1412 const auto &dim_size_in = *shape_iter;
1413 auto &dim_size_out = *res_iter;
1416 if (dim_size_out == 1)
1417 dim_size_out = dim_size_in;
1418 else if (dim_size_in != 1 && dim_size_in != dim_size_out)
1419 pybind11_fail(
"pybind11::vectorize: incompatible size/dimension of inputs!");
1423 bool trivial_broadcast_c =
true;
1424 bool trivial_broadcast_f =
true;
1425 for (
size_t i = 0;
i < N && (trivial_broadcast_c || trivial_broadcast_f); ++
i) {
1426 if (buffers[
i].
size == 1)
1430 if (buffers[
i].ndim != ndim)
1434 if (!
std::equal(buffers[
i].shape.cbegin(), buffers[
i].shape.cend(), shape.cbegin()))
1438 if (trivial_broadcast_c) {
1439 ssize_t expect_stride = buffers[
i].itemsize;
1440 auto end = buffers[
i].shape.crend();
1441 for (
auto shape_iter = buffers[
i].shape.crbegin(), stride_iter = buffers[
i].strides.crbegin();
1442 trivial_broadcast_c && shape_iter !=
end; ++shape_iter, ++stride_iter) {
1443 if (expect_stride == *stride_iter)
1444 expect_stride *= *shape_iter;
1446 trivial_broadcast_c =
false;
1451 if (trivial_broadcast_f) {
1452 ssize_t expect_stride = buffers[
i].itemsize;
1453 auto end = buffers[
i].shape.cend();
1454 for (
auto shape_iter = buffers[
i].shape.cbegin(), stride_iter = buffers[
i].strides.cbegin();
1455 trivial_broadcast_f && shape_iter !=
end; ++shape_iter, ++stride_iter) {
1456 if (expect_stride == *stride_iter)
1457 expect_stride *= *shape_iter;
1459 trivial_broadcast_f =
false;
1470 template <
typename T>
1485 template <
typename Func,
typename Return,
typename... Args>
1495 static constexpr
size_t N =
sizeof...(Args);
1497 static_assert(NVectorized >= 1,
1498 "pybind11::vectorize(...) requires a function with at least one vectorizable argument");
1501 template <
typename T>
1526 template <
size_t...
Index,
size_t... VIndex,
size_t... BIndex>
object run(
1533 std::array<void *, N>
params{{ &args... }};
1536 std::array<buffer_info, NVectorized> buffers{{
reinterpret_cast<array *
>(
params[VIndex])->request()... }};
1540 std::vector<ssize_t> shape(0);
1541 auto trivial =
broadcast(buffers, nd, shape);
1544 size_t size = std::accumulate(shape.begin(), shape.end(), (
size_t) 1, std::multiplies<size_t>());
1548 if (size == 1 && ndim == 0) {
1557 if (size == 0)
return std::move(result);
1561 apply_broadcast(buffers,
params, result, i_seq, vi_seq, bi_seq);
1565 return std::move(result);
1568 template <
size_t...
Index,
size_t... VIndex,
size_t... BIndex>
1570 std::array<void *, N> &
params,
1578 std::array<std::pair<unsigned char *&, const size_t>, NVectorized> vecparams{{
1579 std::pair<unsigned char *&, const size_t>(
1580 reinterpret_cast<unsigned char *&
>(params[VIndex] = buffers[BIndex].ptr),
1585 for (
size_t i = 0;
i <
size; ++
i) {
1587 for (
auto &
x : vecparams)
x.first +=
x.second;
1591 template <
size_t...
Index,
size_t... VIndex,
size_t... BIndex>
1593 std::array<void *, N> &
params,
1602 ++
iter, ++input_iter) {
1604 params[VIndex] = input_iter.template data<BIndex>()
1611 template <
typename Func,
typename Return,
typename... Args>
1614 return detail::vectorize_helper<Func, Return, Args...>(
f);
1624 template <typename Return, typename... Args>
1627 return detail::vectorize_helper<Return (*)(Args...), Return, Args...>(
f);
1638 template <
typename Return,
typename Class,
typename... Args,
1639 typename Helper = detail::vectorize_helper<decltype(std::mem_fn(std::declval<Return (Class::*)(Args...)>())), Return, Class *, Args...>>
1641 return Helper(std::mem_fn(f));
1645 template <
typename Return,
typename Class,
typename... Args,
1646 typename Helper = detail::vectorize_helper<decltype(std::mem_fn(std::declval<Return (Class::*)(Args...)
const>())), Return,
const Class *, Args...>>
1647 Helper
vectorize(Return (Class::*f)(Args...)
const) {
1648 return Helper(std::mem_fn(f));
1653 #if defined(_MSC_VER) 1654 #pragma warning(pop)
typename std::conditional< B, T, F >::type conditional_t
detail::unchecked_reference< T, Dims > unchecked() const &
const void * data(Ix...index) const
array(ssize_t count, const T *ptr, handle base=handle())
bool has_fields() const
Returns true for structured data types.
detail::unchecked_mutable_reference< T, Dims > mutable_unchecked()&
bool PyArrayDescr_Check_(PyObject *obj) const
detail::any_container< ssize_t > ShapeContainer
const T * data(Ix...ix) const
Pointer access to the data at the given indices.
constexpr ssize_t itemsize() const
array_iterator< T > array_begin(const buffer_info &buffer)
object operator()(typename vectorize_arg< Args >::type...args)
enable_if_t<!Dyn, ssize_t > size() const
Returns the total number of elements in the referenced array, i.e. the product of the shapes...
void append(T &&val) const
std::vector< ssize_t > strides
int flags() const
Return the NumPy array flags.
vectorize_helper< Func, Return, Args... > vectorize_extractor(const Func &f, Return(*)(Args...))
object base() const
Base object.
PYBIND11_NOINLINE void register_structured_dtype(any_container< field_descriptor > fields, const std::type_info &tinfo, ssize_t itemsize, bool(*direct_converter)(PyObject *, void *&))
const ssize_t * shape() const
Dimensions of the array.
PYBIND11_NOINLINE void load_numpy_internals(numpy_internals *&ptr)
array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base=handle())
constexpr int platform_lookup()
PyObject * ptr() const
Return the underlying PyObject * pointer.
std::array< common_iter, N > m_common_iterator
PyTypeObject * PyArray_Type_
#define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN)
enable_if_t< Dyn, ssize_t > size() const
std::tuple< typename vectorize_arg< Args >::call_type... > arg_call_types
ssize_t nbytes() const
Total number of bytes.
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)
iterator iter(handle obj)
dtype strip_padding(ssize_t itemsize)
static void append_extents(list &shape)
ssize_t shape(ssize_t dim) const
Returns the shape (i.e. size) of dimension dim
void * mutable_data(Ix...index)
char kind() const
Single-character type code.
PyObject_HEAD char * data
array_t(handle h, borrowed_t)
remove_reference_t< T > call_type
#define PYBIND11_NAMESPACE
multi_array_iterator & operator++()
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun)
PyObject_HEAD PyObject * typeobj
constexpr size_t constexpr_sum()
Compile-time integer sum.
static std::vector< ssize_t > f_strides(const std::vector< ssize_t > &shape, ssize_t itemsize)
void increment(size_type dim)
unsigned int(* PyArray_GetNDArrayCFeatureVersion_)()
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
static bool compare(const buffer_info &b)
PyExc_RuntimeError[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
const ssize_t * strides() const
Strides of the array.
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
const handle & inc_ref() const &
T * mutable_data(Ix...index)
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
Tuple< Args... > make_tuple(Args...args)
Creates a tuple object, deducing the target type from the types of arguments.
static std::vector< ssize_t > c_strides(const std::vector< ssize_t > &shape, ssize_t itemsize)
numpy_type_info * get_type_info(bool throw_if_missing=true)
array_iterator< T > array_end(const buffer_info &buffer)
ssize_t shape(ssize_t dim) const
Dimension along a given axis.
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)
ssize_t index_at(Ix...index) const
typename std::add_pointer< T >::type array_iterator
void check_dimensions(Ix...index) const
array(ShapeContainer shape, const T *ptr, handle base=handle())
const T & operator[](ssize_t index) const
array_t(const buffer_info &info, handle base=handle())
bool convert(const int &y)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
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)
ssize_t itemsize() const
Byte size of a single element.
ssize_t offset_at(Ix...index) const
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
T & operator()(Ix...index)
Mutable, unchecked access to data at the given indices.
#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun)
void check_dimensions_impl(ssize_t axis, const ssize_t *shape, ssize_t i, Ix...index) const
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
#define PYBIND11_DECL_CHAR_FMT
container_type::value_type value_type
pybind11::dtype dtype() const
Array descriptor (dtype)
std::unordered_map< std::type_index, numpy_type_info > registered_dtypes
#define PYBIND11_DEPRECATED(reason)
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 &)
#define PYBIND11_STR_TYPE
static SmartStereoProjectionParams params
T * mutable_data(Ix...ix)
Mutable pointer access to the data at the given indices.
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())
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())
void fail_dim_check(ssize_t dim, const std::string &msg) const
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... >)
void increment_common_iterator(size_t dim)
ssize_t ndim() const
Returns the number of dimensions of the array.
PyTypeObject * PyArrayDescr_Type_
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
static PyObject * raw_array(PyObject *ptr, int ExtraFlags=0)
Create array from any object – always returns a new reference.
remove_reference_t< Func > f
const T & at(Ix...index) const
static array ensure(handle h, int ExtraFlags=0)
void check_dimensions_impl(ssize_t, const ssize_t *) const
ssize_t strides(ssize_t dim) const
Stride along a given axis.
static module_ import(const char *name)
Import and return a module or throws error_already_set.
PYBIND11_NOINLINE detail::type_info * get_type_info(PyTypeObject *type)
array_t(handle h, stolen_t)
bool PyArray_Check_(PyObject *obj) const
static bool check_(handle h)
void check_writeable() const
std::is_same< bools< Ts::value..., true >, bools< true, Ts::value... >> all_of
ssize_t ndim() const
Number of dimensions.
dtype(const buffer_info &info)
const T * data(Ix...index) const
ssize_t index_at(Ix...index) const
ssize_t size() const
Total number of elements.
bool writeable() const
If set, the array is writeable (otherwise the buffer is read-only)
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)
ssize_t byte_offset(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.
Information record describing a Python buffer object.
common_iterator(void *ptr, const container_type &strides, const container_type &shape)
bool owndata() const
If set, the array owns the data (will be freed when the array is deleted)
Container::iterator get(Container &c, Position position)
detail::unchecked_mutable_reference< T, Dims > mutable_unchecked()&
static dtype from_args(object args)
This is essentially the same as calling numpy.dtype(args) in Python.
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)
void run(Expr &expr, Dev &dev)
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
const T & operator()(Ix...index) const
container_type::size_type size_type
typename make_index_sequence_impl< N >::type make_index_sequence
#define PYBIND11_NOINLINE
ssize_t offset_at() const
array_t(ShapeContainer shape, const T *ptr=nullptr, handle base=handle())
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)
#define PYBIND11_NAMESPACE_END(name)
buffer_info request(bool writable=false) const
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 itemsize() const
Size of the data type in bytes.
PyArray_Proxy * array_proxy(void *ptr)
T & mutable_at(Ix...index)
typename array_info< T >::type remove_all_extents_t
ssize_t offset_at(const arr &a, Ix...idx)
bool(* PyArray_EquivTypes_)(PyObject *, PyObject *)
void apply_broadcast(std::array< buffer_info, NVectorized > &buffers, std::array< void *, N > ¶ms, array_t< Return > &output_array, index_sequence< Index... >, index_sequence< VIndex... >, index_sequence< BIndex... >)