已合并
Add test_matmul_cuda ut for npu #8349
wang-guangbin创建于 2023年12月13日
Add test_matmul_cuda ut for npu #8349
已合并
wang-guangbin创建于 2023年12月13日
refs/pull/8349/head合入到master
2 个文件变更+184-0
Atest/test_matmul_npu.py+169-0
@@ -0,0 +1,169 @@
1+# Owner(s): ["module: linear algebra"]
2+ 
3+import unittest
4+from functools import partial
5+ 
6+import torch
7+from torch.testing import make_tensor
8+import torch_npu
9+import torch_npu.testing
10+from torch.testing._internal.common_device_type import (
11+ dtypes,
12+ instantiate_device_type_tests,
13+ tol as xtol,
14+ toleranceOverride,
15+)
16+ 
17+from torch.testing._internal.common_utils import (
18+ IS_JETSON,
19+ parametrize,
20+ run_tests,
21+ skipIfRocmVersionLessThan,
22+ TEST_WITH_ROCM,
23+ TestCase,
24+)
25+ 
26+# Protects against includes accidentally setting the default dtype
27+# NOTE: jit_metaprogramming_utils sets the default dtype to double!
28+torch.set_default_dtype(torch.float32)
29+if torch.get_default_dtype() is not torch.float32:
30+ raise RuntimeError("The torch default dtype is not float32!")
31+ 
32+ 
33+class TestMatmul(TestCase):
34+ def setUp(self):
35+ super(self.__class__, self).setUp()
36+ 
37+ def tearDown(self):
38+ super(self.__class__, self).tearDown()
39+ 
40+ @skipIfRocmVersionLessThan((5, 2))
41+ # imported 'tol' as 'xtol' to avoid aliasing in code above
42+ @toleranceOverride({torch.float16: xtol(atol=1e-1, rtol=1e-1),
43+ torch.bfloat16: xtol(atol=1e-1, rtol=1e-1),
44+ torch.float32: xtol(atol=1e-1, rtol=1e-1)})
45+ @dtypes(torch.float16, torch.bfloat16, torch.float32)
46+ @parametrize("size", [100, 1000, 10000])
47+ def test_addmm(self, size: int, dtype: torch.dtype):
W
Wwang-guangbin2023年12月15日

已修改

likedislike
48+ #
49+ # Check for catastrophic cuBLAS inaccuracy by measuring the deviation between
50+ # results from the NPU invocation of torch.addmm and the CPU invocation
51+ # (which does not use NPU backend).
52+ #
53+ # Get dims
54+ n, m, p = (size + 1, size, size + 2)
55+ # Make random tensors on CPU (seed set on common_utils.py import)
56+ # (Not using numpy because it does not support bfloat16)
57+ make_arg = partial(make_tensor, dtype=dtype, device="cpu")
58+ m_beta = make_arg(1)
59+ m_input = make_arg((n, p))
60+ m_1 = make_arg((n, m))
61+ m_2 = make_arg((m, p))
62+ # *(B)FLOAT16 Special Handling*
63+ # Backend does not tensorize float16 on CPU,
64+ # and bloat16 may present accuracy issues,
65+ # so convert to float32 for these cases
66+ # (but keep same for other types, e.g. float32 and int*)
67+ if dtype == torch.float16 or dtype == torch.bfloat16:
68+ m_beta = m_beta.to(dtype=torch.float32)
69+ m_input = m_input.to(dtype=torch.float32)
70+ m_1 = m_1.to(dtype=torch.float32)
71+ m_2 = m_2.to(dtype=torch.float32)
72+ # Get CPU result
73+ res_cpu = torch.addmm(m_input, m_1, m_2, beta=m_beta.item())
74+ # *(B)FLOAT16 Special Handling*``
75+ # Convert back to (b)float16
76+ if dtype == torch.float16 or dtype == torch.bfloat16:
77+ m_beta = m_beta.to(dtype=dtype)
78+ m_input = m_input.to(dtype=dtype)
79+ m_1 = m_1.to(dtype=dtype)
80+ m_2 = m_2.to(dtype=dtype)
81+ res_cpu = res_cpu.to(dtype=dtype)
82+ # Move arg tensors to NPU
83+ m_beta = m_beta.to("npu")
84+ m_input = m_input.to("npu")
85+ m_1 = m_1.to("npu")
86+ m_2 = m_2.to("npu")
87+ # Get NPU result
88+ res_npu = torch.addmm(m_input, m_1, m_2, beta=m_beta.item())
89+ # Move to CPU for comparison
90+ res_npu = res_npu.to("cpu")
91+ # Compare
92+ self.assertEqual(res_cpu, res_npu)
93+ 
94+ def test_addmm_alignment(self):
95+ dtype = torch.half
96+ device = 'npu'
97+ # perturb X, A, or B alignment
98+ for idx in range(0, 3):
99+ for offset in range(1, 3):
100+ offsets = [0, 0, 0]
101+ offsets[idx] = offset
102+ x_offset, a_offset, b_offset = offsets
103+ A = torch.rand((5120 * 2560 + a_offset), requires_grad=True, dtype=dtype, device=device)
104+ A = A[a_offset:].reshape(5120, 2560)
105+ X = torch.rand((26 * 2560 + x_offset), requires_grad=True, dtype=dtype, device=device)
106+ X = X[x_offset:].reshape(26, 1, 2560)
107+ B = torch.rand((5120 + b_offset), requires_grad=True, dtype=dtype, device=device)
108+ B = B[b_offset:].reshape(5120)
109+ out = torch.nn.functional.linear(X, A, B)
110+ self.assertEqual(out, torch.matmul(X, A.transpose(1, 0)) + B)
111+ 
112+ @unittest.skipIf(IS_JETSON, "Too large for Jetson")
113+ @toleranceOverride({torch.float32: xtol(atol=1e-5, rtol=1e-5)})
114+ @dtypes(*([torch.float32, torch.float16, torch.bfloat16]))
115+ @parametrize(
116+ "batch_size, N, M, P",
117+ [(2, 100, 100, 100),
118+ (2, 1000, 1000, 1000),
119+ (1, 10000, 1000, 10000),
120+ (1, 10000, 10000, 10000)],
121+ name_fn=lambda batch_size, N, M, P: f"{batch_size}_{N}_{M}_{P}",
122+ )
123+ def test_baddbmm_large_input(self, device, batch_size, N, M, P, dtype):
124+ cpu_dtype = dtype
125+ if dtype == torch.float16 or dtype == torch.bfloat16:
126+ cpu_dtype = torch.float32
127+ 
128+ M1 = torch.rand((N, M), device=device, dtype=dtype)
129+ M2 = torch.rand((M, P), device=device, dtype=dtype)
130+ A = torch.rand((N, P), device=device, dtype=dtype)
131+ 
132+ def _convert_to_cpu(t):
133+ return t.to(device='cpu', dtype=cpu_dtype)
134+ M1_cpu, M2_cpu, A_cpu = map(_convert_to_cpu, [M1, M2, A])
135+ 
136+ # linear
137+ out1_cpu = torch.nn.functional.linear(M1_cpu, M2_cpu.t(), A_cpu).to(dtype=dtype)
138+ out1_gpu = torch.nn.functional.linear(M1, M2.t(), A).cpu()
139+ self.assertEqual(out1_cpu, out1_gpu)
140+ # test multiply the identity matrix
141+ if N == M and M == P:
142+ M2_eye = torch.eye(N, device=device, dtype=dtype)
143+ out1_eye_gpu = torch.nn.functional.linear(M1, M2_eye.t(), torch.zeros_like(A))
144+ self.assertEqual(M1_cpu.to(dtype=dtype), out1_eye_gpu.cpu())
145+ 
146+ # baddbmm
147+ def _expand_to_batch(t: torch.Tensor):
148+ return t.expand((batch_size, ) + t.size())
149+ alpha, beta = 1.0, 1.0
150+ M1, M2, A, M1_cpu, M2_cpu, A_cpu = map(_expand_to_batch, [M1, M2, A, M1_cpu, M2_cpu, A_cpu])
151+ 
152+ out2_cpu = torch.baddbmm(A_cpu, M1_cpu, M2_cpu, beta=beta, alpha=alpha).to(dtype=dtype)
153+ out2_gpu = torch.baddbmm(A, M1, M2, beta=beta, alpha=alpha).cpu()
154+ self.assertEqual(out2_cpu, out2_gpu)
155+ # test multiply the identity matrix
156+ if N == M and M == P:
157+ M2_eye = torch.eye(N, device=device, dtype=dtype).expand(batch_size, N, N)
158+ out2_eye_gpu = torch.baddbmm(torch.zeros_like(A), M1, M2_eye, beta=beta, alpha=alpha)
159+ self.assertEqual(M1_cpu.to(dtype=dtype), out2_eye_gpu.cpu())
160+ 
161+ # cross comparison
162+ self.assertEqual(out1_gpu, out2_gpu[0])
163+ 
164+ 
165+instantiate_device_type_tests(TestMatmul, globals(), only_for='privateuse1')
166+ 
167+ 
168+if __name__ == '__main__':
169+ run_tests()
Mtest/unsupported_test_cases/.pytorch-disabled-tests.json+15-0
@@ -1203,6 +1203,20 @@
1203 "test_repr_nn_ConvTranspose1d_npu_complex32 (__main__.TestModulePRIVATEUSE1)": ["", [""]],1203 "test_repr_nn_ConvTranspose1d_npu_complex32 (__main__.TestModulePRIVATEUSE1)": ["", [""]],
1204 "test_repr_nn_ConvTranspose2d_npu_complex32 (__main__.TestModulePRIVATEUSE1)": ["", [""]],1204 "test_repr_nn_ConvTranspose2d_npu_complex32 (__main__.TestModulePRIVATEUSE1)": ["", [""]],
1205 "test_repr_nn_ConvTranspose3d_npu_complex32 (__main__.TestModulePRIVATEUSE1)": ["", [""]],1205 "test_repr_nn_ConvTranspose3d_npu_complex32 (__main__.TestModulePRIVATEUSE1)": ["", [""]],
1206+ "test_addmm_size_10000_npu_bfloat16 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1207+ "test_addmm_size_10000_npu_float32 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1208+ "test_addmm_size_1000_npu_bfloat16 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1209+ "test_addmm_size_1000_npu_float32 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1210+ "test_addmm_size_100_npu_bfloat16 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1211+ "test_addmm_size_100_npu_float32 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1212+ "test_baddbmm_large_input_1_10000_10000_10000_npu_bfloat16 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1213+ "test_baddbmm_large_input_1_10000_10000_10000_npu_float32 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1214+ "test_baddbmm_large_input_1_10000_1000_10000_npu_bfloat16 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1215+ "test_baddbmm_large_input_1_10000_1000_10000_npu_float32 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1216+ "test_baddbmm_large_input_2_1000_1000_1000_npu_bfloat16 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1217+ "test_baddbmm_large_input_2_1000_1000_1000_npu_float32 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1218+ "test_baddbmm_large_input_2_100_100_100_npu_bfloat16 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1219+ "test_baddbmm_large_input_2_100_100_100_npu_float32 (main.TestMatmulPRIVATEUSE1)": ["", [""]],
1206 "test_alpha_mismatch_npu (__main__.TestTypePromotionPRIVATEUSE1)": ["", [""]],1220 "test_alpha_mismatch_npu (__main__.TestTypePromotionPRIVATEUSE1)": ["", [""]],
1207 "test_alternate_result_npu (__main__.TestTypePromotionPRIVATEUSE1)": ["", [""]],1221 "test_alternate_result_npu (__main__.TestTypePromotionPRIVATEUSE1)": ["", [""]],
1208 "test_bfloat16_npu (__main__.TestTypePromotionPRIVATEUSE1)": ["", [""]],1222 "test_bfloat16_npu (__main__.TestTypePromotionPRIVATEUSE1)": ["", [""]],
@@ -1433,6 +1447,7 @@
1433 "test_unique_npu_int64 (__main__.TestSortAndSelectPRIVATEUSE1)": ["", [""]],1447 "test_unique_npu_int64 (__main__.TestSortAndSelectPRIVATEUSE1)": ["", [""]],
1434 "test_unique_npu_int8 (__main__.TestSortAndSelectPRIVATEUSE1)": ["", [""]],1448 "test_unique_npu_int8 (__main__.TestSortAndSelectPRIVATEUSE1)": ["", [""]],
1435 "test_unique_npu_uint8 (__main__.TestSortAndSelectPRIVATEUSE1)": ["", [""]],1449 "test_unique_npu_uint8 (__main__.TestSortAndSelectPRIVATEUSE1)": ["", [""]],
1450+ "test_unique_dim_npu (__main__.TestSortAndSelectPRIVATEUSE1)": ["", [""]],
1436 "test_advancedindex_npu_float64 (__main__.TestIndexingPRIVATEUSE1)": ["", [""]],1451 "test_advancedindex_npu_float64 (__main__.TestIndexingPRIVATEUSE1)": ["", [""]],
1437 "test_batchnorm_non_contig_cpu_SyncBatchNorm (__main__.TestNN)": ["", [""]],1452 "test_batchnorm_non_contig_cpu_SyncBatchNorm (__main__.TestNN)": ["", [""]],
1438 "test_affine_grid (__main__.TestNN)": ["", [""]],1453 "test_affine_grid (__main__.TestNN)": ["", [""]],