Skip to content

Commit 9df6278

Browse files
committed
Add tests
1 parent 9e728f0 commit 9df6278

File tree

6 files changed

+126
-40
lines changed

6 files changed

+126
-40
lines changed

tripy/tests/integration/test_cast.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,27 @@
2323
from tests.conftest import skip_if_older_than_sm89
2424
from tests.helper import NUMPY_TO_TRIPY
2525

26+
dtype_pairs = [
27+
(np.int32, np.float32),
28+
(np.float32, np.int32),
29+
(np.int32, np.int8),
30+
(np.float32, np.int8),
31+
(np.int8, np.int32),
32+
(np.int8, np.float32),
33+
# important to test conversion into bool because default StableHLO semantics
34+
# are simply to truncate to i1, which is not desirable
35+
(np.float32, bool),
36+
(np.int32, bool),
37+
# requires a dequantization first
38+
# TODO(#219): Dequantize fails with dynamic shapes
39+
# (np.int8, bool),
40+
]
41+
2642

2743
class TestCast:
2844
@pytest.mark.parametrize(
2945
"input_dtype, target_dtype",
30-
[
31-
(np.int32, np.float32),
32-
(np.float32, np.int32),
33-
(np.int32, np.int8),
34-
(np.float32, np.int8),
35-
(np.int8, np.int32),
36-
(np.int8, np.float32),
37-
# important to test conversion into bool because default StableHLO semantics
38-
# are simply to truncate to i1, which is not desirable
39-
(np.float32, bool),
40-
(np.int32, bool),
41-
# requires a dequantization first
42-
# TODO(#219): Dequantize fails with dynamic shapes
43-
# (np.int8, bool),
44-
],
46+
dtype_pairs,
4547
)
4648
def test_cast(self, input_dtype, target_dtype, eager_or_compiled):
4749
tp_target_dtype = NUMPY_TO_TRIPY[target_dtype]
@@ -83,3 +85,18 @@ def test_cast_from_bool(self, target_dtype, eager_or_compiled):
8385

8486
np_compare_to_zero = np_input.astype(target_dtype) == 0
8587
assert np.array_equal(tp_compare_to_zero, np_compare_to_zero)
88+
89+
@pytest.mark.parametrize(
90+
"input_dtype, target_dtype",
91+
dtype_pairs,
92+
)
93+
def test_cast_tensor_method(self, input_dtype, target_dtype, eager_or_compiled):
94+
"""Test that tensor.cast() method works and produces same result as free function."""
95+
tp_target_dtype = NUMPY_TO_TRIPY[target_dtype]
96+
97+
input_tensor = tp.copy(tp.Tensor(np.ones((2, 3), dtype=input_dtype)), tp.device("gpu"))
98+
99+
output = eager_or_compiled(lambda t: t.cast(tp_target_dtype), input_tensor)
100+
101+
np_input = cp.from_dlpack(input_tensor).get()
102+
assert np.array_equal(cp.from_dlpack(output).get(), np_input.astype(target_dtype))

tripy/tests/integration/test_copy.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,40 @@
1616
import numpy as np
1717
import nvtripy as tp
1818

19+
import pytest
20+
1921

2022
class TestCopy:
21-
def test_to_cpu(self):
23+
@pytest.mark.parametrize(
24+
"copy_func",
25+
[
26+
lambda tensor, device: tp.copy(tensor, device), # Free function
27+
lambda tensor, device: tensor.copy(device), # Tensor method
28+
],
29+
)
30+
def test_copy_tensor_method(self, copy_func):
31+
"""Test that both copy methods work with compilation."""
2232
gpu_tensor = tp.Tensor(cp.ones((2, 2), dtype=cp.float32))
2333
assert gpu_tensor.device.kind == "gpu"
2434

25-
cpu_tensor = tp.copy(gpu_tensor, tp.device("cpu"))
26-
assert cpu_tensor.device.kind == "cpu"
35+
cpu_tensor = copy_func(gpu_tensor, tp.device("cpu"))
2736

37+
assert cpu_tensor.device.kind == "cpu"
2838
# If the tensor is really in CPU memory, we should be able to construct a NumPy array from it
2939
assert np.from_dlpack(cpu_tensor).shape == (2, 2)
3040

31-
def test_to_gpu(self):
41+
@pytest.mark.parametrize(
42+
"copy_func",
43+
[
44+
lambda tensor, device: tp.copy(tensor, device), # Free function
45+
lambda tensor, device: tensor.copy(device), # Tensor method
46+
],
47+
)
48+
def test_to_gpu(self, copy_func):
3249
cpu_tensor = tp.Tensor(np.ones((2, 2), dtype=np.float32))
3350
assert cpu_tensor.device.kind == "cpu"
3451

35-
gpu_tensor = tp.copy(cpu_tensor, tp.device("gpu"))
52+
gpu_tensor = copy_func(cpu_tensor, tp.device("gpu"))
3653
assert gpu_tensor.device.kind == "gpu"
3754

3855
# If the tensor is really in GPU memory, we should be able to construct a Cupy array from it

tripy/tests/integration/test_flatten.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,19 @@
1717
import pytest
1818
import nvtripy as tp
1919

20+
test_cases = [
21+
((2, 3, 4), 0, -1, (24,)), # Flatten all dimensions
22+
((2, 3, 4), 1, -1, (2, 12)), # Flatten dimensions 1 through end
23+
((2, 3, 4), 1, 2, (2, 12)), # Flatten dimensions 1 through 2
24+
((2, 3, 4), 0, 1, (6, 4)), # Flatten dimensions 0 through 1
25+
((2, 3, 4, 5), 1, 3, (2, 60)), # Flatten dimensions 1 through 3
26+
]
27+
2028

2129
class TestFlatten:
2230
@pytest.mark.parametrize(
2331
"shape, start_dim, end_dim, expected_shape",
24-
[
25-
((2, 3, 4), 0, -1, (24,)), # Flatten all dimensions
26-
((2, 3, 4), 1, -1, (2, 12)), # Flatten dimensions 1 through end
27-
((2, 3, 4), 1, 2, (2, 12)), # Flatten dimensions 1 through 2
28-
((2, 3, 4), 0, 1, (6, 4)), # Flatten dimensions 0 through 1
29-
((2, 3, 4, 5), 1, 3, (2, 60)), # Flatten dimensions 1 through 3
30-
],
32+
test_cases,
3133
)
3234
def test_flatten(self, shape, start_dim, end_dim, expected_shape, eager_or_compiled):
3335
cp_a = cp.arange(np.prod(shape)).reshape(shape).astype(np.float32)
@@ -55,3 +57,15 @@ def test_flatten_with_unknown_dims(self, eager_or_compiled):
5557
a = tp.ones((2, 3, 4, 5))
5658
b = eager_or_compiled(tp.flatten, a, start_dim=1, end_dim=-1)
5759
assert np.array_equal(cp.from_dlpack(b).get(), np.ones((2, 60), dtype=np.float32))
60+
61+
@pytest.mark.parametrize(
62+
"shape, start_dim, end_dim, expected_shape",
63+
test_cases,
64+
)
65+
def test_flatten_tensor_method(self, shape, start_dim, end_dim, expected_shape, eager_or_compiled):
66+
"""Test that tensor.flatten() method works and produces same result as free function."""
67+
cp_a = cp.arange(np.prod(shape)).reshape(shape).astype(np.float32)
68+
a = tp.Tensor(cp_a)
69+
b = eager_or_compiled(lambda t: t.flatten(start_dim=start_dim, end_dim=end_dim), a)
70+
assert b.shape == expected_shape
71+
assert np.array_equal(cp.from_dlpack(b).get(), cp_a.reshape(expected_shape).get())

tripy/tests/integration/test_reshape.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@
2020
import pytest
2121
import nvtripy as tp
2222

23+
test_cases = [
24+
((2, 4), (1, 8)),
25+
((2, 4, 8, 9), (8, 8, 9)),
26+
((2, 4), (8,)), # change rank of output
27+
((2, 4), (1, -1)), # check negative dim
28+
]
29+
2330

2431
class TestReshape:
2532
@pytest.mark.parametrize(
2633
"shape, new_shape",
27-
[
28-
((2, 4), (1, 8)),
29-
((2, 4, 8, 9), (8, 8, 9)),
30-
((2, 4), (8,)), # change rank of output
31-
((2, 4), (1, -1)), # check negative dim
32-
],
34+
test_cases,
3335
)
3436
def test_static_reshape(self, shape, new_shape, eager_or_compiled):
3537
cp_a = cp.arange(np.prod(shape)).reshape(shape).astype(np.float32)
@@ -49,3 +51,16 @@ def test_reshape_shape_with_unknown(self, eager_or_compiled):
4951
a = tp.ones((2, 3, 4))
5052
out = eager_or_compiled(tp.reshape, a, (2, a.shape[1], a.shape[2] / 2, -1))
5153
assert np.array_equal(cp.from_dlpack(out).get(), np.ones((2, 3, 2, 2), dtype=np.float32))
54+
55+
@pytest.mark.parametrize(
56+
"shape, new_shape",
57+
test_cases,
58+
)
59+
def test_reshape_tensor_method(self, shape, new_shape, eager_or_compiled):
60+
"""Test that tensor.reshape() method works and produces same result as free function."""
61+
cp_a = cp.arange(np.prod(shape)).reshape(shape).astype(np.float32)
62+
a = tp.Tensor(cp_a)
63+
b = eager_or_compiled(lambda t: t.reshape(new_shape), a)
64+
if -1 in new_shape:
65+
new_shape = tuple(np.prod(shape) // -np.prod(new_shape) if d == -1 else d for d in new_shape)
66+
assert np.array_equal(cp.from_dlpack(b).get(), cp_a.reshape(new_shape).get())

tripy/tests/integration/test_squeeze.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,18 +15,30 @@
1515
import nvtripy as tp
1616
import pytest
1717

18+
test_cases = [
19+
((1, 2, 1), 0, (2, 1)), # Squeeze first dimension
20+
((1, 2, 1), (0, 2), (2,)), # Squeeze first and third dimensions
21+
((1, 2, 1), tuple(), (1, 2, 1)), # No dimensions to squeeze
22+
((1, 2, 1), (-3, -1), (2,)), # Squeeze using negative dimensions
23+
]
24+
1825

1926
class TestSqueeze:
2027
@pytest.mark.parametrize(
2128
"input_shape, dims, expected_shape",
22-
[
23-
((1, 2, 1), 0, (2, 1)), # Squeeze first dimension
24-
((1, 2, 1), (0, 2), (2,)), # Squeeze first and third dimensions
25-
((1, 2, 1), tuple(), (1, 2, 1)), # No dimensions to squeeze
26-
((1, 2, 1), (-3, -1), (2,)), # Squeeze using negative dimensions
27-
],
29+
test_cases,
2830
)
2931
def test_squeeze(self, input_shape, dims, expected_shape):
3032
input_tensor = tp.ones(input_shape, dtype=tp.float32)
3133
output_tensor = tp.squeeze(input_tensor, dims=dims)
3234
assert output_tensor.shape == expected_shape
35+
36+
@pytest.mark.parametrize(
37+
"input_shape, dims, expected_shape",
38+
test_cases,
39+
)
40+
def test_squeeze_tensor_method(self, input_shape, dims, expected_shape):
41+
"""Test that tensor.squeeze() method works and produces same result as free function."""
42+
input_tensor = tp.ones(input_shape, dtype=tp.float32)
43+
output_tensor = input_tensor.squeeze(dims)
44+
assert output_tensor.shape == expected_shape

tripy/tests/integration/test_unsqueeze.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,14 @@ def func(a):
4141
return tp.unsqueeze(a, 3) == tp.Tensor(3.0)
4242

4343
c = tp.compile(func, args=[tp.InputInfo(((1, 2, 3), 2, 3), dtype=tp.float32)])
44+
45+
@pytest.mark.parametrize("axis", [-1, 0, 2])
46+
def test_unsqueeze_tensor_method(self, axis, eager_or_compiled):
47+
"""Test that tensor.unsqueeze() method works and produces same result as free function."""
48+
inp = np.ones((4, 2, 2, 3), dtype=np.float32)
49+
50+
out = eager_or_compiled(lambda t: t.unsqueeze(axis), tp.Tensor(inp))
51+
ref_out = np.expand_dims(inp, axis=axis)
52+
assert tp.allclose(out, tp.Tensor(ref_out))
53+
54+
assert out.shape == tuple(ref_out.shape)

0 commit comments

Comments
 (0)