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

Enhance two integration tests #511

Merged
merged 8 commits into from
Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from 3 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
90 changes: 48 additions & 42 deletions tests/integration/test_append.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,10 @@

import numpy as np
import pytest
from utils.utils import run_test

import cunumeric as num


def _run_test(arr, values, test_args):
for axis in test_args:
b = np.append(arr, values, axis)
c = num.append(arr, values, axis)
is_equal = True
err_arr = [b, c]

if len(b) != len(c):
is_equal = False
err_arr = [b, c]
else:
for each in zip(b, c):
if not np.array_equal(*each):
err_arr = each
is_equal = False
break
print_msg = (
f"np.append(array({arr.shape}), array({values.shape}), {axis})"
)
assert is_equal, (
f"Failed, {print_msg}\n"
f"numpy result: {err_arr[0]}, {b.shape}\n"
f"cunumeric_result: {err_arr[1]}, {c.shape}\n"
f"cunumeric and numpy shows"
f" different result\n"
)
print(
f"Passed, {print_msg}, np: ({b.shape}, {b.dtype})"
f", cunumeric: ({c.shape}, {c.dtype}"
)


DIM = 10

# test append w/ 1D, 2D and 3D arrays
Expand All @@ -61,6 +29,7 @@ def _run_test(arr, values, test_args):
(1, 1),
(1, 1, 1),
(1, DIM),
(1, DIM, 1),
(DIM, DIM),
(DIM, DIM, DIM),
]
Expand All @@ -69,16 +38,53 @@ def _run_test(arr, values, test_args):
@pytest.mark.parametrize("size", SIZES, ids=str)
def test_append(size):
a = np.random.randint(low=0, high=100, size=size)
test_args = [-1] + list(range(a.ndim))

test_args = list(range(a.ndim)) + [None]

# test the exception for 1D array on append
_run_test(a, a, test_args)

if a.ndim > 1:
# 1D array
b = np.random.randint(low=0, high=100, size=(DIM,))
_run_test(a, b, [None])
for axis in test_args:
size_b = list(size)
size_b[axis] = size[axis] + 10
b = np.random.randint(low=0, high=100, size=size_b)
print_msg = f"np.append(array({a.shape}), array({b.shape}), {axis})"
run_test("append", [a, b], {"axis": axis}, print_msg)


@pytest.mark.parametrize("size_b", SIZES, ids=str)
@pytest.mark.parametrize("size_a", SIZES, ids=str)
def test_append_axis_none(size_a, size_b):
axis = None
a = np.random.randint(low=0, high=100, size=size_a)
b = np.random.randint(low=0, high=100, size=size_b)
print_msg = f"np.append(array({a.shape}), array({b.shape}), {axis})"
run_test("append", [a, b], {"axis": axis}, print_msg)


class TestAppendErrors:

def setup(self):
size_a = (1, DIM)
self.a = np.random.randint(low=0, high=100, size=size_a)

def test_bad_dimension(self):
size_b = (1, DIM, 1)
b = np.random.randint(low=0, high=100, size=size_b)

msg = "All arguments to concatenate must have the " \
"same number of dimensions"
with pytest.raises(ValueError, match=msg):
num.append(self.a, b, axis=1)

def test_bad_index(self):
with pytest.raises(IndexError):
num.append(self.a, self.a, axis=5)


def test_bad_shape(self):
size_c = (10, DIM)
c = np.random.randint(low=0, high=100, size=size_c)
## In cunumeric eager execution and np, ValueError is raised
## In cunumeric gpu test, AssertionError is raised
with pytest.raises(AssertionError):
num.append(self.a, c, axis=1)


if __name__ == "__main__":
Expand Down
230 changes: 175 additions & 55 deletions tests/integration/test_array_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# limitations under the License.
#

from itertools import product

import numpy as np
import pytest

Expand All @@ -32,80 +34,167 @@ def test_array():
assert x.dtype == y.dtype


CREATION_FUNCTIONS = ("zeros", "ones")
FILLED_VALUES = [0, 1, 1000, 123.456]
SIZES = (0, 1, 2)
NDIMS = 5
DTYPES = (np.uint32, np.int32, np.float64, np.complex128)


def test_empty():
xe = num.empty((2, 3))
ye = np.empty((2, 3))
assert xe.shape == ye.shape
assert xe.dtype == ye.dtype
par = (SIZES, range(NDIMS), DTYPES)
for size, ndims, dtype in product(*par):
shape = ndims * [size]

xf = num.empty(shape, dtype=dtype)
yf = np.empty(shape, dtype=dtype)

def test_zeros():
xz = num.zeros((2, 3))
yz = np.zeros((2, 3))
assert np.array_equal(xz, yz)
assert xz.dtype == yz.dtype
assert xf.shape == yf.shape
assert xf.dtype == yf.dtype


def test_ones():
xo = num.ones((2, 3))
yo = np.ones((2, 3))
assert np.array_equal(xo, yo)
assert xo.dtype == yo.dtype
@pytest.mark.parametrize("fn", CREATION_FUNCTIONS)
def test_creation_func(fn):
num_f = getattr(num, fn)
np_f = getattr(np, fn)

par = (SIZES, range(NDIMS), DTYPES)
for size, ndims, dtype in product(*par):
shape = ndims * [size]

def test_full():
xf = num.full((2, 3), 3)
yf = np.full((2, 3), 3)
assert np.array_equal(xf, yf)
assert xf.dtype == yf.dtype
xf = num_f(shape, dtype=dtype)
yf = np_f(shape, dtype=dtype)

assert np.array_equal(xf, yf)
assert xf.dtype == yf.dtype

def test_empty_like():
x = num.array([1, 2, 3])
y = num.array(x)
xel = num.empty_like(x)
yel = np.empty_like(y)
assert xel.shape == yel.shape
assert xel.dtype == yel.dtype

@pytest.mark.parametrize("value", FILLED_VALUES)
def test_full(value):
par = (SIZES, range(NDIMS), DTYPES)
for size, ndims, dtype in product(*par):
shape = ndims * [size]

def test_zeros_like():
x = num.array([1, 2, 3])
y = num.array(x)
xzl = num.zeros_like(x)
yzl = np.zeros_like(y)
assert np.array_equal(xzl, yzl)
assert xzl.dtype == yzl.dtype
xf = num.full(shape, value, dtype=dtype)
yf = np.full(shape, value, dtype=dtype)

assert np.array_equal(xf, yf)
assert xf.dtype == yf.dtype

def test_ones_like():
x = num.array([1, 2, 3])
y = num.array(x)
xol = num.ones_like(x)
yol = np.ones_like(y)
assert np.array_equal(xol, yol)
assert xol.dtype == yol.dtype

SHAPES_NEGATIVE = [
-1,
(-1, 2, 3),
## it raises RuntimeError("Unable to find attachment to remove")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@magnatelee Is this expected or an issue here? Thanks

## when num.array is removed at the end as global variable
# num.array([2, -3, 4]),
np.array([2, -3, 4]),
]


@pytest.mark.parametrize('shape', SHAPES_NEGATIVE, ids=str)
class TestCreationErrors:

def test_empty_with_negative_shape(self, shape):
with pytest.raises(ValueError):
num.empty(shape)

def test_zeros_with_negative_shape(self, shape):
with pytest.raises(ValueError):
num.zeros(shape)

def test_ones_with_negative_shape(self, shape):
with pytest.raises(ValueError):
num.ones(shape)

def test_full_with_negative_shape(self, shape):
with pytest.raises(ValueError):
num.full(shape, 10)


# additional special case for full
def test_full_assertion():
## pass in cunumeric + gpu, but fail for
## cunumeric + eager execution
## num.full((2, 3), [1])
with pytest.raises(AssertionError):
num.full((2, 3), [10, 20, 30])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest splitting these individual cases into individual tests, similar to the suggestion above. Then also the shape could be passed using pytest.mark.parametrize, which could be applied to the class:

@pytest.mark.parametrize('shape', shapes)
class TestCreationErrors:

    def test_empty(self, shape):
        with pytest.raises(ValueError):
            num.empty(shape)

    def test_zeros(self, shape):
        with pytest.raises(ValueError):
            num.zeros(shape)

    .....

# additional special case for full
def test_creation_full_assertion():
    num.full((2, 3), [1])
    with pytest.raises(AssertionError):
        num.full((2, 3), [10, 20, 30])

Though, my same concern above about AssertionError also applies here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's found only in eager execution test, it raises ValueError. In other tests, it raises AssertionError.



DATA_ARGS = [
# Array scalars
(np.array(3.0), None),
(np.array(3), "f8"),
# 1D arrays
(np.array([]), None),
(np.arange(6, dtype="f4"), None),
(np.arange(6), "c16"),
# 2D arrays
(np.array([[]]), None),
(np.arange(6).reshape(2, 3), None),
(np.arange(6).reshape(3, 2), "i1"),
# 3D arrays
(np.arange(24).reshape(2, 3, 4), None),
(np.arange(24).reshape(4, 3, 2), "f4"),
]
LIKE_FUNCTIONS = ("zeros_like", "ones_like")


@pytest.mark.parametrize("x_np,dtype", DATA_ARGS)
def test_empty_like(x_np, dtype):
x = num.array(x_np)
xfl = num.empty_like(x, dtype=dtype)
yfl = np.empty_like(x_np, dtype=dtype)

assert xfl.shape == yfl.shape
assert xfl.dtype == yfl.dtype


@pytest.mark.parametrize("x_np,dtype", DATA_ARGS)
@pytest.mark.parametrize("fn", LIKE_FUNCTIONS)
def test_func_like(fn, x_np, dtype):
num_f = getattr(num, fn)
np_f = getattr(np, fn)

x = num.array(x_np)
xfl = num_f(x, dtype=dtype)
yfl = np_f(x_np, dtype=dtype)

def test_full_like():
x = num.array([1, 2, 3])
y = num.array(x)
xfl = num.full_like(x, 3)
yfl = np.full_like(y, 3)
assert np.array_equal(xfl, yfl)
assert xfl.dtype == yfl.dtype

# xfls = num.full_like(x, '3', dtype=np.str_)
# yfls = np.full_like(y, '3', dtype=np.str_)
# assert(num.array_equal(xfls, yfls))
# assert(xfls.dtype == yfls.dtype)

@pytest.mark.parametrize("value", FILLED_VALUES)
@pytest.mark.parametrize("x_np, dtype", DATA_ARGS)
def test_full_like(x_np, dtype, value):
x = num.array(x_np)

xfl = num.full_like(x, value, dtype=dtype)
yfl = np.full_like(x_np, value, dtype=dtype)
assert np.array_equal(xfl, yfl)
assert xfl.dtype == yfl.dtype


def test_full_like_assertion():
x = num.array([[1, 2, 3],[4, 5, 6]])
## pass in cunumeric + gpu, but fail for
## cunumeric + eager execution
## num.full_like(x, [1])
with pytest.raises(AssertionError):
num.full_like(x, [10, 20, 30])


ARANGE_ARGS = [
(1,),
(0,),
(10,),
(2.0, 10.0),
(2, 30, 3),
(3.5,),
(2, 10),
(-2.5, 10.0),
### output: num: array([ 1, -1, -3, -5, -7]),
### np: array([ 1. , -1.5, -4. , -6.5, -9. ]
# (1, -10, -2.5),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@magnatelee Is this difference in results between numpy and cunumeric here expected or a bug?

(1.0, -10.0, -2.5),
(-10, 10, 10),
]


Expand All @@ -117,13 +206,44 @@ def test_arange(args):
assert x.dtype == y.dtype


def test_arange_with_dtype():
x = num.arange(10, dtype=np.int32)
y = np.arange(10, dtype=np.int32)
@pytest.mark.parametrize("dtype", [np.int32, np.float64], ids=str)
@pytest.mark.parametrize("args", ARANGE_ARGS, ids=str)
def test_arange_with_dtype(args, dtype):
x = num.arange(*args, dtype=dtype)
y = np.arange(*args, dtype=dtype)
assert np.array_equal(x, y)
assert x.dtype == y.dtype


class TestArrangeErrors:

def test_negative_sizes(self):
with pytest.raises(ValueError):
###np.arange(-10) returns [] successfully
num.arange(-10)
with pytest.raises(ValueError):
###np.arange(2, -10) returns [] successfully
num.arange(2, -10)

def test_inf(self):
with pytest.raises(OverflowError):
num.arange(0, num.inf)

def test_nan(self):
with pytest.raises(ValueError):
num.arange(0, 1, num.nan)

def test_zero_division(self):
with pytest.raises(ZeroDivisionError):
num.arange(0, 10, 0)
with pytest.raises(ZeroDivisionError):
num.arange(0.0, 10.0, 0.0)
with pytest.raises(ZeroDivisionError):
num.arange(0, 0, 0)
with pytest.raises(ZeroDivisionError):
num.arange(0.0, 0.0, 0.0)
bryevdv marked this conversation as resolved.
Show resolved Hide resolved


def test_zero_with_nd_ndarray_shape():
shape = num.array([2, 3, 4])
x = num.zeros(shape)
Expand Down
Loading