Data Structures |
struct | _simple_cobj |
Defines |
#define | _UMATHMODULE |
#define | NPY_NO_DEPRECATED_API |
#define | NPY_UF_DBG_TRACING 0 |
#define | NPY_UF_DBG_PRINT(s) |
#define | NPY_UF_DBG_PRINT1(s, p1) |
#define | NPY_UF_DBG_PRINT2(s, p1, p2) |
#define | NPY_UF_DBG_PRINT3(s, p1, p2, p3) |
#define | USE_USE_DEFAULTS 1 |
#define | USE_NEW_ITERATOR_GENFUNC 1 |
#define | HANDLEIT(NAME, str) |
#define | NO_UFUNCLOOP 0 |
#define | ZERO_EL_REDUCELOOP 0 |
#define | ONE_UFUNCLOOP 1 |
#define | ONE_EL_REDUCELOOP 1 |
#define | NOBUFFER_UFUNCLOOP 2 |
#define | NOBUFFER_REDUCELOOP 2 |
#define | BUFFER_UFUNCLOOP 3 |
#define | BUFFER_REDUCELOOP 3 |
#define | SIGNATURE_NOBUFFER_UFUNCLOOP 4 |
#define | _GETATTR_(str, rstr) |
#define | _SETCPTR(cobj, val) ((_simple_cobj *)(cobj))->c_obj = (val) |
Functions |
static int | _does_loop_use_arrays (void *data) |
static int | _error_handler (int method, PyObject *errobj, char *errtype, int retstatus, int *first) |
NPY_NO_EXPORT int | PyUFunc_getfperr (void) |
NPY_NO_EXPORT int | PyUFunc_handlefperr (int errmask, PyObject *errobj, int retstatus, int *first) |
NPY_NO_EXPORT int | PyUFunc_checkfperr (int errmask, PyObject *errobj, int *first) |
NPY_NO_EXPORT void | PyUFunc_clearfperr () |
static void | _find_array_prepare (PyObject *args, PyObject *kwds, PyObject **output_prep, int nin, int nout) |
static int | _extract_pyvals (PyObject *ref, char *name, int *bufsize, int *errmask, PyObject **errobj) |
NPY_NO_EXPORT int | PyUFunc_GetPyValues (char *name, int *bufsize, int *errmask, PyObject **errobj) |
static int | _has_reflected_op (PyObject *op, char *name) |
static int | _next_non_white_space (const char *str, int offset) |
static int | _is_alpha_underscore (char ch) |
static int | _is_alnum_underscore (char ch) |
static int | _get_end_of_name (const char *str, int offset) |
static int | _is_same_name (const char *s1, const char *s2) |
static int | _parse_signature (PyUFuncObject *self, const char *signature) |
static int | get_ufunc_arguments (PyUFuncObject *self, PyObject *args, PyObject *kwds, PyArrayObject **out_op, NPY_ORDER *out_order, NPY_CASTING *out_casting, PyObject **out_extobj, PyObject **out_typetup, int *out_subok, PyArrayObject **out_wheremask) |
static int | check_for_trivial_loop (PyUFuncObject *self, PyArrayObject **op, PyArray_Descr **dtype, npy_intp buffersize) |
static void | trivial_two_operand_loop (PyArrayObject **op, PyUFuncGenericFunction innerloop, void *innerloopdata) |
static void | trivial_three_operand_loop (PyArrayObject **op, PyUFuncGenericFunction innerloop, void *innerloopdata) |
static int | prepare_ufunc_output (PyUFuncObject *self, PyArrayObject **op, PyObject *arr_prep, PyObject *arr_prep_args, int i) |
static int | iterator_loop (PyUFuncObject *self, PyArrayObject **op, PyArray_Descr **dtype, NPY_ORDER order, npy_intp buffersize, PyObject **arr_prep, PyObject *arr_prep_args, PyUFuncGenericFunction innerloop, void *innerloopdata) |
static int | execute_ufunc_loop (PyUFuncObject *self, int trivial_loop_ok, PyArrayObject **op, PyArray_Descr **dtype, NPY_ORDER order, npy_intp buffersize, PyObject **arr_prep, PyObject *arr_prep_args, PyUFuncGenericFunction innerloop, void *innerloopdata) |
static int | execute_ufunc_masked_loop (PyUFuncObject *self, PyArrayObject *wheremask, PyArrayObject **op, PyArray_Descr **dtype, NPY_ORDER order, npy_intp buffersize, PyObject **arr_prep, PyObject *arr_prep_args, PyUFuncGenericMaskedFunction innerloop, NpyAuxData *innerloopdata) |
static PyObject * | make_arr_prep_args (npy_intp nin, PyObject *args, PyObject *kwds) |
static int | PyUFunc_GeneralizedFunction (PyUFuncObject *self, PyObject *args, PyObject *kwds, PyArrayObject **op) |
NPY_NO_EXPORT int | PyUFunc_GenericFunction (PyUFuncObject *self, PyObject *args, PyObject *kwds, PyArrayObject **op) |
static int | get_binary_op_function (PyUFuncObject *self, int *otype, PyUFuncGenericFunction *out_innerloop, void **out_innerloopdata) |
static PyObject * | PyUFunc_ReductionOp (PyUFuncObject *self, PyArrayObject *arr, PyArrayObject *out, int axis, int otype, int operation, char *opname) |
static PyObject * | PyUFunc_Reduce (PyUFuncObject *self, PyArrayObject *arr, PyArrayObject *out, int axis, int otype) |
static PyObject * | PyUFunc_Accumulate (PyUFuncObject *self, PyArrayObject *arr, PyArrayObject *out, int axis, int otype) |
static PyObject * | PyUFunc_Reduceat (PyUFuncObject *self, PyArrayObject *arr, PyArrayObject *ind, PyArrayObject *out, int axis, int otype) |
static PyObject * | PyUFunc_GenericReduction (PyUFuncObject *self, PyObject *args, PyObject *kwds, int operation) |
static void | _find_array_wrap (PyObject *args, PyObject *kwds, PyObject **output_wrap, int nin, int nout) |
static PyObject * | ufunc_generic_call (PyUFuncObject *self, PyObject *args, PyObject *kwds) |
NPY_NO_EXPORT PyObject * | ufunc_geterr (PyObject *NPY_UNUSED(dummy), PyObject *args) |
static int | ufunc_update_use_defaults (void) |
NPY_NO_EXPORT PyObject * | ufunc_seterr (PyObject *NPY_UNUSED(dummy), PyObject *args) |
NPY_NO_EXPORT int | PyUFunc_ReplaceLoopBySignature (PyUFuncObject *func, PyUFuncGenericFunction newfunc, int *signature, PyUFuncGenericFunction *oldfunc) |
NPY_NO_EXPORT PyObject * | PyUFunc_FromFuncAndData (PyUFuncGenericFunction *func, void **data, char *types, int ntypes, int nin, int nout, int identity, char *name, char *doc, int check_return) |
NPY_NO_EXPORT PyObject * | PyUFunc_FromFuncAndDataAndSignature (PyUFuncGenericFunction *func, void **data, char *types, int ntypes, int nin, int nout, int identity, char *name, char *doc, int check_return, const char *signature) |
NPY_NO_EXPORT int | PyUFunc_SetUsesArraysAsData (void **data, size_t i) |
static int | cmp_arg_types (int *arg1, int *arg2, int n) |
static NPY_INLINE void | _free_loop1d_list (PyUFunc_Loop1d *data) |
static void | _loop1d_list_free (void *ptr) |
NPY_NO_EXPORT int | PyUFunc_RegisterLoopForType (PyUFuncObject *ufunc, int usertype, PyUFuncGenericFunction function, int *arg_types, void *data) |
static void | ufunc_dealloc (PyUFuncObject *self) |
static PyObject * | ufunc_repr (PyUFuncObject *self) |
static PyObject * | ufunc_outer (PyUFuncObject *self, PyObject *args, PyObject *kwds) |
static PyObject * | ufunc_reduce (PyUFuncObject *self, PyObject *args, PyObject *kwds) |
static PyObject * | ufunc_accumulate (PyUFuncObject *self, PyObject *args, PyObject *kwds) |
static PyObject * | ufunc_reduceat (PyUFuncObject *self, PyObject *args, PyObject *kwds) |
static PyObject * | _makeargs (int num, char *ltr, int null_if_none) |
static char | _typecharfromnum (int num) |
static PyObject * | ufunc_get_doc (PyUFuncObject *self) |
static PyObject * | ufunc_get_nin (PyUFuncObject *self) |
static PyObject * | ufunc_get_nout (PyUFuncObject *self) |
static PyObject * | ufunc_get_nargs (PyUFuncObject *self) |
static PyObject * | ufunc_get_ntypes (PyUFuncObject *self) |
static PyObject * | ufunc_get_types (PyUFuncObject *self) |
static PyObject * | ufunc_get_name (PyUFuncObject *self) |
static PyObject * | ufunc_get_identity (PyUFuncObject *self) |
static PyObject * | ufunc_get_signature (PyUFuncObject *self) |
Variables |
static int | PyUFunc_NUM_NODEFAULTS = 0 |
static PyObject * | PyUFunc_PYVALS_NAME = NULL |
static struct PyMethodDef | ufunc_methods [] |
static PyGetSetDef | ufunc_getset [] |
NPY_NO_EXPORT PyTypeObject | PyUFunc_Type |
static void _find_array_prepare |
( |
PyObject * |
args, |
|
|
PyObject * |
kwds, |
|
|
PyObject ** |
output_prep, |
|
|
int |
nin, |
|
|
int |
nout |
|
) |
| [static] |
This function analyzes the input arguments and determines an appropriate __array_prepare__ function to call for the outputs.
If an output argument is provided, then it is prepped with its own __array_prepare__ not with the one determined by the input arguments.
if the provided output argument is already an ndarray, the prepping function is None (which means no prepping will be done --- not even PyArray_Return).
A NULL is placed in output_prep for outputs that should just have PyArray_Return called.
If a 'subok' parameter is passed and isn't True, don't wrap
If we have some preps defined, find the one of highest priority
Here prep is the prepping function determined from the input arrays (could be NULL).
For all the output arrays decide what to do.
1) Use the prep function determined from the input arrays This is the default if the output array is not passed in.
2) Use the __array_prepare__ method of the output object. This is special cased for exact ndarray so that no PyArray_Return is done in that case.
Output argument one may also be in a keyword argument
Output argument one may also be in a keyword argument
None signals to not call any wrapping
static void _find_array_wrap |
( |
PyObject * |
args, |
|
|
PyObject * |
kwds, |
|
|
PyObject ** |
output_wrap, |
|
|
int |
nin, |
|
|
int |
nout |
|
) |
| [static] |
This function analyzes the input arguments and determines an appropriate __array_wrap__ function to call for the outputs.
If an output argument is provided, then it is wrapped with its own __array_wrap__ not with the one determined by the input arguments.
if the provided output argument is already an array, the wrapping function is None (which means no wrapping will be done --- not even PyArray_Return).
A NULL is placed in output_wrap for outputs that should just have PyArray_Return called.
If a 'subok' parameter is passed and isn't True, don't wrap
If we have some wraps defined, find the one of highest priority
Here wrap is the wrapping function determined from the input arrays (could be NULL).
For all the output arrays decide what to do.
1) Use the wrap function determined from the input arrays This is the default if the output array is not passed in.
2) Use the __array_wrap__ method of the output object passed in. -- this is special cased for exact ndarray so that no PyArray_Return is done in that case.
Output argument one may also be in a keyword argument
Output argument one may also be in a keyword argument
None signals to not call any wrapping
*** GENERIC UFUNC USING ITERATOR ****
Parses the positional and keyword arguments for a generic ufunc call.
Note that if an error is returned, the caller must free the non-zero references in out_op. This function does not do its own clean-up.
Check number of arguments
Get input arguments
- TODO: There should be a comment here explaining what
- context does.
Indicate not implemented if there are flexible objects (structured type or string) but no object types.
Not sure - adding this increased to 246 errors, 150 failures.
Get positional output arguments
Translate None to NULL
If it's an array, can use it
Get keyword output and other arguments. Raise an error if anything else is present in the keyword dictionary.
Provides a policy for allowed casting
Another way to specify 'sig'
Allow this parameter to be None
Overrides the global parameters buffer size, error mask, and error object
First output may be specified as a keyword parameter
Allows the default output layout to be overridden
Allows a specific function inner loop to be selected
Provides a boolean array 'where=' mask if out_wheremask is supplied.
Use remapped axes for generalized ufunc
These parameters come from extobj= or from a TLS global
The selected inner loop
The dimensions which get passed to the inner loop
The strides which get passed to the inner loop
The __array_prepare__ function to call for each output
This is either args, or args with the out= parameter from kwds added appropriately.
Currently trying out SAME_KIND casting rule by default.
When provided, extobj and typetup contain borrowed references
Initialize all the operands and dtypes to NULL
Get all the arguments
Figure out the number of dimensions needed by the iterator
Fill in op_axes for all the operands
Note that n may be negative if broadcasting extends into the core dimensions.
Broadcast all the unspecified dimensions normally
Use the signature information for the rest
Get the buffersize, errormask, and error object globals
FAIL with NotImplemented if the other object has the __r<op>__ method and has __array_priority__ as an attribute (signalling it can handle ndarray's) and is not already an ndarray or a subtype of the same type.
If both are same subtype of object arrays, then proceed
Get the appropriate __array_prepare__ function to call for each output
Set up arr_prep_args if a prep function was needed
If the loop wants the arrays, provide them
Set up the iterator per-op flags. For generalized ufuncs, we can't do buffering, so must COPY or UPDATEIFCOPY.
Create the iterator
Fill in any allocated outputs
Set up the inner strides array. Because we're not doing buffering, the strides are fixed throughout the looping.
The strides after the first nop match core_dim_ixs
Set up the inner dimensions array
Move the core dimensions to start at the second element
Remove all the core dimensions from the iterator
The first nop strides are for the inner loop (but only can copy them after removing the core axes
Start with the floating-point exception flags cleared
Do the ufunc loop
Get the variables needed for the loop
Check whether any errors occurred during the loop
The caller takes ownership of all the references in op
- This generic function is called with the ufunc object, the arguments to it,
-
and an array of (pointers to) PyArrayObjects which are NULL.
'op' is an array of at least NPY_MAXARGS PyArrayObject *.
System Message: WARNING/2 (
<string>
, line 4);
backlink Inline emphasis start-string without end-string.
These parameters come from extobj= or from a TLS global
The selected inner loop
The selected masked inner loop, when the 'where=' parameter or arrays with missing values are in op.
The mask provided in the 'where=' parameter
The __array_prepare__ function to call for each output
This is either args, or args with the out= parameter from kwds added appropriately.
Currently trying out SAME_KIND casting rule by default.
When provided, extobj and typetup contain borrowed references
Initialize all the operands and dtypes to NULL
Get all the arguments
For now just the where mask triggers this, but later arrays with missing data will trigger it as well.
Get the buffersize, errormask, and error object globals
This checks whether a trivial loop is ok, making copies of scalar and one dimensional operands if that will help.
Only do the trivial loop check for the unmasked version.
FAIL with NotImplemented if the other object has the __r<op>__ method and has __array_priority__ as an attribute (signalling it can handle ndarray's) and is not already an ndarray or a subtype of the same type.
If both are same subtype of object arrays, then proceed
Get the appropriate __array_prepare__ function to call for each output
Set up arr_prep_args if a prep function was needed
If the loop wants the arrays, provide them.
- TODO: Remove this, since this is already basically broken
- with the addition of the masked inner loops and not worth fixing.
Start with the floating-point exception flags cleared
Do the ufunc loop
Check whether any errors occurred during the loop
The caller takes ownership of all the references in op
Reduceat performs a reduce over an axis using the indices as a guide
op.reduceat(array,indices) computes op.reduce(array[indices[i]:indices[i+1]] for i=0..end with an implicit indices[i+1]=len(array) assumed when i=end-1
if indices[i+1] <= indices[i]+1 then the result is array[indices[i]] for that value
op.accumulate(array) is the same as op.reduceat(array,indices)[::2] where indices is range(len(array)-1) with a zero placed in every other sample indices = zeros(len(array)*2-1) indices[1::2] = range(1,len(array))
output shape is based on the size of indices
The reduceat indices - ind must be validated outside this call
The selected inner loop
These parameters come from extobj= or from a TLS global
Check for out-of-bounds values in indices array
Take a reference to out for later returning
Set up the output data type, using the input's exact data type if the type number didn't change to preserve metadata
Set up the op_axes for the outer loop
Use the i-th iteration dimension to match up ind
Likewise with accumulate, must do UPDATEIFCOPY
The way reduceat is set up, we can't do buffering, so make a copy instead when necessary.
The per-operand flags for the outer loop
Remove the inner loop axis from the outer iterator
In case COPY or UPDATEIFCOPY occurred
Allocate the output for when there's no outer iterator
If the output has zero elements, return now.
Get the variables needed for the loop
Execute the loop with just the outer iterator
Copy the first element to start the reduction
Inner loop like REDUCE
Execute the loop with no iterators
Copy the first element to start the reduction
Inner loop like REDUCE
References PyArray_LONG.
The implementation of the reduction operators with the new iterator turned into a bit of a long function here, but I think the design of this part needs to be changed to be more like einsum, so it may not be worth refactoring it too much. Consider this timing:
>>> a = arange(10000)
>>> timeit sum(a)
10000 loops, best of 3: 17 us per loop
>>> timeit einsum("i->",a)
100000 loops, best of 3: 13.5 us per loop
The selected inner loop
These parameters come from extobj= or from a TLS global
Take a reference to out for later returning
Set up the output data type, using the input's exact data type if the type number didn't change to preserve metadata
Set up the op_axes for the outer loop
The per-operand flags for the outer loop
This is because we can't buffer, so must do UPDATEIFCOPY
The way accumulate is set up, we can't do buffering, so make a copy instead when necessary.
Add some more flags
In case COPY or UPDATEIFCOPY occurred
Get the output
If the reduction unit has size zero, either return the reduction unit for UFUNC_REDUCE, or return the zero-sized output array for UFUNC_ACCUMULATE.
Only allocate an inner iterator if it's necessary
Also set the dtype for buffering arr
The per-operand flags for the inner loop
Should never get an inner iterator for ACCUMULATE
Get the variables needed for the loop
Execute the loop with two nested iterators
Only UFUNC_REDUCE uses iter_inner
Reset the inner iterator to the outer's data
Copy the first element to start the reduction
Turn the two items into three for the inner loop
Execute the loop with just the outer iterator
Copy the first element to start the reduction
Turn the two items into three for the inner loop
Execute the loop with just the inner iterator
Only UFUNC_REDUCE uses iter_inner
Reset the inner iterator to prepare the buffers
Copy the first element to start the reduction
Turn the two items into three for the inner loop
Execute the loop with no iterators
Turn the two items into three for the inner loop
Copy the first element to start the reduction