numpy 2.0.0
src/multiarray/ctors.h File Reference

Go to the source code of this file.

Functions

NPY_NO_EXPORT PyObject * PyArray_NewFromDescr (PyTypeObject *subtype, PyArray_Descr *descr, int nd, intp *dims, intp *strides, void *data, int flags, PyObject *obj)
NPY_NO_EXPORT PyObject * PyArray_New (PyTypeObject *, int nd, intp *, int, intp *, void *, int, int, PyObject *)
NPY_NO_EXPORT PyObject * PyArray_FromAny (PyObject *op, PyArray_Descr *newtype, int min_depth, int max_depth, int flags, PyObject *context)
NPY_NO_EXPORT PyObject * PyArray_CheckFromAny (PyObject *op, PyArray_Descr *descr, int min_depth, int max_depth, int requires, PyObject *context)
NPY_NO_EXPORT PyObject * PyArray_FromArray (PyArrayObject *arr, PyArray_Descr *newtype, int flags)
NPY_NO_EXPORT PyObject * PyArray_FromStructInterface (PyObject *input)
NPY_NO_EXPORT PyObject * PyArray_FromInterface (PyObject *input)
NPY_NO_EXPORT PyObject * PyArray_FromArrayAttr (PyObject *op, PyArray_Descr *typecode, PyObject *context)
NPY_NO_EXPORT PyObject * PyArray_EnsureArray (PyObject *op)
NPY_NO_EXPORT PyObject * PyArray_EnsureAnyArray (PyObject *op)
NPY_NO_EXPORT int PyArray_MoveInto (PyArrayObject *dest, PyArrayObject *src)
NPY_NO_EXPORT int PyArray_CopyAnyInto (PyArrayObject *dest, PyArrayObject *src)
NPY_NO_EXPORT PyObject * PyArray_CheckAxis (PyArrayObject *arr, int *axis, int flags)
NPY_NO_EXPORT int PyArray_CopyAnyIntoOrdered (PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
NPY_NO_EXPORT size_t _array_fill_strides (intp *strides, intp *dims, int nd, size_t itemsize, int inflag, int *objflags)
NPY_NO_EXPORT void _unaligned_strided_byte_copy (char *dst, intp outstrides, char *src, intp instrides, intp N, int elsize)
NPY_NO_EXPORT void _strided_byte_swap (void *p, intp stride, intp n, int size)
NPY_NO_EXPORT void copy_and_swap (void *dst, void *src, int itemsize, intp numitems, intp srcstrides, int swap)
NPY_NO_EXPORT void byte_swap_vector (void *p, intp n, int size)
NPY_NO_EXPORT int PyArray_AssignFromSequence (PyArrayObject *self, PyObject *v)

Function Documentation

NPY_NO_EXPORT size_t _array_fill_strides ( npy_intp strides,
npy_intp dims,
int  nd,
size_t  itemsize,
int  inflag,
int *  objflags 
)
FIXME: remove those from here
This is the main array creation routine.
Flags argument has multiple related meanings depending on data and strides:
If data is given, then flags is flags associated with data. If strides is not given, then a contiguous strides array will be created and the NPY_ARRAY_C_CONTIGUOUS bit will be set. If the flags argument has the NPY_ARRAY_F_CONTIGUOUS bit set, then a FORTRAN-style strides array will be created (and of course the NPY_ARRAY_F_CONTIGUOUS flag bit will be set).
If data is not given but created here, then flags will be NPY_ARRAY_DEFAULT and a non-zero flags argument can be used to indicate a FORTRAN style array is desired.

Only make Fortran strides if not contiguous as well

NPY_NO_EXPORT void _strided_byte_swap ( void *  p,
intp  stride,
intp  n,
int  size 
)

<

no byteswap necessary

References c.

Referenced by _new_sort().

NPY_NO_EXPORT void _unaligned_strided_byte_copy ( char *  dst,
intp  outstrides,
char *  src,
intp  instrides,
intp  N,
int  elsize 
)

Referenced by _copyswap(), and _new_sort().

NPY_NO_EXPORT void byte_swap_vector ( void *  p,
intp  n,
int  size 
)
NPY_NO_EXPORT void copy_and_swap ( void *  dst,
void *  src,
int  itemsize,
npy_intp  numitems,
npy_intp  srcstrides,
int  swap 
)
If numitems > 1, then dst must be contiguous

References PyArray_DATA.

NPY_NO_EXPORT int PyArray_AssignFromSequence ( PyArrayObject self,
PyObject *  v 
)
NPY_NO_EXPORT PyObject* PyArray_CheckAxis ( PyArrayObject arr,
int *  axis,
int  flags 
)
PyArray_CheckAxis <blockquote> check that axis is valid convert 0-d arrays to 1-d arrays</blockquote>

References _PyArray_Descr::elsize.

Referenced by PyArray_ArgMax(), and PyArray_Prod().

NPY_NO_EXPORT PyObject* PyArray_CheckFromAny ( PyObject *  op,
PyArray_Descr descr,
int  min_depth,
int  max_depth,
int  requires,
PyObject *  context 
)
flags is any of NPY_ARRAY_C_CONTIGUOUS (formerly CONTIGUOUS), NPY_ARRAY_F_CONTIGUOUS (formerly FORTRAN), NPY_ARRAY_ALIGNED, NPY_ARRAY_WRITEABLE, NPY_ARRAY_NOTSWAPPED, NPY_ARRAY_ENSURECOPY, NPY_ARRAY_UPDATEIFCOPY, NPY_ARRAY_FORCECAST, NPY_ARRAY_ENSUREARRAY, NPY_ARRAY_ELEMENTSTRIDES
or'd (|) together
Any of these flags present means that the returned array should guarantee that aspect of the array. Otherwise the returned array won't guarantee it -- it will depend on the object as to whether or not it has such features.
Note that NPY_ARRAY_ENSURECOPY is enough to guarantee NPY_ARRAY_C_CONTIGUOUS, NPY_ARRAY_ALIGNED and NPY_ARRAY_WRITEABLE and therefore it is redundant to include those as well.
NPY_ARRAY_BEHAVED == NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE NPY_ARRAY_CARRAY = NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_BEHAVED NPY_ARRAY_FARRAY = NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_BEHAVED
NPY_ARRAY_F_CONTIGUOUS can be set in the FLAGS to request a FORTRAN array. Fortran arrays are always behaved (aligned, notswapped, and writeable) and not (C) CONTIGUOUS (if > 1d).
NPY_ARRAY_UPDATEIFCOPY flag sets this flag in the returned array if a copy is made and the base argument points to the (possibly) misbehaved array. When the new array is deallocated, the original array held in base is updated with the contents of the new array.
NPY_ARRAY_FORCECAST will cause a cast to occur regardless of whether or not it is safe.
steals a reference to descr -- accepts NULL
NPY_NO_EXPORT int PyArray_CopyAnyInto ( PyArrayObject dst,
PyArrayObject src 
)
Copy an Array into another array -- memory must not overlap

Does not require src and dest to have "broadcastable" shapes (only the same number of elements).

TODO: For NumPy 2.0, this could accept an order parameter which
only allows NPY_CORDER and NPY_FORDER. Could also rename this to CopyAsFlat to make the name more intuitive.

Returns 0 on success, -1 on error.

References MAX_DIMS, PyArray_NDIM, and PyArray_Ravel().

Referenced by PyArray_TypeNumFromName().

NPY_NO_EXPORT int PyArray_CopyAnyIntoOrdered ( PyArrayObject dst,
PyArrayObject src,
NPY_ORDER  order 
)
TODO: Put the order parameter in PyArray_CopyAnyInto and remove this

If the shapes match and a particular order is forced for both, use the more efficient CopyInto
Zero-sized arrays require nothing be done
This copy is based on matching C-order traversals of src and dst. By using two iterators, we can find maximal sub-chunks that can be processed at once.
Get all the values needed for the inner loop
Since buffering is disabled, we can cache the stride
Since buffering is disabled, we can cache the stride
Because buffering is disabled in the iterator, the inner loop strides will be the same throughout the iteration loop. Thus, we can pass them to this function to take advantage of contiguous strides, etc.
The tests did not trigger this code, so added a new function ndarray.setasflat to the Python exposure in order to test it.
Transfer the biggest amount that fits both
If we exhausted the dst block, refresh it
If we exhausted the src block, refresh it

Referenced by PyArray_FromArrayAttr().

NPY_NO_EXPORT PyObject* PyArray_EnsureAnyArray ( PyObject *  op)

Referenced by _strings_richcompare().

NPY_NO_EXPORT PyObject* PyArray_EnsureArray ( PyObject *  op)
end old calls
This is a quick wrapper around PyArray_FromAny(op, NULL, 0, 0, ENSUREARRAY)
that special cases Arrays and PyArray_Scalars up front It steals a reference to the object It also guarantees that the result is PyArray_Type Because it decrefs op if any conversion needs to take place so it can be used like PyArray_EnsureArray(some_function(...))

References NpyIter_Deallocate().

NPY_NO_EXPORT PyObject* PyArray_FromAny ( PyObject *  op,
PyArray_Descr newtype,
int  min_depth,
int  max_depth,
int  flags,
PyObject *  context 
)
Does not check for NPY_ARRAY_ENSURECOPY and NPY_ARRAY_NOTSWAPPED in flags
Steals a reference to newtype --- which can be NULL

This is the main code to make a NumPy array from a Python Object. It is called from many different places.
Get either the array or its parameters if it isn't an array
If the requested dtype is flexible, adapt it
If we got dimensions and dtype instead of an array
TODO: would be nice to do this too, but it's
a behavior change. It's also a bit tricky for downcasting to small integer and float types, and might be better to modify PyArray_AssignFromSequence and descr->f->setitem to have a 'casting' parameter and to check each value with scalar rules like in PyArray_MinScalarType.
if (!(flags&NPY_ARRAY_FORCECAST) && ndim > 0 &&

<blockquote class="first"> !PyArray_CanCastTo(dtype, newtype)) {</blockquote>

System Message: WARNING/2 (<string>, line 4) Block quote ends without a blank line; unexpected unindent.

Py_DECREF(dtype); Py_XDECREF(newtype); PyErr_SetString(PyExc_TypeError,

System Message: ERROR/3 (<string>, line 7) Unexpected indentation.

<blockquote> "object cannot be safely cast to array " "of required type");</blockquote>

System Message: WARNING/2 (<string>, line 9) Block quote ends without a blank line; unexpected unindent.

return NULL;

System Message: WARNING/2 (<string>, line 10) Definition list ends without a blank line; unexpected unindent.
}
Create an array and copy the data

Referenced by array_subscript_nice(), einsum_sub_op_from_str(), new_array_for_sum(), and PyArray_CompareLists().

NPY_NO_EXPORT PyObject* PyArray_FromArray ( PyArrayObject arr,
PyArray_Descr newtype,
int  flags 
)
steals reference to newtype --- acc. NULL

Can't cast unless ndim-0 array, NPY_ARRAY_FORCECAST is specified or the cast is safe.
Don't copy if sizes are compatible
If no copy then just increase the reference count and return the input
The desired output type is different than the input array type and copy was not specified

Referenced by PyArray_ArgMax(), and PyArray_TakeFrom().

NPY_NO_EXPORT PyObject* PyArray_FromArrayAttr ( PyObject *  op,
PyArray_Descr typecode,
PyObject *  context 
)
NPY_NO_EXPORT PyObject* PyArray_FromInterface ( PyObject *  input)

Get the memory from __array_data__ and __array_offset__
Get the shape
Get the typestring -- ignore array_descr
Get the strides

NPY_NO_EXPORT PyObject* PyArray_FromStructInterface ( PyObject *  input)
NPY_NO_EXPORT int PyArray_MoveInto ( PyArrayObject dst,
PyArrayObject src 
)
Move the memory of one array into another, allowing for overlapping data. <blockquote>
This is in general a difficult problem to solve efficiently, because strides can be negative. Consider "a = np.arange(3); a[::-1] = a", which previously produced the incorrect [0, 1, 0].
Instead of trying to be fancy, we simply check for overlap and make a temporary copy when one exists.
Returns 0 on success, negative on failure. </blockquote>

Performance fix for expresions like "a[1000:6000] += x". In this case, first an in-place add is done, followed by an assignment, equivalently expressed like this: <blockquote> tmp = a[1000:6000] # Calls array_subscript_nice in mapping.c np.add(tmp, x, tmp) a[1000:6000] = tmp # Calls array_ass_sub in mapping.c</blockquote>
In the assignment the underlying data type, shape, strides, and data pointers are identical, but src != dst because they are separately generated slices. By detecting this and skipping the redundant copy of values to themselves, we potentially give a big speed boost.
Note that we don't call EquivTypes, because usually the exact same dtype object will appear, and we don't want to slow things down with a complicated comparison. The comparisons are ordered to try and reject this with as little work as possible.
printf("Redundant copy operation detectedn");
A special case is when there is just one dimension with positive strides, and we pass that to CopyInto, which correctly handles it for most cases. It may still incorrectly handle copying of partially-overlapping data elements, where the data pointer was offset by a fraction of the element size.
Allocate a temporary copy array.

NPY_NO_EXPORT PyObject* PyArray_New ( PyTypeObject *  subtype,
int  nd,
npy_intp dims,
int  type_num,
npy_intp strides,
void *  data,
int  itemsize,
int  flags,
PyObject *  obj 
)
NPY_NO_EXPORT PyObject* PyArray_NewFromDescr ( PyTypeObject *  subtype,
PyArray_Descr descr,
int  nd,
npy_intp dims,
npy_intp strides,
void *  data,
int  flags,
PyObject *  obj 
)
Generic new array creation routine. <blockquote> steals a reference to descr (even on failure)</blockquote>

Check dimensions
Compare to PyArray_OverflowMultiplyList that returns 0 in this case.
Care needs to be taken to avoid integer overflow when multiplying the dimensions together to get the total size of the array. Hence before each multiplication we first check that the product will not exceed the maximum allowable size.

<

fill it in
we allow strides even when we create the memory, but be careful with this...
Allocate something even for zero-space arrays e.g. shape=(0,) -- otherwise buffer exposure (a.data) doesn't work as it should.
It is bad to have unitialized OBJECT pointers which could also be sub-fields of a VOID array
If data is passed in, this object won't own it by default. Caller must arrange for this to be reset if truly desired
If the strides were provided to the function, need to update the flags to get the right CONTIGUOUS, ALIGN properties
call the __array_finalize__ method if a subtype. If obj is NULL, then call method with Py_None
A C-function is stored here

Referenced by array_real_get(), array_swapaxes(), npyiter_flip_negative_strides(), PyArray_CastScalarDirect(), PyArray_CastToType(), PyArray_TakeFrom(), and PyArray_Zeros().