diff options
| author | Mark Wiebe <mwwiebe@gmail.com> | 2011-08-07 07:26:53 -0700 |
|---|---|---|
| committer | Charles Harris <charlesr.harris@gmail.com> | 2011-08-27 07:26:53 -0600 |
| commit | c57efbc5ab9cd4ea6bc3b8d54f16b295a5d448bc (patch) | |
| tree | d8423e039fbee7c94744f59b7164fa6407af1241 /numpy | |
| parent | b769df7101b5e764ed5965067f35906a6d461380 (diff) | |
| download | numpy-c57efbc5ab9cd4ea6bc3b8d54f16b295a5d448bc.tar.gz | |
ENH: missingdata: Implement wheremasked scalar assignment with overwritena=True
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/core/SConscript | 1 | ||||
| -rw-r--r-- | numpy/core/setup.py | 1 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/array_assign.c | 289 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/array_assign.h | 32 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/array_assign_scalar.c | 434 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/convert.c | 2 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/ctors.c | 16 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 3 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/dtype_transfer.c | 136 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/item_selection.c | 2 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/lowlevel_strided_loops.c.src | 12 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/mapping.c | 6 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/na_mask.c | 40 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/na_mask.h | 11 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/nditer_api.c | 8 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/nditer_constr.c | 8 | ||||
| -rw-r--r-- | numpy/core/src/multiarray/nditer_impl.h | 4 | ||||
| -rw-r--r-- | numpy/core/src/private/lowlevel_strided_loops.h | 49 |
18 files changed, 649 insertions, 405 deletions
diff --git a/numpy/core/SConscript b/numpy/core/SConscript index 60fde8e30..56b3a04f3 100644 --- a/numpy/core/SConscript +++ b/numpy/core/SConscript @@ -444,6 +444,7 @@ if ENABLE_SEPARATE_COMPILATION: pjoin('src', 'multiarray', 'hashdescr.c'), pjoin('src', 'multiarray', 'arrayobject.c'), pjoin('src', 'multiarray', 'array_assign.c'), + pjoin('src', 'multiarray', 'array_assign_scalar.c'), pjoin('src', 'multiarray', 'datetime.c'), pjoin('src', 'multiarray', 'datetime_strings.c'), pjoin('src', 'multiarray', 'datetime_busday.c'), diff --git a/numpy/core/setup.py b/numpy/core/setup.py index c721cf219..c08fd1601 100644 --- a/numpy/core/setup.py +++ b/numpy/core/setup.py @@ -752,6 +752,7 @@ def configuration(parent_package='',top_path=None): join('src', 'multiarray', 'arrayobject.c'), join('src', 'multiarray', 'arraytypes.c.src'), join('src', 'multiarray', 'array_assign.c'), + join('src', 'multiarray', 'array_assign_scalar.c'), join('src', 'multiarray', 'buffer.c'), join('src', 'multiarray', 'calculation.c'), join('src', 'multiarray', 'common.c'), diff --git a/numpy/core/src/multiarray/array_assign.c b/numpy/core/src/multiarray/array_assign.c index e13f00333..4ac41ecdf 100644 --- a/numpy/core/src/multiarray/array_assign.c +++ b/numpy/core/src/multiarray/array_assign.c @@ -1,5 +1,6 @@ /* - * This file implements several array assignment routines. + * This file implements some helper functions for the array assignment + * routines. The actual assignment routines are in array_assign_*.c * * Written by Mark Wiebe (mwwiebe@gmail.com) * Copyright (c) 2011 by Enthought, Inc. @@ -17,22 +18,10 @@ #include "npy_config.h" #include "numpy/npy_3kcompat.h" -#include "convert_datatype.h" -#include "methods.h" -#include "shape.h" -#include "lowlevel_strided_loops.h" #include "array_assign.h" -/* - * Broadcasts strides to match the given dimensions. Can be used, - * for instance, to set up a raw iteration. - * - * 'strides_name' is used to produce an error message if the strides - * cannot be broadcast. - * - * Returns 0 on success, -1 on failure. - */ -static int +/* See array_assign.h for parameter documentation */ +NPY_NO_EXPORT int broadcast_strides(int ndim, npy_intp *shape, int strides_ndim, npy_intp *strides_shape, npy_intp *strides, char *strides_name, @@ -87,12 +76,9 @@ broadcast_error: { } } -/* - * Checks whether a data pointer + set of strides refers to a raw - * array which is fully aligned data. - */ -static int -strides_are_aligned(int ndim, char *data, npy_intp *strides, int alignment) +/* See array_assign.h for parameter documentation */ +NPY_NO_EXPORT int +raw_array_is_aligned(int ndim, char *data, npy_intp *strides, int alignment) { if (alignment > 1) { npy_intp align_check = (npy_intp)data; @@ -109,264 +95,3 @@ strides_are_aligned(int ndim, char *data, npy_intp *strides, int alignment) } } -/* - * Assigns the scalar value to every element of the destination raw array. - * - * Returns 0 on success, -1 on failure. - */ -static 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]; - NPY_BEGIN_THREADS_DEF; - - PyArray_StridedTransferFn *stransfer = NULL; - NpyAuxData *transferdata = NULL; - int aligned, needs_api = 0; - npy_intp src_itemsize = src_dtype->elsize; - - /* Check alignment */ - aligned = strides_are_aligned(ndim, dst_data, dst_strides, - dst_dtype->alignment); - if (((npy_intp)src_data & (src_dtype->alignment - 1)) != 0) { - 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_BEGIN_THREADS; - } - - 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, - shape_it, dst_data, dst_strides_it); - - if (!needs_api) { - NPY_END_THREADS; - } - - NPY_AUXDATA_FREE(transferdata); - - return (needs_api && PyErr_Occurred()) ? -1 : 0; -} - -/* - * Assigns the scalar value to every element of the destination raw array - * where the 'wheremask' value is True. - * - * Returns 0 on success, -1 on failure. - */ -static int -raw_array_wheremasked_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, - PyArray_Descr *wheremask_dtype, char *wheremask_data, - npy_intp *wheremask_strides) -{ - int idim; - npy_intp shape_it[NPY_MAXDIMS], dst_strides_it[NPY_MAXDIMS]; - npy_intp wheremask_strides_it[NPY_MAXDIMS]; - npy_intp coord[NPY_MAXDIMS]; - NPY_BEGIN_THREADS_DEF; - - PyArray_MaskedStridedTransferFn *stransfer = NULL; - NpyAuxData *transferdata = NULL; - int aligned, needs_api = 0; - npy_intp src_itemsize = src_dtype->elsize; - - /* Check alignment */ - aligned = strides_are_aligned(ndim, dst_data, dst_strides, - dst_dtype->alignment); - if (((npy_intp)src_data & (src_dtype->alignment - 1)) != 0) { - aligned = 0; - } - - /* Use raw iteration with no heap allocation */ - if (PyArray_PrepareTwoRawArrayIter( - ndim, shape, - dst_data, dst_strides, - wheremask_data, wheremask_strides, - &ndim, shape_it, - &dst_data, dst_strides_it, - &wheremask_data, wheremask_strides_it) < 0) { - return -1; - } - - /* Get the function to do the casting */ - if (PyArray_GetMaskedDTypeTransferFunction(aligned, - 0, dst_strides_it[0], wheremask_strides_it[0], - src_dtype, dst_dtype, wheremask_dtype, - 0, - &stransfer, &transferdata, - &needs_api) != NPY_SUCCEED) { - return -1; - } - - if (!needs_api) { - NPY_BEGIN_THREADS; - } - - NPY_RAW_ITER_START(idim, ndim, coord, shape_it) { - /* Process the innermost dimension */ - stransfer(dst_data, dst_strides_it[0], src_data, 0, - (npy_mask *)wheremask_data, wheremask_strides_it[0], - shape_it[0], src_itemsize, transferdata); - } NPY_RAW_ITER_TWO_NEXT(idim, ndim, coord, shape_it, - dst_data, dst_strides_it, - wheremask_data, wheremask_strides_it); - - if (!needs_api) { - NPY_END_THREADS; - } - - NPY_AUXDATA_FREE(transferdata); - - return (needs_api && PyErr_Occurred()) ? -1 : 0; -} - -/* See array_assign.h for documentation */ -NPY_NO_EXPORT int -array_assign_scalar(PyArrayObject *dst, - PyArray_Descr *src_dtype, char *src_data, - PyArrayObject *wheremask, - NPY_CASTING casting, npy_bool overwritena) -{ - int allocated_src_data = 0, dst_has_maskna = PyArray_HASMASKNA(dst); - npy_longlong scalarbuffer[4]; - - /* Check the casting rule */ - if (!can_cast_scalar_to(src_dtype, src_data, - PyArray_DESCR(dst), casting)) { - PyObject *errmsg; - errmsg = PyUString_FromString("Cannot cast scalar from "); - PyUString_ConcatAndDel(&errmsg, - PyObject_Repr((PyObject *)src_dtype)); - PyUString_ConcatAndDel(&errmsg, - PyUString_FromString(" to ")); - PyUString_ConcatAndDel(&errmsg, - PyObject_Repr((PyObject *)PyArray_DESCR(dst))); - PyUString_ConcatAndDel(&errmsg, - PyUString_FromFormat(" according to the rule %s", - npy_casting_to_string(casting))); - PyErr_SetObject(PyExc_TypeError, errmsg); - return -1; - } - - /* - * Make a copy of the src data if it's a different dtype than 'dst' - * or isn't aligned, and the destination we're copying to has - * more than one element. - */ - if ((!PyArray_EquivTypes(PyArray_DESCR(dst), src_dtype) || - ((npy_intp)src_data & (src_dtype->alignment - 1)) != 0) && - PyArray_SIZE(dst) > 1) { - char *tmp_src_data; - - /* - * Use a static buffer to store the aligned/cast version, - * or allocate some memory if more space is needed. - */ - if (sizeof(scalarbuffer) >= PyArray_DESCR(dst)->elsize) { - tmp_src_data = (char *)&scalarbuffer[0]; - } - else { - tmp_src_data = PyArray_malloc(PyArray_DESCR(dst)->elsize); - allocated_src_data = 1; - } - if (PyArray_CastRawArrays(1, src_data, tmp_src_data, 0, 0, - src_dtype, PyArray_DESCR(dst), 0) != NPY_SUCCEED) { - goto fail; - } - - /* Replace src_data/src_dtype */ - src_data = tmp_src_data; - src_dtype = PyArray_DESCR(dst); - } - - if (wheremask == NULL) { - /* A straightforward value assignment */ - if (overwritena || !dst_has_maskna) { - /* If assigning to an array with an NA mask, set to all exposed */ - if (dst_has_maskna) { - if (PyArray_AssignMaskNA(dst, 1) < 0) { - goto fail; - } - } - - /* Do the assignment with raw array iteration */ - if (raw_array_assign_scalar(PyArray_NDIM(dst), PyArray_DIMS(dst), - PyArray_DESCR(dst), PyArray_DATA(dst), PyArray_STRIDES(dst), - src_dtype, src_data) < 0) { - goto fail; - } - } - /* A value assignment without overwriting NA values */ - else { - } - } - else { - /* A straightforward where-masked assignment */ - if (overwritena || !dst_has_maskna) { - npy_intp wheremask_strides[NPY_MAXDIMS]; - - /* Broadcast the wheremask to 'dst' for raw iteration */ - if (broadcast_strides(PyArray_NDIM(dst), PyArray_DIMS(dst), - PyArray_NDIM(wheremask), PyArray_DIMS(wheremask), - PyArray_STRIDES(wheremask), "where mask", - wheremask_strides) < 0) { - goto fail; - } - - /* Do the masked assignment with raw array iteration */ - if (raw_array_wheremasked_assign_scalar( - PyArray_NDIM(dst), PyArray_DIMS(dst), - PyArray_DESCR(dst), PyArray_DATA(dst), PyArray_STRIDES(dst), - src_dtype, src_data, - PyArray_DESCR(wheremask), PyArray_DATA(wheremask), - wheremask_strides) < 0) { - goto fail; - } - } - /* A masked value assignment without overwriting NA values */ - else { - } - } - - if (allocated_src_data) { - PyArray_free(src_data); - } - - return 0; - -fail: - if (allocated_src_data) { - PyArray_free(src_data); - } - - return -1; -} diff --git a/numpy/core/src/multiarray/array_assign.h b/numpy/core/src/multiarray/array_assign.h index 68263c157..ddbcf6dae 100644 --- a/numpy/core/src/multiarray/array_assign.h +++ b/numpy/core/src/multiarray/array_assign.h @@ -68,4 +68,36 @@ array_assign_flat(PyArrayObject *dst, NPY_ORDER dst_order, PyArrayObject *wheremask, NPY_CASTING casting, npy_bool overwritena); + + + +/* + * Internal detail of how much to buffer during array assignments which + * need it. This is for more complex NA masking operations where masks + * need to be inverted or combined together. + */ +#define NPY_ARRAY_ASSIGN_BUFFERSIZE 8192 + +/* + * Broadcasts strides to match the given dimensions. Can be used, + * for instance, to set up a raw iteration. + * + * 'strides_name' is used to produce an error message if the strides + * cannot be broadcast. + * + * Returns 0 on success, -1 on failure. + */ +NPY_NO_EXPORT int +broadcast_strides(int ndim, npy_intp *shape, + int strides_ndim, npy_intp *strides_shape, npy_intp *strides, + char *strides_name, + npy_intp *out_strides); + +/* + * Checks whether a data pointer + set of strides refers to a raw + * array which is fully aligned data. + */ +NPY_NO_EXPORT int +raw_array_is_aligned(int ndim, char *data, npy_intp *strides, int alignment); + #endif diff --git a/numpy/core/src/multiarray/array_assign_scalar.c b/numpy/core/src/multiarray/array_assign_scalar.c new file mode 100644 index 000000000..502d8c733 --- /dev/null +++ b/numpy/core/src/multiarray/array_assign_scalar.c @@ -0,0 +1,434 @@ +/* + * This file implements assignment from a scalar to an ndarray. + * + * Written by Mark Wiebe (mwwiebe@gmail.com) + * Copyright (c) 2011 by Enthought, Inc. + * + * See LICENSE.txt for the license. + */ + +#define PY_SSIZE_T_CLEAN +#include <Python.h> + +#define NPY_NO_DEPRECATED_API +#define _MULTIARRAYMODULE +#include <numpy/ndarraytypes.h> + +#include "npy_config.h" +#include "numpy/npy_3kcompat.h" + +#include "convert_datatype.h" +#include "methods.h" +#include "shape.h" +#include "lowlevel_strided_loops.h" +#include "na_mask.h" + +#include "array_assign.h" + +/* + * Assigns the scalar value to every element of the destination raw array. + * + * Returns 0 on success, -1 on failure. + */ +static 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]; + NPY_BEGIN_THREADS_DEF; + + PyArray_StridedUnaryOp *stransfer = NULL; + NpyAuxData *transferdata = NULL; + int aligned, needs_api = 0; + npy_intp src_itemsize = src_dtype->elsize; + + /* Check alignment */ + aligned = raw_array_is_aligned(ndim, dst_data, dst_strides, + dst_dtype->alignment); + if (((npy_intp)src_data & (src_dtype->alignment - 1)) != 0) { + 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_BEGIN_THREADS; + } + + 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, + shape_it, dst_data, dst_strides_it); + + if (!needs_api) { + NPY_END_THREADS; + } + + NPY_AUXDATA_FREE(transferdata); + + return (needs_api && PyErr_Occurred()) ? -1 : 0; +} + +/* + * Assigns the scalar value to every element of the destination raw array + * where the 'wheremask' value is True. + * + * Returns 0 on success, -1 on failure. + */ +static int +raw_array_wheremasked_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, + PyArray_Descr *wheremask_dtype, char *wheremask_data, + npy_intp *wheremask_strides) +{ + int idim; + npy_intp shape_it[NPY_MAXDIMS], dst_strides_it[NPY_MAXDIMS]; + npy_intp wheremask_strides_it[NPY_MAXDIMS]; + npy_intp coord[NPY_MAXDIMS]; + NPY_BEGIN_THREADS_DEF; + + PyArray_MaskedStridedUnaryOp *stransfer = NULL; + NpyAuxData *transferdata = NULL; + int aligned, needs_api = 0; + npy_intp src_itemsize = src_dtype->elsize; + + /* Check alignment */ + aligned = raw_array_is_aligned(ndim, dst_data, dst_strides, + dst_dtype->alignment); + if (((npy_intp)src_data & (src_dtype->alignment - 1)) != 0) { + aligned = 0; + } + + /* Use raw iteration with no heap allocation */ + if (PyArray_PrepareTwoRawArrayIter( + ndim, shape, + dst_data, dst_strides, + wheremask_data, wheremask_strides, + &ndim, shape_it, + &dst_data, dst_strides_it, + &wheremask_data, wheremask_strides_it) < 0) { + return -1; + } + + /* Get the function to do the casting */ + if (PyArray_GetMaskedDTypeTransferFunction(aligned, + 0, dst_strides_it[0], wheremask_strides_it[0], + src_dtype, dst_dtype, wheremask_dtype, + 0, + &stransfer, &transferdata, + &needs_api) != NPY_SUCCEED) { + return -1; + } + + if (!needs_api) { + NPY_BEGIN_THREADS; + } + + NPY_RAW_ITER_START(idim, ndim, coord, shape_it) { + /* Process the innermost dimension */ + stransfer(dst_data, dst_strides_it[0], src_data, 0, + (npy_mask *)wheremask_data, wheremask_strides_it[0], + shape_it[0], src_itemsize, transferdata); + } NPY_RAW_ITER_TWO_NEXT(idim, ndim, coord, shape_it, + dst_data, dst_strides_it, + wheremask_data, wheremask_strides_it); + + if (!needs_api) { + NPY_END_THREADS; + } + + NPY_AUXDATA_FREE(transferdata); + + return (needs_api && PyErr_Occurred()) ? -1 : 0; +} + +/* + * Assigns the scalar value to every element of the destination raw array + * except for those which are masked as NA. + * + * Returns 0 on success, -1 on failure. + */ +static int +raw_array_assign_scalar_dont_overwritena(int ndim, npy_intp *shape, + PyArray_Descr *dst_dtype, char *dst_data, npy_intp *dst_strides, + PyArray_Descr *src_dtype, char *src_data, + PyArray_Descr *maskna_dtype, char *maskna_data, + npy_intp *maskna_strides) +{ + int idim; + npy_intp shape_it[NPY_MAXDIMS], dst_strides_it[NPY_MAXDIMS]; + npy_intp maskna_strides_it[NPY_MAXDIMS]; + npy_intp coord[NPY_MAXDIMS]; + NPY_BEGIN_THREADS_DEF; + + PyArray_MaskedStridedUnaryOp *stransfer = NULL; + NpyAuxData *transferdata = NULL; + int aligned, needs_api = 0; + npy_intp src_itemsize = src_dtype->elsize; + + PyArray_StridedUnaryOp *maskinv_stransfer = NULL; + NpyAuxData *maskinv_transferdata = NULL; + + char *maskna_buffer; + npy_intp maskna_itemsize; + + /* Check alignment */ + aligned = raw_array_is_aligned(ndim, dst_data, dst_strides, + dst_dtype->alignment); + if (((npy_intp)src_data & (src_dtype->alignment - 1)) != 0) { + aligned = 0; + } + + /* Use raw iteration with no heap allocation */ + if (PyArray_PrepareTwoRawArrayIter( + ndim, shape, + dst_data, dst_strides, + maskna_data, maskna_strides, + &ndim, shape_it, + &dst_data, dst_strides_it, + &maskna_data, maskna_strides_it) < 0) { + return -1; + } + + /* Allocate a buffer for inverting the mask */ + maskna_itemsize = maskna_dtype->elsize; + maskna_buffer = PyArray_malloc(NPY_ARRAY_ASSIGN_BUFFERSIZE * + maskna_itemsize); + if (maskna_buffer == NULL) { + PyErr_NoMemory(); + return -1; + } + + /* Get the function to do the casting */ + if (PyArray_GetMaskedDTypeTransferFunction(aligned, + 0, dst_strides_it[0], maskna_itemsize, + src_dtype, dst_dtype, maskna_dtype, + 0, + &stransfer, &transferdata, + &needs_api) != NPY_SUCCEED) { + PyArray_free(maskna_buffer); + return -1; + } + + /* Get the function to invert the mask */ + if (PyArray_GetMaskInversionFunction( + maskna_strides_it[0], maskna_dtype, + &maskinv_stransfer, &maskinv_transferdata) < 0) { + PyArray_free(maskna_buffer); + NPY_AUXDATA_FREE(transferdata); + return -1; + } + + if (!needs_api) { + NPY_BEGIN_THREADS; + } + + NPY_RAW_ITER_START(idim, ndim, coord, shape_it) { + npy_intp buffered_count, count; + /* Process the innermost dimension a buffer size at a time */ + count = shape_it[0]; + do { + buffered_count = shape_it[0] > NPY_ARRAY_ASSIGN_BUFFERSIZE + ? count + : NPY_ARRAY_ASSIGN_BUFFERSIZE; + /* TODO: invert the mask into the buffer here */ + stransfer(dst_data, dst_strides_it[0], src_data, 0, + (npy_mask *)maskna_buffer, maskna_itemsize, + buffered_count, src_itemsize, transferdata); + count -= buffered_count; + } while (count > 0); + } NPY_RAW_ITER_TWO_NEXT(idim, ndim, coord, shape_it, + dst_data, dst_strides_it, + maskna_data, maskna_strides_it); + + if (!needs_api) { + NPY_END_THREADS; + } + + NPY_AUXDATA_FREE(transferdata); + NPY_AUXDATA_FREE(maskinv_transferdata); + + return (needs_api && PyErr_Occurred()) ? -1 : 0; +} + + +/* See array_assign.h for documentation */ +NPY_NO_EXPORT int +array_assign_scalar(PyArrayObject *dst, + PyArray_Descr *src_dtype, char *src_data, + PyArrayObject *wheremask, + NPY_CASTING casting, npy_bool overwritena) +{ + int allocated_src_data = 0, dst_has_maskna = PyArray_HASMASKNA(dst); + npy_longlong scalarbuffer[4]; + + /* Check the casting rule */ + if (!can_cast_scalar_to(src_dtype, src_data, + PyArray_DESCR(dst), casting)) { + PyObject *errmsg; + errmsg = PyUString_FromString("Cannot cast scalar from "); + PyUString_ConcatAndDel(&errmsg, + PyObject_Repr((PyObject *)src_dtype)); + PyUString_ConcatAndDel(&errmsg, + PyUString_FromString(" to ")); + PyUString_ConcatAndDel(&errmsg, + PyObject_Repr((PyObject *)PyArray_DESCR(dst))); + PyUString_ConcatAndDel(&errmsg, + PyUString_FromFormat(" according to the rule %s", + npy_casting_to_string(casting))); + PyErr_SetObject(PyExc_TypeError, errmsg); + return -1; + } + + /* + * Make a copy of the src data if it's a different dtype than 'dst' + * or isn't aligned, and the destination we're copying to has + * more than one element. + */ + if ((!PyArray_EquivTypes(PyArray_DESCR(dst), src_dtype) || + ((npy_intp)src_data & (src_dtype->alignment - 1)) != 0) && + PyArray_SIZE(dst) > 1) { + char *tmp_src_data; + + /* + * Use a static buffer to store the aligned/cast version, + * or allocate some memory if more space is needed. + */ + if (sizeof(scalarbuffer) >= PyArray_DESCR(dst)->elsize) { + tmp_src_data = (char *)&scalarbuffer[0]; + } + else { + tmp_src_data = PyArray_malloc(PyArray_DESCR(dst)->elsize); + allocated_src_data = 1; + } + if (PyArray_CastRawArrays(1, src_data, tmp_src_data, 0, 0, + src_dtype, PyArray_DESCR(dst), 0) != NPY_SUCCEED) { + goto fail; + } + + /* Replace src_data/src_dtype */ + src_data = tmp_src_data; + src_dtype = PyArray_DESCR(dst); + } + + if (wheremask == NULL) { + /* A straightforward value assignment */ + if (overwritena || !dst_has_maskna) { + /* If assigning to an array with an NA mask, set to all exposed */ + if (dst_has_maskna) { + if (PyArray_AssignMaskNA(dst, 1) < 0) { + goto fail; + } + } + + /* Do the assignment with raw array iteration */ + if (raw_array_assign_scalar(PyArray_NDIM(dst), PyArray_DIMS(dst), + PyArray_DESCR(dst), PyArray_DATA(dst), PyArray_STRIDES(dst), + src_dtype, src_data) < 0) { + goto fail; + } + } + /* A value assignment without overwriting NA values */ + else { + if (raw_array_assign_scalar_dont_overwritena( + PyArray_NDIM(dst), PyArray_DIMS(dst), + PyArray_DESCR(dst), PyArray_DATA(dst), PyArray_STRIDES(dst), + src_dtype, src_data, + PyArray_MASKNA_DTYPE(dst), PyArray_MASKNA_DATA(dst), + PyArray_MASKNA_STRIDES(dst)) < 0) { + goto fail; + } + } + } + else { + if (PyArray_ContainsNA(wheremask)) { + if (!dst_has_maskna) { + PyErr_SetString(PyExc_ValueError, + "Cannot assign NA value to an array which " + "does not support NAs"); + goto fail; + } + else { + /* TODO: add support for this */ + PyErr_SetString(PyExc_ValueError, + "A where mask with NA values is not supported " + "yet"); + goto fail; + } + } + + /* A straightforward where-masked assignment */ + if (overwritena || !dst_has_maskna) { + npy_intp wheremask_strides[NPY_MAXDIMS]; + + /* If assigning to an array with an NA mask, set to all exposed */ + if (dst_has_maskna) { + /* + * TODO: If the where mask has NA values, this part + * changes too. + */ + if (PyArray_AssignMaskNA(dst, 1) < 0) { + goto fail; + } + } + + /* Broadcast the wheremask to 'dst' for raw iteration */ + if (broadcast_strides(PyArray_NDIM(dst), PyArray_DIMS(dst), + PyArray_NDIM(wheremask), PyArray_DIMS(wheremask), + PyArray_STRIDES(wheremask), "where mask", + wheremask_strides) < 0) { + goto fail; + } + + /* Do the masked assignment with raw array iteration */ + if (raw_array_wheremasked_assign_scalar( + PyArray_NDIM(dst), PyArray_DIMS(dst), + PyArray_DESCR(dst), PyArray_DATA(dst), PyArray_STRIDES(dst), + src_dtype, src_data, + PyArray_DESCR(wheremask), PyArray_DATA(wheremask), + wheremask_strides) < 0) { + goto fail; + } + } + /* A masked value assignment without overwriting NA values */ + else { + /* TODO: This function is next */ + } + } + + if (allocated_src_data) { + PyArray_free(src_data); + } + + return 0; + +fail: + if (allocated_src_data) { + PyArray_free(src_data); + } + + return -1; +} diff --git a/numpy/core/src/multiarray/convert.c b/numpy/core/src/multiarray/convert.c index 4a5ab207c..593c9f91f 100644 --- a/numpy/core/src/multiarray/convert.c +++ b/numpy/core/src/multiarray/convert.c @@ -377,7 +377,7 @@ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj) NPY_NO_EXPORT int PyArray_FillWithZero(PyArrayObject *a) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; PyArray_Descr *dtype = PyArray_DESCR(a); NpyIter *iter; diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 19d8513bb..452c52731 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -2821,10 +2821,10 @@ PyArray_EnsureAnyArray(PyObject *op) NPY_NO_EXPORT int PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order) { - PyArray_StridedTransferFn *stransfer = NULL; - PyArray_MaskedStridedTransferFn *maskedstransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; + PyArray_MaskedStridedUnaryOp *maskedstransfer = NULL; NpyAuxData *transferdata = NULL; - PyArray_StridedTransferFn *maskna_stransfer = NULL; + PyArray_StridedUnaryOp *maskna_stransfer = NULL; NpyAuxData *maskna_transferdata = NULL; NpyIter *dst_iter, *src_iter; @@ -3169,7 +3169,7 @@ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) /* Special case for simple strides and no NA mask */ if (!dst_has_maskna && PyArray_NDIM(dst) >= PyArray_NDIM(src) && PyArray_TRIVIALLY_ITERABLE_PAIR(dst, src)) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; char *dst_data, *src_data; npy_intp count, dst_stride, src_stride, src_itemsize; @@ -3221,7 +3221,7 @@ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) } /* Copying unmasked into unmasked */ else if (!dst_has_maskna) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; PyArrayObject *op[2]; npy_uint32 op_flags[2]; @@ -3332,7 +3332,7 @@ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) } /* Copying non NA-masked into NA-masked */ else if (!src_has_maskna) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; PyArrayObject *op[2]; npy_uint32 op_flags[2]; @@ -3462,7 +3462,7 @@ PyArray_CopyInto(PyArrayObject *dst, PyArrayObject *src) } /* Copying NA-masked into NA-masked */ else { - PyArray_MaskedStridedTransferFn *stransfer = NULL; + PyArray_MaskedStridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; PyArrayObject *op[2]; npy_uint32 op_flags[2]; @@ -3612,7 +3612,7 @@ NPY_NO_EXPORT int PyArray_MaskedCopyInto(PyArrayObject *dst, PyArrayObject *src, PyArrayObject *mask, NPY_CASTING casting) { - PyArray_MaskedStridedTransferFn *stransfer = NULL; + PyArray_MaskedStridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; NPY_BEGIN_THREADS_DEF; diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 4f832bd12..d5e937a67 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -714,13 +714,12 @@ validate_object_field_overlap(PyArray_Descr *dtype) PyObject *names, *fields, *key, *tup, *title; Py_ssize_t i, j, names_size; PyArray_Descr *fld_dtype, *fld2_dtype; - int fld_offset, fld2_offset, align; + int fld_offset, fld2_offset; /* Get some properties from the dtype */ names = dtype->names; names_size = PyTuple_GET_SIZE(names); fields = dtype->fields; - align = PyDataType_FLAGCHK(dtype, NPY_ALIGNED_STRUCT); for (i = 0; i < names_size; ++i) { key = PyTuple_GET_ITEM(names, i); diff --git a/numpy/core/src/multiarray/dtype_transfer.c b/numpy/core/src/multiarray/dtype_transfer.c index a4fe27842..650042902 100644 --- a/numpy/core/src/multiarray/dtype_transfer.c +++ b/numpy/core/src/multiarray/dtype_transfer.c @@ -57,7 +57,7 @@ static int get_decsrcref_transfer_function(int aligned, npy_intp src_stride, PyArray_Descr *src_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api); @@ -70,7 +70,7 @@ static int get_setdstzero_transfer_function(int aligned, npy_intp dst_stride, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api); @@ -81,7 +81,7 @@ get_setdstzero_transfer_function(int aligned, */ NPY_NO_EXPORT int get_bool_setdstone_transfer_function(npy_intp dst_stride, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *NPY_UNUSED(out_needs_api)); @@ -213,7 +213,7 @@ NPY_NO_EXPORT int PyArray_GetStridedZeroPadCopyFn(int aligned, npy_intp src_stride, npy_intp dst_stride, npy_intp src_itemsize, npy_intp dst_itemsize, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { if (src_itemsize == dst_itemsize) { @@ -250,7 +250,7 @@ PyArray_GetStridedZeroPadCopyFn(int aligned, /* Wraps a transfer function + data in alignment code */ typedef struct { NpyAuxData base; - PyArray_StridedTransferFn *wrapped, + PyArray_StridedUnaryOp *wrapped, *tobuffer, *frombuffer; NpyAuxData *wrappeddata, *todata, *fromdata; npy_intp src_itemsize, dst_itemsize; @@ -325,7 +325,7 @@ _strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride, NpyAuxData *data) { _align_wrap_data *d = (_align_wrap_data *)data; - PyArray_StridedTransferFn *wrapped = d->wrapped, + PyArray_StridedUnaryOp *wrapped = d->wrapped, *tobuffer = d->tobuffer, *frombuffer = d->frombuffer; npy_intp inner_src_itemsize = d->src_itemsize, @@ -369,7 +369,7 @@ _strided_to_strided_contig_align_wrap_init_dest(char *dst, npy_intp dst_stride, NpyAuxData *data) { _align_wrap_data *d = (_align_wrap_data *)data; - PyArray_StridedTransferFn *wrapped = d->wrapped, + PyArray_StridedUnaryOp *wrapped = d->wrapped, *tobuffer = d->tobuffer, *frombuffer = d->frombuffer; npy_intp inner_src_itemsize = d->src_itemsize, @@ -426,11 +426,11 @@ _strided_to_strided_contig_align_wrap_init_dest(char *dst, npy_intp dst_stride, NPY_NO_EXPORT int wrap_aligned_contig_transfer_function( npy_intp src_itemsize, npy_intp dst_itemsize, - PyArray_StridedTransferFn *tobuffer, NpyAuxData *todata, - PyArray_StridedTransferFn *frombuffer, NpyAuxData *fromdata, - PyArray_StridedTransferFn *wrapped, NpyAuxData *wrappeddata, + PyArray_StridedUnaryOp *tobuffer, NpyAuxData *todata, + PyArray_StridedUnaryOp *frombuffer, NpyAuxData *fromdata, + PyArray_StridedUnaryOp *wrapped, NpyAuxData *wrappeddata, int init_dest, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { _align_wrap_data *data; @@ -524,7 +524,7 @@ wrap_copy_swap_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *dtype, int should_swap, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { _wrap_copy_swap_data *data; @@ -655,7 +655,7 @@ static int get_nbo_cast_numeric_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, int src_type_num, int dst_type_num, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { /* Emit a warning if complex imaginary is being cast away */ @@ -943,7 +943,7 @@ static int get_nbo_cast_datetime_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { PyArray_DatetimeMetaData *src_meta, *dst_meta; @@ -1019,7 +1019,7 @@ static int get_nbo_datetime_to_string_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { PyArray_DatetimeMetaData *src_meta; @@ -1064,12 +1064,12 @@ static int get_datetime_to_unicode_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { NpyAuxData *castdata = NULL, *todata = NULL, *fromdata = NULL; - PyArray_StridedTransferFn *caststransfer, *tobuffer, *frombuffer; + PyArray_StridedUnaryOp *caststransfer, *tobuffer, *frombuffer; PyArray_Descr *str_dtype; /* Get an ASCII string data type, adapted to match the UNICODE one */ @@ -1134,7 +1134,7 @@ static int get_nbo_string_to_datetime_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { PyArray_DatetimeMetaData *dst_meta; @@ -1186,12 +1186,12 @@ static int get_unicode_to_datetime_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { NpyAuxData *castdata = NULL, *todata = NULL, *fromdata = NULL; - PyArray_StridedTransferFn *caststransfer, *tobuffer, *frombuffer; + PyArray_StridedUnaryOp *caststransfer, *tobuffer, *frombuffer; PyArray_Descr *str_dtype; /* Get an ASCII string data type, adapted to match the UNICODE one */ @@ -1258,7 +1258,7 @@ get_nbo_cast_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api, int *out_needs_wrap) @@ -1465,11 +1465,11 @@ get_cast_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { - PyArray_StridedTransferFn *caststransfer; + PyArray_StridedUnaryOp *caststransfer; NpyAuxData *castdata, *todata = NULL, *fromdata = NULL; int needs_wrap = 0; npy_intp src_itemsize = src_dtype->elsize, @@ -1506,7 +1506,7 @@ get_cast_transfer_function(int aligned, } /* Otherwise, we have to copy and/or swap to aligned temporaries */ else { - PyArray_StridedTransferFn *tobuffer, *frombuffer; + PyArray_StridedUnaryOp *tobuffer, *frombuffer; /* Get the copy/swap operation from src */ PyArray_GetDTypeCopySwapFn(aligned, @@ -1553,11 +1553,11 @@ get_cast_transfer_function(int aligned, /* Copies 1 element to N contiguous elements */ typedef struct { NpyAuxData base; - PyArray_StridedTransferFn *stransfer; + PyArray_StridedUnaryOp *stransfer; NpyAuxData *data; npy_intp N, dst_itemsize; /* If this is non-NULL the source type has references needing a decref */ - PyArray_StridedTransferFn *stransfer_finish_src; + PyArray_StridedUnaryOp *stransfer_finish_src; NpyAuxData *data_finish_src; } _one_to_n_data; @@ -1608,7 +1608,7 @@ _strided_to_strided_one_to_n(char *dst, npy_intp dst_stride, NpyAuxData *data) { _one_to_n_data *d = (_one_to_n_data *)data; - PyArray_StridedTransferFn *subtransfer = d->stransfer; + PyArray_StridedUnaryOp *subtransfer = d->stransfer; NpyAuxData *subdata = d->data; npy_intp subN = d->N, dst_itemsize = d->dst_itemsize; @@ -1631,7 +1631,7 @@ _strided_to_strided_one_to_n_with_finish(char *dst, npy_intp dst_stride, NpyAuxData *data) { _one_to_n_data *d = (_one_to_n_data *)data; - PyArray_StridedTransferFn *subtransfer = d->stransfer, + PyArray_StridedUnaryOp *subtransfer = d->stransfer, *stransfer_finish_src = d->stransfer_finish_src; NpyAuxData *subdata = d->data, *data_finish_src = data_finish_src; npy_intp subN = d->N, dst_itemsize = d->dst_itemsize; @@ -1662,13 +1662,13 @@ _strided_to_strided_one_to_n_with_finish(char *dst, npy_intp dst_stride, */ static int wrap_transfer_function_one_to_n( - PyArray_StridedTransferFn *stransfer_inner, + PyArray_StridedUnaryOp *stransfer_inner, NpyAuxData *data_inner, - PyArray_StridedTransferFn *stransfer_finish_src, + PyArray_StridedUnaryOp *stransfer_finish_src, NpyAuxData *data_finish_src, npy_intp dst_itemsize, npy_intp N, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { _one_to_n_data *data; @@ -1706,11 +1706,11 @@ get_one_to_n_transfer_function(int aligned, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, npy_intp N, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { - PyArray_StridedTransferFn *stransfer, *stransfer_finish_src = NULL; + PyArray_StridedUnaryOp *stransfer, *stransfer_finish_src = NULL; NpyAuxData *data, *data_finish_src = NULL; /* @@ -1759,7 +1759,7 @@ get_one_to_n_transfer_function(int aligned, /* Copies N contiguous elements to N contiguous elements */ typedef struct { NpyAuxData base; - PyArray_StridedTransferFn *stransfer; + PyArray_StridedUnaryOp *stransfer; NpyAuxData *data; npy_intp N, src_itemsize, dst_itemsize; } _n_to_n_data; @@ -1802,7 +1802,7 @@ _strided_to_strided_n_to_n(char *dst, npy_intp dst_stride, NpyAuxData *data) { _n_to_n_data *d = (_n_to_n_data *)data; - PyArray_StridedTransferFn *subtransfer = d->stransfer; + PyArray_StridedUnaryOp *subtransfer = d->stransfer; NpyAuxData *subdata = d->data; npy_intp subN = d->N, src_subitemsize = d->src_itemsize, dst_subitemsize = d->dst_itemsize; @@ -1826,7 +1826,7 @@ _contig_to_contig_n_to_n(char *dst, npy_intp NPY_UNUSED(dst_stride), NpyAuxData *data) { _n_to_n_data *d = (_n_to_n_data *)data; - PyArray_StridedTransferFn *subtransfer = d->stransfer; + PyArray_StridedUnaryOp *subtransfer = d->stransfer; NpyAuxData *subdata = d->data; npy_intp subN = d->N, src_subitemsize = d->src_itemsize, dst_subitemsize = d->dst_itemsize; @@ -1843,12 +1843,12 @@ _contig_to_contig_n_to_n(char *dst, npy_intp NPY_UNUSED(dst_stride), */ static int wrap_transfer_function_n_to_n( - PyArray_StridedTransferFn *stransfer_inner, + PyArray_StridedUnaryOp *stransfer_inner, NpyAuxData *data_inner, npy_intp src_stride, npy_intp dst_stride, npy_intp src_itemsize, npy_intp dst_itemsize, npy_intp N, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata) { _n_to_n_data *data; @@ -1889,11 +1889,11 @@ get_n_to_n_transfer_function(int aligned, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, npy_intp N, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { - PyArray_StridedTransferFn *stransfer; + PyArray_StridedUnaryOp *stransfer; NpyAuxData *data; /* @@ -1931,12 +1931,12 @@ typedef struct { /* Copies element with subarray broadcasting */ typedef struct { NpyAuxData base; - PyArray_StridedTransferFn *stransfer; + PyArray_StridedUnaryOp *stransfer; NpyAuxData *data; npy_intp src_N, dst_N, src_itemsize, dst_itemsize; - PyArray_StridedTransferFn *stransfer_decsrcref; + PyArray_StridedUnaryOp *stransfer_decsrcref; NpyAuxData *data_decsrcref; - PyArray_StridedTransferFn *stransfer_decdstref; + PyArray_StridedUnaryOp *stransfer_decdstref; NpyAuxData *data_decdstref; /* This gets a run-length encoded representation of the transfer */ npy_intp run_count; @@ -2004,7 +2004,7 @@ _strided_to_strided_subarray_broadcast(char *dst, npy_intp dst_stride, NpyAuxData *data) { _subarray_broadcast_data *d = (_subarray_broadcast_data *)data; - PyArray_StridedTransferFn *subtransfer = d->stransfer; + PyArray_StridedUnaryOp *subtransfer = d->stransfer; NpyAuxData *subdata = d->data; npy_intp run, run_count = d->run_count, src_subitemsize = d->src_itemsize, @@ -2045,11 +2045,11 @@ _strided_to_strided_subarray_broadcast_withrefs(char *dst, npy_intp dst_stride, NpyAuxData *data) { _subarray_broadcast_data *d = (_subarray_broadcast_data *)data; - PyArray_StridedTransferFn *subtransfer = d->stransfer; + PyArray_StridedUnaryOp *subtransfer = d->stransfer; NpyAuxData *subdata = d->data; - PyArray_StridedTransferFn *stransfer_decsrcref = d->stransfer_decsrcref; + PyArray_StridedUnaryOp *stransfer_decsrcref = d->stransfer_decsrcref; NpyAuxData *data_decsrcref = d->data_decsrcref; - PyArray_StridedTransferFn *stransfer_decdstref = d->stransfer_decdstref; + PyArray_StridedUnaryOp *stransfer_decdstref = d->stransfer_decdstref; NpyAuxData *data_decdstref = d->data_decdstref; npy_intp run, run_count = d->run_count, src_subitemsize = d->src_itemsize, @@ -2102,7 +2102,7 @@ get_subarray_broadcast_transfer_function(int aligned, npy_intp src_size, npy_intp dst_size, PyArray_Dims src_shape, PyArray_Dims dst_shape, int move_references, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -2289,7 +2289,7 @@ get_subarray_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -2386,7 +2386,7 @@ get_subarray_transfer_function(int aligned, /**************************** COPY FIELDS *******************************/ typedef struct { npy_intp src_offset, dst_offset, src_itemsize; - PyArray_StridedTransferFn *stransfer; + PyArray_StridedUnaryOp *stransfer; NpyAuxData *data; } _single_field_transfer; @@ -2497,7 +2497,7 @@ get_fields_transfer_function(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -2869,7 +2869,7 @@ static int get_decsrcref_fields_transfer_function(int aligned, npy_intp src_stride, PyArray_Descr *src_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -2940,7 +2940,7 @@ static int get_setdestzero_fields_transfer_function(int aligned, npy_intp dst_stride, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -3005,11 +3005,11 @@ get_setdestzero_fields_transfer_function(int aligned, typedef struct { NpyAuxData base; /* The transfer function being wrapped */ - PyArray_StridedTransferFn *stransfer; + PyArray_StridedUnaryOp *stransfer; NpyAuxData *transferdata; /* The src decref function if necessary */ - PyArray_StridedTransferFn *decsrcref_stransfer; + PyArray_StridedUnaryOp *decsrcref_stransfer; NpyAuxData *decsrcref_transferdata; } _masked_wrapper_transfer_data; @@ -3067,7 +3067,7 @@ void _strided_masked_wrapper_decsrcref_transfer_function( _masked_wrapper_transfer_data *d = (_masked_wrapper_transfer_data *)transferdata; npy_intp subloopsize; - PyArray_StridedTransferFn *unmasked_stransfer, *decsrcref_stransfer; + PyArray_StridedUnaryOp *unmasked_stransfer, *decsrcref_stransfer; NpyAuxData *unmasked_transferdata, *decsrcref_transferdata; unmasked_stransfer = d->stransfer; @@ -3112,7 +3112,7 @@ void _strided_masked_wrapper_transfer_function( _masked_wrapper_transfer_data *d = (_masked_wrapper_transfer_data *)transferdata; npy_intp subloopsize; - PyArray_StridedTransferFn *unmasked_stransfer; + PyArray_StridedUnaryOp *unmasked_stransfer; NpyAuxData *unmasked_transferdata; unmasked_stransfer = d->stransfer; @@ -3177,7 +3177,7 @@ _null_to_contig_set_bool_one(char *dst, /* Only for the bool type, sets the destination to 1 */ NPY_NO_EXPORT int get_bool_setdstone_transfer_function(npy_intp dst_stride, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *NPY_UNUSED(out_needs_api)) { @@ -3274,7 +3274,7 @@ NPY_NO_EXPORT int get_setdstzero_transfer_function(int aligned, npy_intp dst_stride, PyArray_Descr *dst_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -3314,7 +3314,7 @@ get_setdstzero_transfer_function(int aligned, else if (PyDataType_HASSUBARRAY(dst_dtype)) { PyArray_Dims dst_shape = {NULL, -1}; npy_intp dst_size = 1; - PyArray_StridedTransferFn *contig_stransfer; + PyArray_StridedUnaryOp *contig_stransfer; NpyAuxData *contig_data; if (out_needs_api) { @@ -3401,7 +3401,7 @@ NPY_NO_EXPORT int get_decsrcref_transfer_function(int aligned, npy_intp src_stride, PyArray_Descr *src_dtype, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -3427,7 +3427,7 @@ get_decsrcref_transfer_function(int aligned, else if (PyDataType_HASSUBARRAY(src_dtype)) { PyArray_Dims src_shape = {NULL, -1}; npy_intp src_size = 1; - PyArray_StridedTransferFn *stransfer; + PyArray_StridedUnaryOp *stransfer; NpyAuxData *data; if (out_needs_api) { @@ -3483,7 +3483,7 @@ NPY_NO_EXPORT int PyArray_GetDTypeCopySwapFn(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *dtype, - PyArray_StridedTransferFn **outstransfer, + PyArray_StridedUnaryOp **outstransfer, NpyAuxData **outtransferdata) { npy_intp itemsize = dtype->elsize; @@ -3529,7 +3529,7 @@ PyArray_GetDTypeTransferFunction(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { @@ -3755,11 +3755,11 @@ PyArray_GetMaskedDTypeTransferFunction(int aligned, PyArray_Descr *dst_dtype, PyArray_Descr *mask_dtype, int move_references, - PyArray_MaskedStridedTransferFn **out_stransfer, + PyArray_MaskedStridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; _masked_wrapper_transfer_data *data; @@ -3831,7 +3831,7 @@ PyArray_CastRawArrays(npy_intp count, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; int aligned = 1, needs_api = 0; @@ -4110,7 +4110,7 @@ PyArray_CastRawNDimArrays(int ndim, npy_intp *shape, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; int idim; npy_intp src_align, dst_align; diff --git a/numpy/core/src/multiarray/item_selection.c b/numpy/core/src/multiarray/item_selection.c index 8e861d460..8a38f4531 100644 --- a/numpy/core/src/multiarray/item_selection.c +++ b/numpy/core/src/multiarray/item_selection.c @@ -138,7 +138,7 @@ PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int axis, if (use_maskna) { char *dst_maskna = NULL, *src_maskna = NULL; npy_intp itemsize = PyArray_DESCR(obj)->elsize; - PyArray_MaskedStridedTransferFn *maskedstransfer = NULL; + PyArray_MaskedStridedUnaryOp *maskedstransfer = NULL; NpyAuxData *transferdata = NULL; int needs_api = 0; diff --git a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src index 4476e0a35..82cf49ea2 100644 --- a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src +++ b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src @@ -311,7 +311,7 @@ _contig_to_contig(char *dst, npy_intp NPY_UNUSED(dst_stride), } -NPY_NO_EXPORT PyArray_StridedTransferFn * +NPY_NO_EXPORT PyArray_StridedUnaryOp * PyArray_GetStridedCopyFn(int aligned, npy_intp src_stride, npy_intp dst_stride, npy_intp itemsize) { @@ -466,7 +466,7 @@ PyArray_GetStridedCopyFn(int aligned, npy_intp src_stride, * #not_pair = 1, 0# */ -NPY_NO_EXPORT PyArray_StridedTransferFn * +NPY_NO_EXPORT PyArray_StridedUnaryOp * @function@(int aligned, npy_intp src_stride, npy_intp dst_stride, npy_intp itemsize) { @@ -848,7 +848,7 @@ static void /**end repeat**/ -NPY_NO_EXPORT PyArray_StridedTransferFn * +NPY_NO_EXPORT PyArray_StridedUnaryOp * PyArray_GetStridedNumericCastFn(int aligned, npy_intp src_stride, npy_intp dst_stride, int src_type_num, int dst_type_num) @@ -929,7 +929,7 @@ PyArray_TransferNDimToStrided(npy_intp ndim, npy_intp *coords, npy_intp coords_inc, npy_intp *shape, npy_intp shape_inc, npy_intp count, npy_intp src_itemsize, - PyArray_StridedTransferFn *stransfer, + PyArray_StridedUnaryOp *stransfer, NpyAuxData *data) { npy_intp i, M, N, coord0, shape0, src_stride0, coord1, shape1, src_stride1; @@ -1048,7 +1048,7 @@ PyArray_TransferStridedToNDim(npy_intp ndim, npy_intp *coords, npy_intp coords_inc, npy_intp *shape, npy_intp shape_inc, npy_intp count, npy_intp src_itemsize, - PyArray_StridedTransferFn *stransfer, + PyArray_StridedUnaryOp *stransfer, NpyAuxData *data) { npy_intp i, M, N, coord0, shape0, dst_stride0, coord1, shape1, dst_stride1; @@ -1168,7 +1168,7 @@ PyArray_TransferMaskedStridedToNDim(npy_intp ndim, npy_intp *coords, npy_intp coords_inc, npy_intp *shape, npy_intp shape_inc, npy_intp count, npy_intp src_itemsize, - PyArray_MaskedStridedTransferFn *stransfer, + PyArray_MaskedStridedUnaryOp *stransfer, NpyAuxData *data) { npy_intp i, M, N, coord0, shape0, dst_stride0, coord1, shape1, dst_stride1; diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c index 30f00576b..4d37da61c 100644 --- a/numpy/core/src/multiarray/mapping.c +++ b/numpy/core/src/multiarray/mapping.c @@ -762,7 +762,7 @@ array_boolean_subscript(PyArrayObject *self, PyArrayObject *op[2] = {self, bmask}; npy_uint32 flags, op_flags[2]; npy_intp fixed_strides[3]; - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; NpyIter_IterNextFunc *iternext; @@ -1068,7 +1068,7 @@ array_ass_boolean_subscript(PyArrayObject *self, /* Regular inner loop */ if (!self_has_maskna) { - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; npy_intp self_stride = innerstrides[0]; npy_intp bmask_stride = innerstrides[1]; @@ -1119,7 +1119,7 @@ array_ass_boolean_subscript(PyArrayObject *self, } /* NA masked inner loop */ else { - PyArray_MaskedStridedTransferFn *stransfer = NULL; + PyArray_MaskedStridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; npy_intp i; npy_intp self_stride = innerstrides[0]; diff --git a/numpy/core/src/multiarray/na_mask.c b/numpy/core/src/multiarray/na_mask.c index 286fe5c1b..d6c8d1463 100644 --- a/numpy/core/src/multiarray/na_mask.c +++ b/numpy/core/src/multiarray/na_mask.c @@ -577,3 +577,43 @@ printf("\n"); return 0; } + +static void +_strided_bool_mask_inversion(char *dst, npy_intp dst_stride, + char *src, npy_intp src_stride, + npy_intp N, npy_intp NPY_UNUSED(src_itemsize), + NpyAuxData *NPY_UNUSED(data)) +{ + while (N > 0) { + *dst = !(*src); + dst += dst_stride; + src += src_stride; + --N; + } +} + +NPY_NO_EXPORT int +PyArray_GetMaskInversionFunction(npy_intp mask_stride, + PyArray_Descr *mask_dtype, + PyArray_StridedUnaryOp **out_stransfer, + NpyAuxData **out_transferdata) +{ + /* Will use the transferdata with the field version */ + if (PyDataType_HASFIELDS(mask_dtype)) { + PyErr_SetString(PyExc_RuntimeError, + "field-based masks are not supported yet"); + return -1; + } + + if (mask_dtype->type_num != NPY_BOOL && mask_dtype->type_num != NPY_MASK) { + PyErr_SetString(PyExc_RuntimeError, + "unsupported data type for mask"); + return -1; + } + + /* TODO: Specialize for contiguous data */ + + *out_stransfer = &_strided_bool_mask_inversion; + *out_transferdata = NULL; + return 0; +} diff --git a/numpy/core/src/multiarray/na_mask.h b/numpy/core/src/multiarray/na_mask.h index 22944b781..d0538cda3 100644 --- a/numpy/core/src/multiarray/na_mask.h +++ b/numpy/core/src/multiarray/na_mask.h @@ -1,6 +1,8 @@ #ifndef _NPY_PRIVATE__NA_MASK_H_ #define _NPY_PRIVATE__NA_MASK_H_ +#include "lowlevel_strided_loops.h" + /* * Assigns the given NA value to all the elements in the array. * @@ -26,4 +28,13 @@ PyArray_AssignMaskNA(PyArrayObject *arr, npy_mask maskvalue); NPY_NO_EXPORT PyObject * PyArray_IsNA(PyObject *obj); +/* + * Gets a strided unary operation which inverts mask values. + */ +NPY_NO_EXPORT int +PyArray_GetMaskInversionFunction(npy_intp mask_stride, + PyArray_Descr *mask_dtype, + PyArray_StridedUnaryOp **out_stransfer, + NpyAuxData **out_transferdata); + #endif diff --git a/numpy/core/src/multiarray/nditer_api.c b/numpy/core/src/multiarray/nditer_api.c index b3402129f..0c925d8b9 100644 --- a/numpy/core/src/multiarray/nditer_api.c +++ b/numpy/core/src/multiarray/nditer_api.c @@ -1838,7 +1838,7 @@ npyiter_copy_from_buffers(NpyIter *iter) npy_intp reduce_outerdim = 0; npy_intp *reduce_outerstrides = NULL; - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; npy_intp axisdata_incr = NIT_AXISDATA_SIZEOF(itflags, ndim, nop) / @@ -1962,7 +1962,7 @@ npyiter_copy_from_buffers(NpyIter *iter) dst_coords, axisdata_incr, dst_shape, axisdata_incr, op_transfersize, dtypes[iop]->elsize, - (PyArray_MaskedStridedTransferFn *)stransfer, + (PyArray_MaskedStridedUnaryOp *)stransfer, transferdata); } /* WRITEMASKED operand */ @@ -1989,7 +1989,7 @@ npyiter_copy_from_buffers(NpyIter *iter) dst_coords, axisdata_incr, dst_shape, axisdata_incr, op_transfersize, dtypes[iop]->elsize, - (PyArray_MaskedStridedTransferFn *)stransfer, + (PyArray_MaskedStridedUnaryOp *)stransfer, transferdata); } /* Regular operand */ @@ -2064,7 +2064,7 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) npy_intp *reduce_outerstrides = NULL; char **reduce_outerptrs = NULL; - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; /* diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c index 9f7b7948d..a7f3ab30e 100644 --- a/numpy/core/src/multiarray/nditer_constr.c +++ b/numpy/core/src/multiarray/nditer_constr.c @@ -3355,13 +3355,13 @@ npyiter_allocate_transfer_functions(NpyIter *iter) PyArrayObject **op = NIT_OPERANDS(iter); PyArray_Descr **op_dtype = NIT_DTYPES(iter); npy_intp *strides = NAD_STRIDES(axisdata), op_stride; - PyArray_StridedTransferFn **readtransferfn = NBF_READTRANSFERFN(bufferdata), + PyArray_StridedUnaryOp **readtransferfn = NBF_READTRANSFERFN(bufferdata), **writetransferfn = NBF_WRITETRANSFERFN(bufferdata); NpyAuxData **readtransferdata = NBF_READTRANSFERDATA(bufferdata), **writetransferdata = NBF_WRITETRANSFERDATA(bufferdata); npy_int8 *maskna_indices = NIT_MASKNA_INDICES(iter); - PyArray_StridedTransferFn *stransfer = NULL; + PyArray_StridedUnaryOp *stransfer = NULL; NpyAuxData *transferdata = NULL; int needs_api = 0; @@ -3433,7 +3433,7 @@ npyiter_allocate_transfer_functions(NpyIter *iter) op_orig_dtype, mask_dtype, move_references, - (PyArray_MaskedStridedTransferFn **)&stransfer, + (PyArray_MaskedStridedUnaryOp **)&stransfer, &transferdata, &needs_api) != NPY_SUCCEED) { goto fail; @@ -3460,7 +3460,7 @@ npyiter_allocate_transfer_functions(NpyIter *iter) op_orig_dtype, mask_dtype, move_references, - (PyArray_MaskedStridedTransferFn **)&stransfer, + (PyArray_MaskedStridedUnaryOp **)&stransfer, &transferdata, &needs_api) != NPY_SUCCEED) { goto fail; diff --git a/numpy/core/src/multiarray/nditer_impl.h b/numpy/core/src/multiarray/nditer_impl.h index 753b8188f..de361470d 100644 --- a/numpy/core/src/multiarray/nditer_impl.h +++ b/numpy/core/src/multiarray/nditer_impl.h @@ -251,11 +251,11 @@ struct NpyIter_BD { (&(bufferdata)->bd_flexdata + 2*(nop))) #define NBF_REDUCE_OUTERPTRS(bufferdata) ((char **) \ (&(bufferdata)->bd_flexdata + 3*(nop))) -#define NBF_READTRANSFERFN(bufferdata) ((PyArray_StridedTransferFn **) \ +#define NBF_READTRANSFERFN(bufferdata) ((PyArray_StridedUnaryOp **) \ (&(bufferdata)->bd_flexdata + 4*(nop))) #define NBF_READTRANSFERDATA(bufferdata) ((NpyAuxData **) \ (&(bufferdata)->bd_flexdata + 5*(nop))) -#define NBF_WRITETRANSFERFN(bufferdata) ((PyArray_StridedTransferFn **) \ +#define NBF_WRITETRANSFERFN(bufferdata) ((PyArray_StridedUnaryOp **) \ (&(bufferdata)->bd_flexdata + 6*(nop))) #define NBF_WRITETRANSFERDATA(bufferdata) ((NpyAuxData **) \ (&(bufferdata)->bd_flexdata + 7*(nop))) diff --git a/numpy/core/src/private/lowlevel_strided_loops.h b/numpy/core/src/private/lowlevel_strided_loops.h index a4ba0526d..f25019015 100644 --- a/numpy/core/src/private/lowlevel_strided_loops.h +++ b/numpy/core/src/private/lowlevel_strided_loops.h @@ -8,12 +8,13 @@ */ /* - * This function pointer is for functions that transfer an arbitrarily strided - * input to a an arbitrarily strided output. It may be a fully general - * function, or a specialized function when the strides or item size - * have special values. + * This function pointer is for unary operations that input an + * arbitrarily strided one-dimensional array segment and output + * an arbitrarily strided array segment of the same size. + * It may be a fully general function, or a specialized function + * when the strides or item size have particular known values. * - * Examples of transfer functions are a straight copy, a byte-swap, + * Examples of unary operations are a straight copy, a byte-swap, * and a casting operation, * * The 'transferdata' parameter is slightly special, following a @@ -21,20 +22,20 @@ * Use NPY_AUXDATA_CLONE and NPY_AUXDATA_FREE to deal with this data. * */ -typedef void (PyArray_StridedTransferFn)(char *dst, npy_intp dst_stride, +typedef void (PyArray_StridedUnaryOp)(char *dst, npy_intp dst_stride, char *src, npy_intp src_stride, npy_intp N, npy_intp src_itemsize, NpyAuxData *transferdata); /* * This is for pointers to functions which behave exactly as - * for PyArray_StridedTransferFn, but with an additional mask controlling - * which values are transferred. + * for PyArray_StridedUnaryOp, but with an additional mask controlling + * which values are transformed. * - * In particular, the 'i'-th element is transfered if and only if - * NpyMask_IsExposed(mask[i*mask_stride]). + * In particular, the 'i'-th element is operated on if and only if + * NpyMaskValue_IsExposed(mask[i*mask_stride]). */ -typedef void (PyArray_MaskedStridedTransferFn)(char *dst, npy_intp dst_stride, +typedef void (PyArray_MaskedStridedUnaryOp)(char *dst, npy_intp dst_stride, char *src, npy_intp src_stride, npy_mask *mask, npy_intp mask_stride, npy_intp N, npy_intp src_itemsize, @@ -57,7 +58,7 @@ typedef void (PyArray_MaskedStridedTransferFn)(char *dst, npy_intp dst_stride, * Should be the item size if it will always be the same, 0 otherwise. * */ -NPY_NO_EXPORT PyArray_StridedTransferFn * +NPY_NO_EXPORT PyArray_StridedUnaryOp * PyArray_GetStridedCopyFn(int aligned, npy_intp src_stride, npy_intp dst_stride, npy_intp itemsize); @@ -72,7 +73,7 @@ PyArray_GetStridedCopyFn(int aligned, * * Parameters are as for PyArray_GetStridedCopyFn. */ -NPY_NO_EXPORT PyArray_StridedTransferFn * +NPY_NO_EXPORT PyArray_StridedUnaryOp * PyArray_GetStridedCopySwapFn(int aligned, npy_intp src_stride, npy_intp dst_stride, npy_intp itemsize); @@ -87,7 +88,7 @@ PyArray_GetStridedCopySwapFn(int aligned, * * Parameters are as for PyArray_GetStridedCopyFn. */ -NPY_NO_EXPORT PyArray_StridedTransferFn * +NPY_NO_EXPORT PyArray_StridedUnaryOp * PyArray_GetStridedCopySwapPairFn(int aligned, npy_intp src_stride, npy_intp dst_stride, npy_intp itemsize); @@ -106,7 +107,7 @@ NPY_NO_EXPORT int PyArray_GetStridedZeroPadCopyFn(int aligned, npy_intp src_stride, npy_intp dst_stride, npy_intp src_itemsize, npy_intp dst_itemsize, - PyArray_StridedTransferFn **outstransfer, + PyArray_StridedUnaryOp **outstransfer, NpyAuxData **outtransferdata); /* @@ -115,7 +116,7 @@ PyArray_GetStridedZeroPadCopyFn(int aligned, * to dst_type_num. If a conversion is unsupported, returns NULL * without setting a Python exception. */ -NPY_NO_EXPORT PyArray_StridedTransferFn * +NPY_NO_EXPORT PyArray_StridedUnaryOp * PyArray_GetStridedNumericCastFn(int aligned, npy_intp src_stride, npy_intp dst_stride, int src_type_num, int dst_type_num); @@ -130,14 +131,14 @@ NPY_NO_EXPORT int PyArray_GetDTypeCopySwapFn(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *dtype, - PyArray_StridedTransferFn **outstransfer, + PyArray_StridedUnaryOp **outstransfer, NpyAuxData **outtransferdata); /* * If it's possible, gives back a transfer function which casts and/or * byte swaps data with the dtype 'src_dtype' into data with the dtype * 'dst_dtype'. If the outtransferdata is populated with a non-NULL value, - * it must be deallocated with the ``PyArray_FreeStridedTransferData`` + * it must be deallocated with the NPY_AUXDATA_FREE * function when the transfer function is no longer required. * * aligned: @@ -165,7 +166,7 @@ PyArray_GetDTypeCopySwapFn(int aligned, * out_transferdata: * The auxiliary data for the transfer function is placed here. * When finished with the transfer function, the caller must call - * ``PyArray_FreeStridedTransferData`` on this data. + * NPY_AUXDATA_FREE on this data. * out_needs_api: * If this is non-NULL, and the transfer function produced needs * to call into the (Python) API, this gets set to 1. This @@ -183,7 +184,7 @@ PyArray_GetDTypeTransferFunction(int aligned, npy_intp src_stride, npy_intp dst_stride, PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int move_references, - PyArray_StridedTransferFn **out_stransfer, + PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api); @@ -211,7 +212,7 @@ PyArray_GetMaskedDTypeTransferFunction(int aligned, PyArray_Descr *dst_dtype, PyArray_Descr *mask_dtype, int move_references, - PyArray_MaskedStridedTransferFn **out_stransfer, + PyArray_MaskedStridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata, int *out_needs_api); @@ -292,7 +293,7 @@ PyArray_TransferNDimToStrided(npy_intp ndim, npy_intp *coords, npy_intp coords_inc, npy_intp *shape, npy_intp shape_inc, npy_intp count, npy_intp src_itemsize, - PyArray_StridedTransferFn *stransfer, + PyArray_StridedUnaryOp *stransfer, NpyAuxData *transferdata); NPY_NO_EXPORT npy_intp @@ -302,7 +303,7 @@ PyArray_TransferStridedToNDim(npy_intp ndim, npy_intp *coords, npy_intp coords_inc, npy_intp *shape, npy_intp shape_inc, npy_intp count, npy_intp src_itemsize, - PyArray_StridedTransferFn *stransfer, + PyArray_StridedUnaryOp *stransfer, NpyAuxData *transferdata); NPY_NO_EXPORT npy_intp @@ -313,7 +314,7 @@ PyArray_TransferMaskedStridedToNDim(npy_intp ndim, npy_intp *coords, npy_intp coords_inc, npy_intp *shape, npy_intp shape_inc, npy_intp count, npy_intp src_itemsize, - PyArray_MaskedStridedTransferFn *stransfer, + PyArray_MaskedStridedUnaryOp *stransfer, NpyAuxData *data); /* |
