Register CPU CI for 17 e2e tests and partition xeon base-c suite (#35227)
Co-authored-by: Zhang, Mingxu <mingxu.zhang@intel.com> Co-authored-by: MingxuZh <109504044+MingxuZh@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Zhang, Mingxu
MingxuZh
Copilot Autofix powered by AI
Claude
parent
11b1b4c374
commit
514b997e6c
+46
-18
@@ -33,6 +33,7 @@ PER_COMMIT_SUITES = {
|
||||
HWBackend.CPU: [
|
||||
"base-a-test-cpu",
|
||||
"base-b-test-cpu",
|
||||
"base-b-tp-test-cpu",
|
||||
"base-c-test-cpu",
|
||||
"base-b-test-cpu-arm64",
|
||||
],
|
||||
@@ -233,18 +234,27 @@ def validate_all_suites(all_tests: List[CIRegistry]):
|
||||
|
||||
|
||||
def filter_tests(
|
||||
ci_tests: List[CIRegistry], hw: HWBackend, suite: str, nightly: bool = False
|
||||
) -> List[CIRegistry]:
|
||||
ci_tests: List[CIRegistry],
|
||||
hw: HWBackend,
|
||||
suites: List[str],
|
||||
nightly: bool = False,
|
||||
) -> tuple[List[CIRegistry], List[CIRegistry]]:
|
||||
# `suites` may hold more than one suite (comma-separated --suite): the
|
||||
# matched tests are unioned so a single runner can partition several
|
||||
# suites as one balanced pool (e.g. base-b + base-c on a Xeon SPR box).
|
||||
suite_set = set(suites)
|
||||
ci_tests = [
|
||||
t
|
||||
for t in ci_tests
|
||||
if t.backend == hw and t.effective_suite == suite and t.nightly == nightly
|
||||
if t.backend == hw and t.effective_suite in suite_set and t.nightly == nightly
|
||||
]
|
||||
|
||||
# Union of all three dicts, not just the per-commit or nightly half:
|
||||
# CUDA nightly suites are selected by name alone, without --nightly.
|
||||
if suite not in _valid_suites_by_backend().get(hw, set()):
|
||||
print(f"Warning: Unknown suite {suite} for backend {hw.name}")
|
||||
valid = _valid_suites_by_backend().get(hw, set())
|
||||
for suite in suites:
|
||||
if suite not in valid:
|
||||
print(f"Warning: Unknown suite {suite} for backend {hw.name}")
|
||||
|
||||
enabled_tests = [t for t in ci_tests if t.disabled is None]
|
||||
skipped_tests = [t for t in ci_tests if t.disabled is not None]
|
||||
@@ -292,10 +302,11 @@ def pretty_print_tests(
|
||||
|
||||
|
||||
def load_live_est(
|
||||
partition_model_file: Optional[str], suite: str, repo_root: str
|
||||
partition_model_file: Optional[str], suites: List[str], repo_root: str
|
||||
) -> Optional[Dict[str, float]]:
|
||||
"""`CIRegistry.filename -> est seconds` from `model.json est[suite]`;
|
||||
None on any miss (caller falls back to in-source `est_time`)."""
|
||||
"""`CIRegistry.filename -> est seconds` from `model.json est[suite]`,
|
||||
merged across all requested `suites`; None if no suite yielded any entry
|
||||
(caller then falls back to in-source `est_time`)."""
|
||||
if not partition_model_file or not os.path.exists(partition_model_file):
|
||||
return None
|
||||
try:
|
||||
@@ -305,18 +316,26 @@ def load_live_est(
|
||||
return None
|
||||
if not isinstance(partition_model, dict):
|
||||
return None
|
||||
suite_est = partition_model.get("est", {}).get(suite)
|
||||
if not isinstance(suite_est, dict) or not suite_est:
|
||||
est_by_suite = partition_model.get("est", {})
|
||||
if not isinstance(est_by_suite, dict):
|
||||
return None
|
||||
return {
|
||||
os.path.join(repo_root, relpath): float(elapsed)
|
||||
for relpath, elapsed in suite_est.items()
|
||||
}
|
||||
merged: Dict[str, float] = {}
|
||||
for suite in suites:
|
||||
suite_est = est_by_suite.get(suite)
|
||||
if not isinstance(suite_est, dict):
|
||||
continue
|
||||
for relpath, elapsed in suite_est.items():
|
||||
merged[os.path.join(repo_root, relpath)] = float(elapsed)
|
||||
return merged or None
|
||||
|
||||
|
||||
def run_a_suite(args):
|
||||
hw = HW_MAPPING[args.hw]
|
||||
suite = args.suite
|
||||
# --suite accepts a comma-separated list; the matched tests are unioned
|
||||
# into one pool so a single runner can LPT-partition several suites
|
||||
# together (e.g. base-b + base-c on one Xeon SPR box). A single suite is
|
||||
# just a one-element list, so existing callers are unaffected.
|
||||
suites = [s.strip() for s in args.suite.split(",") if s.strip()]
|
||||
nightly = args.nightly
|
||||
auto_partition_id = args.auto_partition_id
|
||||
auto_partition_size = args.auto_partition_size
|
||||
@@ -341,10 +360,10 @@ def run_a_suite(args):
|
||||
|
||||
all_tests = collect_tests(files, sanity_check=sanity_check)
|
||||
validate_all_suites(all_tests)
|
||||
ci_tests, skipped_tests = filter_tests(all_tests, hw, suite, nightly)
|
||||
ci_tests, skipped_tests = filter_tests(all_tests, hw, suites, nightly)
|
||||
|
||||
if auto_partition_size:
|
||||
live_est = load_live_est(args.partition_model_file, suite, repo_root)
|
||||
live_est = load_live_est(args.partition_model_file, suites, repo_root)
|
||||
if live_est is not None:
|
||||
print(
|
||||
f"LPT: {len(live_est)} live est entries from {args.partition_model_file}",
|
||||
@@ -389,7 +408,16 @@ def main():
|
||||
required=True,
|
||||
help="Hardware backend to run tests on.",
|
||||
)
|
||||
parser.add_argument("--suite", type=str, required=True, help="Test suite to run.")
|
||||
parser.add_argument(
|
||||
"--suite",
|
||||
type=str,
|
||||
required=True,
|
||||
help=(
|
||||
"Test suite to run. Accepts a comma-separated list of suites "
|
||||
"(e.g. 'base-b-test-cpu,base-c-test-cpu'); their tests are unioned "
|
||||
"into one pool before partitioning."
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nightly",
|
||||
action="store_true",
|
||||
|
||||
Reference in New Issue
Block a user