1# mypy: ignore-errors 2 3import logging 4import torch 5import re 6import unittest 7import functools 8import os 9from subprocess import CalledProcessError 10import sys 11import torch._inductor.async_compile # noqa: F401 required to warm up AsyncCompile pools 12from torch._inductor.codecache import CppCodeCache 13from torch._inductor.utils import get_gpu_shared_memory, is_big_gpu 14from torch._inductor.utils import GPU_TYPES, get_gpu_type 15from torch.utils._triton import has_triton 16from torch.testing._internal.common_utils import ( 17 LazyVal, 18 IS_FBCODE, 19) 20from torch.testing._internal.common_utils import ( 21 TestCase, 22 IS_CI, 23 IS_WINDOWS, 24) 25 26log: logging.Logger = logging.getLogger(__name__) 27 28def test_cpu(): 29 try: 30 CppCodeCache.load("") 31 return not IS_FBCODE 32 except ( 33 CalledProcessError, 34 OSError, 35 torch._inductor.exc.InvalidCxxCompiler, 36 torch._inductor.exc.CppCompileError, 37 ): 38 return False 39 40HAS_CPU = LazyVal(test_cpu) 41 42HAS_CUDA = torch.cuda.is_available() and has_triton() 43 44HAS_XPU = torch.xpu.is_available() and has_triton() 45 46HAS_GPU = HAS_CUDA or HAS_XPU 47 48GPU_TYPE = get_gpu_type() 49 50HAS_MULTIGPU = any( 51 getattr(torch, gpu).is_available() and getattr(torch, gpu).device_count() >= 2 52 for gpu in GPU_TYPES 53) 54 55def _check_has_dynamic_shape( 56 self: TestCase, 57 code, 58): 59 for_loop_found = False 60 has_dynamic = False 61 lines = code.split("\n") 62 for line in lines: 63 if "for(" in line: 64 for_loop_found = True 65 if re.search(r";.*ks.*;", line) is not None: 66 has_dynamic = True 67 break 68 self.assertTrue( 69 has_dynamic, msg=f"Failed to find dynamic for loop variable\n{code}" 70 ) 71 self.assertTrue(for_loop_found, f"Failed to find for loop\n{code}") 72 73 74def skipDeviceIf(cond, msg, *, device): 75 if cond: 76 def decorate_fn(fn): 77 def inner(self, *args, **kwargs): 78 if not hasattr(self, "device"): 79 warn_msg = "Expect the test class to have attribute device but not found. " 80 if hasattr(self, "device_type"): 81 warn_msg += "Consider using the skip device decorators in common_device_type.py" 82 log.warning(warn_msg) 83 if self.device == device: 84 raise unittest.SkipTest(msg) 85 return fn(self, *args, **kwargs) 86 return inner 87 else: 88 def decorate_fn(fn): 89 return fn 90 91 return decorate_fn 92 93def skip_windows_ci(name: str, file: str) -> None: 94 if IS_WINDOWS and IS_CI: 95 module = os.path.basename(file).strip(".py") 96 sys.stderr.write( 97 f"Windows CI does not have necessary dependencies for {module} tests yet\n" 98 ) 99 if name == "__main__": 100 sys.exit(0) 101 raise unittest.SkipTest("requires sympy/functorch/filelock") 102 103requires_gpu = functools.partial(unittest.skipIf, not HAS_GPU, "requires gpu") 104 105skipCUDAIf = functools.partial(skipDeviceIf, device="cuda") 106skipXPUIf = functools.partial(skipDeviceIf, device="xpu") 107skipCPUIf = functools.partial(skipDeviceIf, device="cpu") 108 109IS_A100 = LazyVal( 110 lambda: HAS_CUDA 111 and get_gpu_shared_memory() == 166912 112) 113 114IS_H100 = LazyVal( 115 lambda: HAS_CUDA 116 and get_gpu_shared_memory() == 232448 117) 118 119IS_BIG_GPU = LazyVal(lambda: HAS_CUDA and is_big_gpu(0)) 120