Skip to content

[None][fix] Revert CBTS-fanout #15614+#15592 on 2809 HEAD to bisect-confirm 2810 perf-sanity aborts - #15723

Open
chenfeiz0326 wants to merge 1 commit into
NVIDIA:mainfrom
chenfeiz0326:bisect-confirm-revert-cbts-fanout
Open

[None][fix] Revert CBTS-fanout #15614+#15592 on 2809 HEAD to bisect-confirm 2810 perf-sanity aborts#15723
chenfeiz0326 wants to merge 1 commit into
NVIDIA:mainfrom
chenfeiz0326:bisect-confirm-revert-cbts-fanout

Conversation

@chenfeiz0326

@chenfeiz0326 chenfeiz0326 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

This PR is a bisect-confirmation build only — do not merge.

Context

In post-merge L0_Test-SBSA-Multi-GPU build 2810 (commit c25c23f7), multiple GB200 perf-sanity stages aborted with "Submit Test Result" and "Clean Up Slurm Resource" SKIPPED. Examples:

  • GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-3
  • GB200-8_GPUs-2_Nodes-PyTorch-PerfSanity-Node2-GPU8-Post-Merge-5

The abort rate stepped up between post-merge builds 2806 (a51931ad) and 2809 (86bb1f46). Proximate cause is a 30-second withSlurmSshCredentials probe to a randomly-drawn OCI HSG login node (login-01 was intermittently slow) — when it timed out, uploadResults SIGTERM'd the stage and the finally block skipped Clean Up. The hypothesis is that the CBTS-fanout change in 7cc568c4ee (PR #15592), extended by 86bb1f4612 (PR #15614), increased the number of parallel narrowed perf-sanity stages, multiplying simultaneous SSH-probe load on the OCI HSG head pool.

What this branch does

Branch base: 86bb1f4612 (2809 HEAD).
Reverts (HEAD-to-old order):

  1. 86bb1f4612[None][infra] take test durations into account to determine cbts splits num (#15614)
  2. 7cc568c4ee[None][infra] use default split when CBTS test-db download fails (#15592)

After both reverts, _cbtsMaybeCollapseSplits returns to the pre-7cc568c4ee "collapse to 1 shard when narrowed count < 20" behavior.

Expected verification result

Trigger the 2810 aborted stage list on this PR. If the CBTS-fanout family is the culprit, the abort rate should drop back to 2806-level (i.e., the uploadResults SSH-probe timeouts should largely disappear).

Paired with companion PR (cherry-pick 7cc568c4ee onto 2806 HEAD) for the bisect-confirmation in the opposite direction.

Summary by CodeRabbit

  • New Features

    • CBTS now uses a simpler split-collapsing approach for narrowed test selections, reducing unnecessary shard splitting when fewer tests remain.
  • Bug Fixes

    • Updated CBTS results and summaries to remove split-count details and keep only the most relevant stage counts.
    • Improved handling of generated test database artifacts when using an override directory, including safer packaging and upload behavior.
  • Documentation

    • Refreshed CBTS docs and decision output examples to match the new result format and selection behavior.

@chenfeiz0326
chenfeiz0326 requested a review from a team June 29, 2026 15:20
@chenfeiz0326
chenfeiz0326 requested a review from a team as a code owner June 29, 2026 15:20
@chenfeiz0326
chenfeiz0326 requested review from mlefeb01 and niukuo June 29, 2026 15:20
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The CBTS pipeline removes duration-based split-resize and affected_stage_split_counts across blocks.py, main.py, L0_MergeRequest.groovy, and tooling. A new count-based split-collapse heuristic (_cbtsMaybeCollapseSplits) is introduced in L0_Test.groovy. Test-db artifact packaging is moved to /tmp. README and reporting tools are updated to match.

Changes

CBTS Split-Collapse Refactor

Layer / File(s) Summary
Remove affected_stage_split_counts from contract and computation
jenkins/scripts/cbts/blocks.py, jenkins/scripts/cbts/main.py
Drops TARGET_SHARD_SECONDS, compute_stage_split_counts, load_durations, duration helpers, and related imports from blocks.py. Removes affected_stage_split_counts field from SelectionResult, to_json(), main() computation, trigger-mode filtering, and stderr diagnostics in main.py. compute_stage_test_counts body is inlined with keep-filter logic.
Split-collapse heuristic in L0_Test.groovy
jenkins/L0_Test.groovy
Adds _cbtsMaybeCollapseSplits(stageName, splitId, splits) that skips split groups when narrowed test count < 20 and collapses to splits=1 otherwise. Applies it at runLLMTestlistOnSlurm and runLLMTestlistOnPlatform entry points. Removes CBTS_STAGE_SUFFIX stage-name suffix logic. renderTestDB conditionally skips test-db re-extraction when override directory already exists.
L0_MergeRequest CBTS result contract and artifact upload
jenkins/L0_MergeRequest.groovy
Removes affected_stage_split_counts from the doc comment and from _cbtsParseSelectionResult return map. Changes cbts_test_db.tar.gz creation and upload to use /tmp path instead of workspace-relative path.
Remove split_counts from dryrun and OpenSearch reporting
jenkins/scripts/cbts/tools/dryrun.py, jenkins/scripts/cbts/tools/report_cbts_decision.py
_fmt_summary no longer outputs the split sizing section. flat_detail in build_document drops split_counts from the OpenSearch payload.
README updated for split-collapse
jenkins/scripts/cbts/README.md
Updates consumption layers table, example JSON (removes affected_stage_split_counts), and Layer 2.5 description to document the new <20 test-count collapse rule.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is relevant, but it does not follow the required template sections for summary, description, test coverage, and checklist. Reformat it to match the template, adding @coderabbitai summary, Description, Test Coverage, PR Checklist, and the final checkbox.
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly describes the main change: reverting two CBTS fanout commits to bisect 2810 perf-sanity aborts.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
jenkins/scripts/cbts/blocks.py (1)

618-631: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Share the keep-filter logic with write_filtered_test_db.

This duplicates the exact filtering/fallback contract used later when writing the narrowed YAML. Since this count drives Groovy split-collapse, future drift could make Jenkins collapse using counts that no longer match the emitted test-db.

♻️ Possible helper extraction
+def _filtered_tests_for_block(
+    tests: list[str],
+    prefix_to_waives: dict[str, set[str]],
+) -> list[str]:
+    kept: list[str] = []
+    for t in tests:
+        target = _entry_target(t)
+        matched_waives: set[str] = set()
+        for prefix, waives in prefix_to_waives.items():
+            if _target_in_filter_subtree(target, prefix):
+                matched_waives |= waives
+        if matched_waives and any(_entry_applies_to_waive(t, w) for w in matched_waives):
+            kept.append(t)
+    return kept
+
 ...
-            kept: list[str] = []
-            for t in block.tests:
-                target = _entry_target(t)
-                matched_waives: set[str] = set()
-                for prefix, waives in prefix_to_waives.items():
-                    if _target_in_filter_subtree(target, prefix):
-                        matched_waives |= waives
-                if not matched_waives:
-                    continue
-                if any(_entry_applies_to_waive(t, w) for w in matched_waives):
-                    kept.append(t)
+            kept = _filtered_tests_for_block(block.tests, prefix_to_waives)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jenkins/scripts/cbts/blocks.py` around lines 618 - 631, The keep-filter logic
in this block duplicates the same matching and safety-fallback behavior used by
write_filtered_test_db, so refactor both to use a shared helper instead of
maintaining two copies. Extract the test-selection and empty-result fallback
into a common function used by the count calculation here and by
write_filtered_test_db, keeping the behavior for _entry_target,
_target_in_filter_subtree, and _entry_applies_to_waive identical in both call
sites.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jenkins/L0_Test.groovy`:
- Around line 1741-1746: The split-collapse logic in _cbtsMaybeCollapseSplits is
happening too late inside the runner, after launchTestJobs has already scheduled
work and runKubernetesPodWithInfraRetry has allocated the pod. Move the CBTS
collapse into the parallelJobs construction/filtering path so splitId/splits are
adjusted before any Kubernetes pod launch, and remove or minimize the in-runner
skip-only handling so collapsed splits never get scheduled in the first place.

---

Nitpick comments:
In `@jenkins/scripts/cbts/blocks.py`:
- Around line 618-631: The keep-filter logic in this block duplicates the same
matching and safety-fallback behavior used by write_filtered_test_db, so
refactor both to use a shared helper instead of maintaining two copies. Extract
the test-selection and empty-result fallback into a common function used by the
count calculation here and by write_filtered_test_db, keeping the behavior for
_entry_target, _target_in_filter_subtree, and _entry_applies_to_waive identical
in both call sites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6629de99-e502-40ee-938f-25b192abff74

📥 Commits

Reviewing files that changed from the base of the PR and between 833ddd2 and 09f7588.

📒 Files selected for processing (7)
  • jenkins/L0_MergeRequest.groovy
  • jenkins/L0_Test.groovy
  • jenkins/scripts/cbts/README.md
  • jenkins/scripts/cbts/blocks.py
  • jenkins/scripts/cbts/main.py
  • jenkins/scripts/cbts/tools/dryrun.py
  • jenkins/scripts/cbts/tools/report_cbts_decision.py
💤 Files with no reviewable changes (1)
  • jenkins/scripts/cbts/tools/dryrun.py

Comment thread jenkins/L0_Test.groovy
Comment on lines +1741 to +1746
def collapse = _cbtsMaybeCollapseSplits(stageName, splitId, splits)
if (collapse.skip) {
return
}
splits = collapse.splits
splitId = collapse.splitId

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

Move split-collapse before pod launch.

By Line 5255, launchTestJobs has already handed every split to runKubernetesPodWithInfraRetry, so returning here only skips the test body after the pod is up. For Kubernetes-backed stages, splitId>1 still burns a full pod/GPU allocation, which means this does not actually collapse stage fanout at the scheduling layer. Apply the CBTS collapse when building/filtering parallelJobs instead of inside the runners.

Also applies to: 3829-3834

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jenkins/L0_Test.groovy` around lines 1741 - 1746, The split-collapse logic in
_cbtsMaybeCollapseSplits is happening too late inside the runner, after
launchTestJobs has already scheduled work and runKubernetesPodWithInfraRetry has
allocated the pod. Move the CBTS collapse into the parallelJobs
construction/filtering path so splitId/splits are adjusted before any Kubernetes
pod launch, and remove or minimize the in-runner skip-only handling so collapsed
splits never get scheduled in the first place.

@chenfeiz0326
chenfeiz0326 force-pushed the bisect-confirm-revert-cbts-fanout branch from 09f7588 to 69311d0 Compare June 29, 2026 15:36
@chenfeiz0326 chenfeiz0326 changed the title [DO NOT MERGE][bisect] Revert CBTS-fanout commits #15614+#15592 on 2809 HEAD [None][fix] Revert CBTS-fanout #15614+#15592 on 2809 HEAD to bisect-confirm 2810 perf-sanity aborts Jun 29, 2026
@chenfeiz0326

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast --stage-list "GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU1-GEN1-NODE2-GPU8-Post-Merge-2,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-1,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-3,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-5,GB200-16_GPUs-4_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE2-GPU8-GEN1-NODE2-GPU8-Post-Merge-1,GB200-20_GPUs-5_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE4-GPU16-Post-Merge-4,GB200-24_GPUs-6_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE2-GPU8-GEN1-NODE4-GPU16-Post-Merge-1,GB200-24_GPUs-6_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE2-GPU8-GEN1-NODE4-GPU16-Post-Merge-2,GB200-36_GPUs-9_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE8-GPU32-Post-Merge-1,GB200-4_GPUs-PyTorch-PerfSanity-Post-Merge-1,GB200-4_GPUs-PyTorch-PerfSanity-Post-Merge-2,GB200-4_GPUs-PyTorch-PerfSanity-Post-Merge-3,GB200-4_GPUs-PyTorch-PerfSanity-Post-Merge-4,GB200-4_GPUs-PyTorch-PerfSanity-Post-Merge-6,GB200-4_GPUs-PyTorch-PerfSanity-Post-Merge-7,GB200-4_GPUs-PyTorch-PerfSanity-Post-Merge-8,GB200-8_GPUs-2_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU1-GEN1-NODE1-GPU2-Post-Merge-1,GB200-8_GPUs-2_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU1-GEN1-NODE1-GPU4-Post-Merge-4,GB200-8_GPUs-2_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU1-GEN1-NODE1-GPU4-Post-Merge-5,GB200-8_GPUs-2_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU1-GEN1-NODE1-GPU4-Post-Merge-7,GB200-8_GPUs-2_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE1-GPU4-Post-Merge-1,GB200-8_GPUs-2_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE1-GPU4-Post-Merge-2,GB200-8_GPUs-2_Nodes-PyTorch-PerfSanity-Node2-GPU8-Post-Merge-1,GB200-8_GPUs-2_Nodes-PyTorch-PerfSanity-Node2-GPU8-Post-Merge-7,GB200-8_GPUs-2_Nodes-PyTorch-PerfSanity-Node2-GPU8-Post-Merge-8,GB200-8_GPUs-2_Nodes-PyTorch-Post-Merge-1"

@chenfeiz0326

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast --stage-list "GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU1-GEN1-NODE2-GPU8-Post-Merge-1,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-1,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-2,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-3,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-4,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-5,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-6,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-8,GB200-16_GPUs-4_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE2-GPU8-GEN1-NODE2-GPU8-Post-Merge-1,GB200-16_GPUs-4_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE2-GPU8-GEN1-NODE2-GPU8-Post-Merge-2"

@chenfeiz0326
chenfeiz0326 force-pushed the bisect-confirm-revert-cbts-fanout branch from 69311d0 to a02214a Compare June 30, 2026 02:21
Signed-off-by: Chenfei Zhang <chenfeiz@nvidia.com>
@chenfeiz0326 chenfeiz0326 reopened this Jun 30, 2026
@chenfeiz0326

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast --stage-list "GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU1-GEN1-NODE2-GPU8-Post-Merge-1,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-1,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-2,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-3,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-4,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-5,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-6,GB200-12_GPUs-3_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE1-GPU4-GEN1-NODE2-GPU8-Post-Merge-8,GB200-16_GPUs-4_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE2-GPU8-GEN1-NODE2-GPU8-Post-Merge-1,GB200-16_GPUs-4_Nodes-PyTorch-Disagg-PerfSanity-CTX1-NODE2-GPU8-GEN1-NODE2-GPU8-Post-Merge-2"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant