numpy.h
Go to the documentation of this file.
1 /*
2  pybind11/numpy.h: Basic NumPy support, vectorize() wrapper
3 
4  Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #pragma once
11 
12 #include "pybind11.h"
13 #include "complex.h"
14 #include <numeric>
15 #include <algorithm>
16 #include <array>
17 #include <cstdint>
18 #include <cstdlib>
19 #include <cstring>
20 #include <sstream>
21 #include <string>
22 #include <functional>
23 #include <utility>
24 #include <vector>
25 #include <typeindex>
26 
27 #if defined(_MSC_VER)
28 # pragma warning(push)
29 # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
30 #endif
31 
32 /* This will be true on all flat address space platforms and allows us to reduce the
33  whole npy_intp / ssize_t / Py_intptr_t business down to just ssize_t for all size
34  and dimension types (e.g. shape, strides, indexing), instead of inflicting this
35  upon the library user. */
36 static_assert(sizeof(ssize_t) == sizeof(Py_intptr_t), "ssize_t != Py_intptr_t");
37 
39 
40 class array; // Forward declaration
41 
43 
44 template <> struct handle_type_name<array> { static constexpr auto name = _("numpy.ndarray"); };
45 
46 template <typename type, typename SFINAE = void> struct npy_format_descriptor;
47 
49  PyObject_HEAD
50  PyObject *typeobj;
51  char kind;
52  char type;
53  char byteorder;
54  char flags;
55  int type_num;
56  int elsize;
57  int alignment;
58  char *subarray;
59  PyObject *fields;
60  PyObject *names;
61 };
62 
63 struct PyArray_Proxy {
64  PyObject_HEAD
65  char *data;
66  int nd;
69  PyObject *base;
70  PyObject *descr;
71  int flags;
72 };
73 
75  PyObject_VAR_HEAD
76  char *obval;
78  int flags;
79  PyObject *base;
80 };
81 
83  PyObject* dtype_ptr;
84  std::string format_str;
85 };
86 
88  std::unordered_map<std::type_index, numpy_type_info> registered_dtypes;
89 
90  numpy_type_info *get_type_info(const std::type_info& tinfo, bool throw_if_missing = true) {
91  auto it = registered_dtypes.find(std::type_index(tinfo));
92  if (it != registered_dtypes.end())
93  return &(it->second);
94  if (throw_if_missing)
95  pybind11_fail(std::string("NumPy type info missing for ") + tinfo.name());
96  return nullptr;
97  }
98 
99  template<typename T> numpy_type_info *get_type_info(bool throw_if_missing = true) {
100  return get_type_info(typeid(typename std::remove_cv<T>::type), throw_if_missing);
101  }
102 };
103 
105  ptr = &get_or_create_shared_data<numpy_internals>("_numpy_internals");
106 }
107 
109  static numpy_internals* ptr = nullptr;
110  if (!ptr)
112  return *ptr;
113 }
114 
115 template <typename T> struct same_size {
116  template <typename U> using as = bool_constant<sizeof(T) == sizeof(U)>;
117 };
118 
119 template <typename Concrete> constexpr int platform_lookup() { return -1; }
120 
121 // Lookup a type according to its size, and return a value corresponding to the NumPy typenum.
122 template <typename Concrete, typename T, typename... Ts, typename... Ints>
123 constexpr int platform_lookup(int I, Ints... Is) {
124  return sizeof(Concrete) == sizeof(T) ? I : platform_lookup<Concrete, Ts...>(Is...);
125 }
126 
127 struct npy_api {
128  enum constants {
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,
136  NPY_BOOL_ = 0,
137  NPY_BYTE_, NPY_UBYTE_,
138  NPY_SHORT_, NPY_USHORT_,
139  NPY_INT_, NPY_UINT_,
140  NPY_LONG_, NPY_ULONG_,
141  NPY_LONGLONG_, NPY_ULONGLONG_,
142  NPY_FLOAT_, NPY_DOUBLE_, NPY_LONGDOUBLE_,
143  NPY_CFLOAT_, NPY_CDOUBLE_, NPY_CLONGDOUBLE_,
144  NPY_OBJECT_ = 17,
145  NPY_STRING_, NPY_UNICODE_, NPY_VOID_,
146  // Platform-dependent normalization
147  NPY_INT8_ = NPY_BYTE_,
148  NPY_UINT8_ = NPY_UBYTE_,
149  NPY_INT16_ = NPY_SHORT_,
150  NPY_UINT16_ = NPY_USHORT_,
151  // `npy_common.h` defines the integer aliases. In order, it checks:
152  // NPY_BITSOF_LONG, NPY_BITSOF_LONGLONG, NPY_BITSOF_INT, NPY_BITSOF_SHORT, NPY_BITSOF_CHAR
153  // and assigns the alias to the first matching size, so we should check in this order.
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_),
162  };
163 
164  typedef struct {
165  Py_intptr_t *ptr;
166  int len;
167  } PyArray_Dims;
168 
169  static npy_api& get() {
170  static npy_api api = lookup();
171  return api;
172  }
173 
174  bool PyArray_Check_(PyObject *obj) const {
175  return (bool) PyObject_TypeCheck(obj, PyArray_Type_);
176  }
177  bool PyArrayDescr_Check_(PyObject *obj) const {
178  return (bool) PyObject_TypeCheck(obj, PyArrayDescr_Type_);
179  }
180 
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 *);
186  // Unused. Not removed because that affects ABI of the class.
187  PyObject *(*PyArray_DescrNewFromType_)(int);
188  int (*PyArray_CopyInto_)(PyObject *, PyObject *);
189  PyObject *(*PyArray_NewCopy_)(PyObject *, int);
190  PyTypeObject *PyArray_Type_;
191  PyTypeObject *PyVoidArrType_Type_;
192  PyTypeObject *PyArrayDescr_Type_;
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 *);
200  // Unused. Not removed because that affects ABI of the class.
201  int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);
202  PyObject* (*PyArray_Resize_)(PyObject*, PyArray_Dims*, int, int);
203 private:
204  enum functions {
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
222  };
223 
224  static npy_api lookup() {
225  module_ m = module::import("numpy.core.multiarray");
226  auto c = m.attr("_ARRAY_API");
227 #if PY_MAJOR_VERSION >= 3
228  void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL);
229 #else
230  void **api_ptr = (void **) PyCObject_AsVoidPtr(c.ptr());
231 #endif
232  npy_api api;
233 #define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];
234  DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion);
235  if (api.PyArray_GetNDArrayCFeatureVersion_() < 0x7)
236  pybind11_fail("pybind11 numpy support requires numpy >= 1.7.0");
237  DECL_NPY_API(PyArray_Type);
238  DECL_NPY_API(PyVoidArrType_Type);
239  DECL_NPY_API(PyArrayDescr_Type);
240  DECL_NPY_API(PyArray_DescrFromType);
241  DECL_NPY_API(PyArray_DescrFromScalar);
242  DECL_NPY_API(PyArray_FromAny);
243  DECL_NPY_API(PyArray_Resize);
244  DECL_NPY_API(PyArray_CopyInto);
245  DECL_NPY_API(PyArray_NewCopy);
246  DECL_NPY_API(PyArray_NewFromDescr);
247  DECL_NPY_API(PyArray_DescrNewFromType);
248  DECL_NPY_API(PyArray_DescrConverter);
249  DECL_NPY_API(PyArray_EquivTypes);
250  DECL_NPY_API(PyArray_GetArrayParamsFromObject);
251  DECL_NPY_API(PyArray_Squeeze);
252  DECL_NPY_API(PyArray_SetBaseObject);
253 #undef DECL_NPY_API
254  return api;
255  }
256 };
257 
258 inline PyArray_Proxy* array_proxy(void* ptr) {
259  return reinterpret_cast<PyArray_Proxy*>(ptr);
260 }
261 
262 inline const PyArray_Proxy* array_proxy(const void* ptr) {
263  return reinterpret_cast<const PyArray_Proxy*>(ptr);
264 }
265 
267  return reinterpret_cast<PyArrayDescr_Proxy*>(ptr);
268 }
269 
270 inline const PyArrayDescr_Proxy* array_descriptor_proxy(const PyObject* ptr) {
271  return reinterpret_cast<const PyArrayDescr_Proxy*>(ptr);
272 }
273 
274 inline bool check_flags(const void* ptr, int flag) {
275  return (flag == (array_proxy(ptr)->flags & flag));
276 }
277 
278 template <typename T> struct is_std_array : std::false_type { };
279 template <typename T, size_t N> struct is_std_array<std::array<T, N>> : std::true_type { };
280 template <typename T> struct is_complex : std::false_type { };
281 template <typename T> struct is_complex<std::complex<T>> : std::true_type { };
282 
283 template <typename T> struct array_info_scalar {
284  using type = T;
285  static constexpr bool is_array = false;
286  static constexpr bool is_empty = false;
287  static constexpr auto extents = _("");
288  static void append_extents(list& /* shape */) { }
289 };
290 // Computes underlying type and a comma-separated list of extents for array
291 // types (any mix of std::array and built-in arrays). An array of char is
292 // treated as scalar because it gets special handling.
293 template <typename T> struct array_info : array_info_scalar<T> { };
294 template <typename T, size_t N> struct array_info<std::array<T, N>> {
295  using type = typename array_info<T>::type;
296  static constexpr bool is_array = true;
297  static constexpr bool is_empty = (N == 0) || array_info<T>::is_empty;
298  static constexpr size_t extent = N;
299 
300  // appends the extents to shape
301  static void append_extents(list& shape) {
302  shape.append(N);
304  }
305 
306  static constexpr auto extents = _<array_info<T>::is_array>(
307  concat(_<N>(), array_info<T>::extents), _<N>()
308  );
309 };
310 // For numpy we have special handling for arrays of characters, so we don't include
311 // the size in the array extents.
312 template <size_t N> struct array_info<char[N]> : array_info_scalar<char[N]> { };
313 template <size_t N> struct array_info<std::array<char, N>> : array_info_scalar<std::array<char, N>> { };
314 template <typename T, size_t N> struct array_info<T[N]> : array_info<std::array<T, N>> { };
315 template <typename T> using remove_all_extents_t = typename array_info<T>::type;
316 
317 template <typename T> using is_pod_struct = all_of<
318  std::is_standard_layout<T>, // since we're accessing directly in memory we need a standard layout type
319 #if !defined(__GNUG__) || defined(_LIBCPP_VERSION) || defined(_GLIBCXX_USE_CXX11_ABI)
320  // _GLIBCXX_USE_CXX11_ABI indicates that we're using libstdc++ from GCC 5 or newer, independent
321  // of the actual compiler (Clang can also use libstdc++, but it always defines __GNUC__ == 4).
322  std::is_trivially_copyable<T>,
323 #else
324  // GCC 4 doesn't implement is_trivially_copyable, so approximate it
325  std::is_trivially_destructible<T>,
327 #endif
329 >;
330 
331 template <ssize_t Dim = 0, typename Strides> ssize_t byte_offset_unsafe(const Strides &) { return 0; }
332 template <ssize_t Dim = 0, typename Strides, typename... Ix>
333 ssize_t byte_offset_unsafe(const Strides &strides, ssize_t i, Ix... index) {
334  return i * strides[Dim] + byte_offset_unsafe<Dim + 1>(strides, index...);
335 }
336 
342 template <typename T, ssize_t Dims>
344 protected:
345  static constexpr bool Dynamic = Dims < 0;
346  const unsigned char *data_;
347  // Storing the shape & strides in local variables (i.e. these arrays) allows the compiler to
348  // make large performance gains on big, nested loops, but requires compile-time dimensions
350  shape_, strides_;
351  const ssize_t dims_;
352 
353  friend class pybind11::array;
354  // Constructor for compile-time dimensions:
355  template <bool Dyn = Dynamic>
356  unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t<!Dyn, ssize_t>)
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];
361  }
362  }
363  // Constructor for runtime dimensions:
364  template <bool Dyn = Dynamic>
365  unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t<Dyn, ssize_t> dims)
366  : data_{reinterpret_cast<const unsigned char *>(data)}, shape_{shape}, strides_{strides}, dims_{dims} {}
367 
368 public:
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");
377  return *reinterpret_cast<const T *>(data_ + byte_offset_unsafe(strides_, ssize_t(index)...));
378  }
383  template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>
384  const T &operator[](ssize_t index) const { return operator()(index); }
385 
387  template <typename... Ix> const T *data(Ix... ix) const { return &operator()(ssize_t(ix)...); }
388 
390  constexpr static ssize_t itemsize() { return sizeof(T); }
391 
393  ssize_t shape(ssize_t dim) const { return shape_[(size_t) dim]; }
394 
396  ssize_t ndim() const { return dims_; }
397 
399  template <bool Dyn = Dynamic>
401  return std::accumulate(shape_.begin(), shape_.end(), (ssize_t) 1, std::multiplies<ssize_t>());
402  }
403  template <bool Dyn = Dynamic>
405  return std::accumulate(shape_, shape_ + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());
406  }
407 
410  ssize_t nbytes() const {
411  return size() * itemsize();
412  }
413 };
414 
415 template <typename T, ssize_t Dims>
417  friend class pybind11::array;
419  using ConstBase::ConstBase;
420  using ConstBase::Dynamic;
421 public:
423  template <typename... Ix> T& operator()(Ix... index) {
424  static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic,
425  "Invalid number of indices for unchecked array reference");
426  return const_cast<T &>(ConstBase::operator()(index...));
427  }
433  template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>
434  T &operator[](ssize_t index) { return operator()(index); }
435 
437  template <typename... Ix> T *mutable_data(Ix... ix) { return &operator()(ssize_t(ix)...); }
438 };
439 
440 template <typename T, ssize_t Dim>
442  static_assert(Dim == 0 && Dim > 0 /* always fail */, "unchecked array proxy object is not castable");
443 };
444 template <typename T, ssize_t Dim>
445 struct type_caster<unchecked_mutable_reference<T, Dim>> : type_caster<unchecked_reference<T, Dim>> {};
446 
448 
449 class dtype : public object {
450 public:
451  PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_);
452 
453  explicit dtype(const buffer_info &info) {
454  dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format)));
455  // If info.itemsize == 0, use the value calculated from the format string
456  m_ptr = descr.strip_padding(info.itemsize ? info.itemsize : descr.itemsize()).release().ptr();
457  }
458 
459  explicit dtype(const std::string &format) {
460  m_ptr = from_args(pybind11::str(format)).release().ptr();
461  }
462 
463  dtype(const char *format) : dtype(std::string(format)) { }
464 
465  dtype(list names, list formats, list offsets, ssize_t itemsize) {
466  dict args;
467  args["names"] = names;
468  args["formats"] = formats;
469  args["offsets"] = offsets;
470  args["itemsize"] = pybind11::int_(itemsize);
471  m_ptr = from_args(args).release().ptr();
472  }
473 
475  static dtype from_args(object args) {
476  PyObject *ptr = nullptr;
477  if (!detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) || !ptr)
478  throw error_already_set();
479  return reinterpret_steal<dtype>(ptr);
480  }
481 
483  template <typename T> static dtype of() {
485  }
486 
488  ssize_t itemsize() const {
489  return detail::array_descriptor_proxy(m_ptr)->elsize;
490  }
491 
493  bool has_fields() const {
494  return detail::array_descriptor_proxy(m_ptr)->names != nullptr;
495  }
496 
498  char kind() const {
499  return detail::array_descriptor_proxy(m_ptr)->kind;
500  }
501 
502 private:
503  static object _dtype_from_pep3118() {
504  static PyObject *obj = module::import("numpy.core._internal")
505  .attr("_dtype_from_pep3118").cast<object>().release().ptr();
506  return reinterpret_borrow<object>(obj);
507  }
508 
510  // Recursively strip all void fields with empty names that are generated for
511  // padding fields (as of NumPy v1.11).
512  if (!has_fields())
513  return *this;
514 
515  struct field_descr { PYBIND11_STR_TYPE name; object format; pybind11::int_ offset; };
516  std::vector<field_descr> field_descriptors;
517 
518  for (auto field : attr("fields").attr("items")()) {
519  auto spec = field.cast<tuple>();
520  auto name = spec[0].cast<pybind11::str>();
521  auto format = spec[1].cast<tuple>()[0].cast<dtype>();
522  auto offset = spec[1].cast<tuple>()[1].cast<pybind11::int_>();
523  if (!len(name) && format.kind() == 'V')
524  continue;
525  field_descriptors.push_back({(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset});
526  }
527 
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>();
531  });
532 
533  list names, formats, offsets;
534  for (auto& descr : field_descriptors) {
535  names.append(descr.name);
536  formats.append(descr.format);
537  offsets.append(descr.offset);
538  }
539  return dtype(names, formats, offsets, itemsize);
540  }
541 };
542 
543 class array : public buffer {
544 public:
545  PYBIND11_OBJECT_CVT(array, buffer, detail::npy_api::get().PyArray_Check_, raw_array)
546 
547  enum {
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_
551  };
552 
553  array() : array(0, static_cast<const double *>(nullptr)) {}
554 
555  using ShapeContainer = detail::any_container<ssize_t>;
556  using StridesContainer = detail::any_container<ssize_t>;
557 
558  // Constructs an array taking shape/strides from arbitrary container types
559  array(const pybind11::dtype &dt, ShapeContainer shape, StridesContainer strides,
560  const void *ptr = nullptr, handle base = handle()) {
561 
562  if (strides->empty())
563  *strides = c_strides(*shape, dt.itemsize());
564 
565  auto ndim = shape->size();
566  if (ndim != strides->size())
567  pybind11_fail("NumPy: shape ndim doesn't match strides ndim");
568  auto descr = dt;
569 
570  int flags = 0;
571  if (base && ptr) {
572  if (isinstance<array>(base))
573  /* Copy flags from base (except ownership bit) */
574  flags = reinterpret_borrow<array>(base).flags() & ~detail::npy_api::NPY_ARRAY_OWNDATA_;
575  else
576  /* Writable by default, easy to downgrade later on if needed */
577  flags = detail::npy_api::NPY_ARRAY_WRITEABLE_;
578  }
579 
580  auto &api = detail::npy_api::get();
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));
584  if (!tmp)
585  throw error_already_set();
586  if (ptr) {
587  if (base) {
588  api.PyArray_SetBaseObject_(tmp.ptr(), base.inc_ref().ptr());
589  } else {
590  tmp = reinterpret_steal<object>(api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */));
591  }
592  }
593  m_ptr = tmp.release().ptr();
594  }
595 
596  array(const pybind11::dtype &dt, ShapeContainer shape, const void *ptr = nullptr, handle base = handle())
597  : array(dt, std::move(shape), {}, ptr, base) { }
598 
600  array(const pybind11::dtype &dt, T count, const void *ptr = nullptr, handle base = handle())
601  : array(dt, {{count}}, ptr, base) { }
602 
603  template <typename T>
604  array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle())
605  : array(pybind11::dtype::of<T>(), std::move(shape), std::move(strides), ptr, base) { }
606 
607  template <typename T>
608  array(ShapeContainer shape, const T *ptr, handle base = handle())
609  : array(std::move(shape), {}, ptr, base) { }
610 
611  template <typename T>
612  explicit array(ssize_t count, const T *ptr, handle base = handle()) : array({count}, {}, ptr, base) { }
613 
614  explicit array(const buffer_info &info, handle base = handle())
615  : array(pybind11::dtype(info), info.shape, info.strides, info.ptr, base) { }
616 
618  pybind11::dtype dtype() const {
619  return reinterpret_borrow<pybind11::dtype>(detail::array_proxy(m_ptr)->descr);
620  }
621 
623  ssize_t size() const {
624  return std::accumulate(shape(), shape() + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());
625  }
626 
628  ssize_t itemsize() const {
630  }
631 
633  ssize_t nbytes() const {
634  return size() * itemsize();
635  }
636 
638  ssize_t ndim() const {
639  return detail::array_proxy(m_ptr)->nd;
640  }
641 
643  object base() const {
644  return reinterpret_borrow<object>(detail::array_proxy(m_ptr)->base);
645  }
646 
648  const ssize_t* shape() const {
649  return detail::array_proxy(m_ptr)->dimensions;
650  }
651 
654  if (dim >= ndim())
655  fail_dim_check(dim, "invalid axis");
656  return shape()[dim];
657  }
658 
660  const ssize_t* strides() const {
661  return detail::array_proxy(m_ptr)->strides;
662  }
663 
666  if (dim >= ndim())
667  fail_dim_check(dim, "invalid axis");
668  return strides()[dim];
669  }
670 
672  int flags() const {
673  return detail::array_proxy(m_ptr)->flags;
674  }
675 
677  bool writeable() const {
678  return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_WRITEABLE_);
679  }
680 
682  bool owndata() const {
683  return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_OWNDATA_);
684  }
685 
688  template<typename... Ix> const void* data(Ix... index) const {
689  return static_cast<const void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));
690  }
691 
695  template<typename... Ix> void* mutable_data(Ix... index) {
696  check_writeable();
697  return static_cast<void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));
698  }
699 
702  template<typename... Ix> ssize_t offset_at(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)...);
706  }
707 
708  ssize_t offset_at() const { return 0; }
709 
712  template<typename... Ix> ssize_t index_at(Ix... index) const {
713  return offset_at(index...) / itemsize();
714  }
715 
722  template <typename T, ssize_t Dims = -1> detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
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());
727  }
728 
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());
741  }
742 
745  auto& api = detail::npy_api::get();
746  return reinterpret_steal<array>(api.PyArray_Squeeze_(m_ptr));
747  }
748 
752  void resize(ShapeContainer new_shape, bool refcheck = true) {
753  detail::npy_api::PyArray_Dims d = {
754  new_shape->data(), int(new_shape->size())
755  };
756  // try to resize, set ordering param to -1 cause it's not used anyway
757  object new_array = reinterpret_steal<object>(
758  detail::npy_api::get().PyArray_Resize_(m_ptr, &d, int(refcheck), -1)
759  );
760  if (!new_array) throw error_already_set();
761  if (isinstance<array>(new_array)) { *this = std::move(new_array); }
762  }
763 
766  static array ensure(handle h, int ExtraFlags = 0) {
767  auto result = reinterpret_steal<array>(raw_array(h.ptr(), ExtraFlags));
768  if (!result)
769  PyErr_Clear();
770  return result;
771  }
772 
773 protected:
774  template<typename, typename> friend struct detail::npy_format_descriptor;
775 
776  void fail_dim_check(ssize_t dim, const std::string& msg) const {
777  throw index_error(msg + ": " + std::to_string(dim) +
778  " (ndim = " + std::to_string(ndim()) + ")");
779  }
780 
781  template<typename... Ix> ssize_t byte_offset(Ix... index) const {
782  check_dimensions(index...);
783  return detail::byte_offset_unsafe(strides(), ssize_t(index)...);
784  }
785 
786  void check_writeable() const {
787  if (!writeable())
788  throw std::domain_error("array is not writeable");
789  }
790 
791  // Default, C-style strides
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);
795  if (ndim > 0)
796  for (size_t i = ndim - 1; i > 0; --i)
797  strides[i - 1] = strides[i] * shape[i];
798  return strides;
799  }
800 
801  // F-style strides; default when constructing an array_t with `ExtraFlags & f_style`
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];
807  return strides;
808  }
809 
810  template<typename... Ix> void check_dimensions(Ix... index) const {
811  check_dimensions_impl(ssize_t(0), shape(), ssize_t(index)...);
812  }
813 
814  void check_dimensions_impl(ssize_t, const ssize_t*) const { }
815 
816  template<typename... Ix> void check_dimensions_impl(ssize_t axis, const ssize_t* shape, ssize_t i, Ix... index) const {
817  if (i >= *shape) {
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));
821  }
822  check_dimensions_impl(axis + 1, shape + 1, index...);
823  }
824 
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");
829  return nullptr;
830  }
831  return detail::npy_api::get().PyArray_FromAny_(
832  ptr, nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr);
833  }
834 };
835 
836 template <typename T, int ExtraFlags = array::forcecast> class array_t : public array {
837 private:
838  struct private_ctor {};
839  // Delegating constructor needed when both moving and accessing in the same constructor
840  array_t(private_ctor, ShapeContainer &&shape, StridesContainer &&strides, const T *ptr, handle base)
841  : array(std::move(shape), std::move(strides), ptr, base) {}
842 public:
843  static_assert(!detail::array_info<T>::is_array, "Array types cannot be used with array_t");
844 
845  using value_type = T;
846 
847  array_t() : array(0, static_cast<const T *>(nullptr)) {}
850 
851  PYBIND11_DEPRECATED("Use array_t<T>::ensure() instead")
852  array_t(handle h, bool is_borrowed) : array(raw_array_t(h.ptr()), stolen_t{}) {
853  if (!m_ptr) PyErr_Clear();
854  if (!is_borrowed) Py_XDECREF(h.ptr());
855  }
856 
857  array_t(const object &o) : array(raw_array_t(o.ptr()), stolen_t{}) {
858  if (!m_ptr) throw error_already_set();
859  }
860 
861  explicit array_t(const buffer_info& info, handle base = handle()) : array(info, base) { }
862 
863  array_t(ShapeContainer shape, StridesContainer strides, const T *ptr = nullptr, handle base = handle())
864  : array(std::move(shape), std::move(strides), ptr, base) { }
865 
866  explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle())
867  : array_t(private_ctor{}, std::move(shape),
868  ExtraFlags & f_style ? f_strides(*shape, itemsize()) : c_strides(*shape, itemsize()),
869  ptr, base) { }
870 
871  explicit array_t(ssize_t count, const T *ptr = nullptr, handle base = handle())
872  : array({count}, {}, ptr, base) { }
873 
874  constexpr ssize_t itemsize() const {
875  return sizeof(T);
876  }
877 
878  template<typename... Ix> ssize_t index_at(Ix... index) const {
879  return offset_at(index...) / itemsize();
880  }
881 
882  template<typename... Ix> const T* data(Ix... index) const {
883  return static_cast<const T*>(array::data(index...));
884  }
885 
886  template<typename... Ix> T* mutable_data(Ix... index) {
887  return static_cast<T*>(array::mutable_data(index...));
888  }
889 
890  // Reference to element at a given 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());
895  }
896 
897  // Mutable reference to element at a given index
898  template<typename... Ix> T& mutable_at(Ix... index) {
899  if ((ssize_t) sizeof...(index) != ndim())
900  fail_dim_check(sizeof...(index), "index dimension mismatch");
901  return *(static_cast<T*>(array::mutable_data()) + byte_offset(ssize_t(index)...) / itemsize());
902  }
903 
910  template <ssize_t Dims = -1> detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
911  return array::mutable_unchecked<T, Dims>();
912  }
913 
921  template <ssize_t Dims = -1> detail::unchecked_reference<T, Dims> unchecked() const & {
922  return array::unchecked<T, Dims>();
923  }
924 
927  static array_t ensure(handle h) {
928  auto result = reinterpret_steal<array_t>(raw_array_t(h.ptr()));
929  if (!result)
930  PyErr_Clear();
931  return result;
932  }
933 
934  static bool check_(handle h) {
935  const auto &api = detail::npy_api::get();
936  return api.PyArray_Check_(h.ptr())
937  && api.PyArray_EquivTypes_(detail::array_proxy(h.ptr())->descr, dtype::of<T>().ptr())
938  && detail::check_flags(h.ptr(), ExtraFlags & (array::c_style | array::f_style));
939  }
940 
941 protected:
943  static PyObject *raw_array_t(PyObject *ptr) {
944  if (ptr == nullptr) {
945  PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array_t from a nullptr");
946  return nullptr;
947  }
948  return detail::npy_api::get().PyArray_FromAny_(
949  ptr, dtype::of<T>().release().ptr(), 0, 0,
950  detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr);
951  }
952 };
953 
954 template <typename T>
955 struct format_descriptor<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {
956  static std::string format() {
958  }
959 };
960 
961 template <size_t N> struct format_descriptor<char[N]> {
962  static std::string format() { return std::to_string(N) + "s"; }
963 };
964 template <size_t N> struct format_descriptor<std::array<char, N>> {
965  static std::string format() { return std::to_string(N) + "s"; }
966 };
967 
968 template <typename T>
969 struct format_descriptor<T, detail::enable_if_t<std::is_enum<T>::value>> {
970  static std::string format() {
971  return format_descriptor<
973  }
974 };
975 
976 template <typename T>
977 struct format_descriptor<T, detail::enable_if_t<detail::array_info<T>::is_array>> {
978  static std::string format() {
979  using namespace detail;
980  static constexpr auto extents = _("(") + array_info<T>::extents + _(")");
981  return extents.text + format_descriptor<remove_all_extents_t<T>>::format();
982  }
983 };
984 
986 template <typename T, int ExtraFlags>
987 struct pyobject_caster<array_t<T, ExtraFlags>> {
989 
990  bool load(handle src, bool convert) {
991  if (!convert && !type::check_(src))
992  return false;
993  value = type::ensure(src);
994  return static_cast<bool>(value);
995  }
996 
997  static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {
998  return src.inc_ref();
999  }
1001 };
1002 
1003 template <typename T>
1004 struct compare_buffer_info<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {
1005  static bool compare(const buffer_info& b) {
1006  return npy_api::get().PyArray_EquivTypes_(dtype::of<T>().ptr(), dtype(b).ptr());
1007  }
1008 };
1009 
1010 template <typename T, typename = void>
1012 
1013 template <typename T>
1015  static constexpr auto name = _<std::is_same<T, bool>::value>(
1016  _("bool"), _<std::is_signed<T>::value>("numpy.int", "numpy.uint") + _<sizeof(T)*8>()
1017  );
1018 };
1019 
1020 template <typename T>
1021 struct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {
1023  _("numpy.float") + _<sizeof(T)*8>(), _("numpy.longdouble")
1024  );
1025 };
1026 
1027 template <typename T>
1031  _("numpy.complex") + _<sizeof(typename T::value_type)*16>(), _("numpy.longcomplex")
1032  );
1033 };
1034 
1035 template <typename T>
1038 private:
1039  // NB: the order here must match the one in common.h
1040  constexpr static const int values[15] = {
1046  };
1047 
1048 public:
1049  static constexpr int value = values[detail::is_fmt_numeric<T>::index];
1050 
1051  static pybind11::dtype dtype() {
1052  if (auto ptr = npy_api::get().PyArray_DescrFromType_(value))
1053  return reinterpret_steal<pybind11::dtype>(ptr);
1054  pybind11_fail("Unsupported buffer format!");
1055  }
1056 };
1057 
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)); }
1061 template <size_t N> struct npy_format_descriptor<char[N]> { PYBIND11_DECL_CHAR_FMT };
1062 template <size_t N> struct npy_format_descriptor<std::array<char, N>> { PYBIND11_DECL_CHAR_FMT };
1063 #undef PYBIND11_DECL_CHAR_FMT
1064 
1065 template<typename T> struct npy_format_descriptor<T, enable_if_t<array_info<T>::is_array>> {
1066 private:
1068 public:
1069  static_assert(!array_info<T>::is_empty, "Zero-sized arrays are not supported");
1070 
1071  static constexpr auto name = _("(") + array_info<T>::extents + _(")") + base_descr::name;
1072  static pybind11::dtype dtype() {
1073  list shape;
1075  return pybind11::dtype::from_args(pybind11::make_tuple(base_descr::dtype(), shape));
1076  }
1077 };
1078 
1079 template<typename T> struct npy_format_descriptor<T, enable_if_t<std::is_enum<T>::value>> {
1080 private:
1082 public:
1083  static constexpr auto name = base_descr::name;
1084  static pybind11::dtype dtype() { return base_descr::dtype(); }
1085 };
1086 
1088  const char *name;
1091  std::string format;
1093 };
1094 
1097  const std::type_info& tinfo, ssize_t itemsize,
1098  bool (*direct_converter)(PyObject *, void *&)) {
1099 
1101  if (numpy_internals.get_type_info(tinfo, false))
1102  pybind11_fail("NumPy: dtype is already registered");
1103 
1104  // Use ordered fields because order matters as of NumPy 1.14:
1105  // https://docs.scipy.org/doc/numpy/release.html#multiple-field-indexing-assignment-of-structured-arrays
1106  std::vector<field_descriptor> ordered_fields(std::move(fields));
1107  std::sort(ordered_fields.begin(), ordered_fields.end(),
1108  [](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; });
1109 
1110  list names, formats, offsets;
1111  for (auto& field : ordered_fields) {
1112  if (!field.descr)
1113  pybind11_fail(std::string("NumPy: unsupported field dtype: `") +
1114  field.name + "` @ " + tinfo.name());
1115  names.append(PYBIND11_STR_TYPE(field.name));
1116  formats.append(field.descr);
1117  offsets.append(pybind11::int_(field.offset));
1118  }
1119  auto dtype_ptr = pybind11::dtype(names, formats, offsets, itemsize).release().ptr();
1120 
1121  // There is an existing bug in NumPy (as of v1.11): trailing bytes are
1122  // not encoded explicitly into the format string. This will supposedly
1123  // get fixed in v1.12; for further details, see these:
1124  // - https://github.com/numpy/numpy/issues/7797
1125  // - https://github.com/numpy/numpy/pull/7798
1126  // Because of this, we won't use numpy's logic to generate buffer format
1127  // strings and will just do it ourselves.
1128  ssize_t offset = 0;
1129  std::ostringstream oss;
1130  // mark the structure as unaligned with '^', because numpy and C++ don't
1131  // always agree about alignment (particularly for complex), and we're
1132  // explicitly listing all our padding. This depends on none of the fields
1133  // overriding the endianness. Putting the ^ in front of individual fields
1134  // isn't guaranteed to work due to https://github.com/numpy/numpy/issues/9049
1135  oss << "^T{";
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;
1141  }
1142  if (itemsize > offset)
1143  oss << (itemsize - offset) << 'x';
1144  oss << '}';
1145  auto format_str = oss.str();
1146 
1147  // Sanity check: verify that NumPy properly parses our buffer format string
1148  auto& api = npy_api::get();
1149  auto arr = array(buffer_info(nullptr, itemsize, format_str, 1));
1150  if (!api.PyArray_EquivTypes_(dtype_ptr, arr.dtype().ptr()))
1151  pybind11_fail("NumPy: invalid buffer descriptor!");
1152 
1153  auto tindex = std::type_index(tinfo);
1154  numpy_internals.registered_dtypes[tindex] = { dtype_ptr, format_str };
1155  get_internals().direct_conversions[tindex].push_back(direct_converter);
1156 }
1157 
1158 template <typename T, typename SFINAE> struct npy_format_descriptor {
1159  static_assert(is_pod_struct<T>::value, "Attempt to use a non-POD or unimplemented POD type as a numpy dtype");
1160 
1161  static constexpr auto name = make_caster<T>::name;
1162 
1163  static pybind11::dtype dtype() {
1164  return reinterpret_borrow<pybind11::dtype>(dtype_ptr());
1165  }
1166 
1167  static std::string format() {
1168  static auto format_str = get_numpy_internals().get_type_info<T>(true)->format_str;
1169  return format_str;
1170  }
1171 
1173  register_structured_dtype(std::move(fields), typeid(typename std::remove_cv<T>::type),
1174  sizeof(T), &direct_converter);
1175  }
1176 
1177 private:
1178  static PyObject* dtype_ptr() {
1179  static PyObject* ptr = get_numpy_internals().get_type_info<T>(true)->dtype_ptr;
1180  return ptr;
1181  }
1182 
1183  static bool direct_converter(PyObject *obj, void*& value) {
1184  auto& api = npy_api::get();
1185  if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_))
1186  return false;
1187  if (auto descr = reinterpret_steal<object>(api.PyArray_DescrFromScalar_(obj))) {
1188  if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) {
1189  value = ((PyVoidScalarObject_Proxy *) obj)->obval;
1190  return true;
1191  }
1192  }
1193  return false;
1194  }
1195 };
1196 
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)
1200 #else
1201 
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() \
1207  }
1208 
1209 // Extract name, offset and format descriptor for a struct field
1210 #define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #Field)
1211 
1212 // The main idea of this macro is borrowed from https://github.com/swansontec/map-macro
1213 // (C) William Swanson, Paul Fultz
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))
1230 #else
1231 #define PYBIND11_MAP_LIST_NEXT1(test, next) \
1232  PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)
1233 #endif
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__)
1240 // PYBIND11_MAP_LIST(f, t, a1, a2, ...) expands to f(t, a1), f(t, a2), ...
1241 #define PYBIND11_MAP_LIST(f, t, ...) \
1242  PYBIND11_EVAL (PYBIND11_MAP_LIST1 (f, t, __VA_ARGS__, (), 0))
1243 
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__)})
1248 
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))
1252 #else
1253 #define PYBIND11_MAP2_LIST_NEXT1(test, next) \
1254  PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)
1255 #endif
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__)
1262 // PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ...
1263 #define PYBIND11_MAP2_LIST(f, t, ...) \
1264  PYBIND11_EVAL (PYBIND11_MAP2_LIST1 (f, t, __VA_ARGS__, (), 0))
1265 
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__)})
1270 
1271 #endif // __CLION_IDE__
1272 
1273 template <class T>
1275 
1276 template <class T>
1278  return array_iterator<T>(reinterpret_cast<T*>(buffer.ptr));
1279 }
1280 
1281 template <class T>
1283  return array_iterator<T>(reinterpret_cast<T*>(buffer.ptr) + buffer.size);
1284 }
1285 
1287 public:
1288  using container_type = std::vector<ssize_t>;
1289  using value_type = container_type::value_type;
1290  using size_type = container_type::size_type;
1291 
1292  common_iterator() : p_ptr(0), m_strides() {}
1293 
1294  common_iterator(void* ptr, const container_type& strides, const container_type& shape)
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) {
1298  size_type j = i - 1;
1299  auto s = static_cast<value_type>(shape[i]);
1300  m_strides[j] = strides[j] + m_strides[i] - strides[i] * s;
1301  }
1302  }
1303 
1305  p_ptr += m_strides[dim];
1306  }
1307 
1308  void* data() const {
1309  return p_ptr;
1310  }
1311 
1312 private:
1313  char* p_ptr;
1315 };
1316 
1317 template <size_t N> class multi_array_iterator {
1318 public:
1319  using container_type = std::vector<ssize_t>;
1320 
1321  multi_array_iterator(const std::array<buffer_info, N> &buffers,
1322  const container_type &shape)
1323  : m_shape(shape.size()), m_index(shape.size(), 0),
1324  m_common_iterator() {
1325 
1326  // Manual copy to avoid conversion warning if using std::copy
1327  for (size_t i = 0; i < shape.size(); ++i)
1328  m_shape[i] = shape[i];
1329 
1330  container_type strides(shape.size());
1331  for (size_t i = 0; i < N; ++i)
1332  init_common_iterator(buffers[i], shape, m_common_iterator[i], strides);
1333  }
1334 
1336  for (size_t j = m_index.size(); j != 0; --j) {
1337  size_t i = j - 1;
1338  if (++m_index[i] != m_shape[i]) {
1339  increment_common_iterator(i);
1340  break;
1341  } else {
1342  m_index[i] = 0;
1343  }
1344  }
1345  return *this;
1346  }
1347 
1348  template <size_t K, class T = void> T* data() const {
1349  return reinterpret_cast<T*>(m_common_iterator[K].data());
1350  }
1351 
1352 private:
1353 
1355 
1357  const container_type &shape,
1359  container_type &strides) {
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();
1364 
1365  while (buffer_shape_iter != buffer.shape.rend()) {
1366  if (*shape_iter == *buffer_shape_iter)
1367  *strides_iter = *buffer_strides_iter;
1368  else
1369  *strides_iter = 0;
1370 
1371  ++buffer_shape_iter;
1372  ++buffer_strides_iter;
1373  ++shape_iter;
1374  ++strides_iter;
1375  }
1376 
1377  std::fill(strides_iter, strides.rend(), 0);
1378  iterator = common_iter(buffer.ptr, strides, shape);
1379  }
1380 
1382  for (auto &iter : m_common_iterator)
1383  iter.increment(dim);
1384  }
1385 
1388  std::array<common_iter, N> m_common_iterator;
1389 };
1390 
1392 
1393 // Populates the shape and number of dimensions for the set of buffers. Returns a broadcast_trivial
1394 // enum value indicating whether the broadcast is "trivial"--that is, has each buffer being either a
1395 // singleton or a full-size, C-contiguous (`c_trivial`) or Fortran-contiguous (`f_trivial`) storage
1396 // buffer; returns `non_trivial` otherwise.
1397 template <size_t N>
1398 broadcast_trivial broadcast(const std::array<buffer_info, N> &buffers, ssize_t &ndim, std::vector<ssize_t> &shape) {
1399  ndim = std::accumulate(buffers.begin(), buffers.end(), ssize_t(0), [](ssize_t res, const buffer_info &buf) {
1400  return std::max(res, buf.ndim);
1401  });
1402 
1403  shape.clear();
1404  shape.resize((size_t) ndim, 1);
1405 
1406  // Figure out the output size, and make sure all input arrays conform (i.e. are either size 1 or
1407  // the full size).
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;
1414 
1415  // Each input dimension can either be 1 or `n`, but `n` values must match across buffers
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!");
1420  }
1421  }
1422 
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)
1427  continue;
1428 
1429  // Require the same number of dimensions:
1430  if (buffers[i].ndim != ndim)
1432 
1433  // Require all dimensions be full-size:
1434  if (!std::equal(buffers[i].shape.cbegin(), buffers[i].shape.cend(), shape.cbegin()))
1436 
1437  // Check for C contiguity (but only if previous inputs were also C contiguous)
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;
1445  else
1446  trivial_broadcast_c = false;
1447  }
1448  }
1449 
1450  // Check for Fortran contiguity (if previous inputs were also F contiguous)
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;
1458  else
1459  trivial_broadcast_f = false;
1460  }
1461  }
1462  }
1463 
1464  return
1465  trivial_broadcast_c ? broadcast_trivial::c_trivial :
1466  trivial_broadcast_f ? broadcast_trivial::f_trivial :
1468 }
1469 
1470 template <typename T>
1472  static_assert(!std::is_rvalue_reference<T>::value, "Functions with rvalue reference arguments cannot be vectorized");
1473  // The wrapped function gets called with this type:
1475  // Is this a vectorized argument?
1476  static constexpr bool vectorize =
1481  // Accept this type: an array for vectorized types, otherwise the type as-is:
1483 };
1484 
1485 template <typename Func, typename Return, typename... Args>
1487 
1488 // NVCC for some reason breaks if NVectorized is private
1489 #ifdef __CUDACC__
1490 public:
1491 #else
1492 private:
1493 #endif
1494 
1495  static constexpr size_t N = sizeof...(Args);
1496  static constexpr size_t NVectorized = constexpr_sum(vectorize_arg<Args>::vectorize...);
1497  static_assert(NVectorized >= 1,
1498  "pybind11::vectorize(...) requires a function with at least one vectorizable argument");
1499 
1500 public:
1501  template <typename T>
1502  explicit vectorize_helper(T &&f) : f(std::forward<T>(f)) { }
1503 
1505  return run(args...,
1509  }
1510 
1511 private:
1513 
1514  // Internal compiler error in MSVC 19.16.27025.1 (Visual Studio 2017 15.9.4), when compiling with "/permissive-" flag
1515  // when arg_call_types is manually inlined.
1516  using arg_call_types = std::tuple<typename vectorize_arg<Args>::call_type...>;
1517  template <size_t Index> using param_n_t = typename std::tuple_element<Index, arg_call_types>::type;
1518 
1519  // Runs a vectorized function given arguments tuple and three index sequences:
1520  // - Index is the full set of 0 ... (N-1) argument indices;
1521  // - VIndex is the subset of argument indices with vectorized parameters, letting us access
1522  // vectorized arguments (anything not in this sequence is passed through)
1523  // - BIndex is a incremental sequence (beginning at 0) of the same size as VIndex, so that
1524  // we can store vectorized buffer_infos in an array (argument VIndex has its buffer at
1525  // index BIndex in the array).
1526  template <size_t... Index, size_t... VIndex, size_t... BIndex> object run(
1527  typename vectorize_arg<Args>::type &...args,
1529 
1530  // Pointers to values the function was called with; the vectorized ones set here will start
1531  // out as array_t<T> pointers, but they will be changed them to T pointers before we make
1532  // call the wrapped function. Non-vectorized pointers are left as-is.
1533  std::array<void *, N> params{{ &args... }};
1534 
1535  // The array of `buffer_info`s of vectorized arguments:
1536  std::array<buffer_info, NVectorized> buffers{{ reinterpret_cast<array *>(params[VIndex])->request()... }};
1537 
1538  /* Determine dimensions parameters of output array */
1539  ssize_t nd = 0;
1540  std::vector<ssize_t> shape(0);
1541  auto trivial = broadcast(buffers, nd, shape);
1542  auto ndim = (size_t) nd;
1543 
1544  size_t size = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies<size_t>());
1545 
1546  // If all arguments are 0-dimension arrays (i.e. single values) return a plain value (i.e.
1547  // not wrapped in an array).
1548  if (size == 1 && ndim == 0) {
1549  PYBIND11_EXPAND_SIDE_EFFECTS(params[VIndex] = buffers[BIndex].ptr);
1550  return cast(f(*reinterpret_cast<param_n_t<Index> *>(params[Index])...));
1551  }
1552 
1554  if (trivial == broadcast_trivial::f_trivial) result = array_t<Return, array::f_style>(shape);
1555  else result = array_t<Return>(shape);
1556 
1557  if (size == 0) return std::move(result);
1558 
1559  /* Call the function */
1560  if (trivial == broadcast_trivial::non_trivial)
1561  apply_broadcast(buffers, params, result, i_seq, vi_seq, bi_seq);
1562  else
1563  apply_trivial(buffers, params, result.mutable_data(), size, i_seq, vi_seq, bi_seq);
1564 
1565  return std::move(result);
1566  }
1567 
1568  template <size_t... Index, size_t... VIndex, size_t... BIndex>
1569  void apply_trivial(std::array<buffer_info, NVectorized> &buffers,
1570  std::array<void *, N> &params,
1571  Return *out,
1572  size_t size,
1574 
1575  // Initialize an array of mutable byte references and sizes with references set to the
1576  // appropriate pointer in `params`; as we iterate, we'll increment each pointer by its size
1577  // (except for singletons, which get an increment of 0).
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),
1581  buffers[BIndex].size == 1 ? 0 : sizeof(param_n_t<VIndex>)
1582  )...
1583  }};
1584 
1585  for (size_t i = 0; i < size; ++i) {
1586  out[i] = f(*reinterpret_cast<param_n_t<Index> *>(params[Index])...);
1587  for (auto &x : vecparams) x.first += x.second;
1588  }
1589  }
1590 
1591  template <size_t... Index, size_t... VIndex, size_t... BIndex>
1592  void apply_broadcast(std::array<buffer_info, NVectorized> &buffers,
1593  std::array<void *, N> &params,
1594  array_t<Return> &output_array,
1596 
1597  buffer_info output = output_array.request();
1598  multi_array_iterator<NVectorized> input_iter(buffers, output.shape);
1599 
1600  for (array_iterator<Return> iter = array_begin<Return>(output), end = array_end<Return>(output);
1601  iter != end;
1602  ++iter, ++input_iter) {
1604  params[VIndex] = input_iter.template data<BIndex>()
1605  ));
1606  *iter = f(*reinterpret_cast<param_n_t<Index> *>(std::get<Index>(params))...);
1607  }
1608  }
1609 };
1610 
1611 template <typename Func, typename Return, typename... Args>
1612 vectorize_helper<Func, Return, Args...>
1613 vectorize_extractor(const Func &f, Return (*) (Args ...)) {
1614  return detail::vectorize_helper<Func, Return, Args...>(f);
1615 }
1616 
1617 template <typename T, int Flags> struct handle_type_name<array_t<T, Flags>> {
1618  static constexpr auto name = _("numpy.ndarray[") + npy_format_descriptor<T>::name + _("]");
1619 };
1620 
1622 
1623 // Vanilla pointer vectorizer:
1624 template <typename Return, typename... Args>
1625 detail::vectorize_helper<Return (*)(Args...), Return, Args...>
1626 vectorize(Return (*f) (Args ...)) {
1627  return detail::vectorize_helper<Return (*)(Args...), Return, Args...>(f);
1628 }
1629 
1630 // lambda vectorizer:
1632 auto vectorize(Func &&f) -> decltype(
1633  detail::vectorize_extractor(std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr)) {
1634  return detail::vectorize_extractor(std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr);
1635 }
1636 
1637 // Vectorize a class method (non-const):
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...>>
1640 Helper vectorize(Return (Class::*f)(Args...)) {
1641  return Helper(std::mem_fn(f));
1642 }
1643 
1644 // Vectorize a class method (const):
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));
1649 }
1650 
1652 
1653 #if defined(_MSC_VER)
1654 #pragma warning(pop)
1655 #endif
typename std::conditional< B, T, F >::type conditional_t
char * p_ptr
Definition: numpy.h:1313
void * ptr
Definition: buffer_info.h:18
Matrix3f m
detail::unchecked_reference< T, Dims > unchecked() const &
Definition: numpy.h:736
const void * data(Ix...index) const
Definition: numpy.h:688
int array[24]
array(ssize_t count, const T *ptr, handle base=handle())
Definition: numpy.h:612
int nd
Definition: numpy.h:66
functions
Definition: numpy.h:204
bool has_fields() const
Returns true for structured data types.
Definition: numpy.h:493
constants
Definition: numpy.h:128
detail::unchecked_mutable_reference< T, Dims > mutable_unchecked()&
Definition: numpy.h:722
#define max(a, b)
Definition: datatypes.h:20
ssize_t * strides
Definition: numpy.h:68
bool PyArrayDescr_Check_(PyObject *obj) const
Definition: numpy.h:177
PyObject * descr
Definition: numpy.h:70
detail::any_container< ssize_t > ShapeContainer
Definition: numpy.h:555
ssize_t * dimensions
Definition: numpy.h:67
static void register_dtype(any_container< field_descriptor > fields)
Definition: numpy.h:1172
const T * data(Ix...ix) const
Pointer access to the data at the given indices.
Definition: numpy.h:387
static std::string format()
Definition: numpy.h:1167
constexpr ssize_t itemsize() const
Definition: numpy.h:874
array_iterator< T > array_begin(const buffer_info &buffer)
Definition: numpy.h:1277
object operator()(typename vectorize_arg< Args >::type...args)
Definition: numpy.h:1504
Definition: numpy.h:449
Scalar * b
Definition: benchVecAdd.cpp:17
T cast() const &
Definition: cast.h:1789
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...
Definition: numpy.h:400
return int(ret)+1
void append(T &&val) const
Definition: pytypes.h:1313
std::vector< ssize_t > strides
Definition: buffer_info.h:24
int flags() const
Return the NumPy array flags.
Definition: numpy.h:672
vectorize_helper< Func, Return, Args... > vectorize_extractor(const Func &f, Return(*)(Args...))
Definition: numpy.h:1613
static handle cast(const handle &src, return_value_policy, handle)
Definition: numpy.h:997
object base() const
Base object.
Definition: numpy.h:643
PYBIND11_NOINLINE void register_structured_dtype(any_container< field_descriptor > fields, const std::type_info &tinfo, ssize_t itemsize, bool(*direct_converter)(PyObject *, void *&))
Definition: numpy.h:1095
const ssize_t * shape() const
Dimensions of the array.
Definition: numpy.h:648
PYBIND11_NOINLINE void load_numpy_internals(numpy_internals *&ptr)
Definition: numpy.h:104
array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base=handle())
Definition: numpy.h:604
constexpr int platform_lookup()
Definition: numpy.h:119
PyObject * ptr() const
Return the underlying PyObject * pointer.
Definition: pytypes.h:184
ssize_t size
Definition: numpy.h:1090
std::array< common_iter, N > m_common_iterator
Definition: numpy.h:1388
PyTypeObject * PyArray_Type_
Definition: numpy.h:190
Definition: numpy.h:127
static std::string format()
Definition: numpy.h:962
Definition: pytypes.h:1322
#define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN)
enable_if_t< Dyn, ssize_t > size() const
Definition: numpy.h:404
Definition: numpy.h:543
std::tuple< typename vectorize_arg< Args >::call_type... > arg_call_types
Definition: numpy.h:1516
ssize_t nbytes() const
Total number of bytes.
Definition: numpy.h:633
static object _dtype_from_pep3118()
Definition: numpy.h:503
T * data() const
Definition: numpy.h:1348
PYBIND11_NOINLINE internals & get_internals()
Return a reference to the current internals data.
Definition: internals.h:245
array(const pybind11::dtype &dt, ShapeContainer shape, StridesContainer strides, const void *ptr=nullptr, handle base=handle())
Definition: numpy.h:559
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
char byteorder
Definition: numpy.h:53
#define DECL_NPY_API(Func)
array_t(const object &o)
Definition: numpy.h:857
PyArrayDescr_Proxy * descr
Definition: numpy.h:77
leaf::MyValues values
broadcast_trivial
Definition: numpy.h:1391
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.
Definition: pybind11.h:855
std::string format
Definition: numpy.h:1091
array_t(ShapeContainer shape, StridesContainer strides, const T *ptr=nullptr, handle base=handle())
Definition: numpy.h:863
static Cal3_S2 K(500, 500, 0.1, 640/2, 480/2)
Definition: Half.h:150
iterator iter(handle obj)
Definition: pytypes.h:1547
dtype strip_padding(ssize_t itemsize)
Definition: numpy.h:509
py::array arr
#define N
Definition: gksort.c:12
static void append_extents(list &shape)
Definition: numpy.h:301
ssize_t shape(ssize_t dim) const
Returns the shape (i.e. size) of dimension dim
Definition: numpy.h:393
void * mutable_data(Ix...index)
Definition: numpy.h:695
char kind() const
Single-character type code.
Definition: numpy.h:498
PyObject_HEAD char * data
Definition: numpy.h:65
array_t(handle h, borrowed_t)
Definition: numpy.h:848
remove_reference_t< T > call_type
Definition: numpy.h:1474
multi_array_iterator & operator++()
Definition: numpy.h:1335
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun)
Definition: pytypes.h:805
PyObject_HEAD PyObject * typeobj
Definition: numpy.h:50
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)
Definition: numpy.h:802
void increment(size_type dim)
Definition: numpy.h:1304
unsigned int(* PyArray_GetNDArrayCFeatureVersion_)()
Definition: numpy.h:181
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
Definition: numpy.h:329
PyObject * fields
Definition: numpy.h:59
void * data() const
Definition: numpy.h:1308
Array33i a
const double dt
PyExc_RuntimeError[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
const ssize_t * strides() const
Strides of the array.
Definition: numpy.h:660
array()
Definition: numpy.h:553
else if n * info
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
const handle & inc_ref() const &
Definition: pytypes.h:192
static pybind11::dtype dtype()
Definition: numpy.h:1163
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
T * mutable_data(Ix...index)
Definition: numpy.h:886
PyArrayDescr_Proxy * array_descriptor_proxy(PyObject *ptr)
Definition: numpy.h:266
ssize_t nbytes() const
Definition: numpy.h:410
typename select_indices_impl< index_sequence<>, 0, Bs... >::type select_indices
Definition: descr.h:25
void init_common_iterator(const buffer_info &buffer, const container_type &shape, common_iter &iterator, container_type &strides)
Definition: numpy.h:1356
ssize_t itemsize
Definition: buffer_info.h:19
detail::vectorize_helper< Return(*)(Args...), Return, Args... > vectorize(Return(*f)(Args...))
Definition: numpy.h:1626
container_type m_shape
Definition: numpy.h:1386
typename std::tuple_element< Index, arg_call_types >::type param_n_t
Definition: numpy.h:1517
Tuple< Args... > make_tuple(Args...args)
Creates a tuple object, deducing the target type from the types of arguments.
Values result
static std::vector< ssize_t > c_strides(const std::vector< ssize_t > &shape, ssize_t itemsize)
Definition: numpy.h:792
numpy_type_info * get_type_info(bool throw_if_missing=true)
Definition: numpy.h:99
array_iterator< T > array_end(const buffer_info &buffer)
Definition: numpy.h:1282
std::string format
Definition: buffer_info.h:21
ssize_t shape(ssize_t dim) const
Dimension along a given axis.
Definition: numpy.h:653
PyObject_VAR_HEAD char * obval
Definition: numpy.h:76
detail::unchecked_reference< T, Dims > unchecked() const &
Definition: numpy.h:921
std::vector< ssize_t > container_type
Definition: numpy.h:1288
multi_array_iterator(const std::array< buffer_info, N > &buffers, const container_type &shape)
Definition: numpy.h:1321
static npy_api & get()
Definition: numpy.h:169
ssize_t index_at(Ix...index) const
Definition: numpy.h:878
PyObject * base
Definition: numpy.h:79
float * ptr
typename std::add_pointer< T >::type array_iterator
Definition: numpy.h:1274
void check_dimensions(Ix...index) const
Definition: numpy.h:810
array(ShapeContainer shape, const T *ptr, handle base=handle())
Definition: numpy.h:608
const T & operator[](ssize_t index) const
Definition: numpy.h:384
array_t(const buffer_info &info, handle base=handle())
Definition: numpy.h:861
bool convert(const int &y)
PyObject * dtype_ptr
Definition: numpy.h:83
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
object run(typename vectorize_arg< Args >::type &...args, index_sequence< Index... > i_seq, index_sequence< VIndex... > vi_seq, index_sequence< BIndex... > bi_seq)
Definition: numpy.h:1526
type_map< std::vector< bool(*)(PyObject *, void *&)> > direct_conversions
Definition: internals.h:101
array_t()
Definition: numpy.h:847
unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t< Dyn, ssize_t > dims)
Definition: numpy.h:365
ssize_t itemsize() const
Byte size of a single element.
Definition: numpy.h:628
ssize_t offset_at(Ix...index) const
Definition: numpy.h:702
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.
Definition: numpy.h:423
#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun)
Definition: pytypes.h:821
int data[]
void check_dimensions_impl(ssize_t axis, const ssize_t *shape, ssize_t i, Ix...index) const
Definition: numpy.h:816
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
#define PYBIND11_DECL_CHAR_FMT
Definition: numpy.h:1058
container_type::value_type value_type
Definition: numpy.h:1289
pybind11::dtype dtype() const
Array descriptor (dtype)
Definition: numpy.h:618
std::unordered_map< std::type_index, numpy_type_info > registered_dtypes
Definition: numpy.h:88
RealScalar s
#define PYBIND11_DEPRECATED(reason)
dtype(const std::string &format)
Definition: numpy.h:459
typename std::remove_reference< T >::type remove_reference_t
std::vector< ssize_t > container_type
Definition: numpy.h:1319
ssize_t byte_offset_unsafe(const Strides &)
Definition: numpy.h:331
constexpr descr< 0 > concat()
Definition: descr.h:83
detail::any_container< ssize_t > StridesContainer
Definition: numpy.h:556
array(const buffer_info &info, handle base=handle())
Definition: numpy.h:614
static void append_extents(list &)
Definition: numpy.h:288
static SmartStereoProjectionParams params
static const Matrix I
Definition: lago.cpp:35
T * mutable_data(Ix...ix)
Mutable pointer access to the data at the given indices.
Definition: numpy.h:437
static dtype of()
Return dtype associated with a C++ type.
Definition: numpy.h:483
#define NULL
Definition: ccolamd.c:609
static array_t ensure(handle h)
Definition: numpy.h:927
array(const pybind11::dtype &dt, ShapeContainer shape, const void *ptr=nullptr, handle base=handle())
Definition: numpy.h:596
conditional_t< Dynamic, const ssize_t *, std::array< ssize_t,(size_t) Dims > > strides_
Definition: numpy.h:350
const unsigned char * data_
Definition: numpy.h:346
array(const pybind11::dtype &dt, T count, const void *ptr=nullptr, handle base=handle())
Definition: numpy.h:600
void fail_dim_check(ssize_t dim, const std::string &msg) const
Definition: numpy.h:776
T & operator[](ssize_t index)
Definition: numpy.h:434
std::vector< ssize_t > shape
Definition: buffer_info.h:23
static constexpr ssize_t itemsize()
Returns the item size, i.e. sizeof(T)
Definition: numpy.h:390
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 >)
Definition: numpy.h:356
void apply_trivial(std::array< buffer_info, NVectorized > &buffers, std::array< void *, N > &params, Return *out, size_t size, index_sequence< Index... >, index_sequence< VIndex... >, index_sequence< BIndex... >)
Definition: numpy.h:1569
void increment_common_iterator(size_t dim)
Definition: numpy.h:1381
ssize_t ndim() const
Returns the number of dimensions of the array.
Definition: numpy.h:396
PyTypeObject * PyArrayDescr_Type_
Definition: numpy.h:192
Py_intptr_t * ptr
Definition: numpy.h:165
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
Definition: mpreal.h:2201
static PyObject * raw_array(PyObject *ptr, int ExtraFlags=0)
Create array from any object – always returns a new reference.
Definition: numpy.h:826
Definition: pytypes.h:1301
static npy_api lookup()
Definition: numpy.h:224
remove_reference_t< Func > f
Definition: numpy.h:1512
const double h
const T & at(Ix...index) const
Definition: numpy.h:891
ssize_t size
Definition: buffer_info.h:20
static array ensure(handle h, int ExtraFlags=0)
Definition: numpy.h:766
const char * name
Definition: numpy.h:1088
std::string format_str
Definition: numpy.h:84
void check_dimensions_impl(ssize_t, const ssize_t *) const
Definition: numpy.h:814
PyObject * names
Definition: numpy.h:60
ssize_t strides(ssize_t dim) const
Stride along a given axis.
Definition: numpy.h:665
static module_ import(const char *name)
Import and return a module or throws error_already_set.
Definition: pybind11.h:914
PYBIND11_NOINLINE detail::type_info * get_type_info(PyTypeObject *type)
Definition: cast.h:164
array_t(handle h, stolen_t)
Definition: numpy.h:849
bool PyArray_Check_(PyObject *obj) const
Definition: numpy.h:174
static bool check_(handle h)
Definition: numpy.h:934
void check_writeable() const
Definition: numpy.h:786
static PyObject * dtype_ptr()
Definition: numpy.h:1178
std::is_same< bools< Ts::value..., true >, bools< true, Ts::value... >> all_of
ssize_t ndim() const
Number of dimensions.
Definition: numpy.h:638
dtype(const buffer_info &info)
Definition: numpy.h:453
bool load(handle src, bool convert)
Definition: numpy.h:990
const T * data(Ix...index) const
Definition: numpy.h:882
ssize_t index_at(Ix...index) const
Definition: numpy.h:712
ssize_t size() const
Total number of elements.
Definition: numpy.h:623
ssize_t offset
Definition: numpy.h:1089
bool writeable() const
If set, the array is writeable (otherwise the buffer is read-only)
Definition: numpy.h:677
conditional_t< vectorize, array_t< remove_cv_t< call_type >, array::forcecast >, T > type
Definition: numpy.h:1482
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
dtype(const char *format)
Definition: numpy.h:463
numpy_type_info * get_type_info(const std::type_info &tinfo, bool throw_if_missing=true)
Definition: numpy.h:90
Definition: numpy.h:836
vectorize_helper(T &&f)
Definition: numpy.h:1502
ssize_t byte_offset(Ix...index) const
Definition: numpy.h:781
PyObject * base
Definition: numpy.h:69
Definition: pytypes.h:1255
container_type m_strides
Definition: numpy.h:1314
array_t(private_ctor, ShapeContainer &&shape, StridesContainer &&strides, const T *ptr, handle base)
Definition: numpy.h:840
array squeeze()
Return a new view with all of the dimensions of length 1 removed.
Definition: numpy.h:744
Annotation for function names.
Definition: attr.h:36
array_t(ssize_t count, const T *ptr=nullptr, handle base=handle())
Definition: numpy.h:871
Annotation indicating that a class derives from another given type.
Definition: attr.h:42
int flags
Definition: numpy.h:71
const int Dynamic
Definition: Constants.h:21
Information record describing a Python buffer object.
Definition: buffer_info.h:17
common_iterator(void *ptr, const container_type &strides, const container_type &shape)
Definition: numpy.h:1294
bool owndata() const
If set, the array owns the data (will be freed when the array is deleted)
Definition: numpy.h:682
Container::iterator get(Container &c, Position position)
detail::unchecked_mutable_reference< T, Dims > mutable_unchecked()&
Definition: numpy.h:910
static dtype from_args(object args)
This is essentially the same as calling numpy.dtype(args) in Python.
Definition: numpy.h:475
bool check_flags(const void *ptr, int flag)
Definition: numpy.h:274
PyTypeObject * PyVoidArrType_Type_
Definition: numpy.h:191
bool_constant< sizeof(T)==sizeof(U)> as
Definition: numpy.h:116
static PyObject * raw_array_t(PyObject *ptr)
Create array from any object – always returns a new reference.
Definition: numpy.h:943
numpy_internals & get_numpy_internals()
Definition: numpy.h:108
bool equal(const T &obj1, const T &obj2, double tol)
Definition: Testable.h:83
size_t len(handle h)
Definition: pytypes.h:1514
void run(Expr &expr, Dev &dev)
Definition: TensorSyclRun.h:33
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
Definition: numpy.h:374
container_type::size_type size_type
Definition: numpy.h:1290
typename make_index_sequence_impl< N >::type make_index_sequence
ssize_t offset_at() const
Definition: numpy.h:708
static bool direct_converter(PyObject *obj, void *&value)
Definition: numpy.h:1183
array_t(ShapeContainer shape, const T *ptr=nullptr, handle base=handle())
Definition: numpy.h:866
void resize(ShapeContainer new_shape, bool refcheck=true)
Definition: numpy.h:752
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)
Definition: numpy.h:465
const ssize_t dims_
Definition: numpy.h:351
#define PYBIND11_TYPE_CASTER(type, py_name)
Definition: cast.h:979
std::ptrdiff_t j
#define PYBIND11_NAMESPACE_END(name)
buffer_info request(bool writable=false) const
Definition: pytypes.h:1363
container_type m_index
Definition: numpy.h:1387
char * subarray
Definition: numpy.h:58
broadcast_trivial broadcast(const std::array< buffer_info, N > &buffers, ssize_t &ndim, std::vector< ssize_t > &shape)
Definition: numpy.h:1398
Definition: pytypes.h:897
#define PYBIND11_NAMESPACE_BEGIN(name)
ssize_t itemsize() const
Size of the data type in bytes.
Definition: numpy.h:488
PyArray_Proxy * array_proxy(void *ptr)
Definition: numpy.h:258
T & mutable_at(Ix...index)
Definition: numpy.h:898
typename array_info< T >::type remove_all_extents_t
Definition: numpy.h:315
ssize_t offset_at(const arr &a, Ix...idx)
bool(* PyArray_EquivTypes_)(PyObject *, PyObject *)
Definition: numpy.h:196
void apply_broadcast(std::array< buffer_info, NVectorized > &buffers, std::array< void *, N > &params, array_t< Return > &output_array, index_sequence< Index... >, index_sequence< VIndex... >, index_sequence< BIndex... >)
Definition: numpy.h:1592


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:43:05