@@ -457,9 +457,10 @@ PyArray_PutTo(PyArrayObject *self, PyObject* values0, PyObject *indices0,
457457 NPY_BEGIN_THREADS_THRESHOLDED (ni );
458458 }
459459 else {
460- PyArray_Descr * dtype = PyArray_DESCR (self );
461460 if (PyArray_GetDTypeTransferFunction (
462- PyArray_ISALIGNED (self ), itemsize , itemsize , dtype , dtype , 0 ,
461+ PyArray_ISALIGNED (self ) && PyArray_ISALIGNED (values ),
462+ itemsize , itemsize ,
463+ PyArray_DESCR (values ), PyArray_DESCR (self ), 0 ,
463464 & cast_info , & flags ) < 0 ) {
464465 goto fail ;
465466 }
@@ -755,7 +756,9 @@ PyArray_PutMask(PyArrayObject *self, PyObject* values0, PyObject* mask0)
755756
756757 NPY_cast_info_init (& cast_info );
757758 if (PyArray_GetDTypeTransferFunction (
758- PyArray_ISALIGNED (self ), itemsize , itemsize , dtype , dtype , 0 ,
759+ PyArray_ISALIGNED (self ) && PyArray_ISALIGNED (values ),
760+ itemsize , itemsize ,
761+ PyArray_DESCR (values ), PyArray_DESCR (self ), 0 ,
759762 & cast_info , & flags ) < 0 ) {
760763 goto fail ;
761764 }
@@ -778,15 +781,15 @@ PyArray_PutMask(PyArrayObject *self, PyObject* values0, PyObject* mask0)
778781 }
779782 }
780783 }
784+ NPY_END_THREADS ;
781785 NPY_cast_info_xfree (& cast_info );
782786 }
783787 else {
784788 NPY_BEGIN_THREADS ;
785789 npy_fastputmask (dest , src , mask_data , ni , nv , itemsize );
790+ NPY_END_THREADS ;
786791 }
787792
788- NPY_END_THREADS ;
789-
790793 Py_XDECREF (values );
791794 Py_XDECREF (mask );
792795 if (copied ) {
@@ -1024,7 +1027,10 @@ PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject *out,
10241027 PyArrayObject * * mps , * ap ;
10251028 PyArrayMultiIterObject * multi = NULL ;
10261029 npy_intp mi ;
1027- NPY_cast_info cast_info = {.func = NULL };
1030+ /* PyArray_MultiIterFromObjects below bounds n by NPY_MAXARGS */
1031+ NPY_cast_info cast_infos [NPY_MAXARGS ];
1032+ int needs_transfer = 0 ;
1033+ NPY_BEGIN_THREADS_DEF ;
10281034 ap = NULL ;
10291035
10301036 /*
@@ -1118,23 +1124,35 @@ PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject *out,
11181124 npy_intp transfer_strides [2 ] = {elsize , elsize };
11191125 npy_intp one = 1 ;
11201126 NPY_ARRAYMETHOD_FLAGS transfer_flags = 0 ;
1121- if ( PyDataType_REFCHK (dtype )) {
1122- int is_aligned = IsUintAligned ( obj );
1127+ needs_transfer = PyDataType_REFCHK (dtype );
1128+ if ( needs_transfer ) {
11231129 PyArray_Descr * obj_dtype = PyArray_DESCR (obj );
1124- PyArray_GetDTypeTransferFunction (
1125- is_aligned ,
1126- dtype -> elsize ,
1127- obj_dtype -> elsize ,
1128- dtype ,
1129- obj_dtype , 0 , & cast_info ,
1130- & transfer_flags );
1130+ for (i = 0 ; i < n ; i ++ ) {
1131+ NPY_cast_info_init (& cast_infos [i ]);
1132+ }
1133+ for (i = 0 ; i < n ; i ++ ) {
1134+ int is_aligned = IsUintAligned (obj ) && IsUintAligned (mps [i ]);
1135+ if (PyArray_GetDTypeTransferFunction (
1136+ is_aligned ,
1137+ PyArray_DESCR (mps [i ])-> elsize ,
1138+ obj_dtype -> elsize ,
1139+ PyArray_DESCR (mps [i ]),
1140+ obj_dtype , 0 , & cast_infos [i ],
1141+ & transfer_flags ) < 0 ) {
1142+ goto fail ;
1143+ }
1144+ }
11311145 }
11321146
1147+ if (!(transfer_flags & NPY_METH_REQUIRES_PYAPI )) {
1148+ NPY_BEGIN_THREADS_THRESHOLDED (multi -> size );
1149+ }
11331150 while (PyArray_MultiIter_NOTDONE (multi )) {
11341151 mi = * ((npy_intp * )PyArray_MultiIter_DATA (multi , n ));
11351152 if (mi < 0 || mi >= n ) {
11361153 switch (clipmode ) {
11371154 case NPY_RAISE :
1155+ NPY_END_THREADS ;
11381156 PyErr_SetString (PyExc_ValueError ,
11391157 "invalid entry in choice " \
11401158 "array" );
@@ -1161,22 +1179,28 @@ PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject *out,
11611179 break ;
11621180 }
11631181 }
1164- if (cast_info . func == NULL ) {
1182+ if (! needs_transfer ) {
11651183 /* We ensure memory doesn't overlap, so can use memcpy */
11661184 memcpy (ret_data , PyArray_MultiIter_DATA (multi , mi ), elsize );
11671185 }
11681186 else {
11691187 char * args [2 ] = {PyArray_MultiIter_DATA (multi , mi ), ret_data };
1170- if (cast_info .func (& cast_info .context , args , & one ,
1171- transfer_strides , cast_info .auxdata ) < 0 ) {
1188+ if (cast_infos [mi ].func (& cast_infos [mi ].context , args , & one ,
1189+ transfer_strides ,
1190+ cast_infos [mi ].auxdata ) < 0 ) {
11721191 goto fail ;
11731192 }
11741193 }
11751194 ret_data += elsize ;
11761195 PyArray_MultiIter_NEXT (multi );
11771196 }
1197+ NPY_END_THREADS ;
11781198
1179- NPY_cast_info_xfree (& cast_info );
1199+ if (needs_transfer ) {
1200+ for (i = 0 ; i < n ; i ++ ) {
1201+ NPY_cast_info_xfree (& cast_infos [i ]);
1202+ }
1203+ }
11801204 Py_DECREF (multi );
11811205 for (i = 0 ; i < n ; i ++ ) {
11821206 Py_XDECREF (mps [i ]);
@@ -1194,7 +1218,12 @@ PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject *out,
11941218 return (PyObject * )obj ;
11951219
11961220 fail :
1197- NPY_cast_info_xfree (& cast_info );
1221+ NPY_END_THREADS ;
1222+ if (needs_transfer ) {
1223+ for (i = 0 ; i < n ; i ++ ) {
1224+ NPY_cast_info_xfree (& cast_infos [i ]);
1225+ }
1226+ }
11981227 Py_XDECREF (multi );
11991228 for (i = 0 ; i < n ; i ++ ) {
12001229 Py_XDECREF (mps [i ]);
0 commit comments