Skip to content

Commit cd3e144

Browse files
committed
refactor based on review comments
1 parent 953714e commit cd3e144

19 files changed

+151
-115
lines changed

numpy/_core/code_generators/cversions.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,6 @@
7979
# Version 19 (NumPy 2.2.0) No change
8080
0x00000013 = 2b8f1f4da822491ff030b2b37dff07e3
8181
# Version 20 (NumPy 2.3.0)
82-
# Version 20 (NumPy 2.4.0) No change
8382
0x00000014 = e56b74d32a934d085e7c3414cb9999b8,
83+
# Version 21 (NumPy 2.4.0) Add 'same_value' casting, header additions
84+
0x00000015 = e56b74d32a934d085e7c3414cb9999b8,

numpy/_core/include/numpy/dtype_api.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,15 @@ typedef struct PyArrayMethod_Context_tag {
107107

108108
/* Operand descriptors, filled in by resolve_descriptors */
109109
PyArray_Descr *const *descriptors;
110-
void * padding;
110+
#if NPY_FEATURE_VERSION > NPY_2_3_API_VERSION
111+
void * _reserved;
111112
/*
112113
* Optional flag to pass information into the inner loop
113114
* If set, it will be NPY_CASTING
114115
*/
115116
uint64_t flags;
116117
/* Structure may grow (this is harmless for DType authors) */
118+
#endif
117119
} PyArrayMethod_Context;
118120

119121

@@ -150,12 +152,6 @@ typedef struct {
150152
#define NPY_METH_contiguous_indexed_loop 9
151153
#define _NPY_METH_static_data 10
152154

153-
/*
154-
* Constants for same_value casting
155-
*/
156-
#define NPY_SAME_VALUE_OVERFLOW -31
157-
158-
159155
/*
160156
* The resolve descriptors function, must be able to handle NULL values for
161157
* all output (but not input) `given_descrs` and fill `loop_descrs`.

numpy/_core/include/numpy/numpyconfig.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#define NPY_2_1_API_VERSION 0x00000013
8585
#define NPY_2_2_API_VERSION 0x00000013
8686
#define NPY_2_3_API_VERSION 0x00000014
87+
#define NPY_2_4_API_VERSION 0x00000015
8788

8889

8990
/*
@@ -172,8 +173,10 @@
172173
#define NPY_FEATURE_VERSION_STRING "2.0"
173174
#elif NPY_FEATURE_VERSION == NPY_2_1_API_VERSION
174175
#define NPY_FEATURE_VERSION_STRING "2.1"
175-
#elif NPY_FEATURE_VERSION == NPY_2_3_API_VERSION /* also 2.4 */
176+
#elif NPY_FEATURE_VERSION == NPY_2_3_API_VERSION
176177
#define NPY_FEATURE_VERSION_STRING "2.3"
178+
#elif NPY_FEATURE_VERSION == NPY_2_4_API_VERSION
179+
#define NPY_FEATURE_VERSION_STRING "2.4"
177180
#else
178181
#error "Missing version string define for new NumPy version."
179182
#endif

numpy/_core/meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ C_ABI_VERSION = '0x02000000'
5050
# 0x00000013 - 2.1.x
5151
# 0x00000013 - 2.2.x
5252
# 0x00000014 - 2.3.x
53-
C_API_VERSION = '0x00000014'
53+
# 0x00000015 - 2.4.x
54+
C_API_VERSION = '0x00000015'
5455

5556
# Check whether we have a mismatch between the set C API VERSION and the
5657
# actual C API VERSION. Will raise a MismatchCAPIError if so.

numpy/_core/src/multiarray/array_assign_array.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,12 @@ raw_array_assign_array(int ndim, npy_intp const *shape,
132132
}
133133

134134
if (same_value_cast) {
135+
#if NPY_FEATURE_VERSION > NPY_2_3_API_VERSION
135136
cast_info.context.flags |= NPY_SAME_VALUE_CASTING;
137+
#else
138+
PyErr_SetString(PyExc_NotImplementedError,
139+
"raw_array_assign_array with 'same_value' casting not implemented yet");
140+
#endif
136141
}
137142

138143
/* Ensure number of elements exceeds threshold for threading */
@@ -146,16 +151,14 @@ raw_array_assign_array(int ndim, npy_intp const *shape,
146151

147152
npy_intp strides[2] = {src_strides_it[0], dst_strides_it[0]};
148153

154+
int result = 0;
149155
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
150156
/* Process the innermost dimension */
151157
char *args[2] = {src_data, dst_data};
152-
int result = cast_info.func(&cast_info.context,
158+
result = cast_info.func(&cast_info.context,
153159
args, &shape_it[0], strides,
154160
cast_info.auxdata);
155161
if (result < 0) {
156-
if (result == NPY_SAME_VALUE_OVERFLOW) {
157-
goto same_value_overflow;
158-
}
159162
goto fail;
160163
}
161164
} NPY_RAW_ITER_TWO_NEXT(idim, ndim, coord, shape_it,
@@ -173,11 +176,10 @@ raw_array_assign_array(int ndim, npy_intp const *shape,
173176
}
174177

175178
return 0;
176-
same_value_overflow:
177-
PyErr_SetString(PyExc_ValueError, "overflow in 'same_value' casting");
178179
fail:
179180
NPY_END_THREADS;
180181
NPY_cast_info_xfree(&cast_info);
182+
HandleArrayMethodError(result, "astype", method_flags);
181183
return -1;
182184
}
183185

@@ -246,7 +248,7 @@ raw_array_wheremasked_assign_array(int ndim, npy_intp const *shape,
246248
return -1;
247249
}
248250
if (same_value_cast) {
249-
cast_info.context.flags |= NPY_SAME_VALUE_CASTING;
251+
/* cast_info.context.flags |= NPY_SAME_VALUE_CASTING; */
250252
PyErr_SetString(PyExc_NotImplementedError,
251253
"raw_array_wheremasked_assign_array with 'same_value' casting not implemented yet");
252254
return -1;
@@ -265,20 +267,18 @@ raw_array_wheremasked_assign_array(int ndim, npy_intp const *shape,
265267

266268
npy_intp strides[2] = {src_strides_it[0], dst_strides_it[0]};
267269

270+
int result = 0;
268271
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
269272
PyArray_MaskedStridedUnaryOp *stransfer;
270273
stransfer = (PyArray_MaskedStridedUnaryOp *)cast_info.func;
271274

272275
/* Process the innermost dimension */
273276
char *args[2] = {src_data, dst_data};
274-
int result = stransfer(&cast_info.context,
277+
result = stransfer(&cast_info.context,
275278
args, &shape_it[0], strides,
276279
(npy_bool *)wheremask_data, wheremask_strides_it[0],
277280
cast_info.auxdata);
278281
if (result < 0) {
279-
if (result == NPY_SAME_VALUE_OVERFLOW) {
280-
goto same_value_overflow;
281-
}
282282
goto fail;
283283
}
284284
} NPY_RAW_ITER_THREE_NEXT(idim, ndim, coord, shape_it,
@@ -295,14 +295,11 @@ raw_array_wheremasked_assign_array(int ndim, npy_intp const *shape,
295295
return -1;
296296
}
297297
}
298-
299298
return 0;
300-
301-
same_value_overflow:
302-
PyErr_SetString(PyExc_ValueError, "overflow in 'same_value' casting");
303299
fail:
304300
NPY_END_THREADS;
305301
NPY_cast_info_xfree(&cast_info);
302+
HandleArrayMethodError(result, "astype", method_flags);
306303
return -1;
307304
}
308305

numpy/_core/src/multiarray/array_assign_scalar.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,22 @@ raw_array_assign_scalar(int ndim, npy_intp const *shape,
8585
}
8686
NPY_BEGIN_THREADS_THRESHOLDED(nitems);
8787
}
88+
8889
if (casting == NPY_SAME_VALUE_CASTING) {
89-
cast_info.context.flags |= NPY_SAME_VALUE_CASTING;
90+
/* cast_info.context.flags |= NPY_SAME_VALUE_CASTING; */
9091
PyErr_SetString(PyExc_NotImplementedError, "'same_value' casting not implemented yet");
9192
return -1;
9293
}
9394

9495
npy_intp strides[2] = {0, dst_strides_it[0]};
9596

97+
int result = 0;
9698
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
9799
/* Process the innermost dimension */
98100
char *args[2] = {src_data, dst_data};
99-
if (cast_info.func(&cast_info.context,
100-
args, &shape_it[0], strides, cast_info.auxdata) < 0) {
101+
result = cast_info.func(&cast_info.context,
102+
args, &shape_it[0], strides, cast_info.auxdata);
103+
if (result < 0) {
101104
goto fail;
102105
}
103106
} NPY_RAW_ITER_ONE_NEXT(idim, ndim, coord,
@@ -117,6 +120,7 @@ raw_array_assign_scalar(int ndim, npy_intp const *shape,
117120
fail:
118121
NPY_END_THREADS;
119122
NPY_cast_info_xfree(&cast_info);
123+
HandleArrayMethodError(result, "cast", flags);
120124
return -1;
121125
}
122126

@@ -183,23 +187,25 @@ raw_array_wheremasked_assign_scalar(int ndim, npy_intp const *shape,
183187
NPY_BEGIN_THREADS_THRESHOLDED(nitems);
184188
}
185189
if (casting == NPY_SAME_VALUE_CASTING) {
186-
cast_info.context.flags |= NPY_SAME_VALUE_CASTING;
190+
/* cast_info.context.flags |= NPY_SAME_VALUE_CASTING; */
187191
PyErr_SetString(PyExc_NotImplementedError, "'same_value' casting not implemented yet");
188192
return -1;
189193
}
190194

191195
npy_intp strides[2] = {0, dst_strides_it[0]};
196+
int result = 0;
192197

193198
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
194199
/* Process the innermost dimension */
195200
PyArray_MaskedStridedUnaryOp *stransfer;
196201
stransfer = (PyArray_MaskedStridedUnaryOp *)cast_info.func;
197202

198203
char *args[2] = {src_data, dst_data};
199-
if (stransfer(&cast_info.context,
204+
result = stransfer(&cast_info.context,
200205
args, &shape_it[0], strides,
201206
(npy_bool *)wheremask_data, wheremask_strides_it[0],
202-
cast_info.auxdata) < 0) {
207+
cast_info.auxdata);
208+
if (result < 0) {
203209
goto fail;
204210
}
205211
} NPY_RAW_ITER_TWO_NEXT(idim, ndim, coord, shape_it,
@@ -221,6 +227,7 @@ raw_array_wheremasked_assign_scalar(int ndim, npy_intp const *shape,
221227
fail:
222228
NPY_END_THREADS;
223229
NPY_cast_info_xfree(&cast_info);
230+
HandleArrayMethodError(result, "cast", flags);
224231
return -1;
225232
}
226233

numpy/_core/src/multiarray/array_coercion.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,12 @@ npy_cast_raw_scalar_item(
418418
char *args[2] = {from_item, to_item};
419419
const npy_intp strides[2] = {0, 0};
420420
const npy_intp length = 1;
421-
if (cast_info.func(&cast_info.context,
422-
args, &length, strides, cast_info.auxdata) < 0) {
421+
int result = 0;
422+
result = cast_info.func(&cast_info.context,
423+
args, &length, strides, cast_info.auxdata);
424+
if (result < 0) {
423425
NPY_cast_info_xfree(&cast_info);
426+
HandleArrayMethodError(result, "cast", flags);
424427
return -1;
425428
}
426429
NPY_cast_info_xfree(&cast_info);

numpy/_core/src/multiarray/array_method.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "convert_datatype.h"
4040
#include "common.h"
4141
#include "numpy/ufuncobject.h"
42+
#include "dtype_transfer.h"
4243

4344

4445
/*
@@ -793,12 +794,10 @@ boundarraymethod__simple_strided_call(
793794
return NULL;
794795
}
795796

796-
PyArrayMethod_Context context = {
797-
.caller = NULL,
798-
.method = self->method,
799-
.descriptors = descrs,
800-
.flags = 0,
801-
};
797+
PyArrayMethod_Context context;
798+
NPY_context_init(&context, descrs);
799+
context.method = self->method;
800+
802801
PyArrayMethod_StridedLoop *strided_loop = NULL;
803802
NpyAuxData *loop_data = NULL;
804803
NPY_ARRAYMETHOD_FLAGS flags = 0;
@@ -986,3 +985,12 @@ NPY_NO_EXPORT PyTypeObject PyBoundArrayMethod_Type = {
986985
.tp_methods = boundarraymethod_methods,
987986
.tp_getset = boundarraymethods_getters,
988987
};
988+
989+
int HandleArrayMethodError(int result, const char * name , int method_flags)
990+
{
991+
if (result == NPY_SAME_VALUE_FAILURE) {
992+
PyErr_Format(PyExc_ValueError, "'same_value' casting failure in %s", name);
993+
}
994+
return result;
995+
}
996+

numpy/_core/src/multiarray/array_method.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ PyArrayMethod_FromSpec(PyArrayMethod_Spec *spec);
122122
NPY_NO_EXPORT PyBoundArrayMethodObject *
123123
PyArrayMethod_FromSpec_int(PyArrayMethod_Spec *spec, int priv);
124124

125+
/*
126+
* Possible results to be handled in HandleArrayMethodError, after a call
127+
* to a PyArrayMethod_StridedLoop
128+
*/
129+
#define NPY_GENERIC_LOOP_FAILURE -1 /* will have set a PyErr already */
130+
#define NPY_SAME_VALUE_FAILURE -31 /* same_value casting failed */
131+
132+
int HandleArrayMethodError(int result, const char * name , int method_flags);
133+
125134
#ifdef __cplusplus
126135
}
127136
#endif

numpy/_core/src/multiarray/ctors.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2805,12 +2805,13 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
28052805
npy_intp strides[2] = {src_stride, dst_stride};
28062806

28072807
int res = 0;
2808+
int result = 0;
28082809
for(;;) {
28092810
/* Transfer the biggest amount that fits both */
28102811
count = (src_count < dst_count) ? src_count : dst_count;
2811-
if (cast_info.func(&cast_info.context,
2812-
args, &count, strides, cast_info.auxdata) < 0) {
2813-
res = -1;
2812+
result = cast_info.func(&cast_info.context,
2813+
args, &count, strides, cast_info.auxdata);
2814+
if (result < 0) {
28142815
break;
28152816
}
28162817

@@ -2852,6 +2853,10 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
28522853
if (!NpyIter_Deallocate(src_iter)) {
28532854
res = -1;
28542855
}
2856+
if (result < 0) {
2857+
HandleArrayMethodError(result, "cast", flags);
2858+
res = result;
2859+
}
28552860

28562861
if (res == 0 && !(flags & NPY_METH_NO_FLOATINGPOINT_ERRORS)) {
28572862
int fpes = npy_get_floatstatus_barrier((char *)&src_iter);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy