Skip to content

Commit dcc04ef

Browse files
zingoCopilot
andauthored
Arm backend: Make pytest collection seeding deterministic (pytorch#20621)
### Summary Seed the Arm test RNG during pytest configuration in OSS/local test runs so module-level random inputs are deterministic before collection imports test modules. This will make tests behave less random and hopefully fix some flakeynes in testing/CI. For example test_dl3_arm.py failes about 5% of the time before this fix due to it getting non seeded random numbers. Extra cleanup/fixes: Use TEST_SEED for the Arm test session seed, replacing the old ARM_TEST_SEED environment variable name. Keep packaged non-OSS Buck behavior unchanged by skipping that early torch import there, while preserving the per-test seeding fixture. ### Test plan This is tested by all Arm backend pytests Signed-off-by: Zingo Andersen <Zingo.Andersen@arm.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 8f1abad commit dcc04ef

2 files changed

Lines changed: 48 additions & 24 deletions

File tree

backends/arm/test/conftest.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ def pytest_configure(config):
2626
pytest._test_options["llama_inputs"] = config.option.llama_inputs # type: ignore[attr-defined]
2727

2828
logging.basicConfig(stream=sys.stdout)
29+
seed, seed_label = _setup_random_seed()
30+
config._test_seed = seed
31+
config._test_seed_label = seed_label
32+
33+
if os.environ.get("TEST_RUNTIME_IS_NOT_OSS", "0") != "1":
34+
# This imports/uses torch early, which doesn't work in some Buck2 test environments.
35+
# Since this only makes randomness deterministic (reducing flakiness), it's mainly meant for
36+
# local/OSS project test runs.
37+
_set_random_seed(seed)
38+
39+
40+
def pytest_report_header(config):
41+
return config._test_seed_label
2942

3043

3144
def pytest_collection_modifyitems(config, items):
@@ -63,38 +76,44 @@ def pytest_sessionfinish(session, exitstatus):
6376

6477

6578
@pytest.fixture(autouse=True)
66-
def set_random_seed():
79+
def set_random_seed(request):
6780
"""Control random numbers in Arm test suite. Default behavior is to use a
6881
fixed seed (0), which ensures reproducible tests. Use the env variable
69-
ARM_TEST_SEED to set a custom seed, or set it to RANDOM for random seed
70-
behavior.
82+
TEST_SEED to set a custom session seed, or set it to RANDOM to choose a
83+
random session seed.
7184
7285
Examples:
7386
As default use fixed seed (0) for reproducible tests
7487
pytest --config-file=/dev/null --verbose -s --color=yes backends/arm/test/ops/test_avg_pool.py -k <TESTCASE>
75-
Use a random seed for each test
76-
ARM_TEST_SEED=RANDOM pytest --config-file=/dev/null --verbose -s --color=yes backends/arm/test/ops/test_avg_pool.py -k <TESTCASE>
88+
Use a random seed for the test session
89+
TEST_SEED=RANDOM pytest --config-file=/dev/null --verbose -s --color=yes backends/arm/test/ops/test_avg_pool.py -k <TESTCASE>
7790
Rerun with a specific seed
78-
ARM_TEST_SEED=3478246 pytest --config-file=/dev/null --verbose -s --color=yes backends/arm/test/ops/test_avg_pool.py -k <TESTCASE>
91+
TEST_SEED=3478246 pytest --config-file=/dev/null --verbose -s --color=yes backends/arm/test/ops/test_avg_pool.py -k <TESTCASE>
7992
8093
"""
81-
import torch
94+
_set_random_seed(request.config._test_seed)
95+
8296

83-
seed_env = os.environ.get("ARM_TEST_SEED", "0")
97+
def _setup_random_seed():
98+
seed_env = os.environ.get("TEST_SEED", "0")
8499
if seed_env == "RANDOM":
85100
random.seed() # reset seed, in case any other test has fiddled with it
86101
seed = random.randint(0, 2**32 - 1) # nosec B311 - non-crypto seed for tests
87-
torch.manual_seed(seed)
102+
seed_label = f"TEST_SEED=RANDOM using:{seed}"
88103
elif str.isdigit(seed_env):
89104
seed = int(seed_env)
90-
random.seed(seed)
91-
torch.manual_seed(seed)
105+
seed_label = f"TEST_SEED={seed}"
92106
else:
93-
raise TypeError(
94-
"ARM_TEST_SEED env variable must be integers or the string RANDOM"
95-
)
107+
raise TypeError("TEST_SEED env variable must be integers or the string RANDOM")
108+
109+
return seed, seed_label
110+
111+
112+
def _set_random_seed(seed):
113+
import torch
96114

97-
print(f" ARM_TEST_SEED={seed} ", end=" ")
115+
random.seed(seed)
116+
torch.manual_seed(seed)
98117

99118

100119
# ==== End of Pytest fixtures =====

backends/arm/test/targets.bzl

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ def define_arm_tests():
9696
for test_file in test_files:
9797
test_file_name = paths.basename(test_file)
9898
test_name = test_file_name.replace("test_", "").replace(".py", "")
99+
test_env = {
100+
"TEST_RUNTIME_IS_NOT_OSS": "1" if not runtime.is_oss else "0",
101+
}
102+
if not runtime.is_oss and _ENABLE_VGF:
103+
test_env.update({
104+
"MODEL_CONVERTER_PATH": "$(location fbsource//third-party/pypi/ai-ml-sdk-model-converter/0.9.0:model-converter-bin)",
105+
"MODEL_CONVERTER_LIB_DIR": "$(location fbsource//third-party/nvidia-nsight-systems:linux-x86_64)/host-linux-x64",
106+
"LAVAPIPE_LIB_PATH": "$(location fbsource//third-party/mesa:vulkan_lvp)",
107+
"EMULATION_LAYER_TENSOR_SO": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:libVkLayer_Tensor)",
108+
"EMULATION_LAYER_GRAPH_SO": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:libVkLayer_Graph)",
109+
"EMULATION_LAYER_TENSOR_JSON": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:VkLayer_Tensor_json)",
110+
"EMULATION_LAYER_GRAPH_JSON": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:VkLayer_Graph_json)",
111+
})
99112

100113
python_pytest(
101114
name = test_name,
@@ -105,15 +118,7 @@ def define_arm_tests():
105118
compile = "with-source",
106119
typing = False,
107120
skip_on_mode_mac = True,
108-
env = {} if runtime.is_oss else ({
109-
"MODEL_CONVERTER_PATH": "$(location fbsource//third-party/pypi/ai-ml-sdk-model-converter/0.9.0:model-converter-bin)",
110-
"MODEL_CONVERTER_LIB_DIR": "$(location fbsource//third-party/nvidia-nsight-systems:linux-x86_64)/host-linux-x64",
111-
"LAVAPIPE_LIB_PATH": "$(location fbsource//third-party/mesa:vulkan_lvp)",
112-
"EMULATION_LAYER_TENSOR_SO": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:libVkLayer_Tensor)",
113-
"EMULATION_LAYER_GRAPH_SO": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:libVkLayer_Graph)",
114-
"EMULATION_LAYER_TENSOR_JSON": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:VkLayer_Tensor_json)",
115-
"EMULATION_LAYER_GRAPH_JSON": "$(location fbsource//third-party/arm-ml-emulation-layer/v0.9.0/src:VkLayer_Graph_json)",
116-
} if _ENABLE_VGF else {}),
121+
env = test_env,
117122
preload_deps = [
118123
"//executorch/kernels/quantized:custom_ops_generated_lib",
119124
] + ([] if runtime.is_oss or not _ENABLE_VGF else [

0 commit comments

Comments
 (0)