Skip to content

Commit 792b3f7

Browse files
Introduce helper file to work around issue numpy#26990
The helper file defines workaround_PyArray_MultiIter_SIZE, etc which used NumPy 2.0 API when building with NumPy 2.0, and a work-around for earlier versions.
1 parent d5032ad commit 792b3f7

File tree

2 files changed

+127
-39
lines changed

2 files changed

+127
-39
lines changed

mkl_random/mklrand.pyx

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@ cdef extern from "Python.h":
3636
int PyErr_Occurred()
3737
void PyErr_Clear()
3838

39+
cdef extern from "numpy/npy_no_deprecated_api.h":
40+
pass
3941

4042
cimport numpy as cnp
4143
from libc.string cimport memset, memcpy
4244
cimport cpython.tuple
45+
cimport cython
4346

4447
cdef extern from "math.h":
4548
double floor(double x)
@@ -52,6 +55,11 @@ cdef extern from "mklrand_py_helper.h":
5255
char* py_bytes_DataPtr(object b)
5356
int is_bytes_object(object b)
5457

58+
cdef extern from "numpy_multiiter_workaround.h":
59+
cnp.npy_intp cnp_PyArray_MultiIter_SIZE "workaround_PyArray_MultiIter_SIZE"(cnp.broadcast multi) nogil
60+
int cnp_PyArray_MultiIter_NDIM "workaround_PyArray_MultiIter_NDIM"(cnp.broadcast multi) nogil
61+
cnp.npy_intp* cnp_PyArray_MultiIter_DIMS "workaround_PyArray_MultiIter_DIMS"(cnp.broadcast multi) nogil
62+
5563
cdef extern from "randomkit.h":
5664

5765
ctypedef struct irk_state:
@@ -188,7 +196,6 @@ cdef int r = cnp._import_array()
188196
if (r<0):
189197
raise ImportError("Failed to import NumPy")
190198

191-
cimport cython
192199
import numpy as np
193200
import operator
194201
import warnings
@@ -265,20 +272,20 @@ cdef object vec_cont1_array(irk_state *state, irk_cont1_vec func, object size,
265272
array_data = <double *>cnp.PyArray_DATA(array)
266273
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(2, <void *>array, <void *>oa)
267274
res_size = cnp.PyArray_SIZE(array)
268-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
275+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
269276
raise ValueError("size is not compatible with inputs")
270277

271278
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(1, <void *>oa)
272-
imax = cnp.PyArray_MultiIter_SIZE(multi)
279+
imax = cnp_PyArray_MultiIter_SIZE(multi)
273280
n = res_size // imax
274281
with lock, nogil:
275282
for i from 0 <= i < imax:
276283
oa_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 0)
277284
func(state, n, array_data + n*i, oa_data[0])
278285
cnp.PyArray_MultiIter_NEXT(multi)
279286
arr_obj = <object>array
280-
multi_nd = cnp.PyArray_MultiIter_NDIM(multi)
281-
multi_dims = cnp.PyArray_MultiIter_DIMS(multi)
287+
multi_nd = cnp_PyArray_MultiIter_NDIM(multi)
288+
multi_dims = cnp_PyArray_MultiIter_DIMS(multi)
282289
multi_shape = cpython.tuple.PyTuple_New(multi_nd)
283290
for i from 0 <= i < multi_nd:
284291
cpython.tuple.PyTuple_SetItem(multi_shape, i, multi_dims[i])
@@ -324,13 +331,13 @@ cdef object vec_cont2_array(irk_state *state, irk_cont2_vec func, object size,
324331
if size is None:
325332
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(2, <void *>oa, <void *>ob)
326333
array = <cnp.ndarray> cnp.PyArray_SimpleNew(
327-
cnp.PyArray_MultiIter_NDIM(multi),
328-
cnp.PyArray_MultiIter_DIMS(multi),
334+
cnp_PyArray_MultiIter_NDIM(multi),
335+
cnp_PyArray_MultiIter_DIMS(multi),
329336
cnp.NPY_DOUBLE
330337
)
331338
array_data = <double *>cnp.PyArray_DATA(array)
332339
with lock, nogil:
333-
for i from 0 <= i < cnp.PyArray_MultiIter_SIZE(multi):
340+
for i from 0 <= i < cnp_PyArray_MultiIter_SIZE(multi):
334341
oa_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 0)
335342
ob_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 1)
336343
func(state, 1, &array_data[i], oa_data[0], ob_data[0])
@@ -341,11 +348,11 @@ cdef object vec_cont2_array(irk_state *state, irk_cont2_vec func, object size,
341348
array_data = <double *>cnp.PyArray_DATA(array)
342349
multi = <cnp.broadcast >cnp.PyArray_MultiIterNew(3, <void*>array, <void *>oa, <void *>ob)
343350
res_size = cnp.PyArray_SIZE(array)
344-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
351+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
345352
raise ValueError("size is not compatible with inputs")
346353

347354
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(2, <void *>oa, <void *>ob)
348-
imax = cnp.PyArray_MultiIter_SIZE(multi)
355+
imax = cnp_PyArray_MultiIter_SIZE(multi)
349356
n = res_size // imax
350357
with lock, nogil:
351358
for i from 0 <= i < imax:
@@ -354,8 +361,8 @@ cdef object vec_cont2_array(irk_state *state, irk_cont2_vec func, object size,
354361
func(state, n, array_data + n*i, oa_data[0], ob_data[0])
355362
cnp.PyArray_MultiIter_NEXT(multi)
356363
arr_obj = <object> array
357-
multi_nd = cnp.PyArray_MultiIter_NDIM(multi)
358-
multi_dims = cnp.PyArray_MultiIter_DIMS(multi)
364+
multi_nd = cnp_PyArray_MultiIter_NDIM(multi)
365+
multi_dims = cnp_PyArray_MultiIter_DIMS(multi)
359366
multi_shape = cpython.tuple.PyTuple_New(multi_nd)
360367
for i from 0 <= i < multi_nd:
361368
cpython.tuple.PyTuple_SetItem(multi_shape, i, multi_dims[i])
@@ -402,10 +409,10 @@ cdef object vec_cont3_array(irk_state *state, irk_cont3_vec func, object size,
402409

403410
if size is None:
404411
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(3, <void *>oa, <void *>ob, <void *>oc)
405-
array = <cnp.ndarray> cnp.PyArray_SimpleNew(cnp.PyArray_MultiIter_NDIM(multi), cnp.PyArray_MultiIter_DIMS(multi), cnp.NPY_DOUBLE)
412+
array = <cnp.ndarray> cnp.PyArray_SimpleNew(cnp_PyArray_MultiIter_NDIM(multi), cnp_PyArray_MultiIter_DIMS(multi), cnp.NPY_DOUBLE)
406413
array_data = <double *>cnp.PyArray_DATA(array)
407414
with lock, nogil:
408-
for i from 0 <= i < cnp.PyArray_MultiIter_SIZE(multi):
415+
for i from 0 <= i < cnp_PyArray_MultiIter_SIZE(multi):
409416
oa_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 0)
410417
ob_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 1)
411418
oc_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 2)
@@ -418,11 +425,11 @@ cdef object vec_cont3_array(irk_state *state, irk_cont3_vec func, object size,
418425
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(4, <void*>array, <void *>oa,
419426
<void *>ob, <void *>oc)
420427
res_size = cnp.PyArray_SIZE(array)
421-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
428+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
422429
raise ValueError("size is not compatible with inputs")
423430

424431
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(3, <void *>oa, <void *>ob, <void *>oc)
425-
imax = cnp.PyArray_MultiIter_SIZE(multi)
432+
imax = cnp_PyArray_MultiIter_SIZE(multi)
426433
n = res_size // imax
427434
with lock, nogil:
428435
for i from 0 <= i < imax:
@@ -432,8 +439,8 @@ cdef object vec_cont3_array(irk_state *state, irk_cont3_vec func, object size,
432439
func(state, n, array_data + n*i, oa_data[0], ob_data[0], oc_data[0])
433440
cnp.PyArray_MultiIter_NEXT(multi)
434441
arr_obj = <object>array
435-
multi_nd = cnp.PyArray_MultiIter_NDIM(multi)
436-
multi_dims = cnp.PyArray_MultiIter_DIMS(multi)
442+
multi_nd = cnp_PyArray_MultiIter_NDIM(multi)
443+
multi_dims = cnp_PyArray_MultiIter_DIMS(multi)
437444
multi_shape = cpython.tuple.PyTuple_New(multi_nd)
438445
for i from 0 <= i < multi_nd:
439446
cpython.tuple.PyTuple_SetItem(multi_shape, i, multi_dims[i])
@@ -521,13 +528,16 @@ cdef object vec_discnp_array(irk_state *state, irk_discnp_vec func, object size,
521528
cdef Py_ssize_t multi_nd
522529
cdef tuple multi_shape
523530
cdef cnp.npy_intp *multi_dims
531+
cdef int multi_nd_i
524532

525533
if size is None:
526534
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(2, <void *>on, <void *>op)
527-
array = <cnp.ndarray> cnp.PyArray_SimpleNew(cnp.PyArray_MultiIter_NDIM(multi), cnp.PyArray_MultiIter_DIMS(multi), cnp.NPY_INT)
535+
multi_nd_i = cnp_PyArray_MultiIter_NDIM(multi)
536+
multi_dims = cnp_PyArray_MultiIter_DIMS(multi)
537+
array = <cnp.ndarray> cnp.PyArray_SimpleNew(multi_nd_i, multi_dims, cnp.NPY_INT)
528538
array_data = <int *>cnp.PyArray_DATA(array)
529539
with lock, nogil:
530-
for i from 0 <= i < cnp.PyArray_MultiIter_SIZE(multi):
540+
for i from 0 <= i < cnp_PyArray_MultiIter_SIZE(multi):
531541
on_data = <int *>cnp.PyArray_MultiIter_DATA(multi, 0)
532542
op_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 1)
533543
func(state, 1, &array_data[i], on_data[0], op_data[0])
@@ -538,11 +548,11 @@ cdef object vec_discnp_array(irk_state *state, irk_discnp_vec func, object size,
538548
array_data = <int *>cnp.PyArray_DATA(array)
539549
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(3, <void*>array, <void *>on, <void *>op)
540550
res_size = cnp.PyArray_SIZE(array)
541-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
551+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
542552
raise ValueError("size is not compatible with inputs")
543553

544554
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(2, <void *>on, <void *>op)
545-
imax = cnp.PyArray_MultiIter_SIZE(multi)
555+
imax = cnp_PyArray_MultiIter_SIZE(multi)
546556
n = res_size // imax
547557
with lock, nogil:
548558
for i from 0 <= i < imax:
@@ -551,8 +561,8 @@ cdef object vec_discnp_array(irk_state *state, irk_discnp_vec func, object size,
551561
func(state, n, array_data + n * i, on_data[0], op_data[0])
552562
cnp.PyArray_MultiIter_NEXT(multi)
553563
arr_obj = <object>array
554-
multi_nd = cnp.PyArray_MultiIter_NDIM(multi)
555-
multi_dims = cnp.PyArray_MultiIter_DIMS(multi)
564+
multi_nd = cnp_PyArray_MultiIter_NDIM(multi)
565+
multi_dims = cnp_PyArray_MultiIter_DIMS(multi)
556566
multi_shape = cpython.tuple.PyTuple_New(multi_nd)
557567
for i from 0 <= i < multi_nd:
558568
cpython.tuple.PyTuple_SetItem(multi_shape, i, multi_dims[i])
@@ -599,10 +609,10 @@ cdef object vec_discdd_array(irk_state *state, irk_discdd_vec func, object size,
599609

600610
if size is None:
601611
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(2, <void *>on, <void *>op)
602-
array = <cnp.ndarray> cnp.PyArray_SimpleNew(cnp.PyArray_MultiIter_NDIM(multi), cnp.PyArray_MultiIter_DIMS(multi), cnp.NPY_INT)
612+
array = <cnp.ndarray> cnp.PyArray_SimpleNew(cnp_PyArray_MultiIter_NDIM(multi), cnp_PyArray_MultiIter_DIMS(multi), cnp.NPY_INT)
603613
array_data = <int *>cnp.PyArray_DATA(array)
604614
with lock, nogil:
605-
for i from 0 <= i < cnp.PyArray_MultiIter_SIZE(multi):
615+
for i from 0 <= i < cnp_PyArray_MultiIter_SIZE(multi):
606616
on_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 0)
607617
op_data = <double *>cnp.PyArray_MultiIter_DATA(multi, 1)
608618
func(state, 1, &array_data[i], on_data[0], op_data[0])
@@ -613,11 +623,11 @@ cdef object vec_discdd_array(irk_state *state, irk_discdd_vec func, object size,
613623
array_data = <int *>cnp.PyArray_DATA(array)
614624
res_size = cnp.PyArray_SIZE(array)
615625
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(3, <void*>array, <void *>on, <void *>op)
616-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
626+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
617627
raise ValueError("size is not compatible with inputs")
618628

619629
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(2, <void *>on, <void *>op)
620-
imax = cnp.PyArray_MultiIter_SIZE(multi)
630+
imax = cnp_PyArray_MultiIter_SIZE(multi)
621631
n = res_size // imax
622632
with lock, nogil:
623633
for i from 0 <= i < imax:
@@ -626,8 +636,8 @@ cdef object vec_discdd_array(irk_state *state, irk_discdd_vec func, object size,
626636
func(state, n, array_data + n * i, on_data[0], op_data[0])
627637
cnp.PyArray_MultiIter_NEXT(multi)
628638
arr_obj = <object>array
629-
multi_nd = cnp.PyArray_MultiIter_NDIM(multi)
630-
multi_dims = cnp.PyArray_MultiIter_DIMS(multi)
639+
multi_nd = cnp_PyArray_MultiIter_NDIM(multi)
640+
multi_dims = cnp_PyArray_MultiIter_DIMS(multi)
631641
multi_shape = cpython.tuple.PyTuple_New(multi_nd)
632642
for i from 0 <= i < multi_nd:
633643
cpython.tuple.PyTuple_SetItem(multi_shape, i, multi_dims[i])
@@ -675,10 +685,10 @@ cdef object vec_discnmN_array(irk_state *state, irk_discnmN_vec func, object siz
675685

676686
if size is None:
677687
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(3, <void *>on, <void *>om, <void *>oN)
678-
array = <cnp.ndarray> cnp.PyArray_SimpleNew(cnp.PyArray_MultiIter_NDIM(multi), cnp.PyArray_MultiIter_DIMS(multi), cnp.NPY_INT)
688+
array = <cnp.ndarray> cnp.PyArray_SimpleNew(cnp_PyArray_MultiIter_NDIM(multi), cnp_PyArray_MultiIter_DIMS(multi), cnp.NPY_INT)
679689
array_data = <int *>cnp.PyArray_DATA(array)
680690
with lock, nogil:
681-
for i from 0 <= i < cnp.PyArray_MultiIter_SIZE(multi):
691+
for i from 0 <= i < cnp_PyArray_MultiIter_SIZE(multi):
682692
on_data = <int *>cnp.PyArray_MultiIter_DATA(multi, 0)
683693
om_data = <int *>cnp.PyArray_MultiIter_DATA(multi, 1)
684694
oN_data = <int *>cnp.PyArray_MultiIter_DATA(multi, 2)
@@ -691,11 +701,11 @@ cdef object vec_discnmN_array(irk_state *state, irk_discnmN_vec func, object siz
691701
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(4, <void*>array, <void *>on, <void *>om,
692702
<void *>oN)
693703
res_size = cnp.PyArray_SIZE(array)
694-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
704+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
695705
raise ValueError("size is not compatible with inputs")
696706

697707
multi = <cnp.broadcast> cnp.PyArray_MultiIterNew(3, <void *>on, <void *>om, <void *>oN)
698-
imax = cnp.PyArray_MultiIter_SIZE(multi)
708+
imax = cnp_PyArray_MultiIter_SIZE(multi)
699709
n = res_size // imax
700710
with lock, nogil:
701711
for i from 0 <= i < imax:
@@ -705,8 +715,8 @@ cdef object vec_discnmN_array(irk_state *state, irk_discnmN_vec func, object siz
705715
func(state, n, array_data + n*i, on_data[0], om_data[0], oN_data[0])
706716
cnp.PyArray_MultiIter_NEXT(multi)
707717
arr_obj = <object>array
708-
multi_nd = cnp.PyArray_MultiIter_NDIM(multi)
709-
multi_dims = cnp.PyArray_MultiIter_DIMS(multi)
718+
multi_nd = cnp_PyArray_MultiIter_NDIM(multi)
719+
multi_dims = cnp_PyArray_MultiIter_DIMS(multi)
710720
multi_shape = cpython.tuple.PyTuple_New(multi_nd)
711721
for i from 0 <= i < multi_nd:
712722
cpython.tuple.PyTuple_SetItem(multi_shape, i, multi_dims[i])
@@ -783,7 +793,7 @@ cdef object vec_discd_array(irk_state *state, irk_discd_vec func, object size, c
783793
array_data = <int *>cnp.PyArray_DATA(array)
784794
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(2, <void *>array, <void *>oa)
785795
res_size = cnp.PyArray_SIZE(array)
786-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
796+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
787797
raise ValueError("size is not compatible with inputs")
788798

789799
imax = oa.size
@@ -826,7 +836,7 @@ cdef object vec_long_discd_array(irk_state *state, irk_discd_long_vec func, obje
826836
array_data = <long *>cnp.PyArray_DATA(array)
827837
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(2, <void *>array, <void *>oa)
828838
res_size = cnp.PyArray_SIZE(array)
829-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
839+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
830840
raise ValueError("size is not compatible with inputs")
831841

832842
imax = oa.size
@@ -867,7 +877,7 @@ cdef object vec_Poisson_array(irk_state *state, irk_discdptr_vec func1, irk_disc
867877
array_data = <int *>cnp.PyArray_DATA(array)
868878
multi = <cnp.broadcast>cnp.PyArray_MultiIterNew(2, <void *>array, <void *>olambda)
869879
res_size = cnp.PyArray_SIZE(array)
870-
if (cnp.PyArray_MultiIter_SIZE(multi) != res_size):
880+
if (cnp_PyArray_MultiIter_SIZE(multi) != res_size):
871881
raise ValueError("size is not compatible with inputs")
872882

873883
imax = olambda.size
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Copyright (c) 2024-2024, Intel Corporation
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
* Redistributions of source code must retain the above copyright notice,
8+
this list of conditions and the following disclaimer.
9+
* Redistributions in binary form must reproduce the above copyright
10+
notice, this list of conditions and the following disclaimer in the
11+
documentation and/or other materials provided with the distribution.
12+
* Neither the name of Intel Corporation nor the names of its contributors
13+
may be used to endorse or promote products derived from this software
14+
without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
28+
#include "Python.h"
29+
#include "numpy/arrayobject.h"
30+
31+
/* This header file is a work-around for issue
32+
* https://github.com/numpy/numpy/issues/26990
33+
*
34+
* It is included once in mklrandom.pyx
35+
*
36+
* The work-around is needed to support building with
37+
* NumPy < 2.0.0
38+
*
39+
* Once building transitions to using NumPy 2.0 only
40+
* this file can be removed and corresponding changes
41+
* in mklrand.pyx can be applied to always use
42+
* `PyArray_MultiIter_SIZE`, PyArray_MultiIter_NDIM`,
43+
* and `PyArray_MultiIter_DIMS`.
44+
*/
45+
46+
typedef struct {
47+
PyObject_HEAD
48+
int numiter;
49+
npy_intp size;
50+
npy_intp index;
51+
int nd;
52+
npy_intp dimensions[32];
53+
void **iters;
54+
} multi_iter_proxy_st;
55+
56+
npy_intp workaround_PyArray_MultiIter_SIZE(PyArrayMultiIterObject *multi) {
57+
#if defined(NPY_2_0_API_VERSION) && (NPY_API_VERSION >= NPY_2_0_API_VERSION)
58+
return PyArray_MultiIter_SIZE(multi);
59+
#else
60+
return ((multi_iter_proxy_st *)(multi))->size;
61+
#endif
62+
}
63+
64+
int workaround_PyArray_MultiIter_NDIM(PyArrayMultiIterObject *multi) {
65+
#if defined(NPY_2_0_API_VERSION) && (NPY_API_VERSION >= NPY_2_0_API_VERSION)
66+
return PyArray_MultiIter_NDIM(multi);
67+
#else
68+
return ((multi_iter_proxy_st *)(multi))->nd;
69+
#endif
70+
}
71+
72+
npy_intp* workaround_PyArray_MultiIter_DIMS(PyArrayMultiIterObject *multi) {
73+
#if defined(NPY_2_0_API_VERSION) && (NPY_API_VERSION >= NPY_2_0_API_VERSION)
74+
return PyArray_MultiIter_DIMS(multi);
75+
#else
76+
return (((multi_iter_proxy_st *)(multi))->dimensions);
77+
#endif
78+
}

0 commit comments

Comments
 (0)