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 
2630NPY_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 );
0 commit comments