1use std::{ffi::*, ptr::NonNull};
8
9use libc::FILE;
10use pyo3::{
11 exceptions::PyRuntimeError,
12 ffi::{self, PyObject, PyTypeObject},
13 sync::PyOnceLock,
14};
15
16use crate::npyffi::*;
17
18pub(crate) fn numpy_core_name(py: Python<'_>) -> PyResult<&'static str> {
19 static MOD_NAME: PyOnceLock<&'static str> = PyOnceLock::new();
20
21 MOD_NAME
22 .get_or_try_init(py, || {
23 let numpy = PyModule::import(py, "numpy")?;
28 let version_string = numpy.getattr("__version__")?;
29
30 let numpy_lib = PyModule::import(py, "numpy.lib")?;
31 let numpy_version = numpy_lib
32 .getattr("NumpyVersion")?
33 .call1((version_string,))?;
34 let major_version: u8 = numpy_version.getattr("major")?.extract()?;
35
36 Ok(if major_version >= 2 {
37 "numpy._core"
38 } else {
39 "numpy.core"
40 })
41 })
42 .copied()
43}
44
45pub(crate) fn mod_name(py: Python<'_>) -> PyResult<&'static str> {
46 static MOD_NAME: PyOnceLock<String> = PyOnceLock::new();
47 MOD_NAME
48 .get_or_try_init(py, || {
49 let numpy_core = numpy_core_name(py)?;
50 Ok(format!("{numpy_core}.multiarray"))
51 })
52 .map(String::as_str)
53}
54
55const CAPSULE_NAME: &str = "_ARRAY_API";
56
57pub static PY_ARRAY_API: PyArrayAPI = PyArrayAPI(PyOnceLock::new());
77
78pub struct PyArrayAPI(PyOnceLock<NonNull<*const c_void>>);
80
81unsafe impl Send for PyArrayAPI {}
82
83unsafe impl Sync for PyArrayAPI {}
84
85impl PyArrayAPI {
86 pub(super) unsafe fn get<'py>(&self, py: Python<'py>, offset: isize) -> NonNull<*const c_void> {
87 let api = self
88 .0
89 .get_or_try_init(py, || -> PyResult<_> {
90 let api = get_numpy_api(py, mod_name(py)?, CAPSULE_NAME)?;
91
92 let module_version = {
93 let get_abi_version: extern "C" fn() -> c_uint =
95 api.add(0).cast().read();
96 get_abi_version()
97 };
98 if NPY_VERSION < module_version {
99 return Err(PyRuntimeError::new_err(format!(
100 "module compiled against ABI version 0x{:x} but this version of numpy is 0x{:x}",
101 NPY_VERSION, module_version
102 )));
103 }
104
105 let module_feature_version = unsafe {
106 let get_runtime_version: extern "C" fn() -> c_uint =
108 api.add(211).cast().read();
109 get_runtime_version()
110 };
111 if NPY_FEATURE_VERSION > module_feature_version {
112 return Err(PyRuntimeError::new_err(format!(
113 "module was compiled against NumPy C-API version 0x{:x} (NumPy {}) but the running NumPy has C-API version 0x{:x}",
114 NPY_FEATURE_VERSION, NPY_FEATURE_VERSION_STRING, module_feature_version
115 )));
116 }
117
118 let endianness = unsafe {
119 let get_endianness: extern "C" fn() -> c_int =
121 api.add(210).cast().read();
122 get_endianness()
123 };
124
125 #[cfg(target_endian = "big")]
126 if endianness != NPY_CPU_BIG {
127 return Err(PyRuntimeError::new_err(
128 "module compiled as big endian, but detected different endianness at runtime",
129 ));
130 }
131
132 #[cfg(target_endian = "little")]
133 if endianness != NPY_CPU_LITTLE {
134 return Err(PyRuntimeError::new_err(
135 "module compiled as little endian, but detected different endianness at runtime",
136 ));
137 }
138
139 Ok(api)
140 })
141 .expect("Failed to access NumPy array API capsule");
142
143 api.offset(offset)
144 }
145}
146
147impl PyArrayAPI {
150 impl_api![0; PyArray_GetNDArrayCVersion() -> c_uint];
151 impl_api![42; PyArray_INCREF(mp: *mut PyArrayObject) -> c_int];
155 impl_api![43; PyArray_XDECREF(mp: *mut PyArrayObject) -> c_int];
156 impl_api![44; PyArray_SetStringFunction(op: *mut PyObject, repr: c_int)];
157 impl_api![45; PyArray_DescrFromType(type_: c_int) -> *mut PyArray_Descr];
158 impl_api![46; PyArray_TypeObjectFromType(type_: c_int) -> *mut PyObject];
159 impl_api![47; PyArray_Zero(arr: *mut PyArrayObject) -> *mut c_char];
160 impl_api![48; PyArray_One(arr: *mut PyArrayObject) -> *mut c_char];
161 impl_api![49; PyArray_CastToType(arr: *mut PyArrayObject, dtype: *mut PyArray_Descr, is_f_order: c_int) -> *mut PyObject];
162 impl_api![50; PyArray_CopyInto(dest: *mut PyArrayObject, src: *mut PyArrayObject) -> c_int];
163 impl_api![51; PyArray_CopyAnyInto(dest: *mut PyArrayObject, src: *mut PyArrayObject) -> c_int];
164 impl_api![52; PyArray_CanCastSafely(fromtype: c_int, totype: c_int) -> c_int];
165 impl_api![53; PyArray_CanCastTo(from: *mut PyArray_Descr, to: *mut PyArray_Descr) -> npy_bool];
166 impl_api![54; PyArray_ObjectType(op: *mut PyObject, minimum_type: c_int) -> c_int];
167 impl_api![55; PyArray_DescrFromObject(op: *mut PyObject, mintype: *mut PyArray_Descr) -> *mut PyArray_Descr];
168 impl_api![56; PyArray_ConvertToCommonType(op: *mut PyObject, retn: *mut c_int) -> *mut *mut PyArrayObject];
169 impl_api![57; PyArray_DescrFromScalar(sc: *mut PyObject) -> *mut PyArray_Descr];
170 impl_api![58; PyArray_DescrFromTypeObject(type_: *mut PyObject) -> *mut PyArray_Descr];
171 impl_api![59; PyArray_Size(op: *mut PyObject) -> npy_intp];
172 impl_api![60; PyArray_Scalar(data: *mut c_void, descr: *mut PyArray_Descr, base: *mut PyObject) -> *mut PyObject];
173 impl_api![61; PyArray_FromScalar(scalar: *mut PyObject, outcode: *mut PyArray_Descr) -> *mut PyObject];
174 impl_api![62; PyArray_ScalarAsCtype(scalar: *mut PyObject, ctypeptr: *mut c_void)];
175 impl_api![63; PyArray_CastScalarToCtype(scalar: *mut PyObject, ctypeptr: *mut c_void, outcode: *mut PyArray_Descr) -> c_int];
176 impl_api![64; PyArray_CastScalarDirect(scalar: *mut PyObject, indescr: *mut PyArray_Descr, ctypeptr: *mut c_void, outtype: c_int) -> c_int];
177 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];
182 impl_api![70; PyArray_EnsureArray(op: *mut PyObject) -> *mut PyObject];
183 impl_api![71; PyArray_EnsureAnyArray(op: *mut PyObject) -> *mut PyObject];
184 impl_api![72; PyArray_FromFile(fp: *mut FILE, dtype: *mut PyArray_Descr, num: npy_intp, sep: *mut c_char) -> *mut PyObject];
185 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];
186 impl_api![74; PyArray_FromBuffer(buf: *mut PyObject, type_: *mut PyArray_Descr, count: npy_intp, offset: npy_intp) -> *mut PyObject];
187 impl_api![75; PyArray_FromIter(obj: *mut PyObject, dtype: *mut PyArray_Descr, count: npy_intp) -> *mut PyObject];
188 impl_api![76; PyArray_Return(mp: *mut PyArrayObject) -> *mut PyObject];
189 impl_api![77; PyArray_GetField(self_: *mut PyArrayObject, typed: *mut PyArray_Descr, offset: c_int) -> *mut PyObject];
190 impl_api![78; PyArray_SetField(self_: *mut PyArrayObject, dtype: *mut PyArray_Descr, offset: c_int, val: *mut PyObject) -> c_int];
191 impl_api![79; PyArray_Byteswap(self_: *mut PyArrayObject, inplace: npy_bool) -> *mut PyObject];
192 impl_api![80; PyArray_Resize(self_: *mut PyArrayObject, newshape: *mut PyArray_Dims, refcheck: c_int, order: NPY_ORDER) -> *mut PyObject];
193 impl_api![84; PyArray_CopyObject(dest: *mut PyArrayObject, src_object: *mut PyObject) -> c_int];
197 impl_api![85; PyArray_NewCopy(obj: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
198 impl_api![86; PyArray_ToList(self_: *mut PyArrayObject) -> *mut PyObject];
199 impl_api![87; PyArray_ToString(self_: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
200 impl_api![88; PyArray_ToFile(self_: *mut PyArrayObject, fp: *mut FILE, sep: *mut c_char, format: *mut c_char) -> c_int];
201 impl_api![89; PyArray_Dump(self_: *mut PyObject, file: *mut PyObject, protocol: c_int) -> c_int];
202 impl_api![90; PyArray_Dumps(self_: *mut PyObject, protocol: c_int) -> *mut PyObject];
203 impl_api![91; PyArray_ValidType(type_: c_int) -> c_int];
204 impl_api![92; PyArray_UpdateFlags(ret: *mut PyArrayObject, flagmask: c_int)];
205 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];
206 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];
207 impl_api![95; PyArray_DescrNew(base: *mut PyArray_Descr) -> *mut PyArray_Descr];
208 impl_api![96; PyArray_DescrNewFromType(type_num: c_int) -> *mut PyArray_Descr];
209 impl_api![97; PyArray_GetPriority(obj: *mut PyObject, default_: f64) -> f64];
210 impl_api![98; PyArray_IterNew(obj: *mut PyObject) -> *mut PyObject];
211 impl_api![100; PyArray_PyIntAsInt(o: *mut PyObject) -> c_int];
213 impl_api![101; PyArray_PyIntAsIntp(o: *mut PyObject) -> npy_intp];
214 impl_api![102; PyArray_Broadcast(mit: *mut PyArrayMultiIterObject) -> c_int];
215 impl_api![104; PyArray_FillWithScalar(arr: *mut PyArrayObject, obj: *mut PyObject) -> c_int];
217 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];
218 impl_api![106; PyArray_DescrNewByteorder(self_: *mut PyArray_Descr, newendian: c_char) -> *mut PyArray_Descr];
219 impl_api![107; PyArray_IterAllButAxis(obj: *mut PyObject, inaxis: *mut c_int) -> *mut PyObject];
220 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];
221 impl_api![109; PyArray_FromArray(arr: *mut PyArrayObject, newtype: *mut PyArray_Descr, flags: c_int) -> *mut PyObject];
222 impl_api![110; PyArray_FromInterface(origin: *mut PyObject) -> *mut PyObject];
223 impl_api![111; PyArray_FromStructInterface(input: *mut PyObject) -> *mut PyObject];
224 impl_api![112; PyArray_FromArrayAttr(op: *mut PyObject, typecode: *mut PyArray_Descr, context: *mut PyObject) -> *mut PyObject];
225 impl_api![113; PyArray_ScalarKind(typenum: c_int, arr: *mut *mut PyArrayObject) -> NPY_SCALARKIND];
226 impl_api![114; PyArray_CanCoerceScalar(thistype: c_int, neededtype: c_int, scalar: NPY_SCALARKIND) -> c_int];
227 impl_api![116; PyArray_CanCastScalar(from: *mut PyTypeObject, to: *mut PyTypeObject) -> npy_bool];
229 impl_api![118; PyArray_RemoveSmallest(multi: *mut PyArrayMultiIterObject) -> c_int];
231 impl_api![119; PyArray_ElementStrides(obj: *mut PyObject) -> c_int];
232 impl_api![120; PyArray_Item_INCREF(data: *mut c_char, descr: *mut PyArray_Descr)];
233 impl_api![121; PyArray_Item_XDECREF(data: *mut c_char, descr: *mut PyArray_Descr)];
234 impl_api![123; PyArray_Transpose(ap: *mut PyArrayObject, permute: *mut PyArray_Dims) -> *mut PyObject];
236 impl_api![124; PyArray_TakeFrom(self0: *mut PyArrayObject, indices0: *mut PyObject, axis: c_int, out: *mut PyArrayObject, clipmode: NPY_CLIPMODE) -> *mut PyObject];
237 impl_api![125; PyArray_PutTo(self_: *mut PyArrayObject, values0: *mut PyObject, indices0: *mut PyObject, clipmode: NPY_CLIPMODE) -> *mut PyObject];
238 impl_api![126; PyArray_PutMask(self_: *mut PyArrayObject, values0: *mut PyObject, mask0: *mut PyObject) -> *mut PyObject];
239 impl_api![127; PyArray_Repeat(aop: *mut PyArrayObject, op: *mut PyObject, axis: c_int) -> *mut PyObject];
240 impl_api![128; PyArray_Choose(ip: *mut PyArrayObject, op: *mut PyObject, out: *mut PyArrayObject, clipmode: NPY_CLIPMODE) -> *mut PyObject];
241 impl_api![129; PyArray_Sort(op: *mut PyArrayObject, axis: c_int, which: NPY_SORTKIND) -> c_int];
242 impl_api![130; PyArray_ArgSort(op: *mut PyArrayObject, axis: c_int, which: NPY_SORTKIND) -> *mut PyObject];
243 impl_api![131; PyArray_SearchSorted(op1: *mut PyArrayObject, op2: *mut PyObject, side: NPY_SEARCHSIDE, perm: *mut PyObject) -> *mut PyObject];
244 impl_api![132; PyArray_ArgMax(op: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
245 impl_api![133; PyArray_ArgMin(op: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
246 impl_api![134; PyArray_Reshape(self_: *mut PyArrayObject, shape: *mut PyObject) -> *mut PyObject];
247 impl_api![135; PyArray_Newshape(self_: *mut PyArrayObject, newdims: *mut PyArray_Dims, order: NPY_ORDER) -> *mut PyObject];
248 impl_api![136; PyArray_Squeeze(self_: *mut PyArrayObject) -> *mut PyObject];
249 impl_api![137; PyArray_View(self_: *mut PyArrayObject, type_: *mut PyArray_Descr, pytype: *mut PyTypeObject) -> *mut PyObject];
250 impl_api![138; PyArray_SwapAxes(ap: *mut PyArrayObject, a1: c_int, a2: c_int) -> *mut PyObject];
251 impl_api![139; PyArray_Max(ap: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
252 impl_api![140; PyArray_Min(ap: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
253 impl_api![141; PyArray_Ptp(ap: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
254 impl_api![142; PyArray_Mean(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
255 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];
256 impl_api![144; PyArray_Diagonal(self_: *mut PyArrayObject, offset: c_int, axis1: c_int, axis2: c_int) -> *mut PyObject];
257 impl_api![145; PyArray_Clip(self_: *mut PyArrayObject, min: *mut PyObject, max: *mut PyObject, out: *mut PyArrayObject) -> *mut PyObject];
258 impl_api![146; PyArray_Conjugate(self_: *mut PyArrayObject, out: *mut PyArrayObject) -> *mut PyObject];
259 impl_api![147; PyArray_Nonzero(self_: *mut PyArrayObject) -> *mut PyObject];
260 impl_api![148; PyArray_Std(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject, variance: c_int) -> *mut PyObject];
261 impl_api![149; PyArray_Sum(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
262 impl_api![150; PyArray_CumSum(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
263 impl_api![151; PyArray_Prod(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
264 impl_api![152; PyArray_CumProd(self_: *mut PyArrayObject, axis: c_int, rtype: c_int, out: *mut PyArrayObject) -> *mut PyObject];
265 impl_api![153; PyArray_All(self_: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
266 impl_api![154; PyArray_Any(self_: *mut PyArrayObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
267 impl_api![155; PyArray_Compress(self_: *mut PyArrayObject, condition: *mut PyObject, axis: c_int, out: *mut PyArrayObject) -> *mut PyObject];
268 impl_api![156; PyArray_Flatten(a: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
269 impl_api![157; PyArray_Ravel(arr: *mut PyArrayObject, order: NPY_ORDER) -> *mut PyObject];
270 impl_api![158; PyArray_MultiplyList(l1: *mut npy_intp, n: c_int) -> npy_intp];
271 impl_api![159; PyArray_MultiplyIntList(l1: *mut c_int, n: c_int) -> c_int];
272 impl_api![160; PyArray_GetPtr(obj: *mut PyArrayObject, ind: *mut npy_intp) -> *mut c_void];
273 impl_api![161; PyArray_CompareLists(l1: *mut npy_intp, l2: *mut npy_intp, n: c_int) -> c_int];
274 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];
275 impl_api![165; PyArray_Free(op: *mut PyObject, ptr: *mut c_void) -> c_int];
278 impl_api![166; PyArray_Converter(object: *mut PyObject, address: *mut *mut PyObject) -> c_int];
279 impl_api![167; PyArray_IntpFromSequence(seq: *mut PyObject, vals: *mut npy_intp, maxvals: c_int) -> c_int];
280 impl_api![168; PyArray_Concatenate(op: *mut PyObject, axis: c_int) -> *mut PyObject];
281 impl_api![169; PyArray_InnerProduct(op1: *mut PyObject, op2: *mut PyObject) -> *mut PyObject];
282 impl_api![170; PyArray_MatrixProduct(op1: *mut PyObject, op2: *mut PyObject) -> *mut PyObject];
283 impl_api![172; PyArray_Correlate(op1: *mut PyObject, op2: *mut PyObject, mode: c_int) -> *mut PyObject];
285 impl_api![174; PyArray_DescrConverter(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
287 impl_api![175; PyArray_DescrConverter2(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
288 impl_api![176; PyArray_IntpConverter(obj: *mut PyObject, seq: *mut PyArray_Dims) -> c_int];
289 impl_api![177; PyArray_BufferConverter(obj: *mut PyObject, buf: *mut PyArray_Chunk) -> c_int];
290 impl_api![178; PyArray_AxisConverter(obj: *mut PyObject, axis: *mut c_int) -> c_int];
291 impl_api![179; PyArray_BoolConverter(object: *mut PyObject, val: *mut npy_bool) -> c_int];
292 impl_api![180; PyArray_ByteorderConverter(obj: *mut PyObject, endian: *mut c_char) -> c_int];
293 impl_api![181; PyArray_OrderConverter(object: *mut PyObject, val: *mut NPY_ORDER) -> c_int];
294 impl_api![182; PyArray_EquivTypes(type1: *mut PyArray_Descr, type2: *mut PyArray_Descr) -> c_uchar];
295 impl_api![183; PyArray_Zeros(nd: c_int, dims: *mut npy_intp, type_: *mut PyArray_Descr, is_f_order: c_int) -> *mut PyObject];
296 impl_api![184; PyArray_Empty(nd: c_int, dims: *mut npy_intp, type_: *mut PyArray_Descr, is_f_order: c_int) -> *mut PyObject];
297 impl_api![185; PyArray_Where(condition: *mut PyObject, x: *mut PyObject, y: *mut PyObject) -> *mut PyObject];
298 impl_api![186; PyArray_Arange(start: f64, stop: f64, step: f64, type_num: c_int) -> *mut PyObject];
299 impl_api![187; PyArray_ArangeObj(start: *mut PyObject, stop: *mut PyObject, step: *mut PyObject, dtype: *mut PyArray_Descr) -> *mut PyObject];
300 impl_api![188; PyArray_SortkindConverter(obj: *mut PyObject, sortkind: *mut NPY_SORTKIND) -> c_int];
301 impl_api![189; PyArray_LexSort(sort_keys: *mut PyObject, axis: c_int) -> *mut PyObject];
302 impl_api![190; PyArray_Round(a: *mut PyArrayObject, decimals: c_int, out: *mut PyArrayObject) -> *mut PyObject];
303 impl_api![191; PyArray_EquivTypenums(typenum1: c_int, typenum2: c_int) -> c_uchar];
304 impl_api![192; PyArray_RegisterDataType(descr: *mut PyArray_DescrProto) -> c_int];
305 impl_api![193; PyArray_RegisterCastFunc(descr: *mut PyArray_Descr, totype: c_int, castfunc: PyArray_VectorUnaryFunc) -> c_int];
306 impl_api![194; PyArray_RegisterCanCast(descr: *mut PyArray_Descr, totype: c_int, scalar: NPY_SCALARKIND) -> c_int];
307 impl_api![195; PyArray_InitArrFuncs(f: *mut PyArray_ArrFuncs)];
308 impl_api![196; PyArray_IntTupleFromIntp(len: c_int, vals: *mut npy_intp) -> *mut PyObject];
309 impl_api![198; PyArray_ClipmodeConverter(object: *mut PyObject, val: *mut NPY_CLIPMODE) -> c_int];
311 impl_api![199; PyArray_OutputConverter(object: *mut PyObject, address: *mut *mut PyArrayObject) -> c_int];
312 impl_api![200; PyArray_BroadcastToShape(obj: *mut PyObject, dims: *mut npy_intp, nd: c_int) -> *mut PyObject];
313 impl_api![203; PyArray_DescrAlignConverter(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
316 impl_api![204; PyArray_DescrAlignConverter2(obj: *mut PyObject, at: *mut *mut PyArray_Descr) -> c_int];
317 impl_api![205; PyArray_SearchsideConverter(obj: *mut PyObject, addr: *mut c_void) -> c_int];
318 impl_api![206; PyArray_CheckAxis(arr: *mut PyArrayObject, axis: *mut c_int, flags: c_int) -> *mut PyObject];
319 impl_api![207; PyArray_OverflowMultiplyList(l1: *mut npy_intp, n: c_int) -> npy_intp];
320 impl_api![210; PyArray_GetEndianness() -> c_int];
323 impl_api![211; PyArray_GetNDArrayCFeatureVersion() -> c_uint];
324 impl_api![212; PyArray_Correlate2(op1: *mut PyObject, op2: *mut PyObject, mode: c_int) -> *mut PyObject];
325 impl_api![213; PyArray_NeighborhoodIterNew(x: *mut PyArrayIterObject, bounds: *mut npy_intp, mode: c_int, fill: *mut PyArrayObject) -> *mut PyObject];
326 impl_api![224; NpyIter_New(op: *mut PyArrayObject, flags: npy_uint32, order: NPY_ORDER, casting: NPY_CASTING, dtype: *mut PyArray_Descr) -> *mut NpyIter];
333 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];
334 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];
335 impl_api![227; NpyIter_Copy(iter: *mut NpyIter) -> *mut NpyIter];
336 impl_api![228; NpyIter_Deallocate(iter: *mut NpyIter) -> c_int];
337 impl_api![229; NpyIter_HasDelayedBufAlloc(iter: *mut NpyIter) -> npy_bool];
338 impl_api![230; NpyIter_HasExternalLoop(iter: *mut NpyIter) -> npy_bool];
339 impl_api![231; NpyIter_EnableExternalLoop(iter: *mut NpyIter) -> c_int];
340 impl_api![232; NpyIter_GetInnerStrideArray(iter: *mut NpyIter) -> *mut npy_intp];
341 impl_api![233; NpyIter_GetInnerLoopSizePtr(iter: *mut NpyIter) -> *mut npy_intp];
342 impl_api![234; NpyIter_Reset(iter: *mut NpyIter, errmsg: *mut *mut c_char) -> c_int];
343 impl_api![235; NpyIter_ResetBasePointers(iter: *mut NpyIter, baseptrs: *mut *mut c_char, errmsg: *mut *mut c_char) -> c_int];
344 impl_api![236; NpyIter_ResetToIterIndexRange(iter: *mut NpyIter, istart: npy_intp, iend: npy_intp, errmsg: *mut *mut c_char) -> c_int];
345 impl_api![237; NpyIter_GetNDim(iter: *mut NpyIter) -> c_int];
346 impl_api![238; NpyIter_GetNOp(iter: *mut NpyIter) -> c_int];
347 impl_api![239; NpyIter_GetIterNext(iter: *mut NpyIter, errmsg: *mut *mut c_char) -> NpyIter_IterNextFunc];
348 impl_api![240; NpyIter_GetIterSize(iter: *mut NpyIter) -> npy_intp];
349 impl_api![241; NpyIter_GetIterIndexRange(iter: *mut NpyIter, istart: *mut npy_intp, iend: *mut npy_intp)];
350 impl_api![242; NpyIter_GetIterIndex(iter: *mut NpyIter) -> npy_intp];
351 impl_api![243; NpyIter_GotoIterIndex(iter: *mut NpyIter, iterindex: npy_intp) -> c_int];
352 impl_api![244; NpyIter_HasMultiIndex(iter: *mut NpyIter) -> npy_bool];
353 impl_api![245; NpyIter_GetShape(iter: *mut NpyIter, outshape: *mut npy_intp) -> c_int];
354 impl_api![246; NpyIter_GetGetMultiIndex(iter: *mut NpyIter, errmsg: *mut *mut c_char) -> NpyIter_GetMultiIndexFunc];
355 impl_api![247; NpyIter_GotoMultiIndex(iter: *mut NpyIter, multi_index: *mut npy_intp) -> c_int];
356 impl_api![248; NpyIter_RemoveMultiIndex(iter: *mut NpyIter) -> c_int];
357 impl_api![249; NpyIter_HasIndex(iter: *mut NpyIter) -> npy_bool];
358 impl_api![250; NpyIter_IsBuffered(iter: *mut NpyIter) -> npy_bool];
359 impl_api![251; NpyIter_IsGrowInner(iter: *mut NpyIter) -> npy_bool];
360 impl_api![252; NpyIter_GetBufferSize(iter: *mut NpyIter) -> npy_intp];
361 impl_api![253; NpyIter_GetIndexPtr(iter: *mut NpyIter) -> *mut npy_intp];
362 impl_api![254; NpyIter_GotoIndex(iter: *mut NpyIter, flat_index: npy_intp) -> c_int];
363 impl_api![255; NpyIter_GetDataPtrArray(iter: *mut NpyIter) -> *mut *mut c_char];
364 impl_api![256; NpyIter_GetDescrArray(iter: *mut NpyIter) -> *mut *mut PyArray_Descr];
365 impl_api![257; NpyIter_GetOperandArray(iter: *mut NpyIter) -> *mut *mut PyArrayObject];
366 impl_api![258; NpyIter_GetIterView(iter: *mut NpyIter, i: npy_intp) -> *mut PyArrayObject];
367 impl_api![259; NpyIter_GetReadFlags(iter: *mut NpyIter, outreadflags: *mut c_char)];
368 impl_api![260; NpyIter_GetWriteFlags(iter: *mut NpyIter, outwriteflags: *mut c_char)];
369 impl_api![261; NpyIter_DebugPrint(iter: *mut NpyIter)];
370 impl_api![262; NpyIter_IterationNeedsAPI(iter: *mut NpyIter) -> npy_bool];
371 impl_api![263; NpyIter_GetInnerFixedStrideArray(iter: *mut NpyIter, out_strides: *mut npy_intp)];
372 impl_api![264; NpyIter_RemoveAxis(iter: *mut NpyIter, axis: c_int) -> c_int];
373 impl_api![265; NpyIter_GetAxisStrideArray(iter: *mut NpyIter, axis: c_int) -> *mut npy_intp];
374 impl_api![266; NpyIter_RequiresBuffering(iter: *mut NpyIter) -> npy_bool];
375 impl_api![267; NpyIter_GetInitialDataPtrArray(iter: *mut NpyIter) -> *mut *mut c_char];
376 impl_api![268; NpyIter_CreateCompatibleStrides(iter: *mut NpyIter, itemsize: npy_intp, outstrides: *mut npy_intp) -> c_int];
377 impl_api![269; PyArray_CastingConverter(obj: *mut PyObject, casting: *mut NPY_CASTING) -> c_int];
378 impl_api![270; PyArray_CountNonzero(self_: *mut PyArrayObject) -> npy_intp];
379 impl_api![271; PyArray_PromoteTypes(type1: *mut PyArray_Descr, type2: *mut PyArray_Descr) -> *mut PyArray_Descr];
380 impl_api![272; PyArray_MinScalarType(arr: *mut PyArrayObject) -> *mut PyArray_Descr];
381 impl_api![273; PyArray_ResultType(narrs: npy_intp, arr: *mut *mut PyArrayObject, ndtypes: npy_intp, dtypes: *mut *mut PyArray_Descr) -> *mut PyArray_Descr];
382 impl_api![274; PyArray_CanCastArrayTo(arr: *mut PyArrayObject, to: *mut PyArray_Descr, casting: NPY_CASTING) -> npy_bool];
383 impl_api![275; PyArray_CanCastTypeTo(from: *mut PyArray_Descr, to: *mut PyArray_Descr, casting: NPY_CASTING) -> npy_bool];
384 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];
385 impl_api![277; PyArray_NewLikeArray(prototype: *mut PyArrayObject, order: NPY_ORDER, dtype: *mut PyArray_Descr, subok: c_int) -> *mut PyObject];
386 impl_api![279; PyArray_ConvertClipmodeSequence(object: *mut PyObject, modes: *mut NPY_CLIPMODE, n: c_int) -> c_int];
388 impl_api![280; PyArray_MatrixProduct2(op1: *mut PyObject, op2: *mut PyObject, out: *mut PyArrayObject) -> *mut PyObject];
389 impl_api![281; NpyIter_IsFirstVisit(iter: *mut NpyIter, iop: c_int) -> npy_bool];
390 impl_api![282; PyArray_SetBaseObject(arr: *mut PyArrayObject, obj: *mut PyObject) -> c_int];
391 impl_api![283; PyArray_CreateSortedStridePerm(ndim: c_int, strides: *mut npy_intp, out_strideperm: *mut npy_stride_sort_item)];
392 impl_api![284; PyArray_RemoveAxesInPlace(arr: *mut PyArrayObject, flags: *mut npy_bool)];
393 impl_api![285; PyArray_DebugPrint(obj: *mut PyArrayObject)];
394 impl_api![286; PyArray_FailUnlessWriteable(obj: *mut PyArrayObject, name: *const c_char) -> c_int];
395 impl_api![287; PyArray_SetUpdateIfCopyBase(arr: *mut PyArrayObject, base: *mut PyArrayObject) -> c_int];
396 impl_api![288; PyDataMem_NEW(size: usize) -> *mut c_void];
397 impl_api![289; PyDataMem_FREE(ptr: *mut c_void)];
398 impl_api![290; PyDataMem_RENEW(ptr: *mut c_void, size: usize) -> *mut c_void];
399 impl_api![296; PyArray_Partition(op: *mut PyArrayObject, ktharray: *mut PyArrayObject, axis: c_int, which: NPY_SELECTKIND) -> c_int];
404 impl_api![297; PyArray_ArgPartition(op: *mut PyArrayObject, ktharray: *mut PyArrayObject, axis: c_int, which: NPY_SELECTKIND) -> *mut PyObject];
405 impl_api![298; PyArray_SelectkindConverter(obj: *mut PyObject, selectkind: *mut NPY_SELECTKIND) -> c_int];
406 impl_api![299; PyDataMem_NEW_ZEROED(size: usize, elsize: usize) -> *mut c_void];
407 impl_api![300; PyArray_CheckAnyScalarExact(obj: *mut PyObject) -> c_int];
408 impl_api![302; PyArray_ResolveWritebackIfCopy(self_: *mut PyArrayObject) -> c_int];
410 impl_api![303; PyArray_SetWritebackIfCopyBase(arr: *mut PyArrayObject, base: *mut PyArrayObject) -> c_int];
411 }
432
433#[allow(non_snake_case)]
435pub unsafe fn PyArray_Check<'py>(py: Python<'py>, op: *mut PyObject) -> c_int {
436 ffi::PyObject_TypeCheck(op, super::get_type_object(py, NpyTypes::PyArray_Type))
437}
438
439#[allow(non_snake_case)]
441pub unsafe fn PyArray_CheckExact<'py>(py: Python<'py>, op: *mut PyObject) -> c_int {
442 (ffi::Py_TYPE(op) == super::get_type_object(py, NpyTypes::PyArray_Type)) as _
443}
444
445#[cfg(test)]
446mod tests {
447 use super::*;
448
449 #[test]
450 fn call_api() {
451 Python::attach(|py| unsafe {
452 assert_eq!(
453 PY_ARRAY_API.PyArray_MultiplyIntList(py, [1, 2, 3].as_mut_ptr(), 3),
454 6
455 );
456 })
457 }
458}