Skip to content

Commit 9da6bd0

Browse files
committed
Adsk Contrib - Detect C/F order, if not C order : RuntimeError shown, test is still not passing
1 parent 50bf17d commit 9da6bd0

File tree

2 files changed

+47
-66
lines changed

2 files changed

+47
-66
lines changed

src/bindings/python/PyCPUProcessor.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,28 +92,34 @@ written to the dstImgDesc image, leaving srcImgDesc unchanged.
9292
9393
)doc")
9494
.def("applyRGB", [](CPUProcessorRcPtr & self, py::buffer & data)
95-
{
95+
{
9696
py::buffer_info info = data.request();
9797
checkBufferDivisible(info, 3);
9898

99-
// Interpret as single row of RGB pixels
100-
BitDepth bitDepth = getBufferBitDepth(info);
99+
// --- detect C-contiguous ---
100+
bool isC = true;
101+
ptrdiff_t itemsize = info.itemsize;
102+
auto shape = info.shape;
103+
auto strides = info.strides;
104+
py::ssize_t ndim = info.ndim;
101105

102-
py::gil_scoped_release release;
103-
bool isCContiguous = true;
104-
if (info.ndim >= 2)
106+
ptrdiff_t expected = itemsize;
107+
for (py::ssize_t i = ndim - 1; i >= 0; --i)
105108
{
106-
// last dimension stride should be itemsize
107-
if (info.strides.back() != info.itemsize)
108-
{
109-
isCContiguous = false;
110-
}
109+
if (strides[i] != expected) { isC = false; break; }
110+
expected *= shape[i];
111111
}
112-
if (!isCContiguous)
112+
113+
if (!isC)
113114
{
114115
throw std::runtime_error("applyRGB only supports C-contiguous (row-major) arrays");
115116
}
116117

118+
// --- proceed normally ---
119+
BitDepth bitDepth = getBufferBitDepth(info);
120+
121+
py::gil_scoped_release release;
122+
117123
long numChannels = 3;
118124
long width = (long)info.size / numChannels;
119125
long height = 1;
@@ -128,8 +134,9 @@ written to the dstImgDesc image, leaving srcImgDesc unchanged.
128134
chanStrideBytes,
129135
xStrideBytes,
130136
yStrideBytes);
137+
131138
self->apply(img);
132-
},
139+
},
133140
"data"_a,
134141
R"doc(
135142
Apply to a packed RGB array adhering to the Python buffer protocol.

tests/python/CPUProcessorTest.py

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020

2121
class CPUProcessorTest(unittest.TestCase):
22-
FLOAT_DELTA = 1e+5
22+
FLOAT_DELTA = 1e-5
2323
UINT_DELTA = 1
2424

2525
@classmethod
@@ -391,79 +391,53 @@ def test_apply_rgb_buffer_column_major(self):
391391
return
392392

393393
for arr, cpu_proc_fwd, cpu_proc_inv in [
394-
(
395-
self.float_rgb_2d,
396-
self.default_cpu_proc_fwd,
397-
self.default_cpu_proc_inv
398-
),
399-
(
400-
self.float_rgb_3d,
401-
self.default_cpu_proc_fwd,
402-
self.default_cpu_proc_inv
403-
),
404-
(
405-
self.half_rgb_2d,
406-
self.half_cpu_proc_fwd,
407-
self.half_cpu_proc_inv
408-
),
409-
(
410-
self.half_rgb_3d,
411-
self.half_cpu_proc_fwd,
412-
self.half_cpu_proc_inv
413-
),
414-
(
415-
self.uint16_rgb_2d,
416-
self.uint16_cpu_proc_fwd,
417-
self.uint16_cpu_proc_inv
418-
),
419-
(
420-
self.uint16_rgb_3d,
421-
self.uint16_cpu_proc_fwd,
422-
self.uint16_cpu_proc_inv
423-
),
424-
(
425-
self.uint8_rgb_2d,
426-
self.uint8_cpu_proc_fwd,
427-
self.uint8_cpu_proc_inv
428-
),
429-
(
430-
self.uint8_rgb_3d,
431-
self.uint8_cpu_proc_fwd,
432-
self.uint8_cpu_proc_inv
433-
),
394+
(self.float_rgb_2d, self.default_cpu_proc_fwd, self.default_cpu_proc_inv),
395+
(self.float_rgb_3d, self.default_cpu_proc_fwd, self.default_cpu_proc_inv),
396+
(self.half_rgb_2d, self.half_cpu_proc_fwd, self.half_cpu_proc_inv),
397+
(self.half_rgb_3d, self.half_cpu_proc_fwd, self.half_cpu_proc_inv),
398+
(self.uint16_rgb_2d, self.uint16_cpu_proc_fwd, self.uint16_cpu_proc_inv),
399+
(self.uint16_rgb_3d, self.uint16_cpu_proc_fwd, self.uint16_cpu_proc_inv),
400+
(self.uint8_rgb_2d, self.uint8_cpu_proc_fwd, self.uint8_cpu_proc_inv),
401+
(self.uint8_rgb_3d, self.uint8_cpu_proc_fwd, self.uint8_cpu_proc_inv),
434402
]:
435-
# Transpose to column-major format and
436-
# Process duplicate array
403+
# Transpose to F-order (column-major)
437404
arr_copy = arr.copy().T
438405

439-
cpu_proc_fwd.applyRGB(arr_copy)
440-
for i in range(arr_copy.size):
406+
# Expect runtime error for non-C-contiguous array
407+
with self.assertRaises(RuntimeError):
408+
cpu_proc_fwd.applyRGB(arr_copy)
409+
410+
# Convert back to C-order and retry
411+
arr_copy_c = np.ascontiguousarray(arr_copy)
412+
cpu_proc_fwd.applyRGB(arr_copy_c)
413+
414+
# Check forward transform
415+
for i in range(arr_copy_c.size):
441416
if arr.dtype in (np.float32, np.float16):
442417
self.assertAlmostEqual(
443-
arr_copy.flat[i],
418+
arr_copy_c.flat[i],
444419
arr.flat[i] * 0.5,
445420
delta=self.FLOAT_DELTA
446421
)
447422
else:
448423
self.assertAlmostEqual(
449-
arr_copy.flat[i],
424+
arr_copy_c.flat[i],
450425
arr.flat[i] // 2,
451426
delta=self.UINT_DELTA
452427
)
453428

454-
# Inverse transform roundtrips values in place
455-
cpu_proc_inv.applyRGB(arr_copy)
456-
457-
for i in range(arr_copy.size):
429+
# Inverse transform
430+
cpu_proc_inv.applyRGB(arr_copy_c)
431+
for i in range(arr_copy_c.size):
458432
if arr.dtype in (np.float32, np.float16):
459433
self.assertAlmostEqual(
460-
arr_copy.flat[i],
434+
arr_copy_c.flat[i],
461435
arr.flat[i],
462436
delta=self.FLOAT_DELTA
463437
)
464438
else:
465439
self.assertAlmostEqual(
466-
arr_copy.flat[i],
440+
arr_copy_c.flat[i],
467441
arr.flat[i],
468442
delta=self.UINT_DELTA
469443
)

0 commit comments

Comments
 (0)