NPY_NO_EXPORT int _IsAligned(PyArrayObject *ap) { unsigned int i, aligned = 1; const unsigned int alignment = PyArray_DESCR(ap)->alignment; /* The special casing for STRING and VOID types was removed * in accordance with http://projects.scipy.org/numpy/ticket/1227 * It used to be that IsAligned always returned True for these * types, which is indeed the case when they are created using * PyArray_DescrConverter(), but not necessarily when using * PyArray_DescrAlignConverter(). */ if (alignment == 1) { return 1; } aligned = npy_is_aligned(PyArray_DATA(ap), alignment); for (i = 0; i < PyArray_NDIM(ap); i++) { #if NPY_RELAXED_STRIDES_CHECKING if (PyArray_DIM(ap, i) > 1) { /* if shape[i] == 1, the stride is never used */ aligned &= npy_is_aligned((void*)PyArray_STRIDES(ap)[i], alignment); } else if (PyArray_DIM(ap, i) == 0) { /* an array with zero elements is always aligned */ return 1; } #else /* not NPY_RELAXED_STRIDES_CHECKING */ aligned &= npy_is_aligned((void*)PyArray_STRIDES(ap)[i], alignment); #endif /* not NPY_RELAXED_STRIDES_CHECKING */ } return aligned != 0; }
NPY_NO_EXPORT int _IsAligned(PyArrayObject *ap) { unsigned int i; npy_uintp aligned; npy_uintp alignment = PyArray_DESCR(ap)->alignment; /* alignment 1 types should have a efficient alignment for copy loops */ if (PyArray_ISFLEXIBLE(ap) || PyArray_ISSTRING(ap)) { alignment = 16; } if (alignment == 1) { return 1; } aligned = (npy_uintp)PyArray_DATA(ap); for (i = 0; i < PyArray_NDIM(ap); i++) { #if NPY_RELAXED_STRIDES_CHECKING /* skip dim == 1 as it is not required to have stride 0 */ if (PyArray_DIM(ap, i) > 1) { /* if shape[i] == 1, the stride is never used */ aligned |= (npy_uintp)PyArray_STRIDES(ap)[i]; } else if (PyArray_DIM(ap, i) == 0) { /* an array with zero elements is always aligned */ return 1; } #else /* not NPY_RELAXED_STRIDES_CHECKING */ aligned |= (npy_uintp)PyArray_STRIDES(ap)[i]; #endif /* not NPY_RELAXED_STRIDES_CHECKING */ } return npy_is_aligned((void *)aligned, alignment); }
/* * Assigns the scalar value to every element of the destination raw array. * * Returns 0 on success, -1 on failure. */ NPY_NO_EXPORT int raw_array_assign_scalar(int ndim, npy_intp *shape, PyArray_Descr *dst_dtype, char *dst_data, npy_intp *dst_strides, PyArray_Descr *src_dtype, char *src_data) { int idim; npy_intp shape_it[NPY_MAXDIMS], dst_strides_it[NPY_MAXDIMS]; npy_intp coord[NPY_MAXDIMS]; PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; int aligned, needs_api = 0; npy_intp src_itemsize = src_dtype->elsize; NPY_BEGIN_THREADS_DEF; /* Check alignment */ aligned = raw_array_is_aligned(ndim, dst_data, dst_strides, dst_dtype->alignment); if (!npy_is_aligned(src_data, src_dtype->alignment)) { aligned = 0; } /* Use raw iteration with no heap allocation */ if (PyArray_PrepareOneRawArrayIter( ndim, shape, dst_data, dst_strides, &ndim, shape_it, &dst_data, dst_strides_it) < 0) { return -1; } /* Get the function to do the casting */ if (PyArray_GetDTypeTransferFunction(aligned, 0, dst_strides_it[0], src_dtype, dst_dtype, 0, &stransfer, &transferdata, &needs_api) != NPY_SUCCEED) { return -1; } if (!needs_api) { npy_intp nitems = 1, i; for (i = 0; i < ndim; i++) { nitems *= shape_it[i]; } NPY_BEGIN_THREADS_THRESHOLDED(nitems); } NPY_RAW_ITER_START(idim, ndim, coord, shape_it) { /* Process the innermost dimension */ stransfer(dst_data, dst_strides_it[0], src_data, 0, shape_it[0], src_itemsize, transferdata); } NPY_RAW_ITER_ONE_NEXT(idim, ndim, coord,
/* See array_assign.h for parameter documentation */ NPY_NO_EXPORT int raw_array_is_aligned(int ndim, npy_intp *shape, char *data, npy_intp *strides, int alignment) { /* * The code below expects the following: * * that alignment is a power of two, as required by the C standard. * * that casting from pointer to uintp gives a sensible representation * we can use bitwise operations on (perhaps *not* req. by C std, * but assumed by glibc so it should be fine) * * that casting stride from intp to uintp (to avoid dependence on the * signed int representation) preserves remainder wrt alignment, so * stride%a is the same as ((unsigned intp)stride)%a. Req. by C std. * * The code checks whether the lowest log2(alignment) bits of `data` * and all `strides` are 0, as this implies that * (data + n*stride)%alignment == 0 for all integers n. */ if (alignment > 1) { npy_uintp align_check = (npy_uintp)data; int i; for (i = 0; i < ndim; i++) { #if NPY_RELAXED_STRIDES_CHECKING /* skip dim == 1 as it is not required to have stride 0 */ if (shape[i] > 1) { /* if shape[i] == 1, the stride is never used */ align_check |= (npy_uintp)strides[i]; } else if (shape[i] == 0) { /* an array with zero elements is always aligned */ return 1; } #else /* not NPY_RELAXED_STRIDES_CHECKING */ align_check |= (npy_uintp)strides[i]; #endif /* not NPY_RELAXED_STRIDES_CHECKING */ } return npy_is_aligned((void *)align_check, alignment); } else if (alignment == 1) { return 1; } else { /* always return false for alignment == 0, which means cannot-be-aligned */ return 0; } }
NPY_NO_EXPORT int _IsAligned(PyArrayObject *ap) { unsigned int i; npy_uintp aligned; npy_uintp alignment = PyArray_DESCR(ap)->alignment; /* alignment 1 types should have a efficient alignment for copy loops */ if (PyArray_ISFLEXIBLE(ap) || PyArray_ISSTRING(ap)) { npy_intp itemsize = PyArray_ITEMSIZE(ap); /* power of two sizes may be loaded in larger moves */ if (((itemsize & (itemsize - 1)) == 0)) { alignment = itemsize > NPY_MAX_COPY_ALIGNMENT ? NPY_MAX_COPY_ALIGNMENT : itemsize; } else { /* if not power of two it will be accessed bytewise */ alignment = 1; } } if (alignment == 1) { return 1; } aligned = (npy_uintp)PyArray_DATA(ap); for (i = 0; i < PyArray_NDIM(ap); i++) { #if NPY_RELAXED_STRIDES_CHECKING /* skip dim == 1 as it is not required to have stride 0 */ if (PyArray_DIM(ap, i) > 1) { /* if shape[i] == 1, the stride is never used */ aligned |= (npy_uintp)PyArray_STRIDES(ap)[i]; } else if (PyArray_DIM(ap, i) == 0) { /* an array with zero elements is always aligned */ return 1; } #else /* not NPY_RELAXED_STRIDES_CHECKING */ aligned |= (npy_uintp)PyArray_STRIDES(ap)[i]; #endif /* not NPY_RELAXED_STRIDES_CHECKING */ } return npy_is_aligned((void *)aligned, alignment); }