diff --git a/tests/integration/test_extract.py b/tests/integration/test_extract.py index bb873a235a..689d4601a6 100644 --- a/tests/integration/test_extract.py +++ b/tests/integration/test_extract.py @@ -205,8 +205,27 @@ def test_place_mask_reshape(shape, vals): arr_np = mk_seq_array(np, shape) arr_num = mk_seq_array(num, shape) - mask_np = (arr_np % 2).astype(bool) - mask_num = (arr_np % 2).astype(bool) + mask_np = np.arange(0, arr_np.size).astype(bool) + mask_num = num.arange(0, arr_num.size).astype(bool) + + vals_np = np.array(vals).astype(arr_np.dtype) + vals_num = num.array(vals_np) + + np.place(arr_np, mask_np, vals_np) + num.place(arr_num, mask_num, vals_num) + + assert np.array_equal(arr_np, arr_num) + + +@pytest.mark.parametrize("dtype", (np.float32, np.complex64), ids=str) +def test_place_mask_dtype(dtype): + shape = (3, 2, 3) + vals = [42 + 3j] + arr_np = mk_seq_array(np, shape) + arr_num = mk_seq_array(num, shape) + + mask_np = mk_seq_array(np, shape).astype(dtype) + mask_num = mk_seq_array(num, shape).astype(dtype) vals_np = np.array(vals).astype(arr_np.dtype) vals_num = num.array(vals_np) diff --git a/tests/integration/test_prod.py b/tests/integration/test_prod.py index d6935cb74e..ef3b217ce5 100644 --- a/tests/integration/test_prod.py +++ b/tests/integration/test_prod.py @@ -78,10 +78,8 @@ ARR = ([], [[]], [[], []], np.inf, np.Inf, -10.3, 0, 200, 5 + 8j) -DTYPE = ["l", "L", "f", "e", "d"] -COMPLEX_TYPE = ["F"] -NEGATIVE_COMPLEX_TYPE = ["D"] -NEGATIVE_DTYPE = ["h", "i", "H", "I", "?", "b", "B"] +DTYPE = ("l", "L", "f", "e", "d") +INTEGER_DTYPE = ("h", "i", "H", "I", "?", "b", "B") def to_dtype(s): @@ -97,57 +95,26 @@ class TestProdNegative(object): def test_array(self, arr): assert allclose(np.prod(arr), num.prod(arr)) - @pytest.mark.xfail - @pytest.mark.parametrize("dtype", NEGATIVE_DTYPE, ids=to_dtype) - def test_dtype_negative(self, dtype): - size = (5, 5, 5) - arr = np.random.random(size) * 10 + 2 - arr_np = np.array(arr, dtype=dtype) - arr_num = num.array(arr_np) - out_np = np.prod(arr_np) # Numpy return product of all datas - out_num = num.prod(arr_num) - # cuNumeric return an array with a different data - assert allclose(out_np, out_num) - - @pytest.mark.skip - @pytest.mark.parametrize("dtype", NEGATIVE_COMPLEX_TYPE, ids=to_dtype) - def test_dtype_complex_negative(self, dtype): - arr = (num.random.rand(5, 5) * 10 + 2) + ( - num.random.rand(5, 5) * 10 * 1.0j + 0.2j - ) - arr_np = np.array(arr, dtype=dtype) - arr_num = num.array(arr_np) - out_np = np.prod(arr_np) - out_num = num.prod(arr_num) - assert allclose(out_np, out_num) - def test_axis_out_bound(self): + expected_exc = np.AxisError arr = [-1, 0, 1, 2, 10] - msg = r"bounds" - with pytest.raises(np.AxisError, match=msg): + with pytest.raises(expected_exc): + np.prod(arr, axis=2) + with pytest.raises(expected_exc): num.prod(arr, axis=2) - @pytest.mark.xfail - @pytest.mark.parametrize("axis", ((-1, 1), (0, 1), (1, 2), (0, 2))) - def test_axis_tuple(self, axis): - size = (5, 5, 5) - arr_np = np.random.random(size) * 10 - arr_num = num.array(arr_np) - out_np = np.prod(arr_np, axis=axis) - # cuNumeric raises NotImplementedError: - # Need support for reducing multiple dimensions. - # Numpy get results. - out_num = num.prod(arr_num, axis=axis) - assert allclose(out_np, out_num) - def test_out_negative(self): + expected_exc = ValueError in_shape = (2, 3, 4) out_shape = (2, 3, 3) - arr_num = num.random.random(in_shape) * 10 - arr_out = num.random.random(out_shape) * 10 - msg = r"shapes do not match" - with pytest.raises(ValueError, match=msg): - num.prod(arr_num, out=arr_out, axis=2) + arr_np = np.ndarray(in_shape) + out_np = np.ndarray(out_shape) + arr_num = num.ndarray(in_shape) + out_num = num.ndarray(out_shape) + with pytest.raises(expected_exc): + np.prod(arr_np, out=out_np, axis=2) + with pytest.raises(expected_exc): + num.prod(arr_num, out=out_num, axis=2) def test_keepdims(self): in_shape = (2, 3, 4) @@ -157,23 +124,21 @@ def test_keepdims(self): out_num = num.prod(arr_num, axis=2, keepdims=True) assert allclose(out_np, out_num) - @pytest.mark.xfail - def test_initial_scalar_list(self): + @pytest.mark.parametrize( + "initial", + ([2, 3], pytest.param([3], marks=pytest.mark.xfail)), + ids=str, + ) + def test_initial_list(self, initial): + expected_exc = ValueError arr = [[1, 2], [3, 4]] - initial_value = [3] - - out_num = num.prod(arr, initial=initial_value) # array(72) # Numpy raises ValueError: # Input object to FillWithScalar is not a scalar - out_np = np.prod(arr, initial=initial_value) - - assert allclose(out_np, out_num) - - def test_initial_list(self): - arr = [[1, 2], [3, 4]] - initial_value = [2, 3] - with pytest.raises(ValueError): - num.prod(arr, initial=initial_value) + with pytest.raises(expected_exc): + np.prod(arr, initial=initial) + # when LEGATE_TEST=1, cuNumeric casts list to scalar and proceeds + with pytest.raises(expected_exc): + num.prod(arr, initial=initial) def test_initial_empty_array(self): size = (1, 0) @@ -206,6 +171,7 @@ def test_basic(self, size): out_np = np.prod(arr_np) out_num = np.prod(arr_num) assert allclose(out_np, out_num) + assert allclose(out_num, arr_num.prod()) @pytest.mark.parametrize("dtype", DTYPE, ids=to_dtype) def test_dtype(self, dtype): @@ -217,15 +183,43 @@ def test_dtype(self, dtype): out_num = num.prod(arr_num) assert allclose(out_np, out_num) - @pytest.mark.parametrize("dtype", COMPLEX_TYPE, ids=to_dtype) + @pytest.mark.xfail(reason="numpy and cunumeric return different dtypes") + @pytest.mark.parametrize("dtype", INTEGER_DTYPE, ids=to_dtype) + def test_dtype_integer_precision(self, dtype): + arr_np = np.arange(0, 5).astype(dtype) + arr_num = num.arange(0, 5).astype(dtype) + out_np = np.prod(arr_np) + out_num = num.prod(arr_num) + assert allclose(out_num, arr_num.prod()) + # When input precision is less than default platform integer + # NumPy returns the product with dtype of platform integer + # cuNumeric returns the product with dtype of the input array + assert allclose(out_np, out_num) + + @pytest.mark.parametrize( + "dtype", + ( + "F", + pytest.param("D", marks=pytest.mark.xfail), + pytest.param("G", marks=pytest.mark.xfail), + ), + ids=to_dtype, + ) def test_dtype_complex(self, dtype): - arr = (num.random.rand(5, 5) * 10 + 2) + ( - num.random.rand(5, 5) * 10 * 1.0j + 0.2j + arr = (np.random.rand(5, 5) * 10 + 2) + ( + np.random.rand(5, 5) * 10 * 1.0j + 0.2j ) arr_np = np.array(arr, dtype=dtype) - arr_num = num.array(arr_np) + arr_num = num.array(arr, dtype=dtype) out_np = np.prod(arr_np) + # cunumeric always returns [1+0.j] when LEGATE_TEST=1 out_num = num.prod(arr_num) + # When running tests with CUNUMERIC_TEST=1 and dtype is complex256, + # allclose hits assertion error: + # File "/legate/cunumeric/cunumeric/eager.py", line 293, + # in to_deferred_array + # assert self.runtime.is_supported_type(self.array.dtype) + # AssertionError assert allclose(out_np, out_num) @pytest.mark.parametrize("axis", (_ for _ in range(-2, 3, 1))) @@ -237,6 +231,23 @@ def test_axis_basic(self, axis): out_np = np.prod(arr_np, axis=axis) assert allclose(out_np, out_num) + @pytest.mark.xfail(reason="cunumeric raises exceptions when LEGATE_TEST=1") + @pytest.mark.parametrize( + "axis", ((-1, 1), (0, 1), (1, 2), (0, 2)), ids=str + ) + def test_axis_tuple(self, axis): + size = (5, 5, 5) + arr_np = np.random.random(size) * 10 + arr_num = num.array(arr_np) + out_np = np.prod(arr_np, axis=axis) + # when LEGATE_TEST = 1 cuNumeric raises two types of exceptions + # (-1, 1): ValueError: Invalid promotion on dimension 2 for a 1-D store + # others: + # NotImplementedError: Need support for reducing multiple dimensions + # Numpy get results. + out_num = num.prod(arr_num, axis=axis) + assert allclose(out_np, out_num) + @pytest.mark.parametrize("size", SIZES) def test_out_basic(self, size): arr_np = np.random.random(size)