diff --git a/dpnp/dpnp_utils/dpnp_utils_einsum.py b/dpnp/dpnp_utils/dpnp_utils_einsum.py index 5439230ecfb6..af87419b062a 100644 --- a/dpnp/dpnp_utils/dpnp_utils_einsum.py +++ b/dpnp/dpnp_utils/dpnp_utils_einsum.py @@ -109,29 +109,6 @@ def _compute_size_by_dict(indices, idx_dict): return ret -def _compute_size(start, shape): - """ - Compute the total size of a multi-dimensional array starting from a given index. - - Parameters - ---------- - start : int - The starting index from which to compute the size. - shape : tuple - The shape of the multi-dimensional array. - - Returns - ------- - out : int - The total size of the array. - - """ - ret = 1 - for i in range(start, len(shape)): - ret *= shape[i] - return ret - - def _einsum_diagonals(input_subscripts, operands): """ Adopted from _einsum_diagonals in cupy/core/_einsum.py @@ -818,11 +795,11 @@ def _parse_int_subscript(list_subscript): "For this input type lists must contain " "either int or Ellipsis" ) from e - if isinstance(s, int): - if not 0 <= s < len(_einsum_symbols): - raise ValueError( - f"subscript is not within the valid range [0, {len(_einsum_symbols)})." - ) + + if not 0 <= s < len(_einsum_symbols): + raise ValueError( + f"subscript is not within the valid range [0, {len(_einsum_symbols)})." + ) str_subscript += _einsum_symbols[s] return str_subscript @@ -1116,12 +1093,14 @@ def dpnp_einsum( f"'{_chr(label)}' which never appeared in an input." ) if len(output_subscript) != len(set(output_subscript)): + repeated_subscript = [] for label in output_subscript: if output_subscript.count(label) >= 2: - raise ValueError( - "einstein sum subscripts string includes output " - f"subscript '{_chr(label)}' multiple times." - ) + repeated_subscript.append(_chr(label)) + raise ValueError( + "einstein sum subscripts string includes output " + f"subscript {set(repeated_subscript)} multiple times." + ) _einsum_diagonals(input_subscripts, operands) diff --git a/dpnp/dpnp_utils/dpnp_utils_statistics.py b/dpnp/dpnp_utils/dpnp_utils_statistics.py index c86df0cc2ebf..519f064615df 100644 --- a/dpnp/dpnp_utils/dpnp_utils_statistics.py +++ b/dpnp/dpnp_utils/dpnp_utils_statistics.py @@ -25,7 +25,7 @@ import dpnp -from dpnp.dpnp_utils import get_usm_allocations +from dpnp.dpnp_utils import get_usm_allocations, map_dtype_to_device __all__ = ["dpnp_cov"] @@ -73,12 +73,7 @@ def _get_2dmin_array(x, dtype): dtypes.append(y.dtype) dtype = dpnp.result_type(*dtypes) # TODO: remove when dpctl.result_type() is returned dtype based on fp64 - fp64 = queue.sycl_device.has_aspect_fp64 - if not fp64: - if dtype == dpnp.float64: - dtype = dpnp.float32 - elif dtype == dpnp.complex128: - dtype = dpnp.complex64 + dtype = map_dtype_to_device(dtype, queue.sycl_device) X = _get_2dmin_array(m, dtype) if y is not None: diff --git a/tests/test_linalg.py b/tests/test_linalg.py index 92251da6276c..95a1a69d54ba 100644 --- a/tests/test_linalg.py +++ b/tests/test_linalg.py @@ -719,6 +719,10 @@ def test_einsum_error1(self): # different size for same label 5 != 4 assert_raises(ValueError, inp.einsum, "ii", a) + a = inp.arange(25).reshape(5, 5) + # subscript is not within the valid range [0, 52) + assert_raises(ValueError, inp.einsum, a, [53, 53]) + @pytest.mark.parametrize("do_opt", [True, False]) @pytest.mark.parametrize("xp", [numpy, inp]) def test_einsum_error2(self, do_opt, xp): @@ -1740,6 +1744,17 @@ def test_output_order(self): tmp = inp.einsum("...ft,mf->...mt", d, c, order="a", optimize=opt) assert tmp.flags.c_contiguous + def test_einsum_path(self): + # Test einsum path for covergae + a = numpy.random.rand(1, 2, 3, 4) + b = numpy.random.rand(4, 3, 2, 1) + a_dp = inp.array(a) + b_dp = inp.array(b) + expected = numpy.einsum_path("ijkl,dcba->dcba", a, b) + result = inp.einsum_path("ijkl,dcba->dcba", a_dp, b_dp) + assert expected[0] == result[0] + assert expected[1] == result[1] + class TestInv: @pytest.mark.parametrize(