buffer_info.h
Go to the documentation of this file.
1 /*
2  pybind11/buffer_info.h: Python buffer object interface
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 "detail/common.h"
13 
15 
17 
18 // Default, C-style strides
19 inline std::vector<ssize_t> c_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
20  auto ndim = shape.size();
21  std::vector<ssize_t> strides(ndim, itemsize);
22  if (ndim > 0) {
23  for (size_t i = ndim - 1; i > 0; --i) {
24  strides[i - 1] = strides[i] * shape[i];
25  }
26  }
27  return strides;
28 }
29 
30 // F-style strides; default when constructing an array_t with `ExtraFlags & f_style`
31 inline std::vector<ssize_t> f_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
32  auto ndim = shape.size();
33  std::vector<ssize_t> strides(ndim, itemsize);
34  for (size_t i = 1; i < ndim; ++i) {
35  strides[i] = strides[i - 1] * shape[i - 1];
36  }
37  return strides;
38 }
39 
40 template <typename T, typename SFINAE = void>
42 
44 
45 struct buffer_info {
47  void *ptr = nullptr; // Pointer to the underlying storage
48  ssize_t itemsize = 0; // Size of individual items in bytes
49  ssize_t size = 0; // Total number of entries
50  std::string format; // For homogeneous buffers, this should be set to
51  // format_descriptor<T>::format()
52  ssize_t ndim = 0; // Number of dimensions
53  std::vector<ssize_t> shape; // Shape of the tensor (1 entry per dimension)
54  std::vector<ssize_t> strides; // Number of bytes between adjacent entries
55  // (for each per dimension)
56  bool readonly = false; // flag to indicate if the underlying storage may be written to
57 
58  buffer_info() = default;
59 
62  const std::string &format,
63  ssize_t ndim,
64  detail::any_container<ssize_t> shape_in,
65  detail::any_container<ssize_t> strides_in,
66  bool readonly = false)
68  shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) {
69  if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) {
70  pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length");
71  }
72  for (size_t i = 0; i < (size_t) ndim; ++i) {
73  size *= shape[i];
74  }
75  }
76 
77  template <typename T>
79  detail::any_container<ssize_t> shape_in,
80  detail::any_container<ssize_t> strides_in,
81  bool readonly = false)
83  ptr,
84  sizeof(T),
86  static_cast<ssize_t>(shape_in->size()),
87  std::move(shape_in),
88  std::move(strides_in),
89  readonly) {}
90 
93  const std::string &format,
94  ssize_t size,
95  bool readonly = false)
97 
98  template <typename T>
99  buffer_info(T *ptr, ssize_t size, bool readonly = false)
100  : buffer_info(ptr, sizeof(T), format_descriptor<T>::format(), size, readonly) {}
101 
102  template <typename T>
103  buffer_info(const T *ptr, ssize_t size, bool readonly = true)
104  : buffer_info(
105  const_cast<T *>(ptr), sizeof(T), format_descriptor<T>::format(), size, readonly) {}
106 
107  explicit buffer_info(Py_buffer *view, bool ownview = true)
108  : buffer_info(
109  view->buf,
110  view->itemsize,
111  view->format,
112  view->ndim,
113  {view->shape, view->shape + view->ndim},
114  /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects
115  * ignore this flag and return a view with NULL strides.
116  * When strides are NULL, build them manually. */
117  view->strides
118  ? std::vector<ssize_t>(view->strides, view->strides + view->ndim)
119  : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize),
120  (view->readonly != 0)) {
121  // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
122  this->m_view = view;
123  // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
124  this->ownview = ownview;
125  }
126 
127  buffer_info(const buffer_info &) = delete;
128  buffer_info &operator=(const buffer_info &) = delete;
129 
130  buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); }
131 
132  buffer_info &operator=(buffer_info &&rhs) noexcept {
133  ptr = rhs.ptr;
134  itemsize = rhs.itemsize;
135  size = rhs.size;
136  format = std::move(rhs.format);
137  ndim = rhs.ndim;
138  shape = std::move(rhs.shape);
139  strides = std::move(rhs.strides);
140  std::swap(m_view, rhs.m_view);
141  std::swap(ownview, rhs.ownview);
142  readonly = rhs.readonly;
143  return *this;
144  }
145 
147  if (m_view && ownview) {
148  PyBuffer_Release(m_view);
149  delete m_view;
150  }
151  }
152 
153  Py_buffer *view() const { return m_view; }
154  Py_buffer *&view() { return m_view; }
155 
156  /* True if the buffer item type is equivalent to `T`. */
157  // To define "equivalent" by example:
158  // `buffer_info::item_type_is_equivalent_to<int>(b)` and
159  // `buffer_info::item_type_is_equivalent_to<long>(b)` may both be true
160  // on some platforms, but `int` and `unsigned` will never be equivalent.
161  // For the ground truth, please inspect `detail::compare_buffer_info<>`.
162  template <typename T>
165  }
166 
167 private:
168  struct private_ctr_tag {};
169 
171  void *ptr,
172  ssize_t itemsize,
173  const std::string &format,
174  ssize_t ndim,
175  detail::any_container<ssize_t> &&shape_in,
176  detail::any_container<ssize_t> &&strides_in,
177  bool readonly)
178  : buffer_info(
179  ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {}
180 
181  Py_buffer *m_view = nullptr;
182  bool ownview = false;
183 };
184 
186 
187 template <typename T, typename SFINAE>
188 struct compare_buffer_info {
189  static bool compare(const buffer_info &b) {
190  // NOLINTNEXTLINE(bugprone-sizeof-expression) Needed for `PyObject *`
191  return b.format == format_descriptor<T>::format() && b.itemsize == (ssize_t) sizeof(T);
192  }
193 };
194 
195 template <typename T>
196 struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {
197  static bool compare(const buffer_info &b) {
198  return (size_t) b.itemsize == sizeof(T)
199  && (b.format == format_descriptor<T>::value
200  || ((sizeof(T) == sizeof(long))
201  && b.format == (std::is_unsigned<T>::value ? "L" : "l"))
202  || ((sizeof(T) == sizeof(size_t))
203  && b.format == (std::is_unsigned<T>::value ? "N" : "n")));
204  }
205 };
206 
buffer_info::view
Py_buffer *& view()
Definition: buffer_info.h:154
compare
bool compare
Definition: SolverComparer.cpp:98
buffer_info::buffer_info
buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, detail::any_container< ssize_t > shape_in, detail::any_container< ssize_t > strides_in, bool readonly=false)
Definition: buffer_info.h:60
format_descriptor
Definition: wrap/pybind11/include/pybind11/detail/common.h:1023
return_value_policy::move
@ move
format
std::string format(const std::string &str, const std::vector< std::string > &find, const std::vector< std::string > &replace)
Definition: openglsupport.cpp:226
Eigen::internal::strides
EIGEN_ALWAYS_INLINE DSizes< IndexType, NumDims > strides(const DSizes< IndexType, NumDims > &dimensions)
Definition: TensorBlock.h:26
ssize_t
Py_ssize_t ssize_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:475
buffer_info::buffer_info
buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size, bool readonly=false)
Definition: buffer_info.h:91
buffer_info::size
ssize_t size
Definition: buffer_info.h:49
b
Scalar * b
Definition: benchVecAdd.cpp:17
f_strides
std::vector< ssize_t > f_strides(const std::vector< ssize_t > &shape, ssize_t itemsize)
Definition: buffer_info.h:31
buffer_info::private_ctr_tag
Definition: buffer_info.h:168
buffer_info::~buffer_info
~buffer_info()
Definition: buffer_info.h:146
PYBIND11_NAMESPACE_END
#define PYBIND11_NAMESPACE_END(name)
Definition: wrap/pybind11/include/pybind11/detail/common.h:80
T
Eigen::Triplet< double > T
Definition: Tutorial_sparse_example.cpp:6
detail
Definition: testSerializationNonlinear.cpp:70
PYBIND11_NAMESPACE_BEGIN
#define PYBIND11_NAMESPACE_BEGIN(name)
Definition: wrap/pybind11/include/pybind11/detail/common.h:76
compare_buffer_info< T, detail::enable_if_t< std::is_integral< T >::value > >::compare
static bool compare(const buffer_info &b)
Definition: buffer_info.h:197
size
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
view
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 view
Definition: gnuplot_common_settings.hh:27
buffer_info::format
std::string format
Definition: buffer_info.h:50
buffer_info::buffer_info
buffer_info(Py_buffer *view, bool ownview=true)
Definition: buffer_info.h:107
buffer_info::buffer_info
buffer_info(const T *ptr, ssize_t size, bool readonly=true)
Definition: buffer_info.h:103
buffer_info::itemsize
ssize_t itemsize
Definition: buffer_info.h:48
buffer_info::shape
std::vector< ssize_t > shape
Definition: buffer_info.h:53
buffer_info::buffer_info
buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, detail::any_container< ssize_t > &&shape_in, detail::any_container< ssize_t > &&strides_in, bool readonly)
Definition: buffer_info.h:170
buffer_info::readonly
bool readonly
Definition: buffer_info.h:56
std::swap
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)
Definition: NearestNeighbor.hpp:827
buffer_info::ndim
ssize_t ndim
Definition: buffer_info.h:52
PYBIND11_NAMESPACE
Definition: test_custom_type_casters.cpp:24
Eigen::Triplet< double >
common.h
pybind11_fail
PyExc_RuntimeError PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
Definition: wrap/pybind11/include/pybind11/detail/common.h:1013
size_t
std::size_t size_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:476
buffer_info::ownview
bool ownview
Definition: buffer_info.h:182
move
detail::enable_if_t<!detail::move_never< T >::value, T > move(object &&obj)
Definition: cast.h:1119
std
Definition: BFloat16.h:88
buffer_info::operator=
buffer_info & operator=(buffer_info &&rhs) noexcept
Definition: buffer_info.h:132
buffer_info
Information record describing a Python buffer object.
Definition: buffer_info.h:46
buffer_info::ptr
void * ptr
Definition: buffer_info.h:47
compare_buffer_info::compare
static bool compare(const buffer_info &b)
Definition: buffer_info.h:189
buffer_info::buffer_info
buffer_info(T *ptr, detail::any_container< ssize_t > shape_in, detail::any_container< ssize_t > strides_in, bool readonly=false)
Definition: buffer_info.h:78
compare_buffer_info
Definition: buffer_info.h:41
buffer_info::strides
std::vector< ssize_t > strides
Definition: buffer_info.h:54
c_strides
std::vector< ssize_t > c_strides(const std::vector< ssize_t > &shape, ssize_t itemsize)
Definition: buffer_info.h:19
enable_if_t
typename std::enable_if< B, T >::type enable_if_t
from cpp_future import (convenient aliases from C++14/17)
Definition: wrap/pybind11/include/pybind11/detail/common.h:640
buffer_info::item_type_is_equivalent_to
bool item_type_is_equivalent_to() const
Definition: buffer_info.h:163
test_callbacks.value
value
Definition: test_callbacks.py:158
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
pybind_wrapper_test_script.other
other
Definition: pybind_wrapper_test_script.py:42
buffer_info::buffer_info
buffer_info(T *ptr, ssize_t size, bool readonly=false)
Definition: buffer_info.h:99
buffer_info::buffer_info
buffer_info()=default
buffer_info::view
Py_buffer * view() const
Definition: buffer_info.h:153
buffer_info::buffer_info
buffer_info(buffer_info &&other) noexcept
Definition: buffer_info.h:130


gtsam
Author(s):
autogenerated on Sat Jun 1 2024 03:01:15