Skip to content

Commit 6919027

Browse files
committed
surrogate: add autotune workflow
Minimal flow scripts + docs + plumbing to run the OpenROAD surrogate autotuner.
1 parent 93c42b2 commit 6919027

21 files changed

+1912
-6
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ flow/logs
1313
flow/reports
1414
flow/objects
1515
flow/tech
16+
flow/tmp_surrogate
1617

1718
# Tar archives
1819
flow/*tar.gz
@@ -105,3 +106,10 @@ bazel-testlogs
105106

106107
# python venv
107108
venv/
109+
flow/backup_*
110+
111+
# Local scratch notes (kept out of git)
112+
doc.md
113+
114+
# macOS
115+
.DS_Store

doc.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Surrogate autotuner (OpenROAD + ORFS) — status / handoff (2026-01-10)
2+
3+
Canonical end-to-end guides (these are what we expect users to follow):
4+
5+
- ORFS normal branch: `surrogate_autotuner_guide.md`
6+
- ORFS rebased branch: `flow/surrogate_autotuner_guide.md`
7+
8+
This `doc.md` is a “current status” handoff that ties together the 4 branches,
9+
their pairing rules, gating, and known limitations/results.
10+
11+
Note: upstream `.gitignore` ignores `doc.md`, but in these surrogate branches the
12+
file is intentionally tracked (gitignore does not apply to tracked files).
13+
14+
## Current branch set (precisedanon)
15+
16+
The deliverable is **four branches total** (two repos × normal/rebased):
17+
18+
### ORFS (OpenROAD-flow-scripts)
19+
20+
- `orfs-surrogate-normal`
21+
- Base: `93c42b2e6` + **1 commit** (minimal surrogate integration + docs)
22+
- OpenROAD submodule pin: `tools/OpenROAD @ 0b3616e102` (`openroad-surrogate-normal`)
23+
- Guide: `surrogate_autotuner_guide.md`
24+
- `orfs-surrogate-rebased`
25+
- Rebased on The-OpenROAD-Project `master` (then surrogate plumbing + docs)
26+
- OpenROAD submodule pin: `tools/OpenROAD @ f5de6e7462` (`openroad-surrogate-rebased`)
27+
- Guide: `flow/surrogate_autotuner_guide.md`
28+
29+
### OpenROAD (tools/OpenROAD)
30+
31+
- `openroad-surrogate-normal`
32+
- Base: `7bc521f36a` + **1 commit** `0b3616e102` (“surrogate: add autotune support”)
33+
- Surrogate commands are compiled in and available without extra gating.
34+
- `openroad-surrogate-rebased`
35+
- Base: OpenROAD `upstream/master` + `a04f00a450` + `f5de6e7462`
36+
- Compile-time gate: `-D ENABLE_SURROGATE=ON` (default `OFF`)
37+
- Runtime gate: `OPENROAD_ENABLE_SURROGATE=1` (default `OFF`)
38+
- Surrogate TCL commands are only registered when both gates are enabled.
39+
40+
Pairing rules:
41+
42+
- `orfs-surrogate-normal``openroad-surrogate-normal`
43+
- `orfs-surrogate-rebased``openroad-surrogate-rebased`
44+
45+
## Quick run (normal vs rebased)
46+
47+
Normal:
48+
49+
```bash
50+
git checkout orfs-surrogate-normal
51+
git submodule update --init --recursive
52+
./build_openroad.sh --local
53+
54+
# Baseline logs (recommended for calibration)
55+
make -C flow finish DESIGN_CONFIG=designs/<platform>/<design>/config.mk
56+
57+
# Surrogate autotune (example)
58+
make -C flow surrogate_autotune DESIGN_CONFIG=designs/<platform>/<design>/config.mk \
59+
SURROGATE_VALIDATE=1 SURROGATE_VALIDATE_N=14
60+
```
61+
62+
Rebased:
63+
64+
```bash
65+
git checkout orfs-surrogate-rebased
66+
git submodule update --init --recursive
67+
./build_openroad.sh --local --openroad-args "-D ENABLE_SURROGATE=ON"
68+
69+
# Surrogate targets on this branch run OpenROAD with OPENROAD_ENABLE_SURROGATE=1
70+
make -C flow surrogate_autotune DESIGN_CONFIG=designs/<platform>/<design>/config.mk \
71+
SURROGATE_VALIDATE=1 SURROGATE_VALIDATE_N=14
72+
```
73+
74+
## What is shipped (ORFS surface area)
75+
76+
New `flow/Makefile` targets:
77+
78+
- `make -C flow surrogate_tune` (calls OpenROAD `surrogate_optimize` on the current synthesized netlist)
79+
- `make -C flow surrogate_tune_synthaware` (clock sweep: rewrite SDC + re-synth per clock, then tune)
80+
- `make -C flow surrogate_autotune` (orchestrates synth-aware tuning; can optionally run `finish` validations)
81+
82+
Implementation entry points:
83+
84+
- ORFS: `flow/scripts/surrogate_tune.tcl`, `flow/scripts/surrogate_tune_synthaware.py`, `flow/scripts/surrogate_autotune.py`
85+
- OpenROAD: `surrogate_optimize` and `surrogate_supported_features` (C++: `tools/OpenROAD/src/Surrogate.cc`)
86+
87+
## Supported values (objectives + knobs)
88+
89+
### Objectives (`SURROGATE_OBJECTIVE`)
90+
91+
Supported objective names (minimize):
92+
93+
- `effective_clock_period` (default)
94+
- `routed_wirelength`
95+
- `power`
96+
- `instance_area`
97+
- `area`
98+
99+
Note: empirical “expected gains” are currently only characterized on disk for
100+
`effective_clock_period` and `routed_wirelength` at ~`600s` and `K=14` (see below).
101+
102+
### Knob space keys
103+
104+
This integration is intentionally **restricted** vs ORFS’s baseline autotuner.
105+
Only a small fixed set of knob names is supported; unknown keys are ignored.
106+
107+
See the guides for the full “supported knob → ORFS variable” table and valid ranges.
108+
109+
## Expected gains (what users should expect)
110+
111+
From on-disk runs with `SURROGATE_TIME_BUDGET_S=600` and `SURROGATE_VALIDATE_N=14`
112+
(K=14), across `{asap7,nangate45,sky130hd} × {aes,ibex,jpeg}`:
113+
114+
- `routed_wirelength`: median gain `3.35%` (p25 `0.96%`, p75 `7.37%`), best observed `15.78%`, worst `0%`
115+
- `effective_clock_period`: median gain `2.99%` (p25 `1.61%`, p75 `4.71%`), best observed `11.58%`, worst `0%`
116+
117+
Not yet characterized at ~`600s` on disk: `power`, `instance_area`, `area`.
118+
119+
## Outputs / artifacts
120+
121+
Outputs:
122+
123+
- `flow/results/<platform>/<design>/<variant>/surrogate_optimize.json`
124+
- `flow/results/<platform>/<design>/<variant>/surrogate_synthaware.json`
125+
- `flow/results/<platform>/<design>/<variant>/surrogate_autotune.json`
126+
127+
Logs:
128+
129+
- `flow/logs/<platform>/<design>/<variant>/surrogate_tune.log`
130+
- `flow/logs/<platform>/<design>/<variant>/surrogate_tune_synthaware.log`
131+
- `flow/logs/<platform>/<design>/<variant>/surrogate_autotune.log`
132+
133+
## Known limitations / TODOs (explicit)
134+
135+
- Objective support beyond `{effective_clock_period, routed_wirelength}` is **not yet validated** with enough on-disk runs to quote expected gain ranges.
136+
- The knob space is intentionally restricted; this is not a drop-in replacement for baseline ORFS autotuning.
137+
138+
## Disk footprint (practical note)
139+
140+
Full `finish` runs can generate large artifacts under `flow/results/**` (e.g. `.odb`, `.def`, `.gds`, `.spef`).
141+
If you need to reclaim disk, the safest first pass is to keep `flow/logs/**` and remove large, reproducible outputs
142+
under `flow/results/**` for old variants you don’t need.

flow/Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,20 @@ check-yosys:
750750
.PHONY: all
751751
all: check-yosys check-openroad synth floorplan place cts route finish
752752

753+
.PHONY: surrogate_tune
754+
surrogate_tune: check-openroad synth
755+
($(TIME_CMD) $(OPENROAD_CMD) $(SCRIPTS_DIR)/surrogate_tune.tcl) 2>&1 | tee $(abspath $(LOG_DIR)/surrogate_tune.log)
756+
757+
.PHONY: surrogate_tune_synthaware
758+
surrogate_tune_synthaware: check-openroad
759+
@mkdir -p $(LOG_DIR)
760+
($(TIME_CMD) $(PYTHON_EXE) $(SCRIPTS_DIR)/surrogate_tune_synthaware.py) 2>&1 | tee $(abspath $(LOG_DIR)/surrogate_tune_synthaware.log)
761+
762+
.PHONY: surrogate_autotune
763+
surrogate_autotune: check-openroad
764+
@mkdir -p $(LOG_DIR)
765+
($(TIME_CMD) $(PYTHON_EXE) $(SCRIPTS_DIR)/surrogate_autotune.py) 2>&1 | tee $(abspath $(LOG_DIR)/surrogate_autotune.log)
766+
753767
.PHONY: clean
754768
clean:
755769
@echo
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"cts_cluster_size": 10,
3+
"cts_cluster_diameter": 50
4+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"clock_period": {
3+
"type": "float",
4+
"minmax": [300, 600],
5+
"step": 0
6+
},
7+
"core_utilization": {
8+
"type": "int",
9+
"minmax": [20, 99],
10+
"step": 1
11+
},
12+
"core_aspect_ratio": {
13+
"type": "float",
14+
"minmax": [0.9, 1.1],
15+
"step": 0
16+
},
17+
"tns_end_percent": {
18+
"type": "int",
19+
"minmax": [0, 100],
20+
"step": 1
21+
},
22+
"global_padding": {
23+
"type": "int",
24+
"minmax": [0, 3],
25+
"step": 1
26+
},
27+
"detail_padding": {
28+
"type": "int",
29+
"minmax": [0, 3],
30+
"step": 1
31+
},
32+
"enable_dpo": {
33+
"type": "binary",
34+
"minmax": [0, 1],
35+
"step": 1
36+
},
37+
"pin_layer_adjust": {
38+
"type": "float",
39+
"minmax": [0.2, 0.7],
40+
"step": 0
41+
},
42+
"above_layer_adjust": {
43+
"type": "float",
44+
"minmax": [0.2, 0.7],
45+
"step": 0
46+
},
47+
"density_margin_addon": {
48+
"type": "float",
49+
"minmax": [0.0, 0.99],
50+
"step": 0
51+
},
52+
"cts_cluster_size": {
53+
"type": "int",
54+
"minmax": [10, 40],
55+
"step": 1
56+
},
57+
"cts_cluster_diameter": {
58+
"type": "int",
59+
"minmax": [50, 200],
60+
"step": 1
61+
}
62+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"clock_period": {
3+
"type": "float",
4+
"minmax": [300, 600],
5+
"step": 0
6+
},
7+
"core_utilization": {
8+
"type": "int",
9+
"minmax": [20, 99],
10+
"step": 1
11+
},
12+
"core_aspect_ratio": {
13+
"type": "float",
14+
"minmax": [0.9, 1.1],
15+
"step": 0
16+
},
17+
"tns_end_percent": {
18+
"type": "int",
19+
"minmax": [0, 100],
20+
"step": 1
21+
},
22+
"global_padding": {
23+
"type": "int",
24+
"minmax": [0, 3],
25+
"step": 1
26+
},
27+
"detail_padding": {
28+
"type": "int",
29+
"minmax": [0, 3],
30+
"step": 1
31+
},
32+
"enable_dpo": {
33+
"type": "binary",
34+
"minmax": [0, 1],
35+
"step": 1
36+
},
37+
"pin_layer_adjust": {
38+
"type": "float",
39+
"minmax": [0.2, 0.7],
40+
"step": 0
41+
},
42+
"above_layer_adjust": {
43+
"type": "float",
44+
"minmax": [0.2, 0.7],
45+
"step": 0
46+
},
47+
"density_margin_addon": {
48+
"type": "float",
49+
"minmax": [0.0, 0.99],
50+
"step": 0
51+
}
52+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"clock_period": {
3+
"type": "float",
4+
"minmax": [300, 420],
5+
"step": 0
6+
},
7+
"core_utilization": {
8+
"type": "int",
9+
"minmax": [50, 80],
10+
"step": 1
11+
},
12+
"core_aspect_ratio": {
13+
"type": "float",
14+
"minmax": [0.9, 1.1],
15+
"step": 0
16+
},
17+
"tns_end_percent": {
18+
"type": "int",
19+
"minmax": [80, 100],
20+
"step": 1
21+
},
22+
"global_padding": {
23+
"type": "int",
24+
"minmax": [0, 3],
25+
"step": 1
26+
},
27+
"detail_padding": {
28+
"type": "int",
29+
"minmax": [0, 3],
30+
"step": 1
31+
},
32+
"enable_dpo": {
33+
"type": "binary",
34+
"minmax": [0, 1],
35+
"step": 1
36+
},
37+
"pin_layer_adjust": {
38+
"type": "float",
39+
"minmax": [0.2, 0.7],
40+
"step": 0
41+
},
42+
"above_layer_adjust": {
43+
"type": "float",
44+
"minmax": [0.2, 0.7],
45+
"step": 0
46+
},
47+
"density_margin_addon": {
48+
"type": "float",
49+
"minmax": [0.0, 0.35],
50+
"step": 0
51+
}
52+
}
53+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"core_utilization": 38
3+
}

0 commit comments

Comments
 (0)