From 1bd60c9f8e12426bcc1b6003c101cdd62fdc8126 Mon Sep 17 00:00:00 2001 From: Ryan Soklaski Date: Thu, 31 May 2018 21:34:41 -0400 Subject: [PATCH 1/2] TST: Test einsum optimize broadcasting error --- numpy/core/tests/test_einsum.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/numpy/core/tests/test_einsum.py b/numpy/core/tests/test_einsum.py index 9bd85fdb9947..f4ab5e23896d 100644 --- a/numpy/core/tests/test_einsum.py +++ b/numpy/core/tests/test_einsum.py @@ -489,8 +489,16 @@ def check_einsum_sums(self, dtype, do_opt=False): assert_array_equal(np.einsum('ij,ij->j', p, q, optimize=True), [10.] * 2) - p = np.ones((1, 5)) - q = np.ones((5, 5)) + # a blas-compatible contraction broadcasting case which was failing + # for optimize=True (ticket #10930) + x = np.array([2., 3.]) + y = np.array([4.]) + assert_array_equal(np.einsum("i, i", x, y, optimize=False), 20.) + assert_array_equal(np.einsum("i, i", x, y, optimize=True), 20.) + + # all-ones array was bypassing bug (ticket #10930) + p = np.ones((1, 5)) / 2 + q = np.ones((5, 5)) / 2 for optimize in (True, False): assert_array_equal(np.einsum("...ij,...jk->...ik", p, p, optimize=optimize), @@ -498,7 +506,7 @@ def check_einsum_sums(self, dtype, do_opt=False): optimize=optimize)) assert_array_equal(np.einsum("...ij,...jk->...ik", p, q, optimize=optimize), - np.full((1, 5), 5)) + np.full((1, 5), 1.25)) def test_einsum_sums_int8(self): self.check_einsum_sums('i1') From 0ba249a554db6031304c7eddf047e2404ba09c84 Mon Sep 17 00:00:00 2001 From: Ryan Soklaski Date: Thu, 31 May 2018 21:45:35 -0400 Subject: [PATCH 2/2] BUG: Fix check for singleton dimensions in einsum. Was checking array elements rather than array shapes for singleton dimensions. --- numpy/core/einsumfunc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpy/core/einsumfunc.py b/numpy/core/einsumfunc.py index da78748a3501..2a358edc8ad5 100644 --- a/numpy/core/einsumfunc.py +++ b/numpy/core/einsumfunc.py @@ -1109,7 +1109,7 @@ def einsum(*operands, **kwargs): # Checks have already been handled input_str, results_index = einsum_str.split('->') input_left, input_right = input_str.split(',') - if 1 in tmp_operands[0] or 1 in tmp_operands[1]: + if 1 in tmp_operands[0].shape or 1 in tmp_operands[1].shape: left_dims = {dim: size for dim, size in zip(input_left, tmp_operands[0].shape)} right_dims = {dim: size for dim, size in