Skip to content

flow: flow.sh runs the stage through RUN_CMD, like the rest of the flow - #4555

Merged
maliberty merged 3 commits into
The-OpenROAD-Project:masterfrom
oharboe:flow-sh-honor-run-cmd
Sep 26, 2026
Merged

maliberty merged 3 commits into
The-OpenROAD-Project:masterfrom
oharboe:flow-sh-honor-run-cmd

Conversation

@oharboe

@oharboe oharboe commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

What

variables.mk defines RUN_CMD as the way a logged tool invocation is run, and every logged target in flow/Makefile goes through it: yosys metrics, generate_abstract, merge, drc, cdl, lvs, run. The exception is flow.sh, which every stage goes through and which spelled out $PYTHON_EXE $SCRIPTS_DIR/run_command.py by hand. So RUN_CMD governed the peripheral logs and none of the stage logs; an override (stamp lines, tee elsewhere, wrap the tool) silently missed floorplan, place, cts, grt and route.

Fix

flow.sh runs the stage through RUN_CMD, defaulting to the command it spelled out, so a plain make is unchanged.

Depends on

#4554: flow.sh parses the stage log back with genElapsedTime.py, which until that fix dropped the summary row for a prefixed timing line, so this change alone would hand that regression to anyone whose RUN_CMD prefixes lines. This branch is on top of it.

Test

New flow/test/test_flow_sh.py runs flow.sh with stub tools (OPENROAD_EXE=true, OPENROAD_CMD=echo):

  • RUN_CMD unset: the stage log has its timing line and summary row.
  • RUN_CMD set to a recording wrapper: the stage goes through it, and the summary row is still there. Fails before this change ("RUN_CMD did not run the stage").

flow/test/*.py all pass; black clean.

🤖 Generated with Claude Code

oharboe and others added 2 commits September 23, 2026 11:08
genElapsedTime.py writes the per-stage summary, the only place ORFS
reports a hash of a stage's result. It read the elapsed time
positionally: strip the line, delete "Elapsed time: ", split on "[h:]",
on the first "." and on ":". That works only when the timing line starts
the log line. Give it a prefix, as a RUN_CMD wrapper that stamps log
lines does ("[  123.45] "), and the prefix survives the delete, the
split on "." cuts at the prefix's own decimal point, and the line falls
to "Elapsed time not understood". The row is then skipped: elapsed,
peak memory and the sha1sum column vanish, "No elapsed time found" does
not fire because the line was found, and the exit status is 0.

Match the timing line with a regex anchored on its format instead,
hours optional as run_command.py only emits them past an hour. An
unprefixed line gives exactly the number it did before, fraction of a
second dropped as before, and an unparseable line still reaches "not
understood".

test_genElapsedTime_parses_output asserted only that the stage name
appeared, which it does even when the row is dropped; it now asserts
the elapsed and memory columns. Two cases are added: a prefixed line,
which fails before this change, and the hours form.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
variables.mk defines RUN_CMD as the way a logged tool invocation is run,
and every logged target in flow/Makefile goes through it: yosys metrics,
generate_abstract, merge, drc, cdl, lvs, `run`. The exception was
flow.sh, which every stage goes through, and which spelled out
`$PYTHON_EXE $SCRIPTS_DIR/run_command.py` by hand. RUN_CMD governed the
peripheral logs and none of the stage logs; an override (to stamp
lines, tee elsewhere, wrap the tool) silently missed floorplan, place,
cts, grt and route.

flow.sh now runs the stage through RUN_CMD, defaulting to the command it
spelled out, so a plain `make` is unchanged.

Depends on the previous commit: flow.sh parses the stage log back with
genElapsedTime.py, which until then dropped the summary row for a line
a wrapper had prefixed.

flow/test/test_flow_sh.py runs flow.sh with stub tools: with RUN_CMD
unset the stage log has its timing line and summary row; with RUN_CMD
set to a recording wrapper the stage goes through it and the summary
row is still there. The second fails before this change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request updates flow.sh to run stages through a configurable RUN_CMD wrapper and refactors genElapsedTime.py to use a regular expression for parsing elapsed times, allowing it to handle log prefixes and optional hour fields. Comprehensive unit tests are also introduced. The review feedback recommends using a Bash array for RUN_CMD to prevent word-splitting issues if paths contain spaces.

Comment thread flow/scripts/flow.sh
Comment thread flow/scripts/flow.sh
@openroad-ci

openroad-ci commented Sep 23, 2026 •

Copy link
Copy Markdown
Member

🔍 QoR check

Metrics reflect the PR merge build — i.e. what will land on the target branch.

Commit 61cfb62 · Jenkins build #3 · Baseline: build · View build on dashboard

62 design(s) checked — 0 with regression(s), 0 without a comparable baseline.

@maliberty
maliberty merged commit 22a5ef9 into The-OpenROAD-Project:master Sep 26, 2026
13 checks passed
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.

3 participants