已合并
test:This PR adds missing test cases for torch._utils._unflatten_dense_tensors, as there are currently no community-provided tests for this function. #42048
创建于 7月18日
test:This PR adds missing test cases for torch._utils._unflatten_dense_tensors, as there are currently no community-provided tests for this function. #42048
已合并
创建于 7月18日
已删除 :test_unflatten_dense_tensors_v2.7.1合入到Ascend/pytorchv2.7.1
1 个文件变更+132-0
@@ -0,0 +1,132 @@
1+"""
2+Add validation cases for torch._utils APIs on NPU:
3+1. PyTorch community lacks direct Python unit tests for torch._utils._unflatten_dense_tensors.
4+2. This file validates torch._utils._unflatten_dense_tensors (extendable).
5+"""
6+ 
7+import torch
8+from torch.testing._internal.common_utils import TestCase, run_tests
9+ 
10+ 
11+class TestUnflattenDenseTensors(TestCase):
12+ """Test cases for torch._utils._unflatten_dense_tensors."""
13+ 
14+ def setUp(self):
15+ super().setUp()
16+ acc = torch.accelerator.current_accelerator()
17+ self.device = acc.type if acc else "cpu"
18+ 
19+ def _to_device(self, t):
20+ return t.to(self.device)
21+ 
22+ def test_round_trip_basic(self):
23+ # Round-trip: flatten then unflatten should recover original tensors
24+ t1 = self._to_device(torch.ones(4, 4))
25+ t2 = self._to_device(torch.zeros(2, 3))
26+ t3 = self._to_device(torch.randn(5))
27+ tensors = [t1, t2, t3]
28+ 
29+ flat = torch._utils._flatten_dense_tensors(tensors)
30+ result = torch._utils._unflatten_dense_tensors(flat, tensors)
31+ 
32+ self.assertEqual(len(result), len(tensors))
33+ for r, t in zip(result, tensors):
34+ self.assertEqual(r.shape, t.shape)
35+ self.assertEqual(r, t)
36+ 
37+ def test_single_tensor(self):
38+ t = self._to_device(torch.randn(3, 5, 2))
39+ flat = torch._utils._flatten_dense_tensors([t])
40+ result = torch._utils._unflatten_dense_tensors(flat, [t])
41+ 
42+ self.assertEqual(len(result), 1)
43+ self.assertEqual(result[0].shape, t.shape)
44+ self.assertEqual(result[0], t)
45+ 
46+ def test_multiple_tensors_different_sizes(self):
47+ sizes = [(1,), (2, 3), (4, 5, 6), (7, 8)]
48+ tensors = [self._to_device(torch.randn(*s)) for s in sizes]
49+ 
50+ flat = torch._utils._flatten_dense_tensors(tensors)
51+ result = torch._utils._unflatten_dense_tensors(flat, tensors)
52+ 
53+ self.assertEqual(len(result), len(tensors))
54+ for i, (r, t) in enumerate(zip(result, tensors)):
55+ self.assertEqual(r.shape, t.shape, f"tensor {i} shape mismatch")
56+ self.assertEqual(r, t, f"tensor {i} value mismatch")
57+ 
58+ def test_empty_tensor_in_list(self):
59+ t1 = self._to_device(torch.ones(3, 2))
60+ t2 = self._to_device(torch.tensor([]))
61+ t3 = self._to_device(torch.randn(4))
62+ tensors = [t1, t2, t3]
63+ 
64+ flat = torch._utils._flatten_dense_tensors(tensors)
65+ result = torch._utils._unflatten_dense_tensors(flat, tensors)
66+ 
67+ self.assertEqual(len(result), 3)
68+ self.assertEqual(result[0].numel(), 6)
69+ self.assertEqual(result[1].numel(), 0)
70+ self.assertEqual(result[2].numel(), 4)
71+ self.assertEqual(result[0], t1)
72+ # Verify empty tensor preserves shape, dtype and device
73+ self.assertEqual(result[1].shape, t2.shape)
74+ self.assertEqual(result[1].dtype, t2.dtype)
75+ self.assertEqual(result[1], t2)
76+ self.assertEqual(result[2], t3)
77+ 
78+ def test_all_empty_tensors(self):
79+ tensors = [
80+ self._to_device(torch.tensor([])),
81+ self._to_device(torch.tensor([])),
82+ ]
83+ 
84+ flat = torch._utils._flatten_dense_tensors(tensors)
85+ result = torch._utils._unflatten_dense_tensors(flat, tensors)
86+ 
87+ self.assertEqual(len(result), 2)
88+ for r, t in zip(result, tensors):
89+ self.assertEqual(r.shape, t.shape)
90+ self.assertEqual(r, t)
91+ 
92+ def test_different_dtypes(self):
93+ for dtype in [torch.float32, torch.float16, torch.int32]:
94+ with self.subTest(dtype=dtype):
95+ t1 = self._to_device(torch.ones(2, 3, dtype=dtype))
96+ t2 = self._to_device(torch.zeros(4, dtype=dtype))
97+ 
98+ flat = torch._utils._flatten_dense_tensors([t1, t2])
99+ result = torch._utils._unflatten_dense_tensors(flat, [t1, t2])
100+ 
101+ self.assertEqual(result[0].dtype, dtype)
102+ self.assertEqual(result[1].dtype, dtype)
103+ self.assertEqual(result[0], t1)
104+ self.assertEqual(result[1], t2)
105+ 
106+ def test_large_num_tensors(self):
107+ n = 50
108+ tensors = [self._to_device(torch.randn(i + 1)) for i in range(n)]
109+ 
110+ flat = torch._utils._flatten_dense_tensors(tensors)
111+ result = torch._utils._unflatten_dense_tensors(flat, tensors)
112+ 
113+ self.assertEqual(len(result), n)
114+ for r, t in zip(result, tensors):
115+ self.assertEqual(r.shape, t.shape)
116+ self.assertEqual(r, t)
117+ 
118+ def test_tuple_input(self):
119+ t1 = self._to_device(torch.ones(3, 3))
120+ t2 = self._to_device(torch.zeros(2))
121+ tensors = (t1, t2) # tuple, not list
122+ 
123+ flat = torch._utils._flatten_dense_tensors(tensors)
124+ result = torch._utils._unflatten_dense_tensors(flat, tensors)
125+ 
126+ self.assertEqual(len(result), 2)
127+ for r, t in zip(result, tensors):
128+ self.assertEqual(r, t)
129+ 
130+ 
131+if __name__ == "__main__":
132+ run_tests()