Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
c4561de
ci(consumer-graph): make static parser the authoritative graph generator
endurthiabhilash Sep 30, 2026
2e8d190
ci(consumer-graph): commit generated subtree_map as a drift-checked file
endurthiabhilash Sep 30, 2026
cadab7d
ci(test-selection): resolve subtrees from the generated subtree_map
endurthiabhilash Sep 30, 2026
1e0a041
ci(consumer-graph): generate report-only source-dir map
endurthiabhilash Oct 1, 2026
227aba5
ci(test-labels): guard test-label consistency and label-group duplica…
endurthiabhilash Oct 1, 2026
2ff1c9d
ci(consumer-graph): remove the configure-time consumer-graph emit
endurthiabhilash Oct 1, 2026
f6cf619
ci(consumer-graph): degrade gracefully on unresolvable provide_artifact
endurthiabhilash Oct 1, 2026
5878ad8
ci(test-selection): harden subtree-alias map loading
endurthiabhilash Oct 1, 2026
9342855
ci(consumer-graph): regenerate derived maps against latest main
endurthiabhilash Oct 1, 2026
b4e539c
refactor(consumer-graph): trim narrating comments; drop dead edge rec…
endurthiabhilash Oct 1, 2026
0535246
refactor(consumer-graph): plainer test names and comment wording
endurthiabhilash Oct 1, 2026
b0da1b5
test(consumer-graph): add generator, external-repo, and robustness co…
endurthiabhilash Oct 2, 2026
93a8849
refactor(consumer-graph): plainer comments; guard --check against mis…
endurthiabhilash Oct 5, 2026
7025aee
ci(consumer-graph): rename test files to fix collision and naming hook
endurthiabhilash Oct 5, 2026
13ca00c
ci(consumer-graph): regenerate derived maps to match main
endurthiabhilash Oct 7, 2026
5df019b
fix(ci): make every test-matrix job reachable by scoped selection
tony-davis Oct 13, 2026
27de761
ci(consumer-graph): make static parser the authoritative graph generator
endurthiabhilash Sep 30, 2026
52b5e5d
ci(consumer-graph): commit generated subtree_map as a drift-checked file
endurthiabhilash Sep 30, 2026
23b64a2
ci(test-selection): resolve subtrees from the generated subtree_map
endurthiabhilash Sep 30, 2026
f0e4cdd
ci(consumer-graph): generate report-only source-dir map
endurthiabhilash Oct 1, 2026
7991040
ci(test-labels): guard test-label consistency and label-group duplica…
endurthiabhilash Oct 1, 2026
29a671f
ci(consumer-graph): remove the configure-time consumer-graph emit
endurthiabhilash Oct 1, 2026
2eb4260
ci(consumer-graph): degrade gracefully on unresolvable provide_artifact
endurthiabhilash Oct 1, 2026
57e1434
ci(test-selection): harden subtree-alias map loading
endurthiabhilash Oct 1, 2026
01387c2
ci(consumer-graph): regenerate derived maps against latest main
endurthiabhilash Oct 1, 2026
82f67f9
refactor(consumer-graph): trim narrating comments; drop dead edge rec…
endurthiabhilash Oct 1, 2026
d99237f
refactor(consumer-graph): plainer test names and comment wording
endurthiabhilash Oct 1, 2026
f82e2fc
test(consumer-graph): add generator, external-repo, and robustness co…
endurthiabhilash Oct 2, 2026
5f41a25
refactor(consumer-graph): plainer comments; guard --check against mis…
endurthiabhilash Oct 5, 2026
1de981e
ci(consumer-graph): rename test files to fix collision and naming hook
endurthiabhilash Oct 5, 2026
30047e4
ci(consumer-graph): regenerate derived maps to match main
endurthiabhilash Oct 7, 2026
bf34239
ci(consumer-graph): regenerate maps after rebase for profiler-hub
endurthiabhilash Oct 13, 2026
cfd0826
Merge users/tony-davis/selector-reachability (test-job reachability)
endurthiabhilash Oct 13, 2026
d5a2d37
refactor(consumer-graph): resolve subtree map from --therock-dir
endurthiabhilash Oct 14, 2026
7ba79a4
refactor(consumer-graph): assert source-dir-map invariants; selector …
endurthiabhilash Oct 14, 2026
43918f1
test(consumer-graph): pass subtree_alias_map to _normalize_changed_pr…
endurthiabhilash Oct 14, 2026
a51a433
Merge branch 'main' into users/aendurth/issue-7782-pr2-activation
endurthiabhilash Oct 19, 2026
f22bcbc
test(consumer-graph): rename override-retirement test and clarify mes…
endurthiabhilash Nov 6, 2026
d496778
Merge origin/main into users/aendurth/issue-7782-pr2-activation
endurthiabhilash Nov 7, 2026
d701f11
refactor(consumer-graph): drop the source-dir map until it has a cons…
endurthiabhilash Nov 7, 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
2 changes: 1 addition & 1 deletion .github/workflows/test_artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ jobs:
- name: "Determine test dependencies"
id: test_deps
# Reads the committed consumer graph directly (no fetch/configure); kept
# in sync by test_consumer_graph_drift.yml.
# in sync by the consumer-graph parser test in the Test build_tools job.
shell: bash
env:
CHANGED_PROJECTS: ${{ inputs.changed_projects }}
Expand Down
61 changes: 0 additions & 61 deletions .github/workflows/test_consumer_graph_drift.yml

This file was deleted.

3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,3 @@ therock_subproject_merge_compile_commands()

# Write artifact→subprojects manifest for Python scripts to use
therock_write_subproject_manifest()

include(therock_emit_consumer_graph)
therock_emit_consumer_graph("${CMAKE_BINARY_DIR}/therock_consumer_graph.json")
10 changes: 7 additions & 3 deletions build_tools/_therock_utils/cmake_consumer_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
"DEFAULT_GPU_TARGETS",
"FPRINT_FILE_GLOBS",
"INSTALL_OPTIONAL_COMPONENTS",
"HARDENING_DEFERRED",
}
_DECLARATION_KEYWORDS = (
_DECLARATION_FLAGS | _DECLARATION_ONE_VALUE_ARGS | _DECLARATION_MULTI_VALUE_ARGS
Expand Down Expand Up @@ -934,14 +935,17 @@ def _resolve_source_dir_section(
return {value for value in expansion.values if value}


def _declaration_sections(tokens: list[Token]) -> dict[str, list[Token]]:
"""Group a declaration's argument tokens by their keyword (BUILD_DEPS, ...)."""
def _declaration_sections(
tokens: list[Token],
keywords: frozenset[str] | set[str] = _DECLARATION_KEYWORDS,
) -> dict[str, list[Token]]:
"""Group an argument list's tokens by their keyword (BUILD_DEPS, ...)."""
sections: dict[str, list[Token]] = {}
current_keyword: str | None = None
for token in tokens:
if token.kind == "COMMENT":
continue
if token.value in _DECLARATION_KEYWORDS:
if token.value in keywords:
current_keyword = token.value
sections.setdefault(current_keyword, [])
elif current_keyword is not None:
Expand Down
86 changes: 67 additions & 19 deletions build_tools/generate_consumer_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
# Copyright Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT

"""Generate test_tools/therock_consumer_graph.json from the super-project CMake.
"""Generate the committed consumer-graph metadata from the super-project CMake.

Statically parses the tracked CMake files (no configure, no submodules) and writes
the reverse-dependency consumer graph. See cmake_consumer_graph.py for the full
two committed files:

* ``test_tools/therock_consumer_graph.json`` — the reverse-dependency consumer graph.
* ``test_tools/therock_subtree_map.json`` — each external source subtree mapped to the
graph key(s) built from it.

This parser generates both files. See cmake_consumer_graph.py for the full
description and limitations.

``--check`` analyzes in memory and diffs the result against the committed graph
without writing, exiting non-zero on any difference. While the committed graph is
still emitted by CMake, this parser is a conservative *superset* of it, so
``--check`` reports that expected superset delta; it is intentionally not wired
into any CI gate.
``--check`` analyzes in memory and diffs the result against ALL committed files
without writing, exiting non-zero on any difference. It is the drift gate: the
``Test build_tools`` pytest step enforces the same invariant, so a stale committed
file fails CI.
"""

import argparse
Expand All @@ -29,14 +34,17 @@
THIS_SCRIPT_DIR = Path(__file__).resolve().parent
THEROCK_DIR = THIS_SCRIPT_DIR.parent
CONSUMER_GRAPH_PATH = THEROCK_DIR / "test_tools" / "therock_consumer_graph.json"
SUBTREE_MAP_PATH = THEROCK_DIR / "test_tools" / "therock_subtree_map.json"
# Informational artifact→source-subtree map; committed and drift-gated but not yet
# consumed by selection (see module docstring).


def _write_json(path: Path, data: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8")


def _print_delta(comparison) -> None:
def _print_graph_delta(comparison) -> None:
"""Print a concise summary of how the generated graph differs from committed."""
for label, items in (
("generated-only nodes", comparison.generated_only_nodes),
Expand All @@ -49,27 +57,52 @@ def _print_delta(comparison) -> None:
print(f" {item}")


def _map_delta(generated: dict, committed: dict, noun: str) -> list[str]:
"""Return human-readable difference lines between two ``str -> list`` maps."""
lines: list[str] = []
generated_keys, committed_keys = set(generated), set(committed)
for key in sorted(generated_keys - committed_keys):
lines.append(f" generated-only {noun}: {key} -> {generated[key]}")
for key in sorted(committed_keys - generated_keys):
lines.append(f" committed-only {noun}: {key} -> {committed[key]}")
for key in sorted(generated_keys & committed_keys):
if generated[key] != committed[key]:
lines.append(
f" {noun} {key}: generated {generated[key]} != committed {committed[key]}"
)
return lines


def _read_committed_map(path: Path) -> dict:
"""Committed JSON map, or empty if missing so --check reports full drift."""
if not path.exists():
return {}
return json.loads(path.read_text(encoding="utf-8"))


def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(
description="Generate test_tools/therock_consumer_graph.json from the super-project CMake."
description="Generate the committed consumer-graph metadata from the super-project CMake."
)
parser.add_argument(
"--check",
action="store_true",
help=(
"Diff the generated graph against the committed one without writing; "
"exit non-zero on any difference. The parser is currently a superset "
"of the committed graph, so this reports that expected delta and is not "
"wired into a CI gate."
"Diff the generated graph and subtree map against the "
"committed files without writing; exit non-zero on any difference. This "
"is the drift gate."
),
)
args = parser.parse_args(argv)
result = RepositoryAnalyzer(THEROCK_DIR).analyze()
graph = result.build_consumer_graph()
subtree_map = result.build_subtree_map()

if args.check:
committed = load_consumer_graph(CONSUMER_GRAPH_PATH)
comparison = compare_graphs(graph, committed)
differs = False

committed_graph = load_consumer_graph(CONSUMER_GRAPH_PATH)
comparison = compare_graphs(graph, committed_graph)
if (
comparison.generated_only_nodes
or comparison.reference_only_nodes
Expand All @@ -80,15 +113,30 @@ def main(argv: list[str] | None = None) -> int:
"Generated consumer graph differs from "
f"{CONSUMER_GRAPH_PATH.relative_to(THEROCK_DIR).as_posix()}:"
)
_print_delta(comparison)
_print_graph_delta(comparison)
differs = True

committed_subtree = _read_committed_map(SUBTREE_MAP_PATH)
subtree_delta = _map_delta(subtree_map, committed_subtree, "subtree")
if subtree_delta:
print(
"Generated subtree map differs from "
f"{SUBTREE_MAP_PATH.relative_to(THEROCK_DIR).as_posix()}:"
)
print("\n".join(subtree_delta))
differs = True

if differs:
return 1
print("Generated consumer graph matches the committed graph.")
print("Generated consumer graph and subtree map match the committed files.")
return 0

_write_json(CONSUMER_GRAPH_PATH, graph)
_write_json(SUBTREE_MAP_PATH, subtree_map)
print(
f"Wrote consumer graph for {len(graph)} subprojects to "
f"{CONSUMER_GRAPH_PATH.relative_to(THEROCK_DIR).as_posix()}"
f"Wrote consumer graph ({len(graph)} subprojects) and subtree map "
f"({len(subtree_map)} subtrees) to "
f"{CONSUMER_GRAPH_PATH.parent.relative_to(THEROCK_DIR).as_posix()}/"
)
return 0

Expand Down
124 changes: 0 additions & 124 deletions build_tools/github_actions/check_consumer_graph_drift.py

This file was deleted.

5 changes: 3 additions & 2 deletions build_tools/github_actions/configure_external_repo_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@
# to one of these paths yields no matched subtree -> empty changed_projects ->
# TheRock falls back to building and testing everything. Each entry MUST have a
# corresponding mapping in TheRock (build-topology alias + the test selector's
# _EXTERNAL_SUBTREE_ALIASES), so keep this list in lock-step with TheRock when
# adding directories.
# generated subtree map or _SUBTREE_ALIAS_OVERRIDES); the test selector hard-fails
# on an unmapped shared/*, dnn-providers/*, or emulation/* path, so keep this list
# in lock-step with TheRock when adding directories.
CI_RELEVANT_NON_SUBTREE_PREFIXES = {
# hipCCL is a monorepo-native project (projects/hipccl/hipccl3, the unified
# rocPRIM+hipCUB+rocThrust superbuild); it has no upstream repo to subtree-
Expand Down
5 changes: 4 additions & 1 deletion build_tools/github_actions/configure_multi_arch_ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,10 @@ def _resolve_skipped_stages(build_stages: list[str]) -> list[str]:

# Maps build stages to the test labels that can run with artifacts from those
# stages. Used to auto-filter tests when build_stages narrows the build graph.
# Test labels not listed here require a full build.
# Test labels not listed here require a full build. Most labels have a
# fetch_test_configurations.test_matrix entry; kfdtest and composable-kernel are
# real artifacts tested through other paths and have none (see
# label_consistency_test, which guards against a genuinely unknown label).
STAGE_TO_TEST_LABELS: dict[str, list[str]] = {
"compiler-runtime": ["kfdtest"],
"runtime-tests": ["hip-tests", "rocrtst"],
Expand Down
Loading
Loading