已合并
test: add TensorMeta API validation #41434
zhaoziyi-2026创建于 7月13日
test: add TensorMeta API validation #41434
已合并
共 1 个文件变更+43-1
| @@ -1,4 +1,14 @@ | |||
| 1 | -import itertools | 1 | +""" |
群 | |||
| 2 | +Add validation cases for torch._C._TensorMeta API on NPU: | ||
| 3 | + | ||
| 4 | + 1. PyTorch community lacks sufficient and direct API validation for this API, so this case is added. | ||
| 5 | + 2. This file validates Tensor class metaclass relations, NPU Tensor instances, | ||
| 6 | + Tensor subclasses, and direct construction errors. | ||
| 7 | + | ||
| 8 | +Tensor API tests, including NPU Tensor behavior and torch._C._TensorMeta | ||
| 9 | +metaclass consistency checks. | ||
| 10 | +""" | ||
| 11 | + | ||
| 2 | import torch | 12 | import torch |
| 3 | from torch.testing import make_tensor | 13 | from torch.testing import make_tensor |
| 4 | from torch.testing._internal.common_utils import DeterministicGuard | 14 | from torch.testing._internal.common_utils import DeterministicGuard |
| @@ -11,6 +21,38 @@ from torch_npu.testing.decorator import Dtypes, instantiate_tests | |||
| 11 | 21 | ||
| 12 | class TestTensor(TestCase): | 22 | class TestTensor(TestCase): |
| 13 | 23 | ||
| 24 | + def test_tensor_meta_matches_tensor_classes(self): | ||
| 25 | + # _TensorMeta should be the metaclass for Tensor classes, not tensor instances. | ||
| 26 | + tensor_meta = torch._C._TensorMeta | ||
| 27 | + self.assertIs(type(torch.Tensor), tensor_meta) | ||
| 28 | + self.assertEqual(tensor_meta.__module__, "torch._C") | ||
| 29 | + self.assertEqual(tensor_meta.__name__, "_TensorMeta") | ||
| 30 | + self.assertTrue(isinstance(torch.Tensor, tensor_meta)) | ||
| 31 | + self.assertTrue(isinstance(torch.nn.Parameter, tensor_meta)) | ||
| 32 | + self.assertTrue(issubclass(torch.nn.Parameter, torch.Tensor)) | ||
| 33 | + | ||
| 34 | + def test_tensor_meta_with_npu_tensor_instance(self, device="npu"): | ||
| 35 | + # NPU tensors remain Tensor instances while their class is managed by _TensorMeta. | ||
| 36 | + tensor_meta = torch._C._TensorMeta | ||
| 37 | + npu_tensor = torch.empty((2, 3), device=device) | ||
| 38 | + self.assertTrue(isinstance(npu_tensor, torch.Tensor)) | ||
| 39 | + self.assertFalse(isinstance(npu_tensor, tensor_meta)) | ||
| 40 | + self.assertTrue(isinstance(type(npu_tensor), tensor_meta)) | ||
| 41 | + self.assertEqual(npu_tensor.device.type, "npu") | ||
| 42 | + | ||
| 43 | + def test_tensor_meta_subclass_and_direct_construction(self): | ||
| 44 | + # Tensor subclasses use _TensorMeta, but direct _TensorMeta construction is rejected. | ||
| 45 | + tensor_meta = torch._C._TensorMeta | ||
| 46 | + | ||
| 47 | + class CustomTensor(torch.Tensor): | ||
| 48 | + pass | ||
| 49 | + | ||
| 50 | + self.assertIs(type(CustomTensor), tensor_meta) | ||
| 51 | + self.assertTrue(isinstance(CustomTensor, tensor_meta)) | ||
| 52 | + self.assertTrue(issubclass(CustomTensor, torch.Tensor)) | ||
| 53 | + with self.assertRaisesRegex(RuntimeError, "Cannot subclass _TensorBase directly"): | ||
| 54 | + tensor_meta("DirectTensor", (torch._C._TensorBase,), {}) | ||
| 55 | + | ||
| 14 | def test_narrow_empty(self, device="npu"): | 56 | def test_narrow_empty(self, device="npu"): |
| 15 | x = torch.randn(2, 3, 4).to(device=device) | 57 | x = torch.randn(2, 3, 4).to(device=device) |
| 16 | for d in range(x.dim()): | 58 | for d in range(x.dim()): |
使用模板 """ Add validation cases for torch.nn APIs on NPU: