Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1928e80
Adding reuse based on artifact availability and unaffected stages
Jun 30, 2026
1097ec2
Adding reuse based on artifact availability and unaffected stages
Jun 30, 2026
b0d8f67
Adding test cases and fixing bugs
Jun 30, 2026
7bd631c
Moving tests to right location
Jun 30, 2026
58b0a1d
removing redundant import
Jun 30, 2026
9b7a0e1
Fixing copilot detected bug
Jun 30, 2026
fc21126
Fixing formatting
Jun 30, 2026
0648dcc
Adding unit tests
Jun 30, 2026
78fef0c
Merge branch 'main' into users/ammallya/reuse-artifacts
erman-gurses Jul 6, 2026
886eafc
Format
erman-gurses Jul 6, 2026
ce75e62
ci(stage-reuse): verify baseline artifacts per-platform before reusin…
Jul 6, 2026
76397f3
Adding missing debug outputs
Jul 6, 2026
c6fb127
Removing reduandant import
Jul 6, 2026
fe28af9
stage-reuse: disable automatic reuse when no platforms are selected
erman-gurses Jul 7, 2026
4259e85
stage-reuse: simplify build platform selection
erman-gurses Jul 7, 2026
da6adb4
Update docstring
erman-gurses Jul 7, 2026
6851c06
stage-reuse: propagate baseline run id for auto reuse
erman-gurses Jul 7, 2026
397e824
stage-reuse: disable reuse when platforms select different baselines
erman-gurses Jul 7, 2026
e7086a2
Black
erman-gurses Jul 7, 2026
d7c3c09
Merge branch 'main' into users/ammallya/reuse-artifacts
erman-gurses Jul 7, 2026
cb85bc7
Adding documentation
Jul 8, 2026
07f7f7f
fixing ordering regression
Jul 8, 2026
b1f3c37
Refactor and clean up based on Scott's review
Jul 16, 2026
0673a91
Merge branch 'main' into users/ammallya/reuse-artifacts
ammallya Jul 16, 2026
5dc07b4
Fix after new JAX functionality merge
Jul 16, 2026
1c19f0b
Fix for tests
Jul 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/multi_arch_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ on:
type: string
default: ""
description: "Workflow run ID to copy prebuilt stage artifacts from; required when prebuilt_stages is set"
stage_reuse_mode:
type: string
default: "dry-run"
description: "dry-run (report only) | skip-stage (actually skip unaffected stages)"
Comment thread
ammallya marked this conversation as resolved.
Resolved
changed_projects:
type: string
default: ""
Expand Down Expand Up @@ -82,6 +86,7 @@ jobs:
windows_test_labels: ${{ inputs.windows_test_labels || '' }}
prebuilt_stages: ${{ inputs.prebuilt_stages || '' }}
baseline_run_id: ${{ inputs.baseline_run_id || '' }}
stage_reuse_mode: ${{ inputs.stage_reuse_mode || 'dry-run' }}
build_pytorch: ${{ github.event_name != 'workflow_dispatch' || inputs.build_pytorch }}
build_jax: false

Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/setup_multi_arch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ on:
description: "Workflow run ID to copy prebuilt stage artifacts from."
type: string
default: ""
stage_reuse_mode:
description: "dry-run (default) only reports which stages would be skipped; skip-stage actually skips unaffected stages."
type: string
default: "dry-run"
build_pytorch:
description: "Build PyTorch wheels."
type: boolean
Expand Down Expand Up @@ -159,6 +163,10 @@ jobs:
WINDOWS_TEST_LABELS: ${{ inputs.windows_test_labels }}
PREBUILT_STAGES: ${{ inputs.prebuilt_stages }}
BASELINE_RUN_ID: ${{ inputs.baseline_run_id }}
STAGE_REUSE_MODE: ${{ inputs.stage_reuse_mode }}
STAGE_REUSE_CURRENT_SHA: ${{ steps.checkout.outputs.commit }}

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.

you can actaully get this from ${{ github.sha }} (current sha)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It depends on what commit ref you want.

steps.checkout.outputs.commit gets the TheRock commit even when running in rockrel (and maybe rocm-libraries / rocm-systems?), see the workflow output:

For runs in rocm-libraries and rocm-systems, we may want to use baseline runs from those repositories instead of TheRock though.

Ultimately I think the best artifact reuse we'll be able to get will be some query against a database where we say "here are the artifact fingerprints that my current source code produces, fetch me artifacts for any with matching fingerprints from the database", which we'd want to abstract away from the github actions runs API entirely. We wouldn't need to scan commit history or workflow runs with that architecture.

STAGE_REUSE_MAX_AGE_HOURS: "72"
STAGE_REUSE_COMMIT_HISTORY: "50"
Comment thread
ammallya marked this conversation as resolved.
Resolved

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.

These are becoming part of the stage-reuse interface - will make sense to document this environment contract in the module docstring.

Comment thread
ammallya marked this conversation as resolved.
Resolved
# Skip path filtering for external repos (git sha won't exist in TheRock)
SKIP_PATH_FILTERS: ${{ inputs.external_repo != '' && 'true' || '' }}
CI_CONFIG_PATH: ci-config
Expand Down
38 changes: 34 additions & 4 deletions build_tools/github_actions/configure_multi_arch_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,14 +685,38 @@ def decide_jobs(
"""Determine which job groups to run, skip, or satisfy with prebuilt files."""

# Build ROCm.
# TODO(#3399): Use changed files and build_topology.py to:
# 1. set per-stage prebuilt decisions
# 2. skip job groups that aren't reachable from the changed files
# Parse explicit prebuilt stages from workflow_dispatch input.
# Parse explicit prebuilt stages from workflow_dispatch input. These are
# the MANUAL inputs and are always honored, unchanged, in every mode.

stage_decisions: dict[str, JobAction] = {}
if ci_inputs.prebuilt_stages:
for stage in _parse_prebuilt_stages(ci_inputs.prebuilt_stages):
stage_decisions[stage] = JobAction.PREBUILT

# Behind STAGE_REUSE_MODE: in dry-run we only PRINT
# which stages WOULD be skipped and apply nothing; in "skip-stage" the
# eligible stages are merged into stage_decisions so the orchestrator
# skips their builds and copies artifacts instead.
from stage_reuse_decision import (
StageReuseMode,
compute_auto_stage_reuse,
render_step_summary,
)

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.

Is there a reason these imports are local rather than module-level? If it's to avoid import cycles, it might be worth adding a short comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope - follow the style guide. These imports must be moved to the top. https://github.com/ROCm/TheRock/blob/main/docs/development/style_guides/python_style_guide.md#import-organization

No import cycles here. If there are cycles we should break them instead of use local imports.

target_families = _stage_reuse_target_families(ci_inputs)
auto = compute_auto_stage_reuse(

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.

compute_auto_stage_reuse() now performs stage-impact analysis, baseline selection, artifact verification, and reporting. Have we considered separating the planning portion from the reporting/execution plumbing to keep the decision logic independently reusable?

Comment thread
ammallya marked this conversation as resolved.
Resolved
changed_files=git_context.changed_files,
mode=StageReuseMode.from_environ(),
target_families=target_families,
)
for line in auto.report_lines:
print(line)
try:
gha_append_step_summary(render_step_summary(auto))
Comment thread
ammallya marked this conversation as resolved.
Resolved
except Exception as exc: # never fail CI config on a reporting
print(f"[STAGE-REUSE] could not write step summary: {exc}")
# Only skip-stage mode returns non-empty applied_reuse_stages.
for stage in auto.applied_reuse_stages:
Comment thread
erman-gurses marked this conversation as resolved.
Resolved
stage_decisions.setdefault(stage, JobAction.PREBUILT)
build_rocm = BuildRocmDecision(
action=JobAction.RUN,
stage_decisions=stage_decisions,
Expand Down Expand Up @@ -741,6 +765,12 @@ def decide_jobs(
# Step 4: Select Targets
# ---------------------------------------------------------------------------

def _stage_reuse_target_families(ci_inputs: "CIInputs") -> list[str]:
Comment thread
ammallya marked this conversation as resolved.
Resolved
families = list(dict.fromkeys(
[*ci_inputs.linux_amdgpu_families, *ci_inputs.windows_amdgpu_families]))
if "generic" not in families:
families.append("generic")
return families

def _validate_family_names(
names: list[str],
Expand Down
Loading
Loading