diff options
author | Nathaniel J. Smith <njs@pobox.com> | 2012-06-05 20:24:27 +0100 |
---|---|---|
committer | Nathaniel J. Smith <njs@pobox.com> | 2012-06-05 20:24:27 +0100 |
commit | de8c536813472be29a6292721df83d73dbf7016e (patch) | |
tree | 22ed81fa4be26df298a99cc3469e2c321d799a93 /numpy | |
parent | fd78546183651fc47c2d3429d03bed0a4299d475 (diff) | |
parent | 4542c43b567af9064f36759afe6064bbb3315728 (diff) | |
download | numpy-de8c536813472be29a6292721df83d73dbf7016e.tar.gz |
Merge remote-tracking branch 'mwiebe/nditer_buffer_flag' into merge-293
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/nditer_api.c | 314 | ||||
-rw-r--r-- | numpy/core/src/multiarray/nditer_constr.c | 44 | ||||
-rw-r--r-- | numpy/core/src/multiarray/nditer_impl.h | 26 |
3 files changed, 204 insertions, 180 deletions
diff --git a/numpy/core/src/multiarray/nditer_api.c b/numpy/core/src/multiarray/nditer_api.c index a433df406..cceec518b 100644 --- a/numpy/core/src/multiarray/nditer_api.c +++ b/numpy/core/src/multiarray/nditer_api.c @@ -771,7 +771,7 @@ NpyIter_RequiresBuffering(NpyIter *iter) /*int ndim = NIT_NDIM(iter);*/ int iop, nop = NIT_NOP(iter); - char *op_itflags; + npyiter_opitflags *op_itflags; if (!(itflags&NPY_ITFLAG_BUFFER)) { return 0; @@ -1217,7 +1217,7 @@ NpyIter_GetReadFlags(NpyIter *iter, char *outreadflags) /*int ndim = NIT_NDIM(iter);*/ int iop, nop = NIT_NOP(iter); - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); for (iop = 0; iop < nop; ++iop) { outreadflags[iop] = (op_itflags[iop]&NPY_OP_ITFLAG_READ) != 0; @@ -1234,7 +1234,7 @@ NpyIter_GetWriteFlags(NpyIter *iter, char *outwriteflags) /*int ndim = NIT_NDIM(iter);*/ int iop, nop = NIT_NOP(iter); - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); for (iop = 0; iop < nop; ++iop) { outwriteflags[iop] = (op_itflags[iop]&NPY_OP_ITFLAG_WRITE) != 0; @@ -1330,7 +1330,7 @@ NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides) if (itflags&NPY_ITFLAG_BUFFER) { NpyIter_BufferData *data = NIT_BUFFERDATA(iter); - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); npy_intp stride, *strides = NBF_STRIDES(data), *ad_strides = NAD_STRIDES(axisdata0); PyArray_Descr **dtypes = NIT_DTYPES(iter); @@ -1751,14 +1751,14 @@ npyiter_allocate_buffers(NpyIter *iter, char **errmsg) int iop = 0, nop = NIT_NOP(iter); npy_intp i; - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); NpyIter_BufferData *bufferdata = NIT_BUFFERDATA(iter); PyArray_Descr **op_dtype = NIT_DTYPES(iter); npy_intp buffersize = NBF_BUFFERSIZE(bufferdata); char *buffer, **buffers = NBF_BUFFERS(bufferdata); for (iop = 0; iop < nop; ++iop) { - char flags = op_itflags[iop]; + npyiter_opitflags flags = op_itflags[iop]; /* * If we have determined that a buffer may be needed, @@ -1889,7 +1889,7 @@ npyiter_copy_from_buffers(NpyIter *iter) int maskop = NIT_MASKOP(iter); int first_maskna_op = NIT_FIRST_MASKNA_OP(iter); - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); NpyIter_BufferData *bufferdata = NIT_BUFFERDATA(iter); NpyIter_AxisData *axisdata = NIT_AXISDATA(iter), *reduce_outeraxisdata = NULL; @@ -1935,168 +1935,165 @@ npyiter_copy_from_buffers(NpyIter *iter) /* * Copy the data back to the arrays. If the type has refs, * this function moves them so the buffer's refs are released. + * + * The flag USINGBUFFER is set when the buffer was used, so + * only copy back when this flag is on. */ - if ((stransfer != NULL) && (op_itflags[iop]&NPY_OP_ITFLAG_WRITE)) { - /* Copy back only if the pointer was pointing to the buffer */ - npy_intp delta = (ptrs[iop] - buffer); - if (0 <= delta && delta <= buffersize*dtypes[iop]->elsize) { - npy_intp op_transfersize; + if ((stransfer != NULL) && + (op_itflags[iop]&(NPY_OP_ITFLAG_WRITE|NPY_OP_ITFLAG_USINGBUFFER)) + == (NPY_OP_ITFLAG_WRITE|NPY_OP_ITFLAG_USINGBUFFER)) { + npy_intp op_transfersize; - npy_intp src_stride, *dst_strides, *dst_coords, *dst_shape; - int ndim_transfer; + npy_intp src_stride, *dst_strides, *dst_coords, *dst_shape; + int ndim_transfer; - NPY_IT_DBG_PRINT1("Iterator: Operand %d was buffered\n", - (int)iop); + NPY_IT_DBG_PRINT1("Iterator: Operand %d was buffered\n", + (int)iop); - /* - * If this operand is being reduced in the inner loop, - * its buffering stride was set to zero, and just - * one element was copied. - */ - if (op_itflags[iop]&NPY_OP_ITFLAG_REDUCE) { - if (strides[iop] == 0) { - if (reduce_outerstrides[iop] == 0) { - op_transfersize = 1; - src_stride = 0; - dst_strides = &src_stride; - dst_coords = &NAD_INDEX(reduce_outeraxisdata); - dst_shape = &NAD_SHAPE(reduce_outeraxisdata); - ndim_transfer = 1; - } - else { - op_transfersize = NBF_REDUCE_OUTERSIZE(bufferdata); - src_stride = reduce_outerstrides[iop]; - dst_strides = - &NAD_STRIDES(reduce_outeraxisdata)[iop]; - dst_coords = &NAD_INDEX(reduce_outeraxisdata); - dst_shape = &NAD_SHAPE(reduce_outeraxisdata); - ndim_transfer = ndim - reduce_outerdim; - } + /* + * If this operand is being reduced in the inner loop, + * its buffering stride was set to zero, and just + * one element was copied. + */ + if (op_itflags[iop]&NPY_OP_ITFLAG_REDUCE) { + if (strides[iop] == 0) { + if (reduce_outerstrides[iop] == 0) { + op_transfersize = 1; + src_stride = 0; + dst_strides = &src_stride; + dst_coords = &NAD_INDEX(reduce_outeraxisdata); + dst_shape = &NAD_SHAPE(reduce_outeraxisdata); + ndim_transfer = 1; } else { - if (reduce_outerstrides[iop] == 0) { - op_transfersize = NBF_SIZE(bufferdata); - src_stride = strides[iop]; - dst_strides = &ad_strides[iop]; - dst_coords = &NAD_INDEX(axisdata); - dst_shape = &NAD_SHAPE(axisdata); - ndim_transfer = reduce_outerdim ? - reduce_outerdim : 1; - } - else { - op_transfersize = transfersize; - src_stride = strides[iop]; - dst_strides = &ad_strides[iop]; - dst_coords = &NAD_INDEX(axisdata); - dst_shape = &NAD_SHAPE(axisdata); - ndim_transfer = ndim; - } + op_transfersize = NBF_REDUCE_OUTERSIZE(bufferdata); + src_stride = reduce_outerstrides[iop]; + dst_strides = + &NAD_STRIDES(reduce_outeraxisdata)[iop]; + dst_coords = &NAD_INDEX(reduce_outeraxisdata); + dst_shape = &NAD_SHAPE(reduce_outeraxisdata); + ndim_transfer = ndim - reduce_outerdim; } } else { - op_transfersize = transfersize; - src_stride = strides[iop]; - dst_strides = &ad_strides[iop]; - dst_coords = &NAD_INDEX(axisdata); - dst_shape = &NAD_SHAPE(axisdata); - ndim_transfer = ndim; - } - - NPY_IT_DBG_PRINT2("Iterator: Copying buffer to " - "operand %d (%d items)\n", - (int)iop, (int)op_transfersize); - - /* USE_MASKNA operand */ - if (iop < first_maskna_op && maskna_indices[iop] >= 0) { - int iop_maskna = maskna_indices[iop]; - npy_mask *maskptr; - /* TODO: support WRITEMASKED + USE_MASKNA together */ - - /* - * The mask pointer may be in the buffer or in - * the array, detect which one. - */ - delta = (ptrs[iop_maskna] - buffers[iop_maskna]); - if (0 <= delta && - delta <= buffersize*dtypes[iop_maskna]->elsize) { - maskptr = (npy_mask *)buffers[iop_maskna]; + if (reduce_outerstrides[iop] == 0) { + op_transfersize = NBF_SIZE(bufferdata); + src_stride = strides[iop]; + dst_strides = &ad_strides[iop]; + dst_coords = &NAD_INDEX(axisdata); + dst_shape = &NAD_SHAPE(axisdata); + ndim_transfer = reduce_outerdim ? + reduce_outerdim : 1; } else { - maskptr = (npy_mask *)ad_ptrs[iop_maskna]; + op_transfersize = transfersize; + src_stride = strides[iop]; + dst_strides = &ad_strides[iop]; + dst_coords = &NAD_INDEX(axisdata); + dst_shape = &NAD_SHAPE(axisdata); + ndim_transfer = ndim; } + } + } + else { + op_transfersize = transfersize; + src_stride = strides[iop]; + dst_strides = &ad_strides[iop]; + dst_coords = &NAD_INDEX(axisdata); + dst_shape = &NAD_SHAPE(axisdata); + ndim_transfer = ndim; + } + + NPY_IT_DBG_PRINT2("Iterator: Copying buffer to " + "operand %d (%d items)\n", + (int)iop, (int)op_transfersize); - PyArray_TransferMaskedStridedToNDim(ndim_transfer, - ad_ptrs[iop], dst_strides, axisdata_incr, - buffer, src_stride, - maskptr, strides[iop_maskna], - dst_coords, axisdata_incr, - dst_shape, axisdata_incr, - op_transfersize, dtypes[iop]->elsize, - (PyArray_MaskedStridedUnaryOp *)stransfer, - transferdata); + /* USE_MASKNA operand */ + if (iop < first_maskna_op && maskna_indices[iop] >= 0) { + int iop_maskna = maskna_indices[iop]; + npy_mask *maskptr; + /* TODO: support WRITEMASKED + USE_MASKNA together */ + + /* + * The mask pointer may be in the buffer or in + * the array, detect which one. + */ + if ((op_itflags[iop_maskna]&NPY_OP_ITFLAG_USINGBUFFER) != 0) { + maskptr = (npy_mask *)buffers[iop_maskna]; } - /* WRITEMASKED operand */ - else if (op_itflags[iop] & NPY_OP_ITFLAG_WRITEMASKED) { - npy_mask *maskptr; - - /* - * The mask pointer may be in the buffer or in - * the array, detect which one. - */ - delta = (ptrs[maskop] - buffers[maskop]); - if (0 <= delta && - delta <= buffersize*dtypes[maskop]->elsize) { - maskptr = (npy_mask *)buffers[maskop]; - } - else { - maskptr = (npy_mask *)ad_ptrs[maskop]; - } + else { + maskptr = (npy_mask *)ad_ptrs[iop_maskna]; + } + + PyArray_TransferMaskedStridedToNDim(ndim_transfer, + ad_ptrs[iop], dst_strides, axisdata_incr, + buffer, src_stride, + maskptr, strides[iop_maskna], + dst_coords, axisdata_incr, + dst_shape, axisdata_incr, + op_transfersize, dtypes[iop]->elsize, + (PyArray_MaskedStridedUnaryOp *)stransfer, + transferdata); + } + /* WRITEMASKED operand */ + else if (op_itflags[iop] & NPY_OP_ITFLAG_WRITEMASKED) { + npy_mask *maskptr; - PyArray_TransferMaskedStridedToNDim(ndim_transfer, - ad_ptrs[iop], dst_strides, axisdata_incr, - buffer, src_stride, - maskptr, strides[maskop], - dst_coords, axisdata_incr, - dst_shape, axisdata_incr, - op_transfersize, dtypes[iop]->elsize, - (PyArray_MaskedStridedUnaryOp *)stransfer, - transferdata); + /* + * The mask pointer may be in the buffer or in + * the array, detect which one. + */ + if ((op_itflags[maskop]&NPY_OP_ITFLAG_USINGBUFFER) != 0) { + maskptr = (npy_mask *)buffers[maskop]; } - /* Regular operand */ else { - PyArray_TransferStridedToNDim(ndim_transfer, - ad_ptrs[iop], dst_strides, axisdata_incr, - buffer, src_stride, - dst_coords, axisdata_incr, - dst_shape, axisdata_incr, - op_transfersize, dtypes[iop]->elsize, - stransfer, - transferdata); + maskptr = (npy_mask *)ad_ptrs[maskop]; } + + PyArray_TransferMaskedStridedToNDim(ndim_transfer, + ad_ptrs[iop], dst_strides, axisdata_incr, + buffer, src_stride, + maskptr, strides[maskop], + dst_coords, axisdata_incr, + dst_shape, axisdata_incr, + op_transfersize, dtypes[iop]->elsize, + (PyArray_MaskedStridedUnaryOp *)stransfer, + transferdata); + } + /* Regular operand */ + else { + PyArray_TransferStridedToNDim(ndim_transfer, + ad_ptrs[iop], dst_strides, axisdata_incr, + buffer, src_stride, + dst_coords, axisdata_incr, + dst_shape, axisdata_incr, + op_transfersize, dtypes[iop]->elsize, + stransfer, + transferdata); } } /* If there's no copy back, we may have to decrement refs. In * this case, the transfer function has a 'decsrcref' transfer * function, so we can use it to do the decrement. + * + * The flag USINGBUFFER is set when the buffer was used, so + * only decrement refs when this flag is on. */ - else if (stransfer != NULL) { - /* Decrement refs only if the pointer was pointing to the buffer */ - npy_intp delta = (ptrs[iop] - buffer); - if (0 <= delta && delta <= transfersize*dtypes[iop]->elsize) { - NPY_IT_DBG_PRINT1("Iterator: Freeing refs and zeroing buffer " - "of operand %d\n", (int)iop); - /* Decrement refs */ - stransfer(NULL, 0, buffer, dtypes[iop]->elsize, - transfersize, dtypes[iop]->elsize, - transferdata); - /* - * Zero out the memory for safety. For instance, - * if during iteration some Python code copied an - * array pointing into the buffer, it will get None - * values for its references after this. - */ - memset(buffer, 0, dtypes[iop]->elsize*transfersize); - } + else if (stransfer != NULL && + (op_itflags[iop]&NPY_OP_ITFLAG_USINGBUFFER) != 0) { + NPY_IT_DBG_PRINT1("Iterator: Freeing refs and zeroing buffer " + "of operand %d\n", (int)iop); + /* Decrement refs */ + stransfer(NULL, 0, buffer, dtypes[iop]->elsize, + transfersize, dtypes[iop]->elsize, + transferdata); + /* + * Zero out the memory for safety. For instance, + * if during iteration some Python code copied an + * array pointing into the buffer, it will get None + * values for its references after this. + */ + memset(buffer, 0, dtypes[iop]->elsize*transfersize); } } @@ -2116,7 +2113,7 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) int iop, nop = NIT_NOP(iter); int first_maskna_op = NIT_FIRST_MASKNA_OP(iter); - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); NpyIter_BufferData *bufferdata = NIT_BUFFERDATA(iter); NpyIter_AxisData *axisdata = NIT_AXISDATA(iter), *reduce_outeraxisdata = NULL; @@ -2265,6 +2262,7 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) * to the first non-trivial stride. */ stransfer = NULL; + /* The flag NPY_OP_ITFLAG_USINGBUFFER can be ignored here */ break; /* Never need to buffer this operand */ case NPY_OP_ITFLAG_BUFNEVER|NPY_OP_ITFLAG_REDUCE: @@ -2277,6 +2275,7 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) * to the first non-trivial stride. */ stransfer = NULL; + /* The flag NPY_OP_ITFLAG_USINGBUFFER can be ignored here */ break; /* Just a copy */ case 0: @@ -2290,6 +2289,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) ptrs[iop] = ad_ptrs[iop]; strides[iop] = ad_strides[iop]; stransfer = NULL; + /* Signal that the buffer is not being used */ + op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER); } /* If some other op is reduced, we have a double reduce loop */ else if ((itflags&NPY_ITFLAG_REDUCE) && @@ -2303,6 +2304,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) reduce_outerstrides[iop] = NAD_STRIDES(reduce_outeraxisdata)[iop]; stransfer = NULL; + /* Signal that the buffer is not being used */ + op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER); } else { /* In this case, the buffer is being used */ @@ -2313,6 +2316,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) strides[iop]; reduce_outerptrs[iop] = ptrs[iop]; } + /* Signal that the buffer is being used */ + op_itflags[iop] |= NPY_OP_ITFLAG_USINGBUFFER; } break; /* Just a copy, but with a reduction */ @@ -2325,6 +2330,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) ptrs[iop] = ad_ptrs[iop]; reduce_outerstrides[iop] = 0; stransfer = NULL; + /* Signal that the buffer is not being used */ + op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER); } /* It's all in one stride in the reduce outer loop */ else if ((reduce_outerdim > 0) && @@ -2338,6 +2345,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) reduce_outerstrides[iop] = NAD_STRIDES(reduce_outeraxisdata)[iop]; stransfer = NULL; + /* Signal that the buffer is not being used */ + op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER); } /* In this case, the buffer is being used */ else { @@ -2351,6 +2360,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) else { reduce_outerstrides[iop] = dtypes[iop]->elsize; } + /* Signal that the buffer is being used */ + op_itflags[iop] |= NPY_OP_ITFLAG_USINGBUFFER; } } @@ -2360,6 +2371,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) strides[iop] = ad_strides[iop]; reduce_outerstrides[iop] = 0; stransfer = NULL; + /* Signal that the buffer is not being used */ + op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER); } else { /* It's all in one stride in the reduce outer loop */ @@ -2373,6 +2386,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) reduce_outerstrides[iop] = NAD_STRIDES(reduce_outeraxisdata)[iop]; stransfer = NULL; + /* Signal that the buffer is not being used */ + op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER); } /* In this case, the buffer is being used */ else { @@ -2388,6 +2403,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) reduce_outerstrides[iop] = reduce_innersize * dtypes[iop]->elsize; } + /* Signal that the buffer is being used */ + op_itflags[iop] |= NPY_OP_ITFLAG_USINGBUFFER; } } reduce_outerptrs[iop] = ptrs[iop]; @@ -2396,6 +2413,9 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs) /* In this case, the buffer is always being used */ any_buffered = 1; + /* Signal that the buffer is being used */ + op_itflags[iop] |= NPY_OP_ITFLAG_USINGBUFFER; + if (!(op_itflags[iop]&NPY_OP_ITFLAG_REDUCE)) { ptrs[iop] = buffers[iop]; strides[iop] = dtypes[iop]->elsize; @@ -2636,7 +2656,7 @@ npyiter_checkreducesize(NpyIter *iter, npy_intp count, npy_intp reducespace = 1, factor; npy_bool nonzerocoord; - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); char stride0op[NPY_MAXARGS]; /* Default to no outer axis */ diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c index 941ce91c0..f1d0c5c38 100644 --- a/numpy/core/src/multiarray/nditer_constr.c +++ b/numpy/core/src/multiarray/nditer_constr.c @@ -27,14 +27,14 @@ static int npyiter_calculate_ndim(int nop, PyArrayObject **op_in, int oa_ndim); static int -npyiter_check_per_op_flags(npy_uint32 flags, char *op_itflags); +npyiter_check_per_op_flags(npy_uint32 flags, npyiter_opitflags *op_itflags); static int npyiter_prepare_one_operand(PyArrayObject **op, char **op_dataptr, PyArray_Descr *op_request_dtype, PyArray_Descr** op_dtype, npy_uint32 flags, - npy_uint32 op_flags, char *op_itflags); + npy_uint32 op_flags, npyiter_opitflags *op_itflags); static int npyiter_prepare_operands(int nop, int first_maskna_op, PyArrayObject **op_in, @@ -43,16 +43,16 @@ npyiter_prepare_operands(int nop, int first_maskna_op, PyArray_Descr **op_request_dtypes, PyArray_Descr **op_dtype, npy_uint32 flags, - npy_uint32 *op_flags, char *op_itflags, + npy_uint32 *op_flags, npyiter_opitflags *op_itflags, npy_int8 *out_maskop, npy_int8 *out_maskna_indices); static int npyiter_check_casting(int nop, PyArrayObject **op, PyArray_Descr **op_dtype, NPY_CASTING casting, - char *op_itflags); + npyiter_opitflags *op_itflags); static int -npyiter_fill_axisdata(NpyIter *iter, npy_uint32 flags, char *op_itflags, +npyiter_fill_axisdata(NpyIter *iter, npy_uint32 flags, npyiter_opitflags *op_itflags, char **op_dataptr, npy_uint32 *op_flags, int **op_axes, npy_intp *itershape, @@ -74,25 +74,25 @@ static void npyiter_find_best_axis_ordering(NpyIter *iter); static PyArray_Descr * npyiter_get_common_dtype(int first_maskna_op, PyArrayObject **op, - char *op_itflags, PyArray_Descr **op_dtype, + npyiter_opitflags *op_itflags, PyArray_Descr **op_dtype, PyArray_Descr **op_request_dtypes, int only_inputs, int output_scalars); static PyArrayObject * npyiter_new_temp_array(NpyIter *iter, PyTypeObject *subtype, - npy_uint32 flags, char *op_itflags, + npy_uint32 flags, npyiter_opitflags *op_itflags, int op_ndim, npy_intp *shape, PyArray_Descr *op_dtype, int *op_axes); static int npyiter_allocate_arrays(NpyIter *iter, npy_uint32 flags, PyArray_Descr **op_dtype, PyTypeObject *subtype, - npy_uint32 *op_flags, char *op_itflags, + npy_uint32 *op_flags, npyiter_opitflags *op_itflags, int **op_axes, int output_scalars); static int npyiter_fill_maskna_axisdata(NpyIter *iter, int **op_axes); static void npyiter_get_priority_subtype(int first_maskna_op, PyArrayObject **op, - char *op_itflags, + npyiter_opitflags *op_itflags, double *subtype_priority, PyTypeObject **subtype); static int npyiter_allocate_transfer_functions(NpyIter *iter); @@ -120,7 +120,7 @@ NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32 flags, /* Per-operand values */ PyArrayObject **op; PyArray_Descr **op_dtype; - char *op_itflags; + npyiter_opitflags *op_itflags; char **op_dataptr; npy_int8 *perm; @@ -916,7 +916,7 @@ npyiter_calculate_ndim(int nop, PyArrayObject **op_in, * Returns 1 on success, 0 on failure. */ static int -npyiter_check_per_op_flags(npy_uint32 op_flags, char *op_itflags) +npyiter_check_per_op_flags(npy_uint32 op_flags, npyiter_opitflags *op_itflags) { if ((op_flags & NPY_ITER_GLOBAL_FLAGS) != 0) { PyErr_SetString(PyExc_ValueError, @@ -1027,7 +1027,7 @@ npyiter_prepare_one_operand(PyArrayObject **op, PyArray_Descr *op_request_dtype, PyArray_Descr **op_dtype, npy_uint32 flags, - npy_uint32 op_flags, char *op_itflags) + npy_uint32 op_flags, npyiter_opitflags *op_itflags) { /* NULL operands must be automatically allocated outputs */ if (*op == NULL) { @@ -1228,7 +1228,7 @@ npyiter_prepare_operands(int nop, int first_maskna_op, PyArrayObject **op_in, PyArray_Descr **op_request_dtypes, PyArray_Descr **op_dtype, npy_uint32 flags, - npy_uint32 *op_flags, char *op_itflags, + npy_uint32 *op_flags, npyiter_opitflags *op_itflags, npy_int8 *out_maskop, npy_int8 *out_maskna_indices) { @@ -1421,7 +1421,7 @@ static int npyiter_check_casting(int first_maskna_op, PyArrayObject **op, PyArray_Descr **op_dtype, NPY_CASTING casting, - char *op_itflags) + npyiter_opitflags *op_itflags) { int iop; @@ -1559,7 +1559,7 @@ check_mask_for_writemasked_reduction(NpyIter *iter, int iop) * Returns 1 on success, 0 on failure. */ static int -npyiter_fill_axisdata(NpyIter *iter, npy_uint32 flags, char *op_itflags, +npyiter_fill_axisdata(NpyIter *iter, npy_uint32 flags, npyiter_opitflags *op_itflags, char **op_dataptr, npy_uint32 *op_flags, int **op_axes, npy_intp *itershape, @@ -2522,7 +2522,7 @@ npyiter_find_best_axis_ordering(NpyIter *iter) */ static PyArray_Descr * npyiter_get_common_dtype(int first_maskna_op, PyArrayObject **op, - char *op_itflags, PyArray_Descr **op_dtype, + npyiter_opitflags *op_itflags, PyArray_Descr **op_dtype, PyArray_Descr **op_request_dtypes, int only_inputs, int output_scalars) { @@ -2588,7 +2588,7 @@ npyiter_get_common_dtype(int first_maskna_op, PyArrayObject **op, */ static PyArrayObject * npyiter_new_temp_array(NpyIter *iter, PyTypeObject *subtype, - npy_uint32 flags, char *op_itflags, + npy_uint32 flags, npyiter_opitflags *op_itflags, int op_ndim, npy_intp *shape, PyArray_Descr *op_dtype, int *op_axes) { @@ -2822,7 +2822,7 @@ static int npyiter_allocate_arrays(NpyIter *iter, npy_uint32 flags, PyArray_Descr **op_dtype, PyTypeObject *subtype, - npy_uint32 *op_flags, char *op_itflags, + npy_uint32 *op_flags, npyiter_opitflags *op_itflags, int **op_axes, int output_scalars) { npy_uint32 itflags = NIT_ITFLAGS(iter); @@ -3157,7 +3157,7 @@ npyiter_fill_maskna_axisdata(NpyIter *iter, int **op_axes) int first_maskna_op = NIT_FIRST_MASKNA_OP(iter); npy_int8 *perm; - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); npy_int8 *maskna_indices = NIT_MASKNA_INDICES(iter); NpyIter_AxisData *axisdata; npy_intp sizeof_axisdata; @@ -3291,7 +3291,7 @@ npyiter_fill_maskna_axisdata(NpyIter *iter, int **op_axes) */ static void npyiter_get_priority_subtype(int first_maskna_op, PyArrayObject **op, - char *op_itflags, + npyiter_opitflags *op_itflags, double *subtype_priority, PyTypeObject **subtype) { @@ -3317,7 +3317,7 @@ npyiter_allocate_transfer_functions(NpyIter *iter) int first_maskna_op = NIT_FIRST_MASKNA_OP(iter); npy_intp i; - char *op_itflags = NIT_OPITFLAGS(iter); + npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); NpyIter_BufferData *bufferdata = NIT_BUFFERDATA(iter); NpyIter_AxisData *axisdata = NIT_AXISDATA(iter); PyArrayObject **op = NIT_OPERANDS(iter); @@ -3334,7 +3334,7 @@ npyiter_allocate_transfer_functions(NpyIter *iter) int needs_api = 0; for (iop = 0; iop < nop; ++iop) { - char flags = op_itflags[iop]; + npyiter_opitflags flags = op_itflags[iop]; /* * Reduction operands may be buffered with a different stride, * so we must pass NPY_MAX_INTP to the transfer function factory. diff --git a/numpy/core/src/multiarray/nditer_impl.h b/numpy/core/src/multiarray/nditer_impl.h index ea02d5cc4..ef10308fb 100644 --- a/numpy/core/src/multiarray/nditer_impl.h +++ b/numpy/core/src/multiarray/nditer_impl.h @@ -107,21 +107,23 @@ /* Internal iterator per-operand iterator flags */ /* The operand will be written to */ -#define NPY_OP_ITFLAG_WRITE 0x01 +#define NPY_OP_ITFLAG_WRITE 0x0001 /* The operand will be read from */ -#define NPY_OP_ITFLAG_READ 0x02 +#define NPY_OP_ITFLAG_READ 0x0002 /* The operand needs type conversion/byte swapping/alignment */ -#define NPY_OP_ITFLAG_CAST 0x04 +#define NPY_OP_ITFLAG_CAST 0x0004 /* The operand never needs buffering */ -#define NPY_OP_ITFLAG_BUFNEVER 0x08 +#define NPY_OP_ITFLAG_BUFNEVER 0x0008 /* The operand is aligned */ -#define NPY_OP_ITFLAG_ALIGNED 0x10 +#define NPY_OP_ITFLAG_ALIGNED 0x0010 /* The operand is being reduced */ -#define NPY_OP_ITFLAG_REDUCE 0x20 +#define NPY_OP_ITFLAG_REDUCE 0x0020 /* The operand is for temporary use, does not have a backing array */ -#define NPY_OP_ITFLAG_VIRTUAL 0x40 +#define NPY_OP_ITFLAG_VIRTUAL 0x0040 /* The operand requires masking when copying buffer -> array */ -#define NPY_OP_ITFLAG_WRITEMASKED 0x80 +#define NPY_OP_ITFLAG_WRITEMASKED 0x0080 +/* The operand's data pointer is pointing into its buffer */ +#define NPY_OP_ITFLAG_USINGBUFFER 0x0100 /* * The data layout of the iterator is fully specified by @@ -147,6 +149,8 @@ struct NpyIter_InternalOnly { typedef struct NpyIter_AD NpyIter_AxisData; typedef struct NpyIter_BD NpyIter_BufferData; +typedef npy_int16 npyiter_opitflags; + /* Byte sizes of the iterator members */ #define NIT_PERM_SIZEOF(itflags, ndim, nop) \ NPY_INTP_ALIGNED(NPY_MAXDIMS) @@ -161,7 +165,7 @@ typedef struct NpyIter_BD NpyIter_BufferData; #define NIT_OPERANDS_SIZEOF(itflags, ndim, nop) \ ((NPY_SIZEOF_INTP)*(nop)) #define NIT_OPITFLAGS_SIZEOF(itflags, ndim, nop) \ - (NPY_INTP_ALIGNED(nop)) + (NPY_INTP_ALIGNED(sizeof(npyiter_opitflags) * nop)) #define NIT_BUFFERDATA_SIZEOF(itflags, ndim, nop) \ ((itflags&NPY_ITFLAG_BUFFER) ? ((NPY_SIZEOF_INTP)*(6 + 9*nop)) : 0) @@ -224,8 +228,8 @@ typedef struct NpyIter_BD NpyIter_BufferData; &(iter)->iter_flexdata + NIT_BASEOFFSETS_OFFSET(itflags, ndim, nop))) #define NIT_OPERANDS(iter) ((PyArrayObject **)( \ &(iter)->iter_flexdata + NIT_OPERANDS_OFFSET(itflags, ndim, nop))) -#define NIT_OPITFLAGS(iter) ( \ - &(iter)->iter_flexdata + NIT_OPITFLAGS_OFFSET(itflags, ndim, nop)) +#define NIT_OPITFLAGS(iter) ((npyiter_opitflags *)( \ + &(iter)->iter_flexdata + NIT_OPITFLAGS_OFFSET(itflags, ndim, nop))) #define NIT_BUFFERDATA(iter) ((NpyIter_BufferData *)( \ &(iter)->iter_flexdata + NIT_BUFFERDATA_OFFSET(itflags, ndim, nop))) #define NIT_AXISDATA(iter) ((NpyIter_AxisData *)( \ |