Skip to content

Commit d2b808a

Browse files
committedAug 27, 2024··
Fixes for numpy2 / (Fixes #17)
* is_array_contiguous now check the array flags against c_style * matx_to_nparray now has to specifically set the strides (otherwise numpy2 will make a bad assumption about it)
1 parent 8ed2756 commit d2b808a

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed
 

‎cvnp/cvnp.cpp

+1-9
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,7 @@ namespace cvnp
181181

182182
bool is_array_contiguous(const pybind11::array& a)
183183
{
184-
pybind11::ssize_t expected_stride = a.itemsize();
185-
for (int i = a.ndim() - 1; i >=0; --i)
186-
{
187-
pybind11::ssize_t current_stride = a.strides()[i];
188-
if (current_stride != expected_stride)
189-
return false;
190-
expected_stride = expected_stride * a.shape()[i];
191-
}
192-
return true;
184+
return a.flags() & pybind11::array::c_style;
193185
}
194186

195187

‎cvnp/cvnp.h

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace cvnp
4949
return pybind11::array(
5050
pybind11::dtype::of<_Tp>()
5151
, std::vector<std::size_t> {_rows, _cols}
52+
, std::vector<std::size_t>{_cols * sizeof(_Tp), sizeof(_Tp)} // Strides
5253
, m.val
5354
);
5455
}

‎cvnp/cvnp_test_helper.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,21 @@ void display_eye(cv::Matx33d m = cv::Matx33d::eye())
130130
}
131131

132132

133+
cv::Matx21d RoundTripMatx21d(cv::Matx21d & m)
134+
{
135+
//std::cout << "RoundTripMatx21d received " << m(0, 0) << " " << m(1, 0) << "\n";
136+
return m;
137+
}
138+
139+
133140

134141
void pydef_cvnp_test(pybind11::module& m)
135142
{
136143
m.def("make_eye", make_eye);
137144
m.def("display_eye", display_eye);
138145

146+
m.def("RoundTripMatx21d", RoundTripMatx21d);
147+
139148
pybind11::class_<CvNp_TestHelper>(m, "CvNp_TestHelper")
140149
.def(pybind11::init<>())
141150

‎tests/test_cvnp.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def test_matx_not_shared():
139139
# create object
140140
o = CvNp_TestHelper()
141141

142-
m_linked = o.mx_ns # Make a numy array that is a copy of mx_ns *without* shared memory
142+
m_linked = o.mx_ns # Make a numpy array that is a copy of mx_ns *without* shared memory
143143
assert m_linked.shape == (3, 2) # check its shape
144144
m_linked[1, 1] = 3 # a value change in the numpy array made from python
145145
assert o.mx_ns[1, 1] != 3 # is not visible from C++!
@@ -467,9 +467,39 @@ def test_rect():
467467
o.rect_double = (1, 2) # We should give 4 values!
468468

469469

470+
def test_contiguous_check():
471+
# Check regression with numpy 2:
472+
# See https://github.com/pthom/cvnp/issues/17
473+
# The contiguous check was changed to:
474+
# bool is_array_contiguous(const pybind11::array& a) { return a.flags() & pybind11::array::c_style; }
475+
476+
# 1. Check contiguous matrix
477+
m = np.zeros((10,10),dtype=np.uint8)
478+
cvnp_roundtrip(m)
479+
480+
# 2. Check that a non-contiguous matrix raises an error
481+
full_matrix = np.ones([10, 10], np.float32)
482+
sub_matrix = full_matrix[1:5, 2:4]
483+
with pytest.raises(ValueError):
484+
cvnp_roundtrip(sub_matrix)
485+
486+
487+
def test_matx_roundtrip():
488+
# This test was failing with numpy 2 when matx_to_nparray
489+
# did not transmit the stride for small matrices (Matx)
490+
from cvnp import RoundTripMatx21d
491+
m = np.zeros((2, 1), np.float64)
492+
m[0, 0] = 42.1
493+
m[1, 0] = 43.1
494+
m2 = RoundTripMatx21d(m)
495+
assert are_float_close(m2[0, 0], 42.1)
496+
assert are_float_close(m2[1, 0], 43.1)
497+
470498

471499
def main():
472500
# Todo: find a way to call pytest for this file
501+
test_contiguous_check()
502+
test_matx_roundtrip()
473503
test_refcount()
474504
test_mat_shared()
475505
test_mat__shared()

0 commit comments

Comments
 (0)
Please sign in to comment.