Skip to content

Add autonomous DoE-packing loop (planner + packer) - #5

Open
prashkh wants to merge 1 commit into
mainfrom
doe_packing
Open

Add autonomous DoE-packing loop (planner + packer)#5
prashkh wants to merge 1 commit into
mainfrom
doe_packing

Conversation

@prashkh

@prashkh prashkh commented Jun 11, 2026

Copy link
Copy Markdown

A new self-contained example branch: an autonomous agent that designs and floor-plans a photonic Design-of-Experiments (DoE) test chip on a fixed MPW die. It runs entirely free and local (no cloud simulations).

What it does

Two agents share only a file:

  • Planner (plan.py) designs the sweep (which device parameters, ranges, points) and writes blackboard/doe_plan.json.
  • Packer (optimize.py) reads the plan and tiles the die in a build -> verify -> score -> journal loop: ramp replicates to capacity, then void-fill the leftover gaps with real structures until no remaining gap can hold the smallest device.

The point beyond rectangle packing is that every site must be measurable: grating couplers at the fiber-array pitch, bond pads at the probe pitch, and a single shared orientation so a wafer prober lands identically at each site (no rotation). A layout can be DRC-clean and still unmeasurable; the loop checks both.

Verification harness (tools/)

KLayout SiEPIC DRC, exact boolean geometric-collision check, LVS-style connectivity, an orientation gate, and a largest-empty-rectangle void finder, rolled into a single gated figure of merit (maximize structures placed, score zero if any hard check fails).

Notes

  • Generalized device ingestion: bring your own PhotonForge PCells or GDS files via tools/library.py.
  • Frame capture / evolution GIF is optional (Playwright); the loop runs headless without it.
  • This branch replaces the single-device design.py/simulate.py framework with the packing project. See README.md for setup and run instructions.

🤖 Generated with Claude Code


Note

Medium Risk
Large architectural swap and new packing/validation logic; tools/hierarchy.py CLI still imports removed run/design modules, so that entry point may be broken until updated.

Overview
Replaces the single-device Tidy3D auto-design loop (design.py, simulate.py, drc.py, orchestrate.py) with a local DoE chip packing workflow: a planner (plan.py + program_planner.md) writes blackboard/doe_plan.json, and a packer (optimize.py + program.md) fills a fixed 8×3 mm die via replicate ramp plus void-fill until no gap fits the smallest site.

Adds the tools/ harness (PhotonForge PCells/GDS library, measurable test sites with GCs and pads, floorplan.pack_into_die, gated FOM in criteria.py, collisions/DRC/orientation/LER in validation.py + toolbox.py), blackboard/die.yaml, viewer helpers, and optional LiveViewer frame capture / make_gif_from_frames.py. README and .gitignore are rewritten for the new flow; generated output/ and plan artifacts are ignored.

Reviewed by Cursor Bugbot for commit b7d8f39. Bugbot is set up for automated code reviews on this repo. Configure here.

A two-agent example that designs and floor-plans a photonic Design-of-Experiments
test chip on a fixed MPW die, free and local (no cloud simulations):

- plan.py (planner) designs the sweep and writes blackboard/doe_plan.json
- optimize.py (packer) fills the die in a build/verify/score/journal loop:
  ramp replicates to capacity, then void-fill to the packable plateau
- tools/ verification harness: KLayout DRC, geometric collisions, LVS-style
  connectivity, an orientation gate (wafer-prober rule), and a
  largest-empty-rectangle void finder, rolled into a gated figure of merit
- generalized device ingestion: PhotonForge PCells or user GDS via tools/library.py
- frame capture / GIF is optional (Playwright), so the loop runs headless

Replaces the single-device design.py/simulate.py framework on this branch with
the packing project; see README.md for setup and run instructions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 5 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b7d8f39. Configure here.

Comment thread tools/hierarchy.py
sys.path.insert(0, str(ROOT))
from run import build_chip
import design
chip, _, _ = build_chip(design)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hierarchy CLI imports deleted modules

High Severity

Running python -m tools.hierarchy still imports run.build_chip and design, but this PR removes design.py and there is no run.py, so the CLI fails before any hierarchy or validation runs.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7d8f39. Configure here.

Comment thread view_last.py
if step is not None:
gds = exp_dir / f"{int(step):04d}" / "chip.gds"
else:
gds = sorted(glob.glob(str(exp_dir / "*" / "chip.gds")))[-1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

view_last crashes without experiments

Medium Severity

When no output/experiments/*/chip.gds exists, view_last.py indexes an empty glob list and raises IndexError instead of exiting with a clear message.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7d8f39. Configure here.

Comment thread blackboard/die.yaml
@@ -0,0 +1,40 @@
# die.yaml — the fixed constraints for the v1 DoE-packing campaign.
# Read by the planner (plan.py) and the loop (optimize.py); the human-editable "blackboard".

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

die.yaml never loaded by code

Medium Severity

blackboard/die.yaml states it is read by plan.py and optimize.py, but neither file loads YAML; die size and margins are hardcoded elsewhere, so edits to die.yaml have no effect.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7d8f39. Configure here.

Comment thread optimize.py
print(f"\nvoid-fill plateau: no remaining void can hold the smallest "
f"{min_w:.0f}x{min_h:.0f}um site — every packable gap is used. done.",
flush=True)
break

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Void-fill stops on empty pack

Medium Severity

Phase 2 treats an empty void-fill pack as “no packable voids left” and exits, even when fits_smallest_dut still suggests space and the heterogeneous pool simply did not fit that LER bin.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7d8f39. Configure here.

Comment thread optimize.py
AREA_BUDGET = 25.0
MIN_DIM = 2000.0
ALLOW_ROTATION = False # LOCKED: same prober direction for every site
GAP = 8.0 # pack gap (bbox-to-bbox; real geometry is further apart)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimizer ignores plan pack gap

Low Severity

plan.py writes pack.GAP (20 µm) into doe_plan.json, but optimize.py always packs with hardcoded GAP = 8.0, so planner capacity estimates and the packer disagree.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b7d8f39. Configure here.

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.

1 participant