Exemple #1
0
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;
}
Exemple #2
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);
}
Exemple #3
0
/*
 * 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,
Exemple #4
0
/* 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;
    }
}
Exemple #5
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);
}