Skip to content

ABKGroup/HELIX

Repository files navigation

HELIX: Placement Heuristics Evolution via LLM-Instructed Code Exploration

Note: This repository is provided for the purpose of double-blind review for ICCAD 2026. Please do not distribute or deanonymize.

HELIX is a framework for LLM-driven algorithmic evolution of production placement engines. It operates directly on the C++ source of both the global placement (GPL) and detailed placement (DPL) modules in OpenROAD, discovering interpretable algorithmic improvements that a human engineer can read, understand, and adopt.

Rather than writing placement algorithms from scratch, HELIX evolves the existing codebase through a (mu+lambda) evolutionary strategy: tuning numerical parameters, restructuring algorithmic hot-loops, implementing techniques from placement literature, and proposing novel optimizations -- all validated by building, running, and measuring real HPWL and runtime impact on benchmark designs.

Integration with DREAMPlace confirms that the framework generalizes across codebases and languages without modification.


Key Results

Across twelve design--node pairs (NanGate45 and ASAP7), the evolved placers:

  • Reduce post-detailed placement HPWL by up to 9% (4.5% geometric mean)
  • Reduce routed wirelength by up to 23% (5.6% geometric mean)
  • Preserve timing and power
  • Generalize to unseen designs (3 of 6 designs were not part of evolution)

Against a comparable-budget LLM single-shot baseline, HELIX achieves 7x larger fitness gains.


Architecture

                      +----------------+
                      |   spec.yaml    |  configuration
                      +-------+--------+
                              |
                      +-------v--------+
                      |   evo.cli      |  CLI entry-point
                      +-------+--------+
                              |
                 +------------v------------+
                 |    EvolutionaryLoop     |  orchestrator
                 |    (evo/loop.py)        |
                 +------------+------------+
                              |
         +--------------------+--------------------+
         |                    |                    |
  +------v-------+    +------v-------+    +-------v-------+
  |  Bottleneck  |    |    Code      |    |  Generation   |
  |  Analyzer    |    |   Evolver    |    |  Reflection   |
  +--------------+    +------+-------+    +---------------+
                             |
               +-------------+-------------+
               |             |             |
        +------v---+   +----v-----+  +----v-----+
        |  Build   |   |  Bench   |  | Fitness  |
        |  (make)  |   | (openrd) |  |  Score   |
        +----------+   +----------+  +----------+

Lifecycle of One Generation

  1. Bottleneck analysis (generation 0 only) -- an LLM ranks functions by optimization potential given the user's query.
  2. Pipeline detection (generation 0 only) -- LLM-driven detection of orchestrator patterns (functions that sequence multiple optimization sub-algorithms).
  3. Parent selection -- Tournament selection picks mu parents from the population.
  4. Offspring generation -- For each of lambda offspring, the loop selects a parent, samples an operator from the adaptive distribution, assigns a focus target (parameter cluster or algorithm), and dispatches a coding agent to edit C++ source in an isolated git worktree.
  5. Build -- build_worktree.sh overlays modified sources onto the main repo, runs make inside a Singularity container, then restores originals.
  6. Benchmark -- openroad_dpl_bench.sh (or openroad_gpl_bench.sh) runs each design and extracts HPWL / runtime.
  7. Fitness -- Per-design scores are computed via Equation 1 (with adaptive gamma) and aggregated via Equation 2.
  8. Refinement retry -- Near-miss offspring (beat baseline but not parent) receive up to max_refinement_attempts iterative refinement rounds with benchmark feedback and placement diagnostics.
  9. Placement analysis -- DEF files are parsed to compute spatial displacement deltas; heatmaps are generated for visualization.
  10. Reflection -- If runtime regressed or results are mixed across designs, a reflection agent attempts a targeted fix.
  11. Survivor selection -- The top mu individuals survive, scored by fitness (60%), focus-target diversity (25%), and a lineage crowding penalty.
  12. Stagnation injection -- If best fitness has not improved for stagnation_threshold generations, a fresh individual is evolved from the unmodified baseline using mutate_lit on a novel focus target and injected into the population.
  13. Generation reflection -- An LLM analyzes the generation, recommends operator weight adjustments, and identifies tabu regions.
  14. Telemetry -- All calls, outcomes, token consumption, costs, diff sizes, and failure modes are logged to telemetry.jsonl.

Repository Structure

helix/
├── spec.yaml                        # OpenROAD evolution configuration
├── spec_dreamplace.yaml             # DREAMPlace evolution configuration
├── pyproject.toml                   # Package metadata (placement-evo 0.1.0)
├── evo/                             # Main Python package
│   ├── __main__.py                  # python -m evo entry
│   ├── cli.py                       # Click CLI (run, results, ls, show, promote)
│   ├── loop.py                      # EvolutionaryLoop orchestrator
│   ├── config.py                    # Typed dataclasses from spec.yaml
│   ├── models.py                    # Individual, EvolutionHistory, TabuEntry
│   ├── context_builder.py           # Builds per-operator prompt context
│   ├── operator_scheduler.py        # Adaptive operator selection
│   ├── focus_selector.py            # Focus target assignment
│   ├── telemetry.py                 # Per-call telemetry with aggregation
│   ├── constants.py                 # Shared constants and paths
│   ├── refine.py                    # Refinement retry logic
│   ├── preserve.py                  # Best-individual promotion
│   ├── distill.py                   # Literature distillation pipeline
│   ├── single_shot.py               # LLM single-shot baseline
│   ├── adapters/
│   │   ├── base.py                  # AgentAdapter / LLMAdapter ABCs
│   │   ├── agent_cli.py             # Cursor Agent adapter for code editing
│   │   ├── claude_cli.py            # Claude Code adapter for analysis
│   │   └── codex_cli.py             # OpenAI Codex adapter
│   ├── agents/
│   │   ├── bottleneck_analyzer.py   # Query-driven function ranking via LLM
│   │   ├── code_evolver.py          # Full individual lifecycle
│   │   └── build_repair.py          # Automated compilation error fixing
│   ├── operators/
│   │   ├── base.py                  # EvolutionaryOperator ABC
│   │   ├── mutation.py              # Lit, Creative, Struct, Param mutations
│   │   ├── crossover.py             # CrossoverOperator
│   │   ├── reflection.py            # Population + Generation reflection
│   │   └── templates/               # Jinja2 prompt templates
│   │       ├── _base.j2             # Shared prompt skeleton
│   │       ├── mutation_lit.j2      # Literature-guided mutation
│   │       ├── mutation_creative.j2 # Creative/novel mutation
│   │       ├── mutation_struct.j2   # Structural refactoring
│   │       ├── mutation_param.j2    # Parameter tuning
│   │       ├── crossover.j2         # Two-parent crossover
│   │       ├── reflect_population.j2
│   │       ├── reflect_generation.j2
│   │       ├── refine_post.j2       # Refinement retry prompt
│   │       ├── build_repair.j2      # Build error repair
│   │       └── single_shot.j2       # Single-shot baseline
│   ├── fitness/
│   │   └── score.py                 # Fitness equations and baseline loading
│   ├── analysis/
│   │   ├── def_diff.py              # DEF parsing, delta computation, heatmaps
│   │   ├── pipeline_detector.py     # Orchestrator/pipeline pattern detection
│   │   └── render_heatmap.py        # Matplotlib heatmap renderer
│   ├── common/
│   │   ├── io.py                    # Run directory I/O, checkpointing
│   │   ├── json_utils.py            # Robust JSON extraction from LLM output
│   │   └── schemas.py               # Pydantic schemas for structured output
│   └── sandbox/
│       └── workspace.py             # Git worktree create / cleanup
├── scripts/
│   ├── build_worktree.sh            # Source-overlay incremental build
│   ├── openroad_gpl_bench.sh        # Run OpenROAD GPL benchmarks
│   ├── openroad_dpl_bench.sh        # Run OpenROAD DPL benchmarks
│   ├── dreamplace_bench.sh          # Run DREAMPlace benchmarks
│   ├── build_dreamplace_worktree.sh # DREAMPlace worktree setup
│   ├── run_gpl_baseline.sh          # Baseline GPL benchmark runner
│   ├── profile_dpl.sh               # CPU profiling on benchmark designs
│   ├── parse_openroad_metrics.py    # Extract HPWL/runtime from OpenROAD logs
│   ├── parse_dreamplace_metrics.py  # Extract metrics from DREAMPlace logs
│   ├── validate_pipeline.py         # End-to-end pipeline validation
│   ├── extract_parameters.py        # Extract tunable constants from source
│   ├── extract_design_stats.py      # Extract design statistics
│   ├── build_call_graphs.py         # Generate call graph JSON from source
│   ├── generate_pseudocode.py       # LLM-generated pseudocode for functions
│   ├── distill_literature.py        # Distill papers into literature cards
│   ├── sweep_target_density.py      # DREAMPlace target density sweep
│   ├── eval_helix_dreamplace.py     # Evaluate HELIX on DREAMPlace
│   ├── eval_evoplace_configs.py     # Evaluate EvoPlace configurations
│   ├── plot_llm_ss_comparison.py    # Plot LLM single-shot comparison
│   ├── plot_operator_ablation.py    # Plot operator analysis
│   └── plot_evolution_trajectory.py # Plot evolution fitness trajectory
├── corpus/                          # OpenROAD Corpus (ORC)
│   ├── baseline/                    # Reference HPWL and runtime per design
│   ├── call_graphs/                 # Static call graphs (GPL, DPL, DREAMPlace)
│   ├── pseudocode/                  # LLM-generated pseudocode abstractions
│   ├── literature/                  # Distilled paper summaries (97 JSON cards)
│   ├── parameters/                  # Curated tunable constants with ranges
│   ├── profiling/                   # Per-design CPU hotspot data
│   ├── design_stats/                # Design statistics
│   ├── lessons/                     # Consolidated evolution lessons
│   └── docs/                        # Architecture guides and domain references
├── saved_best/                      # Best evolved individuals
│   ├── merged_gpl_dpl/              # Combined GPL+DPL patches and source
│   ├── llm_ss_best/                 # LLM single-shot baseline best
│   └── evo-*/                       # Per-run best individuals with patches
├── evoplace_eval/                   # DREAMPlace evaluation harness
│   ├── dreamplace/                  # Modified DREAMPlace Python modules
│   └── results/                     # ISPD 2005 benchmark results
├── results/                         # Evaluation result summaries
└── example_prompts/                 # Candidate prompts from evolution runs
    └── evo-<timestamp>-<id>/        # Per-run prompt archives
        └── gen<N>-<operator>-<hex>/ # Per-candidate prompt
            └── prompt.txt           # Full LLM prompt used for mutation

Prerequisites

  • Python 3.9+ with pip
  • OpenROAD repository cloned and pre-built (for OpenROAD evolution)
  • DREAMPlace repository cloned and installed (for DREAMPlace evolution)
  • Singularity/Apptainer container image with the build toolchain
  • LLM CLI tools (at least one of the following):
  • (Optional) matplotlib and numpy for placement heatmap generation

Installation

# Clone the repository
git clone <repository-url> helix
cd helix

# Install the Python package in editable mode
pip install -e .

# Verify installation
evo --help

Configuration

HELIX is configured through YAML specification files. Two are provided:

  • spec.yaml -- Configuration for evolving OpenROAD's GPL and DPL modules
  • spec_dreamplace.yaml -- Configuration for evolving DREAMPlace

Before running, update the following paths in the spec file to match your environment:

Key Description
targets.<module>.source_dir Path to the target module's source directory
build.repo_root Path to the OpenROAD or DREAMPlace repository root
build.build_dir Path to the build output directory
build.bench_command Path to the benchmark script
build.singularity_image Path to the Singularity/Apptainer container image
analysis.bo_env_python Path to Python environment for Bayesian optimization

Key Configuration Sections

Section Key Fields Description
target_module "dpl", "gpl", or "dreamplace_gp" Which module to evolve
targets.<module> source_dir, call_graph, pseudocode_dir, entry_functions Per-module paths and metadata
designs.evolution List of design names Designs used for fitness during evolution
designs.evaluation List of design names Full evaluation suite (post-run)
fitness w1, w2, gamma, gamma_end, zeta Fitness equation weights
evolution mu, lambda, G_max, k_tournament Evolutionary algorithm parameters
operator_weights a_param, a_struct, a_lit, a_creative, a_xover Operator probability weights
build repo_root, build_dir, threads, timeout_s Build environment settings
agent model, timeout_s Coding agent settings
llm model, timeout_s Analysis LLM settings

Usage

Running Evolution

# Minimal dry-run (1 generation, 1 parent, 2 offspring)
python -m evo -v run \
    --spec spec.yaml \
    --query "Optimize HPWL in detailed placement" \
    --gens 1 --mu 1 --lam 2

# Full production run (mu=5, lambda=8, 15 generations)
python -m evo -v run \
    --spec spec.yaml \
    --query "Optimize HPWL in detailed placement" \
    --gens 15 --mu 5 --lam 8

# Resume a previous run
python -m evo run --spec spec.yaml --query "..." --resume .evo/runs/<run-id>

Inspecting Results

# List all runs
python -m evo ls

# Show top candidates from latest run
python -m evo results --top 20

# Inspect a specific candidate (with diff and prompt)
python -m evo show <run-id> <candidate-id> --diff --prompt

# Promote a candidate's commit to a named git branch
python -m evo promote <run-id> <candidate-id> my-improvement

LLM Single-Shot Baseline

python -m evo -v single-shot \
    --spec spec.yaml \
    --query "Optimize HPWL in detailed placement" \
    --shots 120

OpenROAD Corpus (ORC)

The ORC is a multi-layered knowledge base that grounds every LLM mutation in structured domain knowledge. It is assembled once per target module and reused across all generations.

Components

Component Location Description
Literature technique cards corpus/literature/cards/ 97 research papers distilled into structured JSON cards
Pseudocode abstractions corpus/pseudocode/ Algorithm-level pseudocode for performance-critical functions
Call graphs corpus/call_graphs/ Static call graphs extracted via Clang-based analysis
Parameter catalog corpus/parameters/ Tunable constants with source locations and mutation ranges
CPU profiling data corpus/profiling/ Per-design hotspot rankings
Architecture guides corpus/docs/ Narrative architecture overviews for GPL and DPL modules
Baseline metrics corpus/baseline/ Reference HPWL and runtime per design

Rebuilding the Corpus

# Generate call graphs from source
python scripts/build_call_graphs.py --source-dir <path-to-module>

# Generate pseudocode abstractions
bash scripts/run_generate_pseudocode.sh

# Distill literature papers into technique cards
python scripts/distill_literature.py --papers-dir <path-to-pdfs>

# Extract tunable parameters from source
python scripts/extract_parameters.py --source-dir <path-to-module>

Fitness Model

Per-design fitness (Equation 1):

f_N(theta) = w1 * (HPWL_baseline / HPWL_candidate)
           - w2 * max(0, runtime_candidate / runtime_baseline - gamma_eff)
           - zeta  (if build crashed or produced illegal placement)

Aggregate fitness (Equation 2):

f_bar = (1 / |designs|) * SUM( f_N )

A candidate matching baseline performance exactly scores w1 (default 1.0). HPWL improvements push fitness above w1. A runtime penalty applies only when the candidate exceeds gamma_eff times the baseline runtime. Build failures receive a penalty of -zeta (default -100).

The runtime tolerance gamma_eff decays linearly over generations:

gamma_eff = gamma_start - (gamma_start - gamma_end) * (generation / G_max)

Early generations allow runtime overhead for algorithmic exploration; late generations enforce runtime neutrality.


Evolutionary Operators

Operator Purpose Line Budget Focus Target
mutate_param Perturb 1--3 numerical constants within annotated ranges 25 Parameter cluster
mutate_struct Restructure control flow or data access patterns 100 Algorithm
mutate_lit Implement a technique from a retrieved literature card 200 Algorithm
mutate_creative Novel heuristic guided by profiling and placement data 200 Algorithm
crossover Merge complementary diffs from two parents 500 None

Line budgets are advisory; the fitness function is the sole arbiter of solution quality. Operator selection probabilities are adapted across generations via three multiplicative factors: progress-based scheduling, stagnation boosting, and Laplace-smoothed empirical success rates.


Evolved Results

The saved_best/ directory contains the best evolved individuals from each evolution run:

  • BEST_INDIVIDUAL.md -- Summary of fitness, per-design metrics, and the evolutionary path (operator, generation, focus target)
  • patches/ -- Git-format patches that can be applied to the baseline OpenROAD repository
  • source/ -- Snapshot of the modified source files

The merged_gpl_dpl/ subdirectory contains the combined GPL+DPL patches used for the end-to-end evaluation reported in the paper.

To apply a patch:

cd <openroad-repo>
git apply <path-to-patch>/cumulative_gpl.patch
git apply <path-to-patch>/cumulative_dpl.patch

Example Prompts

The example_prompts/ directory contains the full LLM prompts used during evolution runs. Each prompt demonstrates how the Context Builder assembles domain knowledge, evolutionary context, and operator-specific instructions into a single coherent prompt for the coding agent.


License

This project is released under the BSD 3-Clause License. See LICENSE for details.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors