diff --git a/numpy/core/src/multiarray/dtype_transfer.c b/numpy/core/src/multiarray/dtype_transfer.c index ee0ec720d953..b64e1684a5ae 100644 --- a/numpy/core/src/multiarray/dtype_transfer.c +++ b/numpy/core/src/multiarray/dtype_transfer.c @@ -185,6 +185,27 @@ _strided_to_strided_zero_pad_copy(char *dst, npy_intp dst_stride, } } +/* + * Does a strided to strided zero-padded copy for the case where + * dst_itemsize < src_itemsize + */ +static void +_strided_to_strided_truncate_copy(char *dst, npy_intp dst_stride, + char *src, npy_intp src_stride, + npy_intp N, npy_intp src_itemsize, + void *data) +{ + _strided_zero_pad_data *d = (_strided_zero_pad_data *)data; + npy_intp dst_itemsize = d->dst_itemsize; + + while (N > 0) { + memcpy(dst, src, dst_itemsize); + src += src_stride; + dst += dst_stride; + --N; + } +} + NPY_NO_EXPORT int PyArray_GetStridedZeroPadCopyFn(int aligned, npy_intp src_stride, npy_intp dst_stride, @@ -192,13 +213,9 @@ PyArray_GetStridedZeroPadCopyFn(int aligned, PyArray_StridedTransferFn **out_stransfer, void **out_transferdata) { - if (src_itemsize >= dst_itemsize) { - /* If the sizes are different, the alignment flag isn't trustworthy */ - if (src_itemsize != dst_itemsize) { - aligned = 0; - } + if (src_itemsize == dst_itemsize) { *out_stransfer = PyArray_GetStridedCopyFn(aligned, src_stride, - dst_stride, dst_itemsize); + dst_stride, src_itemsize); *out_transferdata = NULL; return (*out_stransfer == NULL) ? NPY_FAIL : NPY_SUCCEED; } @@ -213,7 +230,13 @@ PyArray_GetStridedZeroPadCopyFn(int aligned, d->freefunc = &PyArray_free; d->copyfunc = &_strided_zero_pad_data_copy; - *out_stransfer = &_strided_to_strided_zero_pad_copy; + if (src_itemsize < dst_itemsize) { + *out_stransfer = &_strided_to_strided_zero_pad_copy; + } + else { + *out_stransfer = &_strided_to_strided_truncate_copy; + } + *out_transferdata = d; return NPY_SUCCEED; } diff --git a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src index c5f408d81b1a..fc8d71f46ad5 100644 --- a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src +++ b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src @@ -301,34 +301,6 @@ _swap_pair_strided_to_strided(char *dst, npy_intp dst_stride, } } -static void -_strided_to_contig(char *dst, npy_intp dst_stride, - char *src, npy_intp src_stride, - npy_intp N, npy_intp NPY_UNUSED(src_itemsize), - void *NPY_UNUSED(data)) -{ - while (N > 0) { - memcpy(dst, src, dst_stride); - dst += dst_stride; - src += src_stride; - --N; - } -} - -static void -_contig_to_strided(char *dst, npy_intp dst_stride, - char *src, npy_intp NPY_UNUSED(src_stride), - npy_intp N, npy_intp src_itemsize, - void *NPY_UNUSED(data)) -{ - while (N > 0) { - memcpy(dst, src, src_itemsize); - dst += dst_stride; - src += src_itemsize; - --N; - } -} - static void _contig_to_contig(char *dst, npy_intp NPY_UNUSED(dst_stride), char *src, npy_intp NPY_UNUSED(src_stride), @@ -381,7 +353,7 @@ PyArray_GetStridedCopyFn(npy_intp aligned, npy_intp src_stride, } } - return &_strided_to_contig; + return &_strided_to_strided; } /* general dst */ else { @@ -408,7 +380,7 @@ PyArray_GetStridedCopyFn(npy_intp aligned, npy_intp src_stride, /**end repeat**/ } - return &_contig_to_strided; + return &_strided_to_strided; } else { switch (itemsize) { @@ -445,7 +417,7 @@ PyArray_GetStridedCopyFn(npy_intp aligned, npy_intp src_stride, } } - return &_strided_to_contig; + return &_strided_to_strided; } /* general dst */ else { @@ -462,7 +434,7 @@ PyArray_GetStridedCopyFn(npy_intp aligned, npy_intp src_stride, /**end repeat**/ } - return &_contig_to_strided; + return &_strided_to_strided; } /* general src */ else { @@ -578,7 +550,7 @@ NPY_NO_EXPORT PyArray_StridedTransferFn * /**end repeat1**/ } - return &_contig_to_strided; + return &_strided_to_strided; } else { switch (itemsize) { @@ -626,7 +598,7 @@ NPY_NO_EXPORT PyArray_StridedTransferFn * } } - return &_strided_to_contig; + return &_strided_to_strided; } /* general dst */ else { @@ -643,7 +615,7 @@ NPY_NO_EXPORT PyArray_StridedTransferFn * /**end repeat1**/ } - return &_contig_to_strided; + return &_strided_to_strided; } /* general src */ else {