Skip to content

Commit 30d43c4

Browse files
Cris Luengodean0x7d
authored andcommitted
Now shape, size, ndims and itemsize are also signed integers.
1 parent b68959e commit 30d43c4

File tree

13 files changed

+207
-205
lines changed

13 files changed

+207
-205
lines changed

docs/advanced/pycpp/numpy.rst

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ specification.
5757
5858
struct buffer_info {
5959
void *ptr;
60-
size_t itemsize;
60+
ssize_t itemsize;
6161
std::string format;
62-
int ndim;
63-
std::vector<size_t> shape;
62+
ssize_t ndim;
63+
std::vector<ssize_t> shape;
6464
std::vector<ssize_t> strides;
6565
};
6666
@@ -95,8 +95,8 @@ buffer objects (e.g. a NumPy matrix).
9595
throw std::runtime_error("Incompatible buffer dimension!");
9696
9797
auto strides = Strides(
98-
info.strides[rowMajor ? 0 : 1] / sizeof(Scalar),
99-
info.strides[rowMajor ? 1 : 0] / sizeof(Scalar));
98+
info.strides[rowMajor ? 0 : 1] / (py::ssize_t)sizeof(Scalar),
99+
info.strides[rowMajor ? 1 : 0] / (py::ssize_t)sizeof(Scalar));
100100
101101
auto map = Eigen::Map<Matrix, 0, Strides>(
102102
static_cat<Scalar *>(info.ptr), info.shape[0], info.shape[1], strides);
@@ -111,17 +111,14 @@ as follows:
111111
112112
.def_buffer([](Matrix &m) -> py::buffer_info {
113113
return py::buffer_info(
114-
m.data(), /* Pointer to buffer */
115-
sizeof(Scalar), /* Size of one scalar */
116-
/* Python struct-style format descriptor */
117-
py::format_descriptor<Scalar>::format(),
118-
/* Number of dimensions */
119-
2,
120-
/* Buffer dimensions */
121-
{ m.rows(), m.cols() },
122-
/* Strides (in bytes) for each index */
114+
m.data(), /* Pointer to buffer */
115+
sizeof(Scalar), /* Size of one scalar */
116+
py::format_descriptor<Scalar>::format(), /* Python struct-style format descriptor */
117+
2, /* Number of dimensions */
118+
{ m.rows(), m.cols() }, /* Buffer dimensions */
123119
{ sizeof(Scalar) * (rowMajor ? m.cols() : 1),
124120
sizeof(Scalar) * (rowMajor ? 1 : m.rows()) }
121+
/* Strides (in bytes) for each index */
125122
);
126123
})
127124
@@ -321,17 +318,17 @@ where ``N`` gives the required dimensionality of the array:
321318
m.def("sum_3d", [](py::array_t<double> x) {
322319
auto r = x.unchecked<3>(); // x must have ndim = 3; can be non-writeable
323320
double sum = 0;
324-
for (size_t i = 0; i < r.shape(0); i++)
325-
for (size_t j = 0; j < r.shape(1); j++)
326-
for (size_t k = 0; k < r.shape(2); k++)
321+
for (ssize_t i = 0; i < r.shape(0); i++)
322+
for (ssize_t j = 0; j < r.shape(1); j++)
323+
for (ssize_t k = 0; k < r.shape(2); k++)
327324
sum += r(i, j, k);
328325
return sum;
329326
});
330327
m.def("increment_3d", [](py::array_t<double> x) {
331328
auto r = x.mutable_unchecked<3>(); // Will throw if ndim != 3 or flags.writeable is false
332-
for (size_t i = 0; i < r.shape(0); i++)
333-
for (size_t j = 0; j < r.shape(1); j++)
334-
for (size_t k = 0; k < r.shape(2); k++)
329+
for (ssize_t i = 0; i < r.shape(0); i++)
330+
for (ssize_t j = 0; j < r.shape(1); j++)
331+
for (ssize_t k = 0; k < r.shape(2); k++)
335332
r(i, j, k) += 1.0;
336333
}, py::arg().noconvert());
337334

include/pybind11/buffer_info.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,31 @@ NAMESPACE_BEGIN(pybind11)
1515

1616
/// Information record describing a Python buffer object
1717
struct buffer_info {
18-
void *ptr = nullptr; // Pointer to the underlying storage
19-
size_t itemsize = 0; // Size of individual items in bytes
20-
size_t size = 0; // Total number of entries
21-
std::string format; // For homogeneous buffers, this should be set to format_descriptor<T>::format()
22-
size_t ndim = 0; // Number of dimensions
23-
std::vector<size_t> shape; // Shape of the tensor (1 entry per dimension)
18+
void *ptr = nullptr; // Pointer to the underlying storage
19+
ssize_t itemsize = 0; // Size of individual items in bytes
20+
ssize_t size = 0; // Total number of entries
21+
std::string format; // For homogeneous buffers, this should be set to format_descriptor<T>::format()
22+
ssize_t ndim = 0; // Number of dimensions
23+
std::vector<ssize_t> shape; // Shape of the tensor (1 entry per dimension)
2424
std::vector<ssize_t> strides; // Number of entries between adjacent entries (for each per dimension)
2525

2626
buffer_info() { }
2727

28-
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t ndim,
29-
detail::any_container<size_t> shape_in, detail::any_container<ssize_t> strides_in)
28+
buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim,
29+
detail::any_container<ssize_t> shape_in, detail::any_container<ssize_t> strides_in)
3030
: ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim),
3131
shape(std::move(shape_in)), strides(std::move(strides_in)) {
32-
if (ndim != shape.size() || ndim != strides.size())
32+
if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size())
3333
pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length");
34-
for (size_t i = 0; i < ndim; ++i)
34+
for (size_t i = 0; i < (size_t) ndim; ++i)
3535
size *= shape[i];
3636
}
3737

38-
buffer_info(void *ptr, size_t itemsize, const std::string &format, size_t size)
38+
buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size)
3939
: buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}) { }
4040

4141
explicit buffer_info(Py_buffer *view, bool ownview = true)
42-
: buffer_info(view->buf, (size_t) view->itemsize, view->format, (size_t) view->ndim,
42+
: buffer_info(view->buf, view->itemsize, view->format, view->ndim,
4343
{view->shape, view->shape + view->ndim}, {view->strides, view->strides + view->ndim}) {
4444
this->view = view;
4545
this->ownview = ownview;
@@ -78,13 +78,13 @@ NAMESPACE_BEGIN(detail)
7878

7979
template <typename T, typename SFINAE = void> struct compare_buffer_info {
8080
static bool compare(const buffer_info& b) {
81-
return b.format == format_descriptor<T>::format() && b.itemsize == sizeof(T);
81+
return b.format == format_descriptor<T>::format() && b.itemsize == (ssize_t) sizeof(T);
8282
}
8383
};
8484

8585
template <typename T> struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {
8686
static bool compare(const buffer_info& b) {
87-
return b.itemsize == sizeof(T) && (b.format == format_descriptor<T>::value ||
87+
return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor<T>::value ||
8888
((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned<T>::value ? "L" : "l")) ||
8989
((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned<T>::value ? "N" : "n")));
9090
}

include/pybind11/class_support.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
433433
#endif
434434
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
435435
type->tp_dictoffset = type->tp_basicsize; // place dict at the end
436-
type->tp_basicsize += (Py_ssize_t)sizeof(PyObject *); // and allocate enough space for it
436+
type->tp_basicsize += (ssize_t)sizeof(PyObject *); // and allocate enough space for it
437437
type->tp_traverse = pybind11_traverse;
438438
type->tp_clear = pybind11_clear;
439439

@@ -459,18 +459,16 @@ extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int fla
459459
view->ndim = 1;
460460
view->internal = info;
461461
view->buf = info->ptr;
462-
view->itemsize = (Py_ssize_t) info->itemsize;
462+
view->itemsize = info->itemsize;
463463
view->len = view->itemsize;
464464
for (auto s : info->shape)
465-
view->len *= (Py_ssize_t) s;
465+
view->len *= s;
466466
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
467467
view->format = const_cast<char *>(info->format.c_str());
468468
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
469469
view->ndim = (int) info->ndim;
470470
view->strides = &info->strides[0];
471-
// Next is a pointer cast, let's make sure it's safe.
472-
static_assert(sizeof(Py_ssize_t)==sizeof(info->shape[0]), "sizeof(Py_ssize_t) != sizeof(size_t)");
473-
view->shape = (Py_ssize_t *) &info->shape[0];
471+
view->shape = &info->shape[0];
474472
}
475473
Py_INCREF(view->obj);
476474
return 0;

include/pybind11/eigen.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ template <typename T> using is_eigen_other = all_of<
6868
template <bool EigenRowMajor> struct EigenConformable {
6969
bool conformable = false;
7070
EigenIndex rows = 0, cols = 0;
71-
EigenDStride stride{0, 0}; // Only valid if negativestridees is false!
71+
EigenDStride stride{0, 0}; // Only valid if negativestrides is false!
7272
bool negativestrides = false; // If true, do not use stride!
7373

7474
EigenConformable(bool fits = false) : conformable{fits} {}
@@ -207,7 +207,7 @@ template <typename Type_> struct EigenProps {
207207
// Casts an Eigen type to numpy array. If given a base, the numpy array references the src data,
208208
// otherwise it'll make a copy. writeable lets you turn off the writeable flag for the array.
209209
template <typename props> handle eigen_array_cast(typename props::Type const &src, handle base = handle(), bool writeable = true) {
210-
constexpr size_t elem_size = sizeof(typename props::Scalar);
210+
constexpr ssize_t elem_size = sizeof(typename props::Scalar);
211211
array a;
212212
if (props::vector)
213213
a = array({ src.size() }, { elem_size * src.innerStride() }, src.data(), base);
@@ -581,9 +581,9 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
581581
object matrix_type = module::import("scipy.sparse").attr(
582582
rowMajor ? "csr_matrix" : "csc_matrix");
583583

584-
array data((size_t) src.nonZeros(), src.valuePtr());
585-
array outerIndices((size_t) (rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
586-
array innerIndices((size_t) src.nonZeros(), src.innerIndexPtr());
584+
array data(src.nonZeros(), src.valuePtr());
585+
array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
586+
array innerIndices(src.nonZeros(), src.innerIndexPtr());
587587

588588
return matrix_type(
589589
std::make_tuple(data, innerIndices, outerIndices),

0 commit comments

Comments
 (0)