summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/einsum.c.src20
-rw-r--r--numpy/core/src/multiarray/einsum_sumprod.c.src25
-rw-r--r--numpy/core/tests/test_einsum.py15
3 files changed, 36 insertions, 24 deletions
diff --git a/numpy/core/src/multiarray/einsum.c.src b/numpy/core/src/multiarray/einsum.c.src
index 856dce11b..fe7fd0d32 100644
--- a/numpy/core/src/multiarray/einsum.c.src
+++ b/numpy/core/src/multiarray/einsum.c.src
@@ -534,11 +534,13 @@ unbuffered_loop_nop1_ndim2(NpyIter *iter)
* loop provided by the iterator is in Fortran-order.
*/
int needs_api = NpyIter_IterationNeedsAPI(iter);
- NPY_BEGIN_THREADS_THRESHOLDED(shape[1] * shape[0]);
+ if (!needs_api) {
+ NPY_BEGIN_THREADS_THRESHOLDED(shape[1] * shape[0]);
+ }
for (coord = shape[1]; coord > 0; --coord) {
sop(1, ptrs[0], strides[0], shape[0]);
- if(needs_api && PyErr_Occurred()){
+ if (needs_api && PyErr_Occurred()){
return -1;
}
@@ -593,12 +595,14 @@ unbuffered_loop_nop1_ndim3(NpyIter *iter)
* loop provided by the iterator is in Fortran-order.
*/
int needs_api = NpyIter_IterationNeedsAPI(iter);
- NPY_BEGIN_THREADS_THRESHOLDED(shape[2] * shape[1] * shape[0]);
+ if (!needs_api) {
+ NPY_BEGIN_THREADS_THRESHOLDED(shape[2] * shape[1] * shape[0]);
+ }
for (coords[1] = shape[2]; coords[1] > 0; --coords[1]) {
for (coords[0] = shape[1]; coords[0] > 0; --coords[0]) {
sop(1, ptrs[0], strides[0], shape[0]);
- if(needs_api && PyErr_Occurred()){
+ if (needs_api && PyErr_Occurred()){
return -1;
}
@@ -655,7 +659,9 @@ unbuffered_loop_nop2_ndim2(NpyIter *iter)
* loop provided by the iterator is in Fortran-order.
*/
int needs_api = NpyIter_IterationNeedsAPI(iter);
- NPY_BEGIN_THREADS_THRESHOLDED(shape[1] * shape[0]);
+ if (!needs_api) {
+ NPY_BEGIN_THREADS_THRESHOLDED(shape[1] * shape[0]);
+ }
for (coord = shape[1]; coord > 0; --coord) {
sop(2, ptrs[0], strides[0], shape[0]);
@@ -716,7 +722,9 @@ unbuffered_loop_nop2_ndim3(NpyIter *iter)
* loop provided by the iterator is in Fortran-order.
*/
int needs_api = NpyIter_IterationNeedsAPI(iter);
- NPY_BEGIN_THREADS_THRESHOLDED(shape[2] * shape[1] * shape[0]);
+ if (!needs_api) {
+ NPY_BEGIN_THREADS_THRESHOLDED(shape[2] * shape[1] * shape[0]);
+ }
for (coords[1] = shape[2]; coords[1] > 0; --coords[1]) {
for (coords[0] = shape[1]; coords[0] > 0; --coords[0]) {
sop(2, ptrs[0], strides[0], shape[0]);
diff --git a/numpy/core/src/multiarray/einsum_sumprod.c.src b/numpy/core/src/multiarray/einsum_sumprod.c.src
index fa59223fe..5f2ccf2dc 100644
--- a/numpy/core/src/multiarray/einsum_sumprod.c.src
+++ b/numpy/core/src/multiarray/einsum_sumprod.c.src
@@ -1032,20 +1032,14 @@ bool_sum_of_products_outstride0_@noplabel@(int nop, char **dataptr,
* object_sum_of_products_one,
* object_sum_of_products_two,
* object_sum_of_products_three,
+ * object_sum_of_products_contig_any,
* object_sum_of_products_contig_one,
- * object_sum_of_products_contig_two,
- * object_sum_of_products_stride0_contig_outcontig_two,
- * object_sum_of_products_contig_stride0_outcontig_two,
- * object_sum_of_products_stride0_contig_outstride0_two,
- * object_sum_of_products_contig_stride0_outstride0_two,
- * object_sum_of_products_contig_contig_outstride0_two,
+ * object_sum_of_products_contig_two,
* object_sum_of_products_contig_three,
- * object_sum_of_products_contig_any,
- * object_sum_of_products_contig_outstride0_one,
+ * object_sum_of_products_outstride0_any,
* object_sum_of_products_outstride0_one,
* object_sum_of_products_outstride0_two,
- * object_sum_of_products_outstride0_three,
- * object_sum_of_products_outstride0_any#
+ * object_sum_of_products_outstride0_three#
*/
static void
@fn_name@(int nop, char **dataptr,
@@ -1062,17 +1056,12 @@ static void
if (!curr) {
curr = Py_None; // convention is to treat nulls as None
}
- Py_SETREF(prod, PyNumber_Multiply(curr, prod));
+ Py_SETREF(prod, PyNumber_Multiply(prod, curr));
if (!prod) {
return;
}
}
- if (*(PyObject **)dataptr[nop] == NULL) {
- Py_DECREF(prod);
- return;
- }
-
PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
Py_DECREF(prod);
if (!sum) {
@@ -1110,7 +1099,7 @@ _contig_outstride0_unary_specialization_table[NPY_NTYPES] = {
* 1, 1,
* 1, 1, 1,
* 1, 1, 1,
- * 1, 0, 0, 0,
+ * 0, 0, 0, 0,
* 0, 0, 1#
*/
#if @use@
@@ -1141,7 +1130,7 @@ static sum_of_products_fn _binary_specialization_table[NPY_NTYPES][5] = {
* 1, 1,
* 1, 1, 1,
* 0, 0, 0,
- * 1, 0, 0, 0,
+ * 0, 0, 0, 0,
* 0, 0, 1#
*/
#if @use@
diff --git a/numpy/core/tests/test_einsum.py b/numpy/core/tests/test_einsum.py
index bcf23890c..3a06d119f 100644
--- a/numpy/core/tests/test_einsum.py
+++ b/numpy/core/tests/test_einsum.py
@@ -699,6 +699,21 @@ class TestEinsum:
# see issue gh-15776 and issue gh-15256
assert_equal(np.einsum('i,j', [1], [2], out=None), [[2]])
+ def test_object_loop(self):
+
+ class Mult:
+ def __mul__(self, other):
+ return 42
+
+ objMult = np.array([Mult()])
+ objNULL = np.ndarray(buffer = b'\0' * np.intp(0).itemsize, shape=1, dtype=object)
+
+ with pytest.raises(TypeError):
+ np.einsum("i,j", [1], objNULL)
+ with pytest.raises(TypeError):
+ np.einsum("i,j", objNULL, [1])
+ assert np.einsum("i,j", objMult, objMult) == 42
+
def test_subscript_range(self):
# Issue #7741, make sure that all letters of Latin alphabet (both uppercase & lowercase) can be used
# when creating a subscript from arrays