1# mypy: allow-untyped-defs 2import logging 3import os 4import sys 5 6 7# NOTE: [dynamo_test_failures.py] 8# 9# We generate xFailIfTorchDynamo* for all tests in `dynamo_expected_failures` 10# We generate skipIfTorchDynamo* for all tests in `dynamo_skips` 11# 12# For an easier-than-manual way of generating and updating these lists, 13# see scripts/compile_tests/update_failures.py 14# 15# If you're adding a new test, and it's failing PYTORCH_TEST_WITH_DYNAMO=1, 16# either add the appropriate decorators to your test or add skips for them 17# via test/dynamo_skips and test/dynamo_expected_failures. 18# 19# *These are not exactly unittest.expectedFailure and unittest.skip. We'll 20# always execute the test and then suppress the signal, if necessary. 21# If your tests crashes, or is slow, please use @skipIfTorchDynamo instead. 22# 23# The expected failure and skip files are located in test/dynamo_skips and 24# test/dynamo_expected_failures. They're individual files rather than a list so 25# git will merge changes easier. 26 27 28def find_test_dir(): 29 # Find the path to the dynamo expected failure and skip files. 30 from os.path import abspath, basename, dirname, exists, join, normpath 31 32 if sys.platform == "win32": 33 return None 34 35 # Check relative to this file (local build): 36 test_dir = normpath(join(dirname(abspath(__file__)), "../../../test")) 37 if exists(join(test_dir, "dynamo_expected_failures")): 38 return test_dir 39 40 # Check relative to __main__ (installed builds relative to test file): 41 main = sys.modules["__main__"] 42 file = getattr(main, "__file__", None) 43 if file is None: 44 # Generated files do not have a module.__file__ 45 return None 46 test_dir = dirname(abspath(file)) 47 while dirname(test_dir) != test_dir: 48 if basename(test_dir) == "test" and exists( 49 join(test_dir, "dynamo_expected_failures") 50 ): 51 return test_dir 52 test_dir = dirname(test_dir) 53 54 # Not found 55 return None 56 57 58test_dir = find_test_dir() 59if not test_dir: 60 logger = logging.getLogger(__name__) 61 logger.warning( 62 "test/dynamo_expected_failures directory not found - known dynamo errors won't be skipped." 63 ) 64 65# Tests that run without strict mode in PYTORCH_TEST_WITH_INDUCTOR=1. 66# Please don't add anything to this list. 67FIXME_inductor_non_strict = { 68 "test_modules", 69 "test_ops", 70 "test_ops_gradients", 71 "test_torch", 72} 73 74# Tests that run without resetting dynamo in PYTORCH_TEST_WITH_INDUCTOR=1. 75# Please don't add anything to this list. 76# 77# Instead we will gradually remove items from this list. Once the list is empty, 78# we will remove the list. 79FIXME_inductor_dont_reset_dynamo = { 80 "test_modules", 81 "test_ops", 82 "test_ops_gradients", 83} 84 85# We generate unittest.expectedFailure for all of the following tests 86# when run under PYTORCH_TEST_WITH_DYNAMO=1. 87# see NOTE [dynamo_test_failures.py] for more details 88# 89# This lists exists so we can more easily add large numbers of failing tests, 90if test_dir is None: 91 dynamo_expected_failures = set() 92 dynamo_skips = set() 93else: 94 failures_directory = os.path.join(test_dir, "dynamo_expected_failures") 95 skips_directory = os.path.join(test_dir, "dynamo_skips") 96 97 dynamo_expected_failures = set(os.listdir(failures_directory)) 98 dynamo_skips = set(os.listdir(skips_directory)) 99 100# TODO: due to case sensitivity problems, for now list these files by hand 101extra_dynamo_skips = { 102 "TestProxyTensorOpInfoCPU.test_make_fx_exhaustive_T_cpu_float32", 103 "TestProxyTensorOpInfoCPU.test_make_fx_exhaustive_t_cpu_float32", 104 "TestProxyTensorOpInfoCPU.test_make_fx_fake_exhaustive_T_cpu_float32", 105 "TestProxyTensorOpInfoCPU.test_make_fx_fake_exhaustive_t_cpu_float32", 106 "TestProxyTensorOpInfoCPU.test_make_fx_symbolic_exhaustive_T_cpu_float32", 107 "TestProxyTensorOpInfoCPU.test_make_fx_symbolic_exhaustive_t_cpu_float32", 108 "TestProxyTensorOpInfoCPU.test_make_fx_symbolic_exhaustive_inplace_T_cpu_float32", 109 "TestProxyTensorOpInfoCPU.test_make_fx_symbolic_exhaustive_inplace_t_cpu_float32", 110 "TestProxyTensorOpInfoCPU.test_make_fx_symbolic_exhaustive_out_T_cpu_float32", 111 "TestProxyTensorOpInfoCPU.test_make_fx_symbolic_exhaustive_out_t_cpu_float32", 112} 113dynamo_skips = dynamo_skips.union(extra_dynamo_skips) 114 115 116# verify some invariants 117for test in dynamo_expected_failures.union(dynamo_skips): 118 if len(test.split(".")) != 2: 119 raise AssertionError(f'Invalid test name: "{test}"') 120 121intersection = dynamo_expected_failures.intersection(dynamo_skips) 122if len(intersection) > 0: 123 raise AssertionError( 124 "there should be no overlap between dynamo_expected_failures " 125 "and dynamo_skips, got " + str(intersection) 126 ) 127