Skip to content

fix: direct-config param override crash, stale routing STA lifecycle, and sizer crash diagnostics - #283

Merged
Emin017 merged 3 commits into
mainfrom
yell/fix_config
Sep 14, 2026
Merged

Emin017 merged 3 commits into
mainfrom
yell/fix_config

Conversation

@Yell-walkalone

Copy link
Copy Markdown
Contributor

What Changed

  • fix(cli): direct-config/PDK parameters (maps_to=None, e.g. place.random_seed, route.RT.*) crashed every divergence check with AttributeError: 'NoneType' object has no attribute 'items' — both ecc run --set and project-level ecc param set + run, before any EDA step started. _backend_leaf_keys now returns an empty tuple for them (they are applied through their explicit config_target), and a diverging direct-config override reports its canonical parameter name instead of an invented backend leaf key.
  • fix(ecc): timing-driven routing (route.RT.-enable_timing=1) crashed the routing step with AttributeError: 'ECCToolsModule' object has no attribute 'release_sta'. The STA pre-init block (and save_data's unreachable report_timing block) referenced an ecc-tools lifecycle removed on 2026-07-29 (1a4440525). Removed rather than ported: iRT's RTInterface builds its own timing engine from the shared db config (lib paths/SDC set by load_data), verified against the pinned submodule source. The unused is_rt_timing_enable wrapper is dropped with it.
  • feat(sizer): Timing-opt failures now distinguish a fatal signal (signal=SIGABRT(6)) from a plain exit (exit_code=N) and surface the first native fatal banner from the step log, keeping tool crashes, external kills, and timeouts separable in wrapper evidence.

Before/after for the CLI crash (fresh manifest project):

# before: rc=1, no EDA step starts
ecc run --set place.random_seed=3001 --from Synth --to Synth
AttributeError: 'NoneType' object has no attribute 'items'   # effective_config.py:415

# after: rc=0, run succeeds; DreamPlace receives random_seed=3001

Scope

  • CLI - command behavior, Typer command surface, output formats, or workspace commands.
  • Flow/runtime - workspace lifecycle, EngineFlow, step execution, logs, metrics, or artifacts.
  • EDA integration - Yosys, ECC-Tools, DreamPlace, PDKs, or native/runtime wrappers.
  • Build/package - Nix, PyInstaller, wheels, uv.lock, or release artifacts.
  • CI/release - GitHub Actions, version checks, changelog, or release automation.
  • Tests/docs only

Runtime And Packaging Impact

  • No runtime or packaging impact
  • CLI output or machine-readable contract changed
  • Workspace layout, flow state, or artifact paths changed
  • Native toolchain or wrapper behavior changed
  • ecc-tools or ecc-dreamplace dependency changed
  • PyInstaller, Nix, or release artifact changed

Notes:

  • Sizer wrapper failure log line changes from exit code=%d to termination reason + fatal_log_line; it is log text only, no machine-readable contract. The config_layer_diverged warning can now include canonical parameter names for direct-config keys (previously this path crashed instead of warning).
  • Routing behavior with default -enable_timing=0 is unchanged; the enabled path goes from guaranteed crash to running through iRT's self-contained timing engine.
  • No submodule pointer change: the fix adapts ECC to the already-pinned ecc-tools commit.

Validation

List the commands you ran. Mark checks that are not applicable as N/A.

  • uv run pytest test/
  • uv run ruff check chipcompiler test
  • uv run ruff format --check chipcompiler test
  • PyInstaller smoke: ecc --help, ecc --version, ecc version --json (via local release-format bundle build, plus tarball extract smoke)
  • Nix smoke: nix run .#cli -- --help
  • Manual flow smoke:
  • Other:

Exact commands:

uv run pytest test/cli/commands/test_effective_config.py test/cli/commands/test_config_layers.py \
  test/cli/commands/test_manifest_run.py test/cli/params/
uv run pytest test/yosys_lec test/tools/ecc_sizer test/tools/ecc test/runtime/test_signoff_export.py
uv run pytest test/ -m "not integration"        # 2551 passed, 1 pre-existing failure (see below)
uv run ruff check chipcompiler test
uv run ruff format --check chipcompiler test

Manual flow smoke (real gcd design, rtl2gds preset, repo venv):

  • ecc run --set place.random_seed=3001 --from Synth --to place → success; config/dreamplace_ecc.json and the DreamPlace parameter dump contain random_seed: 3001.
  • ecc run --set route.RT.-enable_timing=1 --from Synth --to route → success after the STA fix; router runs in timing mode (enable_timing honored, timing table rendered), route outputs produced.
  • ecc param set place.random_seed 3001 + ecc run on existing workspace → success with the by-design params_ignored_on_existing_run warning; on a fresh workspace the value reaches the generated DreamPlace config.
  • ecc param set route.RT.-enable_timing 1 + ecc run on existing workspace → success; fresh workspace generates "-enable_timing": "1" in config/route_ecc.json and completes through route.

Skipped checks and reason:

  • uv run pytest test/ (integration included): run locally as -m "not integration"; the integration suite runs in CI with a fresh PDK/yosys/Sizer setup. One local non-integration failure is pre-existing and environment-caused: test_pyplacedb_macro_writeback.py::test_macro_writeback_commits_only_frozen_candidates fails against this machine's stale locally-built ecc_py (older than the submodule's macro-writeback-orientation fix) and fails identically on unmodified main.
  • Nix smoke: no nix/ or packaging input changed.

Checklist

  • I kept the change scoped to ECC.
  • I updated docs or user-facing CLI text where behavior changed.
  • I included lockfile or version metadata updates when dependencies changed.
  • I documented any submodule updates and why they are needed.
  • I did not include local caches, virtual environments, or generated build outputs.
  • I explained skipped validation and remaining risk.

Direct config/PDK parameters (maps_to=None) are applied through their
explicit config target and have no legacy backend projection.
_backend_leaf_keys now returns an empty tuple for them instead of
calling .items() on None, and a diverging direct-config override
reports its canonical parameter name rather than an invented backend
leaf key.

Covers both --set runs and project-level ecc.toml [params] runs, with
registry-wide regressions over every schema mapping shape.
The routing path and save_data still called release_sta/init_sta/
report_timing, an STA lifecycle that ecc-tools removed on 2026-07-29
(1a4440525) and that no longer exists on ECCToolsModule or the raw
binding. Enabling route.RT.-enable_timing therefore crashed the routing
step with AttributeError before the router started.

iRT's timing mode is self-contained: RTInterface builds its own timing
engine from the shared db config (lib paths, SDC set by load_data), so
the Python-side pre-init is removed rather than ported. save_data's
report_timing block was unreachable (every caller passed False) and is
dropped together with the parameter; the unused is_rt_timing_enable
wrapper follows.
Timing-opt failures now distinguish a fatal signal
(signal=SIGABRT(6)) from a plain tool exit (exit_code=N) and surface
the first native fatal banner from the step log (e.g. glibc buffer
overflow), so tool crashes, external kills, and timeouts remain
separable in the wrapper evidence.
@Emin017
Emin017 merged commit 95029d5 into main Sep 14, 2026
5 checks passed
@Emin017
Emin017 deleted the yell/fix_config branch September 14, 2026 15:01
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.

2 participants