Skip to content

Commit c85f6eb

Browse files
authored
Add --test_parallel to reduce CTest concurrency for ASan builds (#28675)
## Description The `windows_x64_asan / build_x64` CI pipeline has been failing with OOM (out-of-memory) because ASan-instrumented test binaries consume significantly more memory than normal builds, and CTest was running them at full CPU-count parallelism. This PR adds a `--test_parallel` argument to `build.py` that allows CTest concurrency to be configured independently from the build parallelism (`--parallel`). It then uses `--test_parallel 4` in the Windows x64 ASan workflow to cap test execution to 4 parallel jobs, preventing OOM while keeping build parallelism at full speed. ## Motivation and Context - ASan instrumentation inflates per-process memory usage by ~2-3x. - The existing `--parallel` flag controls both MSBuild and CTest concurrency together; there was no way to keep fast parallel builds while limiting test concurrency. - The CI runner has limited memory, and running all tests in parallel under ASan exceeded available RAM. ## Changes | File | Change | |------|--------| | `tools/ci_build/build_args.py` | Add `--test_parallel` argument (default: `None`, falls back to `--parallel`) | | `tools/ci_build/build.py` | Add `number_of_test_parallel_jobs()` helper; use it for CTest `--parallel`; validate negative values | | `.github/workflows/windows_build_x64_asan.yml` | Pass `--test_parallel 4` to cap ASan test concurrency | ## Testing - `python -m py_compile tools/ci_build/build.py tools/ci_build/build_args.py` — passes - `python tools/ci_build/build.py --help` shows the new `--test_parallel` option - `git diff --check` — no whitespace issues - When `--test_parallel` is omitted, behavior is unchanged (falls back to `--parallel` value)
1 parent 2c4a0c1 commit c85f6eb

3 files changed

Lines changed: 17 additions & 2 deletions

File tree

.github/workflows/windows_build_x64_asan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ jobs:
4444
@echo off
4545
echo %PATH%
4646
python -m pip install -r "%GITHUB_WORKSPACE%\tools\ci_build/github/windows\python\requirements.txt"
47-
python "%GITHUB_WORKSPACE%\tools\ci_build\build.py" --config Debug --build_dir "%RUNNER_TEMP%\build" --skip_submodule_sync --parallel --use_vcpkg --use_vcpkg_ms_internal_asset_cache --cmake_generator "Visual Studio 17 2022" --disable_memleak_checker --enable_address_sanitizer
47+
python "%GITHUB_WORKSPACE%\tools\ci_build\build.py" --config Debug --build_dir "%RUNNER_TEMP%\build" --skip_submodule_sync --parallel --test_parallel 4 --use_vcpkg --use_vcpkg_ms_internal_asset_cache --cmake_generator "Visual Studio 17 2022" --disable_memleak_checker --enable_address_sanitizer

tools/ci_build/build.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ def number_of_parallel_jobs(args):
205205
return os.cpu_count() if args.parallel == 0 else args.parallel
206206

207207

208+
def number_of_test_parallel_jobs(args):
209+
if args.test_parallel is None:
210+
return number_of_parallel_jobs(args)
211+
return os.cpu_count() if args.test_parallel == 0 else args.test_parallel
212+
213+
208214
def number_of_nvcc_threads(args):
209215
if args.nvcc_threads >= 0:
210216
return args.nvcc_threads
@@ -1728,7 +1734,7 @@ def run_onnxruntime_tests(args, source_dir, ctest_path, build_dir, configs):
17281734
test_output = f"--gtest_output=xml:{cwd}/{exe}.{config}.results.xml"
17291735
run_subprocess([os.path.join(cwd, exe), test_output], cwd=cwd, dll_path=dll_path)
17301736
else:
1731-
num_parallel_jobs = number_of_parallel_jobs(args)
1737+
num_parallel_jobs = number_of_test_parallel_jobs(args)
17321738
ctest_cmd = [
17331739
ctest_path,
17341740
"--build-config",
@@ -2574,6 +2580,9 @@ def main():
25742580
build_targets(args, cmake_path, build_dir, configs, num_parallel_jobs, args.targets)
25752581

25762582
if args.test:
2583+
if args.test_parallel is not None and args.test_parallel < 0:
2584+
raise BuildError(f"Invalid test parallel job count: {args.test_parallel}")
2585+
25772586
if args.enable_onnx_tests:
25782587
source_onnx_model_dir = "C:\\local\\models" if is_windows() else "/data/models"
25792588
setup_test_data(source_onnx_model_dir, "models", build_dir, configs)

tools/ci_build/build_args.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ def add_testing_args(parser: argparse.ArgumentParser) -> None:
228228
parser.add_argument("--skip_winml_tests", action="store_true", help="Explicitly disable WinML related tests.")
229229
parser.add_argument("--skip_nodejs_tests", action="store_true", help="Explicitly disable Node.js binding tests.")
230230
parser.add_argument("--ctest_timeout", default="10800", help="Timeout provided to CTest --timeout (seconds).")
231+
parser.add_argument(
232+
"--test_parallel",
233+
default=None,
234+
type=int,
235+
help="Max CTest parallel jobs. Defaults to --parallel. Optional value 0 uses num CPUs.",
236+
)
231237
parser.add_argument("--enable_transformers_tool_test", action="store_true", help="Enable transformers tool test.")
232238
parser.add_argument("--build_micro_benchmarks", action="store_true", help="Build ONNXRuntime micro-benchmarks.")
233239
parser.add_argument("--code_coverage", action="store_true", help="Generate code coverage report (Android only).")

0 commit comments

Comments
 (0)