Skip to content

Commit

Permalink
ENH: Have dtype transfer for equivalent user dtypes prefer user-defin…
Browse files Browse the repository at this point in the history
…ed `copyswapn`
  • Loading branch information
EricCousineau-TRI committed May 18, 2018
1 parent 290aa88 commit 682403e
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
6 changes: 6 additions & 0 deletions doc/release/1.15.0-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ C API changes
checked before the operation whose status we wanted to check was run.
See `#10339 <https://github.com/numpy/numpy/issues/10370>`__.

* ``PyArray_GetDTypeTransferFunction`` now defaults to using user-defined
``copyswapn`` / ``copyswap`` for user-defined dtypes. If this causes a
significant performance hit, consider implementing ``copyswapn`` to reflect
the implementation of ``PyArray_GetStridedCopyFn``.
See `#10898 <https://github.com/numpy/numpy/pull/10898>`__.

New Features
============

Expand Down
9 changes: 6 additions & 3 deletions numpy/core/src/multiarray/dtype_transfer.c
Original file line number Diff line number Diff line change
Expand Up @@ -3400,6 +3400,7 @@ PyArray_GetDTypeTransferFunction(int aligned,
{
npy_intp src_itemsize, dst_itemsize;
int src_type_num, dst_type_num;
int is_builtin;

#if NPY_DT_DBG_TRACING
printf("Calculating dtype transfer from ");
Expand Down Expand Up @@ -3439,6 +3440,7 @@ PyArray_GetDTypeTransferFunction(int aligned,
dst_itemsize = dst_dtype->elsize;
src_type_num = src_dtype->type_num;
dst_type_num = dst_dtype->type_num;
is_builtin = src_type_num < NPY_NTYPES && dst_type_num < NPY_NTYPES;

/* Common special case - number -> number NBO cast */
if (PyTypeNum_ISNUMBER(src_type_num) &&
Expand All @@ -3462,13 +3464,14 @@ PyArray_GetDTypeTransferFunction(int aligned,
}

/*
* If there are no references and the data types are equivalent,
* If there are no references and the data types are equivalent and builtin,
* return a simple copy
*/
if (PyArray_EquivTypes(src_dtype, dst_dtype) &&
!PyDataType_REFCHK(src_dtype) && !PyDataType_REFCHK(dst_dtype) &&
( !PyDataType_HASFIELDS(dst_dtype) ||
is_dtype_struct_simple_unaligned_layout(dst_dtype)) ) {
is_dtype_struct_simple_unaligned_layout(dst_dtype)) &&
is_builtin) {
/*
* We can't pass through the aligned flag because it's not
* appropriate. Consider a size-8 string, it will say it's
Expand All @@ -3494,7 +3497,7 @@ PyArray_GetDTypeTransferFunction(int aligned,
!PyDataType_HASSUBARRAY(dst_dtype) &&
src_type_num != NPY_DATETIME && src_type_num != NPY_TIMEDELTA) {
/* A custom data type requires that we use its copy/swap */
if (src_type_num >= NPY_NTYPES || dst_type_num >= NPY_NTYPES) {
if (!is_builtin) {
/*
* If the sizes and kinds are identical, but they're different
* custom types, then get a cast function
Expand Down

0 comments on commit 682403e

Please sign in to comment.