Skip to content

Commit 536e5fb

Browse files
committed
MNT: move initialization of global tuples to global data struct
1 parent 26c243d commit 536e5fb

File tree

5 files changed

+47
-35
lines changed

5 files changed

+47
-35
lines changed

numpy/_core/src/multiarray/ctors.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,15 +2528,6 @@ PyArray_FromArrayAttr_int(PyObject *op, PyArray_Descr *descr, int copy,
25282528
return Py_NotImplemented;
25292529
}
25302530

2531-
static PyObject *kwnames_is_copy = NULL;
2532-
if (kwnames_is_copy == NULL) {
2533-
kwnames_is_copy = Py_BuildValue("(s)", "copy");
2534-
if (kwnames_is_copy == NULL) {
2535-
Py_DECREF(array_meth);
2536-
return NULL;
2537-
}
2538-
}
2539-
25402531
Py_ssize_t nargs = 0;
25412532
PyObject *arguments[2];
25422533
PyObject *kwnames = NULL;
@@ -2552,7 +2543,7 @@ PyArray_FromArrayAttr_int(PyObject *op, PyArray_Descr *descr, int copy,
25522543
* signature of the __array__ method being called does not have `copy`.
25532544
*/
25542545
if (copy != -1) {
2555-
kwnames = kwnames_is_copy;
2546+
kwnames = npy_ma_global_data->kwnames_is_copy;
25562547
arguments[nargs] = copy == 1 ? Py_True : Py_False;
25572548
}
25582549

numpy/_core/src/multiarray/multiarraymodule.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5008,6 +5008,11 @@ initialize_static_globals(void)
50085008
}
50095009
}
50105010

5011+
npy_ma_global_data->kwnames_is_copy = Py_BuildValue("(s)", "copy");
5012+
if (npy_ma_global_data->kwnames_is_copy == NULL) {
5013+
return -1;
5014+
}
5015+
50115016
npy_ma_global_data->one_obj = PyLong_FromLong((long) 1);
50125017
if (npy_ma_global_data->one_obj == NULL) {
50135018
return -1;

numpy/_core/src/multiarray/multiarraymodule.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ typedef struct npy_ma_global_data_struct {
8989
npy_uint64 uint64;
9090
} unpack_lookup_big[256];
9191

92+
/*
93+
* Used in the __array__ internals to avoid building a tuple inline
94+
*/
95+
PyObject *kwnames_is_copy;
96+
97+
/*
98+
* Used in __imatmul__ to avoid building tuples inline
99+
*/
100+
PyObject *axes_1d_obj_kwargs;
101+
PyObject *axes_2d_obj_kwargs;
102+
92103
/*
93104
* Used for CPU feature detection and dispatch
94105
*

numpy/_core/src/multiarray/number.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
**************** Implement Number Protocol ****************************
2424
*************************************************************************/
2525

26+
// this is not in the global data struct to avoid needing to include the
27+
// definition of the NumericOps struct in multiarraymodule.h
28+
//
29+
// it is filled in during module initialization in a thread-safe manner
2630
NPY_NO_EXPORT NumericOps n_ops; /* NB: static objects initialized to zero */
2731

2832
/*
@@ -118,6 +122,20 @@ _PyArray_SetNumericOps(PyObject *dict)
118122
SET(conjugate);
119123
SET(matmul);
120124
SET(clip);
125+
126+
// initialize static globals needed for matmul
127+
npy_ma_global_data->axes_1d_obj_kwargs = Py_BuildValue(
128+
"{s, [(i), (i, i), (i)]}", "axes", -1, -2, -1, -1);
129+
if (npy_ma_global_data->axes_1d_obj_kwargs == NULL) {
130+
return -1;
131+
}
132+
133+
npy_ma_global_data->axes_2d_obj_kwargs = Py_BuildValue(
134+
"{s, [(i, i), (i, i), (i, i)]}", "axes", -2, -1, -2, -1, -2, -1);
135+
if (npy_ma_global_data->axes_2d_obj_kwargs == NULL) {
136+
return -1;
137+
}
138+
121139
return 0;
122140
}
123141

@@ -271,6 +289,12 @@ array_inplace_matrix_multiply(PyArrayObject *self, PyObject *other)
271289
INPLACE_GIVE_UP_IF_NEEDED(self, other,
272290
nb_inplace_matrix_multiply, array_inplace_matrix_multiply);
273291

292+
PyObject *args = PyTuple_Pack(3, self, other, self);
293+
if (args == NULL) {
294+
return NULL;
295+
}
296+
PyObject *kwargs;
297+
274298
/*
275299
* Unlike `matmul(a, b, out=a)` we ensure that the result is not broadcast
276300
* if the result without `out` would have less dimensions than `a`.
@@ -280,33 +304,11 @@ array_inplace_matrix_multiply(PyArrayObject *self, PyObject *other)
280304
* The error here will be confusing, but for now, we enforce this by
281305
* passing the correct `axes=`.
282306
*/
283-
static PyObject *axes_1d_obj_kwargs = NULL;
284-
static PyObject *axes_2d_obj_kwargs = NULL;
285-
if (NPY_UNLIKELY(axes_1d_obj_kwargs == NULL)) {
286-
axes_1d_obj_kwargs = Py_BuildValue(
287-
"{s, [(i), (i, i), (i)]}", "axes", -1, -2, -1, -1);
288-
if (axes_1d_obj_kwargs == NULL) {
289-
return NULL;
290-
}
291-
}
292-
if (NPY_UNLIKELY(axes_2d_obj_kwargs == NULL)) {
293-
axes_2d_obj_kwargs = Py_BuildValue(
294-
"{s, [(i, i), (i, i), (i, i)]}", "axes", -2, -1, -2, -1, -2, -1);
295-
if (axes_2d_obj_kwargs == NULL) {
296-
return NULL;
297-
}
298-
}
299-
300-
PyObject *args = PyTuple_Pack(3, self, other, self);
301-
if (args == NULL) {
302-
return NULL;
303-
}
304-
PyObject *kwargs;
305307
if (PyArray_NDIM(self) == 1) {
306-
kwargs = axes_1d_obj_kwargs;
308+
kwargs = npy_ma_global_data->axes_1d_obj_kwargs;
307309
}
308310
else {
309-
kwargs = axes_2d_obj_kwargs;
311+
kwargs = npy_ma_global_data->axes_2d_obj_kwargs;
310312
}
311313
PyObject *res = PyObject_Call(n_ops.matmul, args, kwargs);
312314
Py_DECREF(args);

numpy/_core/src/umath/umathmodule.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,12 @@ int initumath(PyObject *m)
287287

288288
s = PyDict_GetItemString(d, "conjugate");
289289
s2 = PyDict_GetItemString(d, "remainder");
290+
290291
/* Setup the array object's numerical structures with appropriate
291292
ufuncs in d*/
292-
_PyArray_SetNumericOps(d);
293+
if (_PyArray_SetNumericOps(d) < 0) {
294+
return -1;
295+
}
293296

294297
PyDict_SetItemString(d, "conj", s);
295298
PyDict_SetItemString(d, "mod", s2);

0 commit comments

Comments
 (0)