1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#ifndef NUMPY_CORE_SRC_MULTIARRAY_ARRAY_METHOD_H_
#define NUMPY_CORE_SRC_MULTIARRAY_ARRAY_METHOD_H_
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#define _MULTIARRAYMODULE
#include <Python.h>
#include <numpy/ndarraytypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "numpy/_dtype_api.h"
/*
* It would be nice to just | flags, but in general it seems that 0 bits
* probably should indicate "default".
* And that is not necessarily compatible with `|`.
*
* NOTE: If made public, should maybe be a function to easier add flags?
*/
#define PyArrayMethod_MINIMAL_FLAGS NPY_METH_NO_FLOATINGPOINT_ERRORS
#define PyArrayMethod_COMBINED_FLAGS(flags1, flags2) \
((NPY_ARRAYMETHOD_FLAGS)( \
((flags1 | flags2) & ~PyArrayMethod_MINIMAL_FLAGS) \
| (flags1 & flags2)))
/*
* Structure of the ArrayMethod. This structure should probably not be made
* public. If necessary, we can make certain operations on it public
* (e.g. to allow users indirect access to `get_strided_loop`).
*
* NOTE: In some cases, it may not be clear whether information should be
* stored here or on the bound version. E.g. `nin` and `nout` (and in the
* future the gufunc `signature`) is already stored on the ufunc so that
* storing these here duplicates the information.
*/
typedef struct PyArrayMethodObject_tag {
PyObject_HEAD
char *name;
int nin, nout;
/* Casting is normally "safe" for functions, but is important for casts */
NPY_CASTING casting;
/* default flags. The get_strided_loop function can override these */
NPY_ARRAYMETHOD_FLAGS flags;
resolve_descriptors_function *resolve_descriptors;
get_loop_function *get_strided_loop;
get_reduction_initial_function *get_reduction_initial;
/* Typical loop functions (contiguous ones are used in current casts) */
PyArrayMethod_StridedLoop *strided_loop;
PyArrayMethod_StridedLoop *contiguous_loop;
PyArrayMethod_StridedLoop *unaligned_strided_loop;
PyArrayMethod_StridedLoop *unaligned_contiguous_loop;
PyArrayMethod_StridedLoop *contiguous_indexed_loop;
/* Chunk only used for wrapping array method defined in umath */
struct PyArrayMethodObject_tag *wrapped_meth;
PyArray_DTypeMeta **wrapped_dtypes;
translate_given_descrs_func *translate_given_descrs;
translate_loop_descrs_func *translate_loop_descrs;
/* Chunk reserved for use by the legacy fallback arraymethod */
char legacy_initial[sizeof(npy_clongdouble)]; /* initial value storage */
} PyArrayMethodObject;
/*
* We will sometimes have to create a ArrayMethod and allow passing it around,
* similar to `instance.method` returning a bound method, e.g. a function like
* `ufunc.resolve()` can return a bound object.
* The current main purpose of the BoundArrayMethod is that it holds on to the
* `dtypes` (the classes), so that the `ArrayMethod` (e.g. for casts) will
* not create references cycles. In principle, it could hold any information
* which is also stored on the ufunc (and thus does not need to be repeated
* on the `ArrayMethod` itself.
*/
typedef struct {
PyObject_HEAD
PyArray_DTypeMeta **dtypes;
PyArrayMethodObject *method;
} PyBoundArrayMethodObject;
extern NPY_NO_EXPORT PyTypeObject PyArrayMethod_Type;
extern NPY_NO_EXPORT PyTypeObject PyBoundArrayMethod_Type;
/*
* Used internally (initially) for real to complex loops only
*/
NPY_NO_EXPORT int
npy_default_get_strided_loop(
PyArrayMethod_Context *context,
int aligned, int NPY_UNUSED(move_references), const npy_intp *strides,
PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
NPY_ARRAYMETHOD_FLAGS *flags);
NPY_NO_EXPORT int
PyArrayMethod_GetMaskedStridedLoop(
PyArrayMethod_Context *context,
int aligned,
npy_intp *fixed_strides,
PyArrayMethod_StridedLoop **out_loop,
NpyAuxData **out_transferdata,
NPY_ARRAYMETHOD_FLAGS *flags);
NPY_NO_EXPORT PyObject *
PyArrayMethod_FromSpec(PyArrayMethod_Spec *spec);
/*
* TODO: This function is the internal version, and its error paths may
* need better tests when a public version is exposed.
*/
NPY_NO_EXPORT PyBoundArrayMethodObject *
PyArrayMethod_FromSpec_int(PyArrayMethod_Spec *spec, int priv);
#ifdef __cplusplus
}
#endif
#endif /* NUMPY_CORE_SRC_MULTIARRAY_ARRAY_METHOD_H_ */
|