1use std::os::raw::*;
8
9use libc::FILE;
10use pyo3::{
11 ffi::{self, PyObject, PyTypeObject},
12 sync::GILOnceCell,
13};
14
15use crate::npyffi::*;
16
17pub(crate) fn numpy_core_name(py: Python<'_>) -> PyResult<&'static str> {
18 static MOD_NAME: GILOnceCell<&'static str> = GILOnceCell::new();
19
20 MOD_NAME
21 .get_or_try_init(py, || {
22 let numpy = PyModule::import(py, "numpy")?;
27 let version_string = numpy.getattr("__version__")?;
28
29 let numpy_lib = PyModule::import(py, "numpy.lib")?;
30 let numpy_version = numpy_lib
31 .getattr("NumpyVersion")?
32 .call1((version_string,))?;
33 let major_version: u8 = numpy_version.getattr("major")?.extract()?;
34
35 Ok(if major_version >= 2 {
36 "numpy._core"
37 } else {
38 "numpy.core"
39 })
40 })
41 .copied()
42}
43
44pub(crate) fn mod_name(py: Python<'_>) -> PyResult<&'static str> {
45 static MOD_NAME: GILOnceCell<String> = GILOnceCell::new();
46 MOD_NAME
47 .get_or_try_init(py, || {
48 let numpy_core = numpy_core_name(py)?;
49 Ok(format!("{}.multiarray", numpy_core))
50 })
51 .map(String::as_str)
52}
53
54const CAPSULE_NAME: &str = "_ARRAY_API";
55
56pub static PY_ARRAY_API: PyArrayAPI = PyArrayAPI(GILOnceCell::new());
76
77pub struct PyArrayAPI(GILOnceCell<*const *const c_void>);
79
80unsafe impl Send for PyArrayAPI {}
81
82unsafe impl Sync for PyArrayAPI {}
83
84impl PyArrayAPI {
85 unsafe fn get<'py>(&self, py: Python<'py>, offset: isize) -> *const *const c_void {
86 let api = self
87 .0
88 .get_or_try_init(py, || get_numpy_api(py, mod_name(py)?, CAPSULE_NAME))
89 .expect("Failed to access NumPy array API capsule");
90
91 api.offset(offset)
92 }
93}
94
95impl PyArrayAPI {
96 impl_api![0; PyArray_GetNDArrayCVersion() -> c_uint];
97 impl_api![40; PyArray_SetNumericOps(dict: *mut PyObject) -> c_int];
98 impl_api![41; PyArray_GetNumericOps() -> *mut PyObject];
99 impl_api![42; PyArray_INCREF(mp: *mut PyArrayObject) -> c_int];
100 impl_api![43; PyArray_XDECREF(mp: *mut PyArrayObject) -> c_int];
101 impl_api![44; PyArray_SetStringFunction(op: *mut PyObject, repr: c_int)];
102 impl_api![45; PyArray_DescrFromType(type_: c_int) -> *mut PyArray_Descr];
103 impl_api![46; PyArray_TypeObjectFromType(type_: c_int) -> *mut PyObject];
104 impl_api![47; PyArray_Zero(arr: *mut PyArrayObject) -> *mut c_char];
105 impl_api![48; PyArray_One(arr: *mut PyArrayObject) -> *mut c_char];
106 impl_api![49; PyArray_CastToType(arr: *mut PyArrayObject, dtype: *mut PyArray_Descr, is_f_order: c_int) -> *mut PyObject];
107 impl_api![50; NumPy1; PyArray_CastTo(out: *mut PyArrayObject, mp: *mut PyArrayObject) -> c_int];
108 impl_api![52; PyArray_CanCastSafely(fromtype: c_int, totype: c_int) -> c_int];
109 impl_api![53; PyArray_CanCastTo(from: *mut PyArray_Descr, to: *mut PyArray_Descr) -> npy_bool];
110 impl_api![54; PyArray_ObjectType(op: *mut PyObject, minimum_type: c_int) -> c_int];
111 impl_api![55; PyArray_DescrFromObject(op: *mut PyObject, mintype: *mut PyArray_Descr) -> *mut PyArray_Descr];
112 impl_api![56; PyArray_ConvertToCommonType(op: *mut PyObject, retn: *mut c_int) -> *mut *mut PyArrayObject];
113 impl_api![57; PyArray_DescrFromScalar(sc: *mut PyObject) -> *mut PyArray_Descr];
114 impl_api![58; PyArray_DescrFromTypeObject(type_: *mut PyObject) -> *mut PyArray_Descr];
115 impl_api![59; PyArray_Size(op: *mut PyObject) -> npy_intp];
116 impl_api![60; PyArray_Scalar(data: *mut c_void, descr: *mut PyArray_Descr, base: *mut PyObject) -> *mut PyObject];
117 impl_api![61; PyArray_FromScalar(scalar: *mut PyObject, outcode: *mut PyArray_Descr) -> *mut PyObject];
118 impl_api![62; PyArray_ScalarAsCtype(scalar: *mut PyObject, ctypeptr: *mut c_void)];
119 impl_api![63; PyArray_CastScalarToCtype(scalar: *mut PyObject, ctypeptr: *mut c_void, outcode: *mut PyArray_Descr) -> c_int];
120 impl_api![64; PyArray_CastScalarDirect(scalar: *mut PyObject, indescr: *mut PyArray_Descr, ctypeptr: *mut c_void, outtype: c_int) -> c_int];
121 impl_api![65; NumPy1; PyArray_ScalarFromObject(object: *mut PyObject) -> *mut PyObject];
122 impl_api![65; NumPy2; PyArray_Pack(descr: *mut PyArray_Descr, item: *mut c_void, value: *const PyObject) -> *mut PyObject];
123 impl_api![66; NumPy1; PyArray_GetCastFunc(descr: *mut PyArray_Descr, type_num: c_int) -> PyArray_VectorUnaryFunc];
124 impl_api![67; NumPy1; PyArray_FromDims(nd: c_int, d: *mut c_int, type_: c_int) -> *mut PyObject];
125 impl_api![68; NumPy1; PyArray_FromDimsAndDataAndDescr(nd: c_int, d: *mut c_int, descr: *mut PyArray_Descr, data: *mut c_char) -> *mut PyObject];
126 impl_api![69; PyArray_FromAny(op: *mut PyObject, newtype: *mut PyArray_Descr, min_depth: c_int, max_depth: c_int, flags: c_int, context: *mut PyObject) -> *mut PyObject];
127 impl_api![70; PyArray_EnsureArray(op: *mut PyObject) -> *mut PyObject];
128 impl_api![71; PyArray_EnsureAnyArray(op: *mut PyObject) -> *mut PyObject];
129 impl_api![72; PyArray_FromFile(fp: *mut FILE, dtype: *mut PyArray_Descr, num: npy_intp, sep: *mut c_char) -> *mut PyObject];
130 impl_api![73; PyArray_FromString(data: *mut c_char, slen: npy_intp, dtype: *mut PyArray_Descr, num: npy_intp, sep: *mut c_char) -> *mut PyObject];
131 impl_api![74; PyArray_FromBuffer(buf: *mut PyObject, type_: *mut PyArray_Descr, count: npy_intp, offset: npy_intp) -> *mut PyObject];
132 impl_api![75; PyArray_FromIter(obj: *mut PyObject, dtype: *mut PyArray_Descr, count: npy_intp) -> *mut PyObject];
133 impl_api![76; PyArray_Return(mp: *mut PyArrayObject) -> *mut PyObject];
134 impl_api![77; PyArray_GetField(self_: *mut PyArrayObject, typed: *mut PyArray_Descr, offset: c_int) -> *mut PyObject];
135 impl_api![78; PyArray_SetField(self_: *mut PyArrayObject, dtype: *mut PyArray_Descr, offset: c_int, val: *mut PyObject) -> c_int];
136 impl_api![79; PyArray_Byteswap(self_: *mut PyArrayObject, inplace: npy_bool) -> *mut PyObject];
137 impl_api![80; PyArray_Resize(self_: *mut PyArrayObject, newshape: *mut PyArray_Dims, refcheck: c_int, order: NPY_ORDER) -> *mut PyObject];
138 impl_api![81; NumPy1; PyArray_MoveInto(dst: *mut PyArrayObject, src: *mut PyArrayObject) -> c_int];
139 impl_api![84; PyArray_CopyObject(dest: *mut PyArrayObject, src_object: *mut PyObject) -> c_int];
140 impl_api![85; PyArray_NewCopy(obj: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
141 impl_api![86; PyArray_ToList(self_: *mut PyArrayObject) -> *mut PyObject];
142 impl_api![87; PyArray_ToString(self_: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
143 impl_api![88; PyArray_ToFile(self_: *mut PyArrayObject, fp: *mut FILE, sep: *mut c_char, format: *mut c_char) -> c_int];
144 impl_api![89; PyArray_Dump(self_: *mut PyObject, file: *mut PyObject, protocol: c_int) -> c_int];
145 impl_api![90; PyArray_Dumps(self_: *mut PyObject, protocol: c_int) -> *mut PyObject];
146 impl_api![91; PyArray_ValidType(type_: c_int) -> c_int];
147 impl_api![92; PyArray_UpdateFlags(ret: *mut PyArrayObject, flagmask: c_int)];
148 impl_api![93; PyArray_New(subtype: *mut PyTypeObject, nd: c_int, dims: *mut npy_intp, type_num: c_int, strides: *mut npy_intp, data: *mut c_void, itemsize: c_int, flags: c_int, obj: *mut PyObject) -> *mut PyObject];
149 impl_api![94; PyArray_NewFromDescr(subtype: *mut PyTypeObject, descr: *mut PyArray_Descr, nd: c_int, dims: *mut npy_intp, strides: *mut npy_intp, data: *mut c_void, flags: c_int, obj: *mut PyObject) -> *mut PyObject];
150 impl_api![95; PyArray_DescrNew(base: *mut PyArray_Descr) -> *mut PyArray_Descr];
151 impl_api![96; PyArray_DescrNewFromType(type_num: c_int) -> *mut PyArray_Descr];
152 impl_api![97; PyArray_GetPriority(obj: *mut PyObject, default_: f64) -> f64];
153 impl_api![98; PyArray_IterNew(obj: *mut PyObject) -> *mut PyObject];
154 impl_api![100; PyArray_PyIntAsInt(o: *mut PyObject) -> c_int];
156 impl_api![101; PyArray_PyIntAsIntp(o: *mut PyObject) -> npy_intp];
157 impl_api![102; PyArray_Broadcast(mit: *mut PyArrayMultiIterObject) -> c_int];
158 impl_api![103; NumPy1; PyArray_FillObjectArray(arr: *mut PyArrayObject, obj: *mut PyObject)];
159 impl_api![104; PyArray_FillWithScalar(arr: *mut PyArrayObject, obj: *mut PyObject) -> c_int];
160 impl_api![105; PyArray_CheckStrides(elsize: c_int, nd: c_int, numbytes: npy_intp, offset: npy_intp, dims: *mut npy_intp, newstrides: *mut npy_intp) -> npy_bool];
161 impl_api![106; PyArray_DescrNewByteorder(self_: *mut PyArray_Descr, newendian: c_char) -> *mut PyArray_Descr];
162 impl_api![107; PyArray_IterAllButAxis(obj: *mut PyObject, inaxis: *mut c_int) -> *mut PyObject];
163 impl_api![108; PyArray_CheckFromAny(op: *mut PyObject, descr: *mut PyArray_Descr, min_depth: c_int, max_depth: c_int, requires: c_int, context: *mut PyObject) -> *mut PyObject];
164 impl_api![109; PyArray_FromArray(arr: *mut PyArrayObject, newtype: *mut PyArray_Descr, flags: c_int) -> *mut PyObject];
165 impl_api![110; PyArray_FromInterface(origin: *mut PyObject) -> *mut PyObject];
166 impl_api![111; PyArray_FromStructInterface(input: *mut PyObject) -> *mut PyObject];
167 impl_api![112; PyArray_FromArrayAttr(op: *mut PyObject, typecode: *mut PyArray_Descr, context: *mut PyObject) -> *mut PyObject];
168 impl_api![113; PyArray_ScalarKind(typenum: c_int, arr: *mut *mut PyArrayObject) -> NPY_SCALARKIND];
169 impl_api![114; PyArray_CanCoerceScalar(thistype: c_int, neededtype: c_int, scalar: NPY_SCALARKIND) -> c_int];
170 impl_api![115; NumPy1; PyArray_NewFlagsObject(obj: *mut PyObject) -> *mut PyObject];
171 impl_api![116; PyArray_CanCastScalar(from: *mut PyTypeObject, to: *mut PyTypeObject) -> npy_bool];
172 impl_api![117; NumPy1; PyArray_CompareUCS4(s1: *mut npy_ucs4, s2: *mut npy_ucs4, len: usize) -> c_int];
173 impl_api![118; PyArray_RemoveSmallest(multi: *mut PyArrayMultiIterObject) -> c_int];
174 impl_api![119; PyArray_ElementStrides(obj: *mut PyObject) -> c_int];
175 impl_api![120; PyArray_Item_INCREF(data: *mut c_char, descr: *mut PyArray_Descr)];
176 impl_api![121; PyArray_Item_XDECREF(data: *mut c_char, descr: *mut PyArray_Descr)];
177 impl_api![122; NumPy1; PyArray_FieldNames(fields: *mut PyObject) -> *mut PyObject];
178 impl_api![123; PyArray_Transpose(ap: *mut PyArrayObject, permute: *mut PyArray_Dims) -> *mut PyObject];
179 impl_api![124; PyArray_TakeFrom(self0: *mut PyArrayObject, indices0: *mut PyObject, axis: c_int, out: *mut PyArrayObject, clipmode: NPY_CLIPMODE) -> *mut PyObject];
180 impl_api![125; PyArray_PutTo(self_: *mut PyArrayObject, values0: *mut PyObject, indices0: *mut PyObject, clipmode: NPY_CLIPMODE) -> *mut PyObject];
181 impl_api![126; PyArray_PutMask(self_: *mut PyArrayObject, values0: *mut PyObject, mask0: *mut PyObject) -> *mut PyObject];
182 impl_api![127; PyArray_Repeat(aop: *mut PyArrayObject, op: *mut PyObject, axis: c_int) -> *mut PyObject];
183 impl_api![128; PyArray_Choose(ip: *mut PyArrayObject, op: *mut PyObject, out: *mut PyArrayObject, clipmode: NPY_CLIPMODE) -> *mut PyObject];
184 impl_api![129; PyArray_Sort(op: *mut PyArrayObject, axis: c_int, which: NPY_SORTKIND) -> c_int];
185 impl_api![130; PyArray_ArgSort(op: *mut PyArrayObject, axis: c_int, which: NPY_SORTKIND) -> *mut PyObject];
186 impl_api![131; PyArray_SearchSorted(op1: *mut PyArrayObject, op2: *mut PyObject, side: NPY_SEARCHSIDE, perm: *mut PyObject) -> *mut PyObject];
187 impl_api![132; PyArray_ArgMax(op: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
188 impl_api![133; PyArray_ArgMin(op: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
189 impl_api![134; PyArray_Reshape(self_: *mut PyArrayObject, shape: *mut PyObject) -> *mut PyObject];
190 impl_api![135; PyArray_Newshape(self_: *mut PyArrayObject, newdims: *mut PyArray_Dims, order: NPY_ORDER) -> *mut PyObject];
191 impl_api![136; PyArray_Squeeze(self_: *mut PyArrayObject) -> *mut PyObject];
192 impl_api![137; PyArray_View(self_: *mut PyArrayObject, type_: *mut PyArray_Descr, pytype: *mut PyTypeObject) -> *mut PyObject];
193 impl_api![138; PyArray_SwapAxes(ap: *mut PyArrayObject, a1: c_int, a2: c_int) -> *mut PyObject];
194 impl_api![139; PyArray_Max(ap: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
195 impl_api![140; PyArray_Min(ap: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
196 impl_api![141; PyArray_Ptp(ap: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
197 impl_api![142; PyArray_Mean(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
198 impl_api![143; PyArray_Trace(self_: *mut PyArrayObject, offset: c_int, axis1: c_int, axis2: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
199 impl_api![144; PyArray_Diagonal(self_: *mut PyArrayObject, offset: c_int, axis1: c_int, axis2: c_int) -> *mut PyObject];
200 impl_api![145; PyArray_Clip(self_: *mut PyArrayObject, min: *mut PyObject, max: *mut PyObject, out: *mut PyArrayObject) -> *mut PyObject];
201 impl_api![146; PyArray_Conjugate(self_: *mut PyArrayObject, out: *mut PyArrayObject) -> *mut PyObject];
202 impl_api![147; PyArray_Nonzero(self_: *mut PyArrayObject) -> *mut PyObject];
203 impl_api![148; PyArray_Std(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject, variance: c_int) -> *mut PyObject];
204 impl_api![149; PyArray_Sum(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
205 impl_api![150; PyArray_CumSum(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
206 impl_api![151; PyArray_Prod(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
207 impl_api![152; PyArray_CumProd(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
208 impl_api![153; PyArray_All(self_: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
209 impl_api![154; PyArray_Any(self_: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
210 impl_api![155; PyArray_Compress(self_: *mut PyArrayObject, condition: *mut PyObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
211 impl_api![156; PyArray_Flatten(a: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
212 impl_api![157; PyArray_Ravel(arr: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
213 impl_api![158; PyArray_MultiplyList(l1: *mut npy_intp, n: c_int) -> npy_intp];
214 impl_api![159; PyArray_MultiplyIntList(l1: *mut c_int, n: c_int) -> c_int];
215 impl_api![160; PyArray_GetPtr(obj: *mut PyArrayObject, ind: *mut npy_intp) -> *mut c_void];
216 impl_api![161; PyArray_CompareLists(l1: *mut npy_intp, l2: *mut npy_intp, n: c_int) -> c_int];
217 impl_api![162; PyArray_AsCArray(op: *mut *mut PyObject, ptr: *mut c_void, dims: *mut npy_intp, nd: c_int, typedescr: *mut PyArray_Descr) -> c_int];
218 impl_api![163; NumPy1; PyArray_As1D(op: *mut *mut PyObject, ptr: *mut *mut c_char, d1: *mut c_int, typecode: c_int) -> c_int];
219 impl_api![164; NumPy1; PyArray_As2D(op: *mut *mut PyObject, ptr: *mut *mut *mut c_char, d1: *mut c_int, d2: *mut c_int, typecode: c_int) -> c_int];
220 impl_api![165; PyArray_Free(op: *mut PyObject, ptr: *mut c_void) -> c_int];
221 impl_api![166; PyArray_Converter(object: *mut PyObject, address: *mut *mut PyObject) -> c_int];
222 impl_api![167; PyArray_IntpFromSequence(seq: *mut PyObject, vals: *mut npy_intp, maxvals: c_int) -> c_int];
223 impl_api![168; PyArray_Concatenate(op: *mut PyObject, axis: c_int) -> *mut PyObject];
224 impl_api![169; PyArray_InnerProduct(op1: *mut PyObject, op2: *mut PyObject) -> *mut PyObject];
225 impl_api![170; PyArray_MatrixProduct(op1: *mut PyObject, op2: *mut PyObject) -> *mut PyObject];
226 impl_api![171; NumPy1; PyArray_CopyAndTranspose(op: *mut PyObject) -> *mut PyObject];
227 impl_api![172; PyArray_Correlate(op1: *mut PyObject, op2: *mut PyObject, mode: c_int) -> *mut PyObject];
228 impl_api![173; NumPy1; PyArray_TypestrConvert(itemsize: c_int, gentype: c_int) -> c_int];
229 impl_api![174; PyArray_DescrConverter(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
230 impl_api![175; PyArray_DescrConverter2(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
231 impl_api![176; PyArray_IntpConverter(obj: *mut PyObject, seq: *mut PyArray_Dims) -> c_int];
232 impl_api![177; PyArray_BufferConverter(obj: *mut PyObject, buf: *mut PyArray_Chunk) -> c_int];
233 impl_api![178; PyArray_AxisConverter(obj: *mut PyObject, axis: *mut c_int) -> c_int];
234 impl_api![179; PyArray_BoolConverter(object: *mut PyObject, val: *mut npy_bool) -> c_int];
235 impl_api![180; PyArray_ByteorderConverter(obj: *mut PyObject, endian: *mut c_char) -> c_int];
236 impl_api![181; PyArray_OrderConverter(object: *mut PyObject, val: *mut NPY_ORDER) -> c_int];
237 impl_api![182; PyArray_EquivTypes(type1: *mut PyArray_Descr, type2: *mut PyArray_Descr) -> c_uchar];
238 impl_api![183; PyArray_Zeros(nd: c_int, dims: *mut npy_intp, type_: *mut PyArray_Descr, is_f_order: c_int) -> *mut PyObject];
239 impl_api![184; PyArray_Empty(nd: c_int, dims: *mut npy_intp, type_: *mut PyArray_Descr, is_f_order: c_int) -> *mut PyObject];
240 impl_api![185; PyArray_Where(condition: *mut PyObject, x: *mut PyObject, y: *mut PyObject) -> *mut PyObject];
241 impl_api![186; PyArray_Arange(start: f64, stop: f64, step: f64, type_num: c_int) -> *mut PyObject];
242 impl_api![187; PyArray_ArangeObj(start: *mut PyObject, stop: *mut PyObject, step: *mut PyObject, dtype: *mut PyArray_Descr) -> *mut PyObject];
243 impl_api![188; PyArray_SortkindConverter(obj: *mut PyObject, sortkind: *mut NPY_SORTKIND) -> c_int];
244 impl_api![189; PyArray_LexSort(sort_keys: *mut PyObject, axis: c_int) -> *mut PyObject];
245 impl_api![190; PyArray_Round(a: *mut PyArrayObject, decimals: c_int, out: *mut PyArrayObject) -> *mut PyObject];
246 impl_api![191; PyArray_EquivTypenums(typenum1: c_int, typenum2: c_int) -> c_uchar];
247 impl_api![192; PyArray_RegisterDataType(descr: *mut PyArray_DescrProto) -> c_int];
248 impl_api![193; PyArray_RegisterCastFunc(descr: *mut PyArray_Descr, totype: c_int, castfunc: PyArray_VectorUnaryFunc) -> c_int];
249 impl_api![194; PyArray_RegisterCanCast(descr: *mut PyArray_Descr, totype: c_int, scalar: NPY_SCALARKIND) -> c_int];
250 impl_api![195; PyArray_InitArrFuncs(f: *mut PyArray_ArrFuncs)];
251 impl_api![196; PyArray_IntTupleFromIntp(len: c_int, vals: *mut npy_intp) -> *mut PyObject];
252 impl_api![197; NumPy1; PyArray_ElementFromName(str: *mut c_char) -> c_int];
253 impl_api![198; PyArray_ClipmodeConverter(object: *mut PyObject, val: *mut NPY_CLIPMODE) -> c_int];
254 impl_api![199; PyArray_OutputConverter(object: *mut PyObject, address: *mut *mut PyArrayObject) -> c_int];
255 impl_api![200; PyArray_BroadcastToShape(obj: *mut PyObject, dims: *mut npy_intp, nd: c_int) -> *mut PyObject];
256 impl_api![201; NumPy1; _PyArray_SigintHandler(signum: c_int)];
257 impl_api![202; NumPy1; _PyArray_GetSigintBuf() -> *mut c_void];
258 impl_api![203; PyArray_DescrAlignConverter(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
259 impl_api![204; PyArray_DescrAlignConverter2(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
260 impl_api![205; PyArray_SearchsideConverter(obj: *mut PyObject, addr: *mut c_void) -> c_int];
261 impl_api![206; PyArray_CheckAxis(arr: *mut PyArrayObject, axis: *mut c_int, flags: c_int) -> *mut PyObject];
262 impl_api![207; PyArray_OverflowMultiplyList(l1: *mut npy_intp, n: c_int) -> npy_intp];
263 impl_api![208; NumPy1; PyArray_CompareString(s1: *mut c_char, s2: *mut c_char, len: usize) -> c_int];
264 impl_api![210; PyArray_GetEndianness() -> c_int];
266 impl_api![211; PyArray_GetNDArrayCFeatureVersion() -> c_uint];
267 impl_api![212; PyArray_Correlate2(op1: *mut PyObject, op2: *mut PyObject, mode: c_int) -> *mut PyObject];
268 impl_api![213; PyArray_NeighborhoodIterNew(x: *mut PyArrayIterObject, bounds: *mut npy_intp, mode: c_int, fill: *mut PyArrayObject) -> *mut PyObject];
269 impl_api![219; NumPy1; PyArray_SetDatetimeParseFunction(op: *mut PyObject)];
270 impl_api![220; NumPy1; PyArray_DatetimeToDatetimeStruct(val: npy_datetime, fr: NPY_DATETIMEUNIT, result: *mut npy_datetimestruct)];
271 impl_api![221; NumPy1; PyArray_TimedeltaToTimedeltaStruct(val: npy_timedelta, fr: NPY_DATETIMEUNIT, result: *mut npy_timedeltastruct)];
272 impl_api![222; NumPy1; PyArray_DatetimeStructToDatetime(fr: NPY_DATETIMEUNIT, d: *mut npy_datetimestruct) -> npy_datetime];
273 impl_api![223; NumPy1; PyArray_TimedeltaStructToTimedelta(fr: NPY_DATETIMEUNIT, d: *mut npy_timedeltastruct) -> npy_datetime];
274 impl_api![224; NpyIter_New(op: *mut PyArrayObject, flags: npy_uint32, order: NPY_ORDER, casting: NPY_CASTING, dtype: *mut PyArray_Descr) -> *mut NpyIter];
275 impl_api![225; NpyIter_MultiNew(nop: c_int, op_in: *mut *mut PyArrayObject, flags: npy_uint32, order: NPY_ORDER, casting: NPY_CASTING, op_flags: *mut npy_uint32, op_request_dtypes: *mut *mut PyArray_Descr) -> *mut NpyIter];
276 impl_api![226; NpyIter_AdvancedNew(nop: c_int, op_in: *mut *mut PyArrayObject, flags: npy_uint32, order: NPY_ORDER, casting: NPY_CASTING, op_flags: *mut npy_uint32, op_request_dtypes: *mut *mut PyArray_Descr, oa_ndim: c_int, op_axes: *mut *mut c_int, itershape: *mut npy_intp, buffersize: npy_intp) -> *mut NpyIter];
277 impl_api![227; NpyIter_Copy(iter: *mut NpyIter) -> *mut NpyIter];
278 impl_api![228; NpyIter_Deallocate(iter: *mut NpyIter) -> c_int];
279 impl_api![229; NpyIter_HasDelayedBufAlloc(iter: *mut NpyIter) -> npy_bool];
280 impl_api![230; NpyIter_HasExternalLoop(iter: *mut NpyIter) -> npy_bool];
281 impl_api![231; NpyIter_EnableExternalLoop(iter: *mut NpyIter) -> c_int];
282 impl_api![232; NpyIter_GetInnerStrideArray(iter: *mut NpyIter) -> *mut npy_intp];
283 impl_api![233; NpyIter_GetInnerLoopSizePtr(iter: *mut NpyIter) -> *mut npy_intp];
284 impl_api![234; NpyIter_Reset(iter: *mut NpyIter, errmsg: *mut *mut c_char) -> c_int];
285 impl_api![235; NpyIter_ResetBasePointers(iter: *mut NpyIter, baseptrs: *mut *mut c_char, errmsg: *mut *mut c_char) -> c_int];
286 impl_api![236; NpyIter_ResetToIterIndexRange(iter: *mut NpyIter, istart: npy_intp, iend: npy_intp, errmsg: *mut *mut c_char) -> c_int];
287 impl_api![237; NpyIter_GetNDim(iter: *mut NpyIter) -> c_int];
288 impl_api![238; NpyIter_GetNOp(iter: *mut NpyIter) -> c_int];
289 impl_api![239; NpyIter_GetIterNext(iter: *mut NpyIter, errmsg: *mut *mut c_char) -> NpyIter_IterNextFunc];
290 impl_api![240; NpyIter_GetIterSize(iter: *mut NpyIter) -> npy_intp];
291 impl_api![241; NpyIter_GetIterIndexRange(iter: *mut NpyIter, istart: *mut npy_intp, iend: *mut npy_intp)];
292 impl_api![242; NpyIter_GetIterIndex(iter: *mut NpyIter) -> npy_intp];
293 impl_api![243; NpyIter_GotoIterIndex(iter: *mut NpyIter, iterindex: npy_intp) -> c_int];
294 impl_api![244; NpyIter_HasMultiIndex(iter: *mut NpyIter) -> npy_bool];
295 impl_api![245; NpyIter_GetShape(iter: *mut NpyIter, outshape: *mut npy_intp) -> c_int];
296 impl_api![246; NpyIter_GetGetMultiIndex(iter: *mut NpyIter, errmsg: *mut *mut c_char) -> NpyIter_GetMultiIndexFunc];
297 impl_api![247; NpyIter_GotoMultiIndex(iter: *mut NpyIter, multi_index: *mut npy_intp) -> c_int];
298 impl_api![248; NpyIter_RemoveMultiIndex(iter: *mut NpyIter) -> c_int];
299 impl_api![249; NpyIter_HasIndex(iter: *mut NpyIter) -> npy_bool];
300 impl_api![250; NpyIter_IsBuffered(iter: *mut NpyIter) -> npy_bool];
301 impl_api![251; NpyIter_IsGrowInner(iter: *mut NpyIter) -> npy_bool];
302 impl_api![252; NpyIter_GetBufferSize(iter: *mut NpyIter) -> npy_intp];
303 impl_api![253; NpyIter_GetIndexPtr(iter: *mut NpyIter) -> *mut npy_intp];
304 impl_api![254; NpyIter_GotoIndex(iter: *mut NpyIter, flat_index: npy_intp) -> c_int];
305 impl_api![255; NpyIter_GetDataPtrArray(iter: *mut NpyIter) -> *mut *mut c_char];
306 impl_api![256; NpyIter_GetDescrArray(iter: *mut NpyIter) -> *mut *mut PyArray_Descr];
307 impl_api![257; NpyIter_GetOperandArray(iter: *mut NpyIter) -> *mut *mut PyArrayObject];
308 impl_api![258; NpyIter_GetIterView(iter: *mut NpyIter, i: npy_intp) -> *mut PyArrayObject];
309 impl_api![259; NpyIter_GetReadFlags(iter: *mut NpyIter, outreadflags: *mut c_char)];
310 impl_api![260; NpyIter_GetWriteFlags(iter: *mut NpyIter, outwriteflags: *mut c_char)];
311 impl_api![261; NpyIter_DebugPrint(iter: *mut NpyIter)];
312 impl_api![262; NpyIter_IterationNeedsAPI(iter: *mut NpyIter) -> npy_bool];
313 impl_api![263; NpyIter_GetInnerFixedStrideArray(iter: *mut NpyIter, out_strides: *mut npy_intp)];
314 impl_api![264; NpyIter_RemoveAxis(iter: *mut NpyIter, axis: c_int) -> c_int];
315 impl_api![265; NpyIter_GetAxisStrideArray(iter: *mut NpyIter, axis: c_int) -> *mut npy_intp];
316 impl_api![266; NpyIter_RequiresBuffering(iter: *mut NpyIter) -> npy_bool];
317 impl_api![267; NpyIter_GetInitialDataPtrArray(iter: *mut NpyIter) -> *mut *mut c_char];
318 impl_api![268; NpyIter_CreateCompatibleStrides(iter: *mut NpyIter, itemsize: npy_intp, outstrides: *mut npy_intp) -> c_int];
319 impl_api![269; PyArray_CastingConverter(obj: *mut PyObject, casting: *mut NPY_CASTING) -> c_int];
320 impl_api![270; PyArray_CountNonzero(self_: *mut PyArrayObject) -> npy_intp];
321 impl_api![271; PyArray_PromoteTypes(type1: *mut PyArray_Descr, type2: *mut PyArray_Descr) -> *mut PyArray_Descr];
322 impl_api![272; PyArray_MinScalarType(arr: *mut PyArrayObject) -> *mut PyArray_Descr];
323 impl_api![273; PyArray_ResultType(narrs: npy_intp, arr: *mut *mut PyArrayObject, ndtypes: npy_intp, dtypes: *mut *mut PyArray_Descr) -> *mut PyArray_Descr];
324 impl_api![274; PyArray_CanCastArrayTo(arr: *mut PyArrayObject, to: *mut PyArray_Descr, casting: NPY_CASTING) -> npy_bool];
325 impl_api![275; PyArray_CanCastTypeTo(from: *mut PyArray_Descr, to: *mut PyArray_Descr, casting: NPY_CASTING) -> npy_bool];
326 impl_api![276; PyArray_EinsteinSum(subscripts: *mut c_char, nop: npy_intp, op_in: *mut *mut PyArrayObject, dtype: *mut PyArray_Descr, order: NPY_ORDER, casting: NPY_CASTING, out: *mut PyArrayObject) -> *mut PyObject];
327 impl_api![277; PyArray_NewLikeArray(prototype: *mut PyArrayObject, order: NPY_ORDER, dtype: *mut PyArray_Descr, subok: c_int) -> *mut PyObject];
328 impl_api![278; NumPy1; PyArray_GetArrayParamsFromObject(op: *mut PyObject, requested_dtype: *mut PyArray_Descr, writeable: npy_bool, out_dtype: *mut *mut PyArray_Descr, out_ndim: *mut c_int, out_dims: *mut npy_intp, out_arr: *mut *mut PyArrayObject, context: *mut PyObject) -> c_int];
329 impl_api![279; PyArray_ConvertClipmodeSequence(object: *mut PyObject, modes: *mut NPY_CLIPMODE, n: c_int) -> c_int];
330 impl_api![280; PyArray_MatrixProduct2(op1: *mut PyObject, op2: *mut PyObject, out: *mut PyArrayObject) -> *mut PyObject];
331 impl_api![281; NpyIter_IsFirstVisit(iter: *mut NpyIter, iop: c_int) -> npy_bool];
332 impl_api![282; PyArray_SetBaseObject(arr: *mut PyArrayObject, obj: *mut PyObject) -> c_int];
333 impl_api![283; PyArray_CreateSortedStridePerm(ndim: c_int, strides: *mut npy_intp, out_strideperm: *mut npy_stride_sort_item)];
334 impl_api![284; PyArray_RemoveAxesInPlace(arr: *mut PyArrayObject, flags: *mut npy_bool)];
335 impl_api![285; PyArray_DebugPrint(obj: *mut PyArrayObject)];
336 impl_api![286; PyArray_FailUnlessWriteable(obj: *mut PyArrayObject, name: *const c_char) -> c_int];
337 impl_api![287; PyArray_SetUpdateIfCopyBase(arr: *mut PyArrayObject, base: *mut PyArrayObject) -> c_int];
338 impl_api![288; PyDataMem_NEW(size: usize) -> *mut c_void];
339 impl_api![289; PyDataMem_FREE(ptr: *mut c_void)];
340 impl_api![290; PyDataMem_RENEW(ptr: *mut c_void, size: usize) -> *mut c_void];
341 impl_api![291; NumPy1; PyDataMem_SetEventHook(newhook: PyDataMem_EventHookFunc, user_data: *mut c_void, old_data: *mut *mut c_void) -> PyDataMem_EventHookFunc];
342 impl_api![293; NumPy1; PyArray_MapIterSwapAxes(mit: *mut PyArrayMapIterObject, ret: *mut *mut PyArrayObject, getmap: c_int)];
343 impl_api![294; NumPy1; PyArray_MapIterArray(a: *mut PyArrayObject, index: *mut PyObject) -> *mut PyObject];
344 impl_api![295; NumPy1; PyArray_MapIterNext(mit: *mut PyArrayMapIterObject)];
345 impl_api![296; PyArray_Partition(op: *mut PyArrayObject, ktharray: *mut PyArrayObject, axis: c_int, which: NPY_SELECTKIND) -> c_int];
346 impl_api![297; PyArray_ArgPartition(op: *mut PyArrayObject, ktharray: *mut PyArrayObject, axis: c_int, which: NPY_SELECTKIND) -> *mut PyObject];
347 impl_api![298; PyArray_SelectkindConverter(obj: *mut PyObject, selectkind: *mut NPY_SELECTKIND) -> c_int];
348 impl_api![299; PyDataMem_NEW_ZEROED(size: usize, elsize: usize) -> *mut c_void];
349 impl_api![300; PyArray_CheckAnyScalarExact(obj: *mut PyObject) -> c_int];
350 impl_api![301; NumPy1; PyArray_MapIterArrayCopyIfOverlap(a: *mut PyArrayObject, index: *mut PyObject, copy_if_overlap: c_int, extra_op: *mut PyArrayObject) -> *mut PyObject];
351 impl_api![302; PyArray_ResolveWritebackIfCopy(self_: *mut PyArrayObject) -> c_int];
352 impl_api![303; PyArray_SetWritebackIfCopyBase(arr: *mut PyArrayObject, base: *mut PyArrayObject) -> c_int];
353 impl_api![304; PyDataMem_SetHandler(handler: *mut PyObject) -> *mut PyObject];
354 impl_api![305; PyDataMem_GetHandler() -> *mut PyObject];
355 impl_api![307; NumPy2; NpyDatetime_ConvertDatetime64ToDatetimeStruct(meta: *mut PyArray_DatetimeMetaData, dt: npy_datetime, out: *mut npy_datetimestruct) -> c_int];
356 impl_api![308; NumPy2; NpyDatetime_ConvertDatetimeStructToDatetime64(meta: *mut PyArray_DatetimeMetaData, dts: *const npy_datetimestruct, out: *mut npy_datetime) -> c_int];
357 impl_api![309; NumPy2; NpyDatetime_ConvertPyDateTimeToDatetimeStruct(obj: *mut PyObject, out: *mut npy_datetimestruct, out_bestunit: *mut NPY_DATETIMEUNIT, apply_tzinfo: c_int) -> c_int];
358 impl_api![310; NumPy2; NpyDatetime_GetDatetimeISO8601StrLen(local: c_int, base: NPY_DATETIMEUNIT) -> c_int];
359 impl_api![311; NumPy2; NpyDatetime_MakeISO8601Datetime(dts: *mut npy_datetimestruct, outstr: *mut c_char, outlen: npy_intp, local: c_int, utc: c_int, base: NPY_DATETIMEUNIT, tzoffset: c_int, casting: NPY_CASTING) -> c_int];
360 impl_api![312; NumPy2; NpyDatetime_ParseISO8601Datetime(str: *const c_char, len: pyo3::ffi::Py_ssize_t, unit: NPY_DATETIMEUNIT, casting: NPY_CASTING, out: *mut npy_datetimestruct, out_bestunit: *mut NPY_DATETIMEUNIT, out_special: *mut npy_bool) -> c_int];
361 impl_api![313; NumPy2; NpyString_load(allocator: *mut npy_string_allocator, packed_string: *const npy_packed_static_string, unpacked_string: *mut npy_static_string) -> c_int];
362 impl_api![314; NumPy2; NpyString_pack(out: *mut npy_packed_static_string) -> c_int];
363 impl_api![315; NumPy2; NpyString_pack_null(allocator: *mut npy_string_allocator, packed_string: *mut npy_packed_static_string) -> c_int];
364 impl_api![316; NumPy2; NpyString_acquire_allocator(descr: *const PyArray_StringDTypeObject) -> *mut npy_string_allocator];
365 impl_api![317; NumPy2; NpyString_acquire_allocators(n_descriptors: usize, descrs: *const *mut PyArray_Descr, allocators: *mut *mut npy_string_allocator)];
366 impl_api![318; NumPy2; NpyString_release_allocator(allocator: *mut npy_string_allocator)];
367 impl_api![319; NumPy2; NpyString_release_allocators(length: usize, allocators: *mut *mut npy_string_allocator)];
368 impl_api![361; NumPy2; PyArray_GetDefaultDescr(DType: *mut PyArray_DTypeMeta) -> *mut PyArray_Descr];
369 impl_api![362; NumPy2; PyArrayInitDTypeMeta_FromSpec(DType: *mut PyArray_DTypeMeta, spec: *mut PyArrayDTypeMeta_Spec) -> c_int];
370 impl_api![363; NumPy2; PyArray_CommonDType(dtype1: *mut PyArray_DTypeMeta, dtype2: *mut PyArray_DTypeMeta) -> PyArray_DTypeMeta];
371 impl_api![364; NumPy2; PyArray_PromoteDTypeSequence(length: npy_intp, dtypes_in: *mut *mut PyArray_DTypeMeta) -> *mut PyArray_DTypeMeta];
372 impl_api![365; NumPy2; _PyDataType_GetArrFuncs(descr: *const PyArray_Descr) -> *mut PyArray_ArrFuncs];
373
374 #[allow(non_snake_case)]
375 pub unsafe fn PyArray_CopyInto<'py>(
376 &self,
377 py: Python<'py>,
378 dst: *mut PyArrayObject,
379 src: *mut PyArrayObject,
380 ) -> c_int {
381 let offset = if is_numpy_2(py) { 50 } else { 82 };
382 let fptr = self.get(py, offset)
383 as *const extern "C" fn(dst: *mut PyArrayObject, src: *mut PyArrayObject) -> c_int;
384 (*fptr)(dst, src)
385 }
386
387 #[allow(non_snake_case)]
388 pub unsafe fn PyArray_CastAnyTo<'py>(
389 &self,
390 py: Python<'py>,
391 out: *mut PyArrayObject,
392 mp: *mut PyArrayObject,
393 ) -> c_int {
394 let offset = if is_numpy_2(py) { 51 } else { 83 };
395 let fptr = self.get(py, offset)
396 as *const extern "C" fn(out: *mut PyArrayObject, mp: *mut PyArrayObject) -> c_int;
397 (*fptr)(out, mp)
398 }
399}
400
401macro_rules! impl_array_type {
403 ($(($offset:expr, $tname:ident)),*) => {
404 #[allow(non_camel_case_types)]
406 pub enum NpyTypes { $($tname),* }
407
408 impl PyArrayAPI {
409 pub unsafe fn get_type_object<'py>(&self, py: Python<'py>, ty: NpyTypes) -> *mut PyTypeObject {
411 match ty {
412 $( NpyTypes::$tname => *(self.get(py, $offset)) as _ ),*
413 }
414 }
415 }
416 }
417}
418
419impl_array_type! {
420 (1, PyBigArray_Type),
421 (2, PyArray_Type),
422 (3, PyArrayDescr_Type),
423 (4, PyArrayFlags_Type),
424 (5, PyArrayIter_Type),
425 (6, PyArrayMultiIter_Type),
426 (7, NPY_NUMUSERTYPES),
427 (8, PyBoolArrType_Type),
428 (9, _PyArrayScalar_BoolValues),
429 (10, PyGenericArrType_Type),
430 (11, PyNumberArrType_Type),
431 (12, PyIntegerArrType_Type),
432 (13, PySignedIntegerArrType_Type),
433 (14, PyUnsignedIntegerArrType_Type),
434 (15, PyInexactArrType_Type),
435 (16, PyFloatingArrType_Type),
436 (17, PyComplexFloatingArrType_Type),
437 (18, PyFlexibleArrType_Type),
438 (19, PyCharacterArrType_Type),
439 (20, PyByteArrType_Type),
440 (21, PyShortArrType_Type),
441 (22, PyIntArrType_Type),
442 (23, PyLongArrType_Type),
443 (24, PyLongLongArrType_Type),
444 (25, PyUByteArrType_Type),
445 (26, PyUShortArrType_Type),
446 (27, PyUIntArrType_Type),
447 (28, PyULongArrType_Type),
448 (29, PyULongLongArrType_Type),
449 (30, PyFloatArrType_Type),
450 (31, PyDoubleArrType_Type),
451 (32, PyLongDoubleArrType_Type),
452 (33, PyCFloatArrType_Type),
453 (34, PyCDoubleArrType_Type),
454 (35, PyCLongDoubleArrType_Type),
455 (36, PyObjectArrType_Type),
456 (37, PyStringArrType_Type),
457 (38, PyUnicodeArrType_Type),
458 (39, PyVoidArrType_Type)
459}
460
461#[allow(non_snake_case)]
463pub unsafe fn PyArray_Check<'py>(py: Python<'py>, op: *mut PyObject) -> c_int {
464 ffi::PyObject_TypeCheck(op, PY_ARRAY_API.get_type_object(py, NpyTypes::PyArray_Type))
465}
466
467#[allow(non_snake_case)]
469pub unsafe fn PyArray_CheckExact<'py>(py: Python<'py>, op: *mut PyObject) -> c_int {
470 (ffi::Py_TYPE(op) == PY_ARRAY_API.get_type_object(py, NpyTypes::PyArray_Type)) as _
471}
472
473#[cfg(test)]
474mod tests {
475 use super::*;
476
477 #[test]
478 fn call_api() {
479 Python::with_gil(|py| unsafe {
480 assert_eq!(
481 PY_ARRAY_API.PyArray_MultiplyIntList(py, [1, 2, 3].as_mut_ptr(), 3),
482 6
483 );
484 })
485 }
486}