Conversation
Lift the legalization owner check so Timing Opt can reuse DreamPlace legalize-only, load ECC from explicit DEF/Verilog, and skip the pre-sizer input DB.
Stage Sizer DEF/Verilog under data/to, rebuild ECC from those files, run DreamPlace legalize-only, and publish only the post-legalize layout. Drop the cached EngineDB after any sizer terminal state.
Honor read_def failure, close abandoned engines, and load explicit sources once. Fill the workspace DreamPlace config path before inner legalization if the map is empty.
Clear previous staging before launching Sizer, and delete published Timing Opt files on every unsuccessful save, including exceptions.
Raise if staging or published artifacts cannot be deleted, and reset Timing Opt subflow stages at the start of every Sizer attempt.
Register Timing Opt/sizer workspace configs so `ecc config` can inspect the db and DreamPlace files the inner legalize path actually reads. Split the oversized sizer runner tests into runner, cleanup, and EngineFlow modules.
Restore create_db_engine(workspace, step). Timing Opt inner legalize now replace()s a local step with staging DEF/Verilog and db=None instead of adding loader kwargs.
Opening an old one-stage Sizer workspace rewrote subflow stages to Unstart but left the outer step Success, so resume skipped Timing Opt and routed the unlegalized DEF. Persistently unstart the owner and its downstream suffix when that rewrite happens.
Insert sizer Timing Opt into the default rtl2gds/harden sequence between legalization and routing so CTS cleanup still happens first and Sizer sees a legal layout.
Download the latest successful linux-x64 Sizer build before pytest and export PATH plus CHIPCOMPILER_ECC_SIZER_ROOT so default-flow Timing Opt can run in CI.
Stop opening step.log.file with write truncation. Sizer now inherits the EngineFlow stdio capture so GUI still shows the sizer error when inner legalize later writes its own DreamPlace log.
Sizer now exposes build_step_metrics so EngineFlow can write qor_metrics/summary after a successful Timing Opt. Reuse the legalization DB summary and skip the Sizer binary check so QoR refresh still works when Sizer is only needed at run time.
Candidate reruns and resumes now register their runtime operation under the cloned candidate's own identity (<source>::candidate::<candidate_id>) instead of the source workspace id, and split into two phases: the parent snapshot (preflight + clone / load + verify) runs briefly under the source mutation lock and refuses while the source workspace owns an active operation, while the long EDA execution runs in the isolated candidate workspace without holding the source lock. Sibling candidates therefore execute concurrently, plain source operations keep their exclusive active-operation slot, and the RPC error text keeps mapping to the agent's busy-defer contract. Step stdio redirection takes the shared redirect lock so concurrent candidate steps cannot interleave the fd dup2/rebind; tool subprocesses still inherit correctly routed fds. The agent-side adapter stops refusing a second concurrent start and accepts the derived candidate operation identity while still rejecting foreign workspaces and deferring on a busy source workspace.
# Conflicts: # .github/actions/build-pyinstaller-bundle/action.yml # test/packaging/test_cli_entrypoint.py
There was a problem hiding this comment.
🟡 Changes recommended
There are correctness/portability issues to address in the new agent receipt context logic and one newly added test file violates the repo’s “no __future__ imports” guideline.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR expands ECC’s optional “agent” runtime surface by adding a dedicated ecc-agent-rpc JSON-RPC stdio entrypoint (packaged via PyInstaller) plus supporting candidate execution behaviors (rerun/resume, evidence/receipts, and agent-only runtime helpers).
Changes:
- Add
ecc-agent-rpcentrypoint (PyPI script + PyInstaller hard-linked alias) and smoke tests to ensure it responds with agent capabilities. - Extend agent runtime APIs and execution flow for isolated candidate workspaces (resume support, config preservation, receipts/evidence, and floorplan mode persistence).
- Add agent-focused runtime utilities (Sizer environment prep/preflight, parallel STA worker orchestration, parameter runtime observation/reporting) with broad test coverage.
File summaries
| File | Description |
|---|---|
| test/tools/ecc_dreamplace/test_module.py | Extends DreamPlace config param coverage (random seed). |
| test/test_engine_flow.py | Verifies initialize_config can be disabled when building step workspaces. |
| test/runtime/test_workspace_api.py | Asserts default runtime flow construction uses rtl2gds flow. |
| test/runtime/test_stdio_server.py | Adds regression coverage for stdio protocol isolation from background stdout. |
| test/packaging/test_run_ecc.py | Tests packaged entrypoint routing and exit-code propagation. |
| test/packaging/test_cli_entrypoint.py | Adjusts packaging assertions and verifies agent RPC reuses the same PyInstaller Analysis/exe. |
| test/engine/test_state_machine_regression.py | Removes legacy agent regression from core engine tests. |
| test/cli/test_rpc_cli.py | Ensures CLI help doesn’t expose an --agent flag. |
| pyproject.toml | Adds ecc-agent-rpc script and includes agent in build backend module list. |
| packaging/run_ecc.py | Routes packaged entrypoint to agent RPC vs CLI based on argv stem; propagates exit code. |
| ecc.spec | Creates ecc-agent-rpc as a hardlink to the ecc PyInstaller executable. |
| chipcompiler/runtime/stdio_server.py | Redirects process stdout to stderr while keeping protocol writes on a dup’d fd. |
| chipcompiler/runtime/operations.py | Introduces RuntimeOperationFailed and preserves partial results in failure/cancel events. |
| chipcompiler/engine/flow.py | Adds initialize_config parameter to create_step_workspaces and passes through to step creation. |
| agent/workspace_api.py | Major expansion: candidate rerun lifecycle, cloning/locking, receipts, evidence, preflight, resume plumbing. |
| agent/tools.py | Wraps tool execution with parameter observation, floorplan mode application, STA parallel routing, and loader isolation. |
| agent/test/test_tools.py | Tests plot suppression, loader isolation, runtime report ownership, and STA routing behavior. |
| agent/test/test_sta_parallel.py | Tests Linux parent-death signal handling, worker lifecycle, cancellation, and memory tracking. |
| agent/test/test_sta_benchmark.py | Tests benchmark inventory filtering and STA metric coverage validation/comparison. |
| agent/test/test_runtime.py | Tests agent runtime environment prep and structured operation failure/result retention. |
| agent/test/test_requests.py | Extends request parsing/validation and adds RPC entrypoint capability checks. |
| agent/test/test_parameter_status.py | Validates parameter-status thresholds for DREAMPlace observations. |
| agent/test/test_parameter_runtime_observer.py | Tests parameter observation hooks and report construction semantics. |
| agent/test/test_parameter_receipt_artifacts.py | Tests parameter application receipt binding and artifact integrity. |
| agent/test/test_floorplan_mode.py | Adds persisted floorplan mode override behavior + tamper checks. |
| agent/test/test_floorplan_mode_rerun.py | Exercises floorplan-mode-only reruns and resume behavior end-to-end. |
| agent/test/test_engine.py | Moves agent resume regression test into agent engine tests; adds candidate snapshot suppression test. |
| agent/test/test_candidate_resume.py | Adds candidate resume validation and in-place resume execution behavior tests. |
| agent/test/data/test_candidate_materialization.py | Tightens materialization to one-knob patches and adds snapshot/receipt validation tests. |
| agent/test/data/test_candidate_input_binding.py | Extends canonical edges and allows Floorplan-from-Synthesis (verilog-only) binding. |
| agent/sta_parallel.py | Implements candidate-only parallel STA execution with isolated worker processes. |
| agent/sta_benchmark.py | Adds a CLI benchmark tool to compare serial vs parallel STA schedules on isolated workspace copies. |
| agent/server.py | Ensures agent environment prep at startup and maps request validation errors to JSON-RPC invalid_request. |
| agent/runtime_env.py | Adds packaged Sizer PATH injection, Sizer+DREAMPlace preflight, and LD_* isolation context manager. |
| agent/rpc_server.py | Implements minimal ecc-agent-rpc stdio entrypoint. |
| agent/requests.py | Adds new request models/fields for agent preflight and candidate resume/rerun binding. |
| agent/README.cn.md | Documents the ecc-agent-rpc entrypoint, protocol constraints, and maintenance expectations (CN). |
| agent/plot.py | Adds candidate workspace detection and plot suppression/headless map plotting controls. |
| agent/methods.py | Registers new agent RPC methods (agent.runtime_preflight, candidate.resume). |
| agent/floorplan_mode.py | Implements persisted, tamper-evident floorplan mode overrides for candidates. |
| agent/engine.py | Adds observer notifications, stdout redirect locking, candidate snapshot suppression, and STA memory tracking. |
| agent/data/parameter_runtime_observer.py | Implements DREAMPlace/floorplan parameter observation and v2 runtime report persistence. |
| agent/data/parameter_application_receipt.py | Produces v2 parameter application receipts with stable evidence hashing. |
| agent/data/observed_callable.py | Utility wrapper to preserve operator attributes while intercepting call behavior. |
| agent/data/floorplan_parameter_observer.py | Adds floorplan parameter observation and v2 report generation. |
| agent/data/candidate_materialization.py | Enforces single-knob patches and binds config overlays via immutable snapshots + receipt validation. |
| agent/data/candidate_input_binding.py | Expands canonical input edges and loosens DEF requirement for Synthesis source. |
| agent/candidate_resume.py | Implements resume of failed candidates with strict binding/rollback and structured failure results. |
| agent/candidate_clone.py | Implements safe candidate workspace cloning with step artifact pruning. |
| .gitignore | Ignores top-level checklist.json. |
| .github/actions/build-pyinstaller-bundle/action.yml | Extends PyInstaller smoke test to validate ecc-agent-rpc presence, aliasing, and capability output. |
Review details
- Files reviewed: 51/52 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| tech_lef = Path(getattr(getattr(workspace, "pdk", None), "tech", None)) | ||
| pdk_sha256 = f"sha256:{sha256(tech_lef.read_bytes()).hexdigest()}" | ||
| lef_text = tech_lef.read_text(encoding="utf-8") | ||
| units_match = re.search(r"DATABASE\s+MICRONS\s+(\d+)", lef_text, re.IGNORECASE) | ||
| site_match = re.search( | ||
| r"SITE\s+(?:core7|CoreSite)\b(?P<body>.*?)END\s+(?:core7|CoreSite)", | ||
| lef_text, | ||
| re.IGNORECASE | re.DOTALL, | ||
| ) | ||
| size_match = re.search( | ||
| r"SIZE\s+([0-9]+(?:\.[0-9]+)?)\s+BY", | ||
| site_match.group("body") if site_match else "", | ||
| re.IGNORECASE, | ||
| ) | ||
| if not units_match or not size_match: | ||
| raise ValueError("site width is unavailable") | ||
| site_width_dbu = round(float(units_match.group(1)) * float(size_match.group(1))) |
There was a problem hiding this comment.
Updated in commit 8474449. _parameter_receipt_context now uses workspace.pdk.site_core with re.escape(...) to locate the LEF SITE block instead of hard-coded site names.
The ECC C++ tools keep process-global config and log state, so two candidates executing inside one rpc-server process cross-write logs and leave steps Incomplete. Each candidate rerun/resume now executes its step loop in a dedicated worker subprocess; the parent keeps the operation lifecycle and replays step.started events from the worker result. Unit tests drive the in-process path via ECC_CANDIDATE_STEP_ISOLATION=0; isolated execution falls back in-process when no interpreter is available.
…es the configured value
normalize_design ran opt_clean -purge, stripping internal public net names so equiv_make only matched top-level ports and equiv_induct lacked internal cut-points, producing mass unproven results on functionally equivalent netlists. Drop -purge on the normalize side; the equiv-side purge stays. Same root cause and fix as upstream a6217b9a (ecc#273).
Co-authored-by: YihangQiu <65992277+YihangQiu@users.noreply.github.com>
c4c1c91 to
6b5f295
Compare
sta_workers() gated parallel corners on candidate workspaces only, so GUI flows ran the sta step serially while optimization candidates ran in parallel. The corner snapshot mechanism is a generic ECC facility (each worker loads its own file snapshot), so drop the workspace gate and keep the tool/step, worker-count, and platform checks. ECOS_AGENT_STA_WORKERS (default 2 on Linux) now applies to every agent-runtime sta step.
…ment - ecc-dreamplace efbca335..er 77e343ca (v0.1.0-alpha.6-10): macro-only placement writeback; requires the ECC-side macro placement parameter plumbing arriving with the upstream main merge. - ecc-tools efbca335..fdaa70a97 (v0.1.0-alpha.13-269): requires Boost 1.92.0 exactly (built against /home/yhqiu1/.deps/boost-1.92.0, the upstream CI recipe).
Brings in upstream main through 0d2b176: ECC QoR v3 analysis engine, DreamPlace macro placement step (pairs with ecc-dreamplace 77e343ca), manual macro location flow, lec disabled by default (yosys lec instability), yosys synthesis flag fixes, and sizer/routing-STA crash diagnostics. One test conflict resolved by keeping both the local random_seed fixture and upstream's macro_only key.
The candidate input-edge allowlist still assumed the single-step Floorplan topology, so every isolated candidate rerun failed at bind_candidate_input with 'unsupported candidate input edge: postFloorplan -> place' before any step could execute, leaving candidate workspaces without analysis artifacts and forcing every optimization outcome to evidence_invalid. Declare the current canonical edges for the preFloorplan -> macroPlacement -> postFloorplan phase split (and the tail steps it introduced), resolve the RPC-level Floorplan target to the sub-step range with the Synthesis checkpoint as its source, and cover the current topology with regression tests.
Floorplan-knob candidate reruns failed in three places that still assumed a literal Floorplan flow step: the step-range lookup, the input-binding target resolution, and the candidate-backend tool check. Resolve the RPC-level Floorplan target through a shared FLOORPLAN_TARGET_FLOW_STEP alias with a literal-name fallback. With the aliases in place the rerun exposed the real blocker: the floorplan runner re-pins '[params.die] size' with the realized die bounding box after every floorplan step, and _refresh_floorplan_config forces die_builder.mode back to die_size whenever that pin exists, so a die_util candidate was always reverted and rejected by the terminal mode validation. Treat the realized dimensions as outputs: the runner re-pins the size only in die_size workspaces, and die_util candidates drop the pin in their isolated clone before the flow loads parameters. Verified end to end on a gcd workspace clone: a floorplan.core_util 0.3 -> 0.4 candidate at die_util now runs all 16 steps, keeps the die_util mode, and realizes core_area 2381.4 -> 1796.76 um^2.
# Conflicts: # agent/engine.py # chipcompiler/runtime/operations.py
What Changed
Scope
Select the areas touched by this PR:
uv.lock, or release artifacts.Runtime And Packaging Impact
ecc-toolsorecc-dreamplacedependency changedNotes:
Validation
List the commands you ran. Mark checks that are not applicable as N/A.
uv run pytest test/uv run ruff check chipcompiler testuv run ruff format --check chipcompiler testecc --help,ecc --version,ecc version --jsonnix run .#cli -- --helpSkipped checks and reason:
Checklist