From r2g-skills
Convert clean, signed-off physical-design files (DEF/LEF/liberty/SPEF from an ORFS backend run) into training-ready PyTorch-Geometric graph datasets. Use when the user wants to build a graph dataset from placed-and-routed designs — the five graph views (b–f), the tech-lib/LEF/DEF parser, node/edge feature extraction, or per-cell/per-net labels (congestion, RC parasitics, wirelength, timing, IR drop). Companion to the signoff-loop skill, which produces the physical-design inputs this skill consumes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/r2g-skills:def-graphThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Turn a completed, signed-off backend run into a **training-ready graph dataset**. This is the
references/README.mdreferences/env.local.sh.templatereferences/feature-extraction.mdreferences/graph-dataset.mdreferences/label-extraction.mdscripts/extract/features/case_paths.pyscripts/extract/features/compute_feature_stats.pyscripts/extract/features/edges_gate_pin.pyscripts/extract/features/edges_iopin_net.pyscripts/extract/features/edges_pin_net.pyscripts/extract/features/metadata.pyscripts/extract/features/nodes_gate.pyscripts/extract/features/nodes_iopin.pyscripts/extract/features/nodes_net.pyscripts/extract/features/nodes_pin.pyscripts/extract/graph/build_graphs.pyscripts/extract/graph/graph_lib.pyscripts/extract/graph/netlist_graph.pyscripts/extract/graph/odb_to_def.pyscripts/extract/labels/compute_label_stats.pyTurn a completed, signed-off backend run into a training-ready graph dataset. This is the
X/Y dataset-construction half of the RTL→GDS→Graph pipeline: it reads the physical-design
artifacts a signoff flow produces (6_final.def, 6_final.odb, optional 6_final.spef, plus
the platform liberty/LEF) and emits per-node/per-edge features (X), per-cell/per-net
labels (Y), and five PyTorch-Geometric graph topologies (b–f).
Produce the inputs with the signoff-loop skill (or any ORFS run that leaves a
6_final.def); this skill consumes them. It never runs place-and-route.
Every stage sources scripts/flow/_env.sh on entry, which autodetects ORFS + tool paths
(shared resolver, identical contract to the signoff-loop skill). Nothing to source manually.
Resolution order (first hit wins, per value): caller env → $R2G_ENV_FILE → in-skill
references/env.local.sh → $ORFS_ROOT/env.sh → /opt/openroad_tools_env.sh → autodetect.
The graph-assembly stage additionally needs a torch venv (torch + torch_geometric +
pandas). Point R2G_GRAPH_PYTHON at its bin/python; the label/feature/techlib stages do not
need it. Install on /proj, never $HOME:
python3 -m venv /proj/<you>/pyenvs/r2g-graph
/proj/<you>/pyenvs/r2g-graph/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
/proj/<you>/pyenvs/r2g-graph/bin/pip install torch_geometric pandas
The three stages compose. Each takes a <project-dir> that already holds a signed-off backend
run (a 6_final.def reachable via ORFS results or $R2G_DEF) and [platform].
Platform authority (failure-patterns.md #30): explicit [platform] arg > build provenance >
config.mk. When the arg is omitted, each stage consults the discovered backend's run-meta.json
(via the shared scripts/flow/_provenance.sh) before trusting constraints/config.mk — a campaign
re-point (setup_rtl_designs.py --platform X --force) rewrites config.mk for the whole corpus, and
cell_type_id/*_type_id vocabularies are per-platform, so keying an existing DEF to the re-pointed
platform is a silent-value defect. build_graphs.py stamps the resolved platform into
graph_manifest.json; tools/verify_graph_dataset.py trusts manifest > run-meta.json > config.mk.
Signoff gate (failure-patterns.md #34): a 6_final.def alone is NOT sign-off. Before
building, every stage runs the shared scripts/flow/signoff_gate.py against
reports/{drc,lvs,route}.json + the DEF-run's stage_log.jsonl: required checks (fail-closed —
a MISSING report blocks) are drc ∈ {clean, clean_beol}, lvs ∈ {clean, skipped}, ORFS complete,
route/antenna residuals 0 when provable; timing is recorded but never blocks (negative slack is a
legitimate training label). run_graphs.sh — the dataset builder — enforces by default and
SKIPs a not-signed-off design; run_labels.sh/run_features.sh default to warn (record +
proceed). Override with R2G_SIGNOFF_GATE=strict|enforce|warn|off; an explicit R2G_DEF override
downgrades to warn (a deliberate, recorded operator decision). The verdict always lands in
reports/signoff_gate.json and rides the manifest as signoff_health — the verifier fails a
dataset whose provenance is unrecorded or whose gate verdict is dirty.
ORFS completion requires a reconstructable SIX-STAGE lineage, not merely a clean finish row —
a repair/resume generation is attributed via resume_meta.json's recorded parent_lineage or
sibling ledgers (the latter as the orfs_lineage=reconstructed caveat); an orphan repair-only
run blocks (round-2 pilot P0-4). Strict tier (R2G_SIGNOFF_GATE=strict, pilot P0-1): only
the exact verdict pass builds; pass_with_caveats blocks. Every manifest carries
dataset_tier — strict_clean iff the gate verdict was exactly pass, else research — and a
clean dataset index must filter on it. Each build also stamps a stable corpus-level graph_id
(sha1(platform:design) in [1, 2^24), R2G_GRAPH_ID overrides; pilot P0-5) into the manifest and
every x1 slot; verify_graph_dataset.py --batch enforces corpus-wide uniqueness and reports
BLOCKED / not_applicable (exit 3 single-case) for intentionally denied designs instead of
crashing (pilot H2).
scripts/flow/run_labels.sh <project-dir> [platform]Per-cell / per-net regression targets into <project-dir>/labels/, plus a per-design
reports/labels_stats.json:
6_final.spef, via extract_rc.py): ground cap
(net_ground_cap.csv, per-net node label), coupling cap (coupling_cap.csv, net-pair edge
label), equivalent resistance (equiv_res.csv, same-net pin-pair edge label), + net_driver.csv
(places net↔net coupling edges on driver pins). No SPEF (RCX not run) → header-only RC CSVs.Fail-soft: a missing input or per-label tool error is recorded in the stats file, not fatal.
Platform-agnostic — liberty/LEF/supply-voltage come from the ORFS platform config. Batch
backfill across completed designs: tools/run_labels_batch.sh. See
references/label-extraction.md.
scripts/flow/run_features.sh <project-dir> [platform]Graph-feature CSVs into <project-dir>/features/: metadata.csv (graph-level),
nodes_{gate,net,iopin,pin}.csv, edges_{gate_pin,pin_net,iopin_net}.csv, plus a per-design
reports/features_stats.json. Reads the same 6_final.def (+ optional 6_final.spef) as
the labels, so feature rows join label rows on graph_id+inst_name/net_name. Fail-soft;
SPEF absence degrades cap/RC columns to 0. Batch backfill: tools/run_features_batch.sh. See
references/feature-extraction.md.
scripts/flow/run_graphs.sh <project-dir> [platform]Assembles the five topologies into <project-dir>/dataset/{b..f}_graph.pt — heterogeneous
HeteroData by default (R2G_GRAPH_KIND=homo for the legacy homogeneous format, both for
both) — plus the synthesis-netlist bipartite graph (netlist_graph.pt, always homogeneous) and a
manifest (dataset/graph_manifest.json, mirrored to reports/graph_dataset.json). Runs stages 1–2
automatically when their CSVs are missing or older than the DEF (freshness judged by the
reports/{features,labels}_stats.json stage-completion markers, not an early CSV).
R2G_GRAPH_PYTHON=/proj/<you>/pyenvs/r2g-graph/bin/python \
scripts/flow/run_graphs.sh <project-dir> [platform]
Needs torch + torch_geometric + pandas; machines without them SKIP cleanly with a HINT.
R2G_GRAPH_VARIANTS selects variants (default bcdef); R2G_GRAPH_KIND picks the output
(hetero default / homo / both); GRAPH_TIMEOUT (default 2400s);
R2G_DEF/R2G_ODB/R2G_SPEF pin the DEF/ODB/SPEF for both the feature and label stages
(so X and Y stay joined on the same DEF), enabling a backend-less reference-DEF build.
See references/graph-dataset.md.
Check status + label_health + signoff_health in the manifest before training. status: "ok_with_label_gaps" means ≥1 label file couldn't join (its y slot is all-NaN); the per-file
reason is in label_health. signoff_health.status outside {pass, pass_with_caveats} means the
dataset was built past the signoff gate (warn/off mode) on a design that is not signed off — the
blockers list says why.
| Variant | Nodes kept | Folded into edges |
|---|---|---|
| b | gate, net, iopin, pin | — (gate-pin, pin-net, iopin-net edges) |
| c | gate, net, iopin | pins → gate-net edges (pin features on edge_attr) |
| d | gate, iopin, pin | nets → pin-clique edges (net features on edge_attr) |
| e | iopin, pin | gates AND nets → pin-clique edges |
| f | gate, iopin | nets → gate-clique edges |
Default output is heterogeneous (HeteroData): per-type node stores (gate/net/iopin/pin)
(src_type, relation, dst_type) edge stores (relation = the folded entity — b connects; c/d/e/f
from edge_schema; RC → rc_coupling/rc_resistance). It is a value-preserving re-view of the
homogeneous source of truth below (graph_lib.homo_to_hetero, exact inverse hetero_to_homo).Homogeneous tensor schema (the source of truth; hetero stores re-view it — see
references/graph-dataset.md § Heterogeneous graphs): x[N,10] (node_type, graph_id, 8 per-type
feature slots), y[N,6] (node_type, congestion, IR drop, timing, wirelength, RC ground cap; NaN
where a label doesn't apply). Folded entities carry their features/labels on edge_attr[E,8] /
edge_y[E,6], interleaved [fwd0,rev0,fwd1,rev1,...]. RC coupling-cap + resistance labels ride a
separate parasitic edge set (rc_edge_index / rc_edge_type / rc_edge_y[E,3]), distinct from the
physical-topology edges (present-but-empty where RC doesn't apply, so the schema is uniform). Every
label tensor has a RAW twin (y_raw / edge_y_raw / rc_edge_y_raw) carrying the raw physical
value (EDA-Schema convention) beside the normalized target, so a trainer picks either. Full
schema + per-variant node/edge counts: references/graph-dataset.md.
scripts/extract/techlib/)The shared per-platform tech layer every stage consumes:
profile.py — supply voltage, tap patterns, cell-type strategy per ORFS platform.resolve.py — Python backend for scripts/flow/resolve_platform_paths.sh (same
KEY=VALUE contract): resolves liberty/LEF/tech paths for a platform.def_parse.py — the single DEF/SDC parser (instances, nets, pins, routed segments).lef.py — routing-layer names, pitch/direction, the layer regex matcher.liberty.py — cell / pin / net classifiers (direction, clock, capacitance).cell_types.py — the cell_type_id map (curated for nangate45, runtime-built for all
other platforms; MACRO gets a dedicated id).| Read this | When |
|---|---|
references/graph-dataset.md | Building/reading the PyG b–f graphs, tensor schema, RC-parasitic label views, torch venv, provenance + audit notes. |
references/label-extraction.md | Building the Y side (per-cell/per-net labels + stats). |
references/feature-extraction.md | Building the X side (per-node/per-edge/metadata CSVs + stats). |
scripts/extract/techlib/ | Per-platform tech/LEF/liberty/DEF parsing internals. |
tools/verify_graph_dataset.py (repo-level) | Independently verifying a built dataset against raw DEF/LEF/liberty/SPEF + OpenDB ground truth (--batch over many designs). Three named check groups — topology_checks (all 5 views b–f), feature_stat_checks (column re-derivation + stats-gate honesty + vocab), signoff_report_checks (DRC/LVS gate, ppa geometry, timing↔SDC, C_total/equiv_res vs SPEF; opt-in --signoff-recheck re-runs PDNSim for the IR-drop label). Run it after any corpus regeneration; see references/graph-dataset.md "Comprehensive verification". |
design_cases/<design-name>/
├── labels/ # Y: congestion / wirelength / timing / irdrop CSVs (run_labels.sh)
├── features/ # X: metadata.csv, nodes_{gate,net,iopin,pin}.csv, edges_*.csv (run_features.sh)
├── dataset/ # PyG graphs: {b..f}_graph.pt, netlist_graph.pt, graph_manifest.json (run_graphs.sh)
└── reports/
├── labels_stats.json # per-design label stage stats
├── features_stats.json # per-design feature stage stats
└── graph_dataset.json # mirror of dataset/graph_manifest.json
6_final.def/.odb/.spef with the signoff-loop skill first.tools/verify_graph_dataset.py
against raw DEF/LEF/liberty ground truth — silent value defects (transposed congestion
demand, all-NaN IR-drop, quoted-unit cap scaling) have shipped before and are invisible in
the manifest's row counts. See references/graph-dataset.md audit notes and
the signoff-loop references/failure-patterns.md "Dataset-Extraction Silent-Value Defects".reports/{labels,features}_stats.json and the manifest label_health for degraded columns
rather than assuming a non-empty CSV means correct values.npx claudepluginhub shenshan123/r2g-skillsGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.