Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

in place divide and floor_divide #1587

Merged
merged 4 commits into from
Nov 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 222 additions & 38 deletions tests/test_mathematical.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,9 +1070,9 @@ def test_invalid_out(self, out):
assert_raises(TypeError, numpy.add, a.asnumpy(), 2, out)


class TestHypot:
@pytest.mark.parametrize("dtype", get_float_dtypes())
def test_hypot(self, dtype):
class TestDivide:
vtavana marked this conversation as resolved.
Show resolved Hide resolved
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
def test_divide(self, dtype):
array1_data = numpy.arange(10)
array2_data = numpy.arange(5, 15)
out = numpy.empty(10, dtype=dtype)
Expand All @@ -1081,55 +1081,169 @@ def test_hypot(self, dtype):
dp_array1 = dpnp.array(array1_data, dtype=dtype)
dp_array2 = dpnp.array(array2_data, dtype=dtype)
dp_out = dpnp.array(out, dtype=dtype)
result = dpnp.hypot(dp_array1, dp_array2, out=dp_out)
result = dpnp.divide(dp_array1, dp_array2, out=dp_out)

# original
np_array1 = numpy.array(array1_data, dtype=dtype)
np_array2 = numpy.array(array2_data, dtype=dtype)
expected = numpy.hypot(np_array1, np_array2, out=out)
expected = numpy.divide(np_array1, np_array2, out=out)

assert_allclose(expected, result)
assert_allclose(out, dp_out)
assert_dtype_allclose(result, expected)
assert_dtype_allclose(dp_out, out)

@pytest.mark.parametrize("dtype", get_float_dtypes())
@pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings")
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
def test_out_dtypes(self, dtype):
size = 10

np_array1 = numpy.arange(size, 2 * size, dtype=dtype)
np_array2 = numpy.arange(size, dtype=dtype)
np_out = numpy.empty(size, dtype=numpy.float32)
expected = numpy.hypot(np_array1, np_array2, out=np_out)
np_out = numpy.empty(size, dtype=numpy.complex64)
expected = numpy.divide(np_array1, np_array2, out=np_out)

dp_array1 = dpnp.arange(size, 2 * size, dtype=dtype)
dp_array2 = dpnp.arange(size, dtype=dtype)

dp_out = dpnp.empty(size, dtype=dpnp.float32)
if dtype != dpnp.float32:
dp_out = dpnp.empty(size, dtype=dpnp.complex64)
if dtype != dpnp.complex64:
# dtype of out mismatches types of input arrays
with pytest.raises(TypeError):
dpnp.hypot(dp_array1, dp_array2, out=dp_out)
dpnp.divide(dp_array1, dp_array2, out=dp_out)

# allocate new out with expected type
dp_out = dpnp.empty(size, dtype=dtype)

result = dpnp.hypot(dp_array1, dp_array2, out=dp_out)
result = dpnp.divide(dp_array1, dp_array2, out=dp_out)
assert_dtype_allclose(result, expected)

tol = numpy.finfo(numpy.float32).resolution
assert_allclose(expected, result, rtol=tol, atol=tol)
@pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings")
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
def test_out_overlap(self, dtype):
size = 15
# DPNP
dp_a = dpnp.arange(2 * size, dtype=dtype)
dpnp.divide(dp_a[size::], dp_a[::2], out=dp_a[:size:])

@pytest.mark.parametrize("dtype", get_float_dtypes())
# original
np_a = numpy.arange(2 * size, dtype=dtype)
numpy.divide(np_a[size::], np_a[::2], out=np_a[:size:])

assert_dtype_allclose(dp_a, np_a)

@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
def test_inplace_strided_out(self, dtype):
size = 21

np_a = numpy.arange(size, dtype=dtype)
np_a[::3] /= 4

dp_a = dpnp.arange(size, dtype=dtype)
dp_a[::3] /= 4

assert_allclose(dp_a, np_a)

@pytest.mark.parametrize(
"shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"]
)
def test_invalid_shape(self, shape):
dp_array1 = dpnp.arange(10)
dp_array2 = dpnp.arange(5, 15)
dp_out = dpnp.empty(shape)

with pytest.raises(ValueError):
dpnp.divide(dp_array1, dp_array2, out=dp_out)

@pytest.mark.parametrize(
"out",
[4, (), [], (3, 7), [2, 4]],
ids=["4", "()", "[]", "(3, 7)", "[2, 4]"],
)
def test_invalid_out(self, out):
a = dpnp.arange(10)

assert_raises(TypeError, dpnp.divide, a, 2, out)
assert_raises(TypeError, numpy.divide, a.asnumpy(), 2, out)


class TestFloorDivide:
@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_floor_divide(self, dtype):
array1_data = numpy.arange(10)
array2_data = numpy.arange(5, 15)
out = numpy.empty(10, dtype=dtype)

# DPNP
dp_array1 = dpnp.array(array1_data, dtype=dtype)
dp_array2 = dpnp.array(array2_data, dtype=dtype)
dp_out = dpnp.array(out, dtype=dtype)
result = dpnp.floor_divide(dp_array1, dp_array2, out=dp_out)

# original
np_array1 = numpy.array(array1_data, dtype=dtype)
np_array2 = numpy.array(array2_data, dtype=dtype)
expected = numpy.floor_divide(np_array1, np_array2, out=out)

assert_allclose(result, expected)
assert_allclose(dp_out, out)

@pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings")
@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_out_dtypes(self, dtype):
size = 10

np_array1 = numpy.arange(size, 2 * size, dtype=dtype)
np_array2 = numpy.arange(size, dtype=dtype)
np_out = numpy.empty(size, dtype=numpy.complex64)
expected = numpy.floor_divide(np_array1, np_array2, out=np_out)

dp_array1 = dpnp.arange(size, 2 * size, dtype=dtype)
dp_array2 = dpnp.arange(size, dtype=dtype)

dp_out = dpnp.empty(size, dtype=dpnp.complex64)
if dtype != dpnp.complex64:
# dtype of out mismatches types of input arrays
with pytest.raises(TypeError):
dpnp.floor_divide(dp_array1, dp_array2, out=dp_out)

# allocate new out with expected type
dp_out = dpnp.empty(size, dtype=dtype)

result = dpnp.floor_divide(dp_array1, dp_array2, out=dp_out)
assert_allclose(result, expected)

@pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings")
@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_out_overlap(self, dtype):
size = 15
# DPNP
dp_a = dpnp.arange(2 * size, dtype=dtype)
dpnp.hypot(dp_a[size::], dp_a[::2], out=dp_a[:size:])
dpnp.floor_divide(dp_a[size::], dp_a[::2], out=dp_a[:size:])

# original
np_a = numpy.arange(2 * size, dtype=dtype)
numpy.hypot(np_a[size::], np_a[::2], out=np_a[:size:])
numpy.floor_divide(np_a[size::], np_a[::2], out=np_a[:size:])

tol = numpy.finfo(numpy.float32).resolution
assert_allclose(np_a, dp_a, rtol=tol, atol=tol)
assert_allclose(dp_a, np_a)

@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_inplace_strided_out(self, dtype):
size = 21

np_a = numpy.arange(size, dtype=dtype)
np_a[::3] //= 4

dp_a = dpnp.arange(size, dtype=dtype)
dp_a[::3] //= 4

assert_allclose(dp_a, np_a)

@pytest.mark.parametrize(
"shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"]
Expand All @@ -1140,7 +1254,7 @@ def test_invalid_shape(self, shape):
dp_out = dpnp.empty(shape)

with pytest.raises(ValueError):
dpnp.hypot(dp_array1, dp_array2, out=dp_out)
dpnp.floor_divide(dp_array1, dp_array2, out=dp_out)

@pytest.mark.parametrize(
"out",
Expand All @@ -1150,8 +1264,8 @@ def test_invalid_shape(self, shape):
def test_invalid_out(self, out):
a = dpnp.arange(10)

assert_raises(TypeError, dpnp.hypot, a, 2, out)
assert_raises(TypeError, numpy.hypot, a.asnumpy(), 2, out)
assert_raises(TypeError, dpnp.floor_divide, a, 2, out)
assert_raises(TypeError, numpy.floor_divide, a.asnumpy(), 2, out)


class TestFmax:
Expand Down Expand Up @@ -1316,6 +1430,90 @@ def test_invalid_out(self, out):
assert_raises(TypeError, numpy.fmin, a.asnumpy(), 2, out)


class TestHypot:
@pytest.mark.parametrize("dtype", get_float_dtypes())
def test_hypot(self, dtype):
array1_data = numpy.arange(10)
array2_data = numpy.arange(5, 15)
out = numpy.empty(10, dtype=dtype)

# DPNP
dp_array1 = dpnp.array(array1_data, dtype=dtype)
dp_array2 = dpnp.array(array2_data, dtype=dtype)
dp_out = dpnp.array(out, dtype=dtype)
result = dpnp.hypot(dp_array1, dp_array2, out=dp_out)

# original
np_array1 = numpy.array(array1_data, dtype=dtype)
np_array2 = numpy.array(array2_data, dtype=dtype)
expected = numpy.hypot(np_array1, np_array2, out=out)

assert_allclose(expected, result)
assert_allclose(out, dp_out)

@pytest.mark.parametrize("dtype", get_float_dtypes())
def test_out_dtypes(self, dtype):
size = 10

np_array1 = numpy.arange(size, 2 * size, dtype=dtype)
np_array2 = numpy.arange(size, dtype=dtype)
np_out = numpy.empty(size, dtype=numpy.float32)
expected = numpy.hypot(np_array1, np_array2, out=np_out)

dp_array1 = dpnp.arange(size, 2 * size, dtype=dtype)
dp_array2 = dpnp.arange(size, dtype=dtype)

dp_out = dpnp.empty(size, dtype=dpnp.float32)
if dtype != dpnp.float32:
# dtype of out mismatches types of input arrays
with pytest.raises(TypeError):
dpnp.hypot(dp_array1, dp_array2, out=dp_out)

# allocate new out with expected type
dp_out = dpnp.empty(size, dtype=dtype)

result = dpnp.hypot(dp_array1, dp_array2, out=dp_out)

tol = numpy.finfo(numpy.float32).resolution
assert_allclose(expected, result, rtol=tol, atol=tol)

@pytest.mark.parametrize("dtype", get_float_dtypes())
def test_out_overlap(self, dtype):
size = 15
# DPNP
dp_a = dpnp.arange(2 * size, dtype=dtype)
dpnp.hypot(dp_a[size::], dp_a[::2], out=dp_a[:size:])

# original
np_a = numpy.arange(2 * size, dtype=dtype)
numpy.hypot(np_a[size::], np_a[::2], out=np_a[:size:])

tol = numpy.finfo(numpy.float32).resolution
assert_allclose(np_a, dp_a, rtol=tol, atol=tol)

@pytest.mark.parametrize(
"shape", [(0,), (15,), (2, 2)], ids=["(0,)", "(15, )", "(2,2)"]
)
def test_invalid_shape(self, shape):
dp_array1 = dpnp.arange(10)
dp_array2 = dpnp.arange(5, 15)
dp_out = dpnp.empty(shape)

with pytest.raises(ValueError):
dpnp.hypot(dp_array1, dp_array2, out=dp_out)

@pytest.mark.parametrize(
"out",
[4, (), [], (3, 7), [2, 4]],
ids=["4", "()", "[]", "(3, 7)", "[2, 4]"],
)
def test_invalid_out(self, out):
a = dpnp.arange(10)

assert_raises(TypeError, dpnp.hypot, a, 2, out)
assert_raises(TypeError, numpy.hypot, a.asnumpy(), 2, out)


class TestMaximum:
@pytest.mark.parametrize("dtype", get_all_dtypes(no_none=True))
def test_maximum(self, dtype):
Expand Down Expand Up @@ -1846,17 +2044,3 @@ def test_inplace_remainder(dtype):
dp_a %= 4

assert_allclose(dp_a, np_a)


@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_none=True, no_complex=True)
)
def test_inplace_floor_divide(dtype):
size = 21
np_a = numpy.arange(size, dtype=dtype)
dp_a = dpnp.arange(size, dtype=dtype)

np_a //= 4
dp_a //= 4

assert_allclose(dp_a, np_a)