Skip to content
 
 

Latest commit

 

History

341 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenLithoHub

OpenLithoHub

If you find this project helpful, please drop us a star! It helps us get discovered by the community and is by far the most useful thing you can do for an early-stage open-source project.

Open-source computational lithography benchmarking and workflow toolkit for advanced EUV/curvilinear mask processes.

PyPI License Python 3.10+ CI codecov Open In Colab

Website: openlithohub.com | Docs: docs.openlithohub.com | Playground: HuggingFace Space

中文版 / Chinese Version — kept in sync with this English README; if the two diverge, this English version is authoritative.


What is OpenLithoHub?

OpenLithoHub is an open-source computational lithography benchmarking and workflow toolkit — ILT, OPC, mask optimization, and EUV stochastic defect prediction with honest self-measurement.

Validated results at a glance

EUV Stochastic Defect PredictionBayesianStochasticModel validated across 4 pattern types × 3 nodes, cross-checked against independent MC simulation:

Pattern EUV N3 FP EUV N7 FP ArF 45nm FP Calibration MAE
line/space 11.4% 2.9% 0.07% < 0.016
contact 4.1% 6.0% 7.9% < 0.014
elbow 1.0% 1.9% 1.7% < 0.003
dense logic ~0% 0% 0% < 0.001

Dose-response is monotonically decreasing (19.4× from 10→100 ph/nm²), matching published √(1/dose) EUV shot-noise scaling. Full tables and methodology: BENCHMARKS.md.

Core capabilities

  • Unified dataset access — LithoBench, LithoSim, GAN-OPC, ICCAD'16, ASAP7, FreePDK45, ORFS-routed RISC-V layouts
  • Standardized metrics — EPE, L2, PV Band, shot count, stochastic robustness, imec defect rates, hotspot detection
  • Bayesian stochastic model — per-pixel failure probability, LER, LWR heatmaps via Poisson-MC or MC-Dropout
  • Manufacturing compliance — MRC/DRC rule checking as hard-fail gates
  • OASIS / GDSII workflow — end-to-end tensor→fab-ready mask (manhattan & curvilinear)
  • Model-agnostic evaluation — plug any OPC/ILT model via minimal interface
  • Optional physics plugins — DiffNano (EM solvers) and DiffCFD (litho + spin-coat) as opt-in extras

Honesty boundaries: All benchmarks use synthetic 64×64 layouts. No foundry validation, no production tapeout. CPU-only timing. See BENCHMARKS.md for full methodology.

┌─────────────────────────────────────────────────────────────────────────┐
│                          OpenLithoHub                                   │
├─────────────┬──────────────┬──────────────┬───────────┬─────────────────┤
│  Data Layer │  Benchmark   │   Workflow   │ Vis & UX  │      CLI        │
│ LithoBench  │  EPE/PVBand  │ Tiling/Stitch│ Paper figs│ eval / optimize │
│ LithoSim    │  MRC/DRC     │ Contour Ext. │ Jupyter   │ leaderboard     │
│ Transforms  │  Stochastic  │ OASIS Export │ EDA bridge│ simulate / synth│
│ Dummy gen.  │  Shot Count  │ B-spline Fit │           │ hackathon/export│
└─────────────┴──────────────┴──────────────┴───────────┴─────────────────┘

Installation

pip install --pre openlithohub          # Core (metrics + CLI)
pip install --pre 'openlithohub[all]'   # Everything (data, workflow, models, jupyter)

From source: git clone https://github.com/OpenLithoHub/OpenLithoHub.git && pip install -e ".[dev]"

Docker: docker run --rm ghcr.io/openlithohub/openlithohub:latest eval run ...

Available extras

data, workflow, models, jupyter, export, docs, dev, diffnano (EM solvers), diffcfd (litho + spin-coat), plugins (= both), all. Combine: 'openlithohub[data,workflow]'.

DiffNano and DiffCFD are early-stage research plugins with no third-party validation.

From source (development):

git clone https://github.com/OpenLithoHub/OpenLithoHub.git
cd OpenLithoHub
pip install -e ".[dev]"

Docker (zero-config, GPU-ready):

Pre-built images are published to GitHub Container Registry on every release:

# CPU
docker run --rm -v "$PWD":/data ghcr.io/openlithohub/openlithohub:latest \
  eval run --model dummy-identity --dataset lithobench --data-root /data/lithobench

# GPU (requires nvidia-container-toolkit on the host)
docker run --rm --gpus all -v "$PWD":/data ghcr.io/openlithohub/openlithohub:latest \
  optimize run --input /data/design.oas --model neural-ilt --output /data/optimized.oas

Tagged versions are also available (e.g. ghcr.io/openlithohub/openlithohub:0.1).


Co-Design: Lithography as Coupling Layer

OpenLithoHub's forward lithography model serves as the coupling layer that connects upstream design solvers (EM, CFD) to downstream manufacturability:

from diff_surrogate import CoDesignWorkflow, CoupledLoss
from openlithohub.simulators import HopkinsSimulator, SimulatorConfig

# Lithography forward function feeds printability gradients back to design
def litho_coupling(merged_outputs):
    design_mask = merged_outputs["design"]["mask"]
    sim = HopkinsSimulator(SimulatorConfig(pixel_size_nm=1.0))
    result = sim.simulate(design_mask)
    merged_outputs["litho"] = {"aerial": result.aerial}
    return merged_outputs

wf = CoDesignWorkflow(
    design_params=torch.rand(64, 64),
    forward_fns={"design": design_forward},
    loss_fn=combined_loss,
    coupling_fn=litho_coupling,
)

Install openlithohub[plugins] to use DiffNano/DiffCFD solvers as co-design partners.


Evaluate a model

openlithohub eval run \
  --model dummy-identity \
  --dataset lithobench \
  --data-root ./data/lithobench \
  --format table

Output:

┌──────────────────┬────────────────┐
│ Metric           │ Value          │
├──────────────────┼────────────────┤
│ epe_mean_nm      │ 0.0000         │
│ epe_max_nm       │ 0.0000         │
│ mrc_violation_rate│ 0.0000        │
│ mrc_passed       │ 1.0000         │
└──────────────────┴────────────────┘

Run end-to-end optimization

openlithohub optimize run \
  --input design.oas \
  --model your-model \
  --writer mbmw \
  --node 3nm-euv \
  --drc-check \
  --output optimized.oas

Closed-loop design→litho→DFM report

openlithohub flow run design.gds \
  --pdk asap7 --layer metal1 \
  --node 45nm --tile-nm 2000 \
  --drc --mrc \
  --output report.json

Accepts a standalone GDS / OAS / DEF file or an ORFS product directory. Per-PDK layer maps are configurable (asap7, freepdk45, orfs_asap7, sky130, or a custom JSON file). The report aggregates tile-level EPE, PV Band, DRC, and MRC into a single JSON summary.

Enable diffusion resist (opt-in)

# Default: CTR (constant-threshold resist), threshold=0.225 — comparable numbers
openlithohub simulate run mask.npy --resist-diffusion-nm 0.0

# Opt-in: CAR with Gaussian acid diffusion — more realistic but NON-COMPARABLE
openlithohub simulate run mask.npy --resist-diffusion-nm 20.0

The scored default remains CTR without diffusion, threshold = 0.225. Enabling acid diffusion (or any plugin EM/resist backend) produces non-comparable numbers and is disabled for leaderboard submission.

Run as an HTTP micro-service

For fab-side schedulers (Slurm / LSF) or legacy C++/Perl pipelines that cannot embed Python, run the FastAPI engine and drive it with curl:

pip install "openlithohub[server]"
openlithohub serve --port 8000 &

curl -X POST http://localhost:8000/v1/optimize \
     -F "layout=@design.oas" \
     -F "model=your-model" \
     -F "writer=mbmw" \
     -o optimized.oas

Models stay resident in-process; repeat requests skip weight loading. Open http://localhost:8000/docs in a browser for the auto-generated Swagger UI: every endpoint is documented with its JSON schema and can be exercised interactively (file upload included), no client code needed.

Use as a Python library

The object-oriented façade — Mask, LitheEngine, Report — is the shortest path from a layout file to scored results:

from openlithohub import Mask, LitheEngine

mask      = Mask.from_oasis("design.oas", layer="1:0", pixel_size_nm=1.0)
engine    = LitheEngine(model="neural-ilt", node="3nm-euv")
optimized = engine.optimize(mask)
report    = engine.evaluate(optimized, target=mask)

print(report.epe_mean_nm, report.pvband_mean_nm, report.drc_violations)
optimized.to_oasis("optimized.oas")

The functional API stays available for fine-grained control:

import torch
from openlithohub.benchmark.metrics import compute_epe, compute_pvband
from openlithohub.benchmark.compliance import check_mrc, check_drc

predicted = torch.load("predicted_mask.pt")
target = torch.load("target_mask.pt")

# Edge Placement Error
epe = compute_epe(predicted, target, pixel_size_nm=1.0)
print(f"EPE mean: {epe['epe_mean_nm']:.2f} nm")

# Process Variation Band
pvb = compute_pvband(predicted, defocus_range_nm=20.0)
print(f"PV Band: {pvb['pvband_mean_nm']:.2f} nm")

# Manufacturing compliance
mrc = check_mrc(predicted, min_width_nm=40.0, min_spacing_nm=40.0)
print(f"MRC passed: {mrc.passed} ({mrc.violation_count} violations)")

Register a custom model

import torch
from openlithohub.models.base import LithographyModel, PredictionResult
from openlithohub.models.registry import registry

@registry.register
class MyOPCModel(LithographyModel):
    NAME = "my-opc"
    SUPPORTS_CURVILINEAR = True

    def predict(self, design: torch.Tensor, **kwargs) -> PredictionResult:
        mask = my_optimization_algorithm(design)
        return PredictionResult(mask=mask)

Paper-ready figures

from openlithohub.vis import plot_contours

# Vector PDF, IEEE column-width, colorblind-safe palette
plot_contours(target, predicted, save_path="fig.pdf", style="ieee")

Hermetic dummy layouts (for CI / Colab)

from openlithohub.data import generate_dummy_layout

mask = generate_dummy_layout(size=256, seed=0)  # numpy + torch only, no KLayout

EDA bridge (Calibre / IC Validator)

from openlithohub.workflow import BridgeRules, emit_bridge_bundle

emit_bridge_bundle(
    "optimized.oas",
    BridgeRules(min_width_nm=40.0, min_spacing_nm=40.0),
)
# Writes optimized.svrf, optimized.rs, optimized.bridge.md

Try it in Colab

The notebooks/quickstart.ipynb tutorial runs end-to-end on Colab's stock runtime — install, generate a layout, score it, and produce a paper-ready figure in three minutes.

Notebook last cold-run-verified against PyPI 0.1.0a2 on 2026-05-21.

Open In Colab

For plugging your own model into the harness, use the BYOM tutorial — it walks through subclassing LithographyModel, running the standard metric suite, and formatting a leaderboard submission.

Open BYOM In Colab


Architecture

Layer Module Description
API facade openlithohub.api OO entry points (Mask, LitheEngine, Report) re-exported at the package root
Data openlithohub.data Unified adapters for LithoBench (.npy), LithoSim (HuggingFace), GAN-OPC (paired PNGs), ICCAD'16 hotspot (OASIS via klayout)
Benchmark openlithohub.benchmark EPE (mask & wafer-sim), L2 wafer error, PV Band, shot count, stochastic robustness + per-class defect rates, hotspot detection, MRC/DRC compliance
Models openlithohub.models Abstract LithographyModel interface (NAME class variable) + decorator-based registry
Simulators openlithohub.simulators Forward model registry (register_simulator), Hopkins/SOCS built-in, Calibre/Tachyon commercial adapters (with mock mode), plugin EM backends (RCWA/FDTD/FDFD)
Workflow openlithohub.workflow Layout parsing (OASIS / GDSII / DEF / LEF), tiling, contour extraction (manhattan/curvilinear), OASIS / GDSII export, process-window OPC, OpenAccess layer-purpose helper
Inference openlithohub.inference Shared-weight multi-process inference (multiproc_predict), CompiledCache for torch.compile artifacts
Plugins openlithohub.plugins Optional DiffNano (EM + resist) and DiffCFD (litho + spin-coat + joint optimisation) backends
Constants openlithohub._constants Single source of truth for optical, resist, EUV 3D-mask, and plugin default values
CLI openlithohub.cli eval, optimize, leaderboard, simulate, flow, synth, hackathon, export command groups via Typer

Optional Physics Plugins

OpenLithoHub supports optional physics backends via the plugin system. None are required for the core install.

Plugin What it adds Install extra
DiffNano Rigorous EM simulators (RCWA / FDTD / FDFD) + calibratable resist model (acid diffusion, PEB, development contrast) — registered as diffnano_rcwa, diffnano_fdtd2d, diffnano_fdfd2d backends [diffnano]
DiffCFD Differentiable steady-state CFD — Dill/Mack lithography solver, Meyerhofer spin-coating solver, and joint process optimization (optimize_joint_process) [diffcfd]
pip install --pre 'openlithohub[plugins]'   # installs both

Caveats:

  • Both plugins are early-stage research with no external users or third-party validation. Do not use for production decisions.
  • Plugin EM/resist backends produce non-comparable metric values. Built-in Hopkins + CTR (threshold 0.225) remains the only path for leaderboard submission.
  • Optionality is justified by unvalidated status, install footprint, and independent iteration cadence — not by dependency weight (all are PyTorch-native).

Metrics

Metric Description Reference
EPE Edge Placement Error — distance between predicted and target contour edges Standard
PV Band Process Variation Band — resist contour variation across dose/focus window Standard
Shot Count Mask write time proxy for MBMW and VSB writers Industry
Stochastic Robustness Monte Carlo photon noise simulation for bridge/break probability EUV-specific
MRC Minimum width/spacing rule check (hard-fail) EasyMRC
Curvilinear MRC Minimum curvature radius + minimum feature area for post-ILT curvilinear shapes (MBMW writability) EUV-specific
DRC Design Rule Check: area, notch, width, spacing OpenDRC

Diffusion resist: EPE and PV Band can optionally run through the CAR acid-diffusion model (--resist-diffusion-nm). The scored default remains CTR at threshold 0.225; enabling diffusion produces non-comparable numbers and is disabled for leaderboard submission. Absolute wafer prediction still needs user-calibrated, foundry-confidential parameters — the framework is benchmark-relative, not absolute-predictive.


Supported Datasets

Dataset Format Process Node Task Source
LithoBench NumPy .npy 45nm Mask optimization NeurIPS'23
LithoSim HuggingFace Parquet Sub-28nm Mask optimization NeurIPS'25
GAN-OPC Paired PNGs AI-OPC training TCAD'20
ICCAD'16 Problem C OASIS + CSV N7 EUV Hotspot detection ICCAD'16
ASAP7 standard cells GDSII (klayout) 7nm predictive PDK-aware OPC The-OpenROAD-Project/asap7
FreePDK45 + NanGate OCL GDSII (klayout) 45nm predictive PDK-aware OPC mflowgen/freepdk-45nm
ORFS-routed ASAP7 GDSII (klayout) 7nm RISC-V tile-cut hotspots OpenROAD-flow-scripts

Performance & Benchmarks

All numbers are obtained by running bundled benchmark scripts on real hardware. No data has been estimated, extrapolated, or "reasonably assumed." See docs/benchmarks.md for methodology, forward model configuration, and per-pattern breakdowns.

Model quality — synthetic-8 (Table 1)

Eight hand-crafted 64×64 layouts (square, h-line, line/space, T, L, cross, contacts, dense lines) at 8 nm/px, graded with a single shared HopkinsSimulator (wavelength / NA / threshold identical for every row).

Model EPE mean (nm) Wafer EPE (nm) L2 (px) PVB mean (nm) MRC pass
dummy-identity 0.000 4.529 299.9 18.340 88%
rule-based-opc 4.242 7.786 356.4 16.000 88%
levelset-ilt (200 iter) 0.322 4.482 294.9 18.516 75%
openilt (MOSAIC L2+PVB) 0.000 4.529 299.9 18.340 88%
neural-ilt (v0.1 seed) 0.000 4.529 299.9 18.340 88%
  • levelset-ilt is the only model that improves wafer L2 (294.9 vs identity's 299.9), at the cost of a lower MRC pass rate (75%) — the gradient-descent mask creates narrow features that violate min_width_nm=40.
  • openilt and neural-ilt converge to identity on these simple patterns — their forward model already reproduces the target without modification. They diverge on real layouts with non-trivial corner rounding.
  • rule-based-opc intentionally deviates from the target mask (mask-EPE rises to 4.242 nm) but reduces PVB (16.0 vs 18.3 nm) — the expected bias-OPC trade-off.
  • dummy-identity is a floor, not a competitor — mask-EPE is zero by construction (design == target) but wafer-EPE and L2 are nonzero due to diffraction.

Model quality — ICCAD16 testcase1 (Table 2)

Real EUV layout (1.9 µm × 1.5 µm, 475×375 px at 4 nm/px) from Yang2016_ICCAD16Bench. EPE/L2 columns omitted — the dataset ships no reference OPC mask.

Model PVB mean (nm) PVB max (nm) MRC viol rate
dummy-identity 14.82 64.0 15.93%
rule-based-opc 12.39 32.0 14.89%
levelset-ilt 10.49 32.0 0.97%
openilt 14.82 64.0 15.93%
neural-ilt (v0.1) 0.00 0.0 0%
gan-opc (v0.1) 10.97 48.0 8.48%
gan-opc (v0.2) 11.76 64.0 5.99%
  • levelset-ilt achieves the best PVB (10.49 nm) with near-zero MRC violations (0.97%) — same ranking as synthetic-8.
  • neural-ilt v0.1 shows a degenerate result (zero PVB, zero violations) because weights trained on synthetic 64-px tiles produce a near-blank mask on the 475×375 grid — this is an out-of-distribution failure, not a competitive score.
  • gan-opc v0.2 vs v0.1: MRC violations drop 29% (8.48%→5.99%) but PVB rises 7% (10.97→11.76 nm), reflecting the Hopkins-in-the-loop trade-off.

Cross-reference with published results (Table 3)

Comparing OpenLithoHub's reimplementations against original paper results. Non-strict same-condition comparison, for reference only — test layouts, process nodes, and evaluation methodologies differ. All paper numbers are from ICCAD 2013 contest benchmarks (10 clips, 32 nm M1, 1024 nm × 1024 nm, 1 nm/px); OpenLithoHub numbers are from ICCAD16 testcase1 (7 nm EUV, 475 × 375 px, 4 nm/px) — a fundamentally different benchmark.

Method Source Reported (ICCAD13) OpenLithoHub reimpl. (ICCAD16) Caveats
MOSAIC (SGD, L2+PVB) Gao et al., DAC 2014 (DOI 6881379) PVB avg ≈ 56 890 nm², TAT ≈ 1703 s PVB 14.82 nm (identity) OpenILT converges to identity on clean patterns; ICCAD13 vs ICCAD16 metrics not directly comparable
Neural-ILT (U-Net) Jiang et al., ICCAD 2020 (DOI 3415704) L2 avg 38 504 nm², TAT ≈ 11 s (GPU) N/A (degenerate on ICCAD16) v0.1 trained on synthetic only; paper uses 2048×2048 masks on GPU
GAN-OPC (PGAN-OPC) Yang et al., DAC 2018 / TCAD 2020 (DOI 3196056) L2 avg 39 949 nm², TAT ≈ 371 s PVB 10.97 nm, MRC viol 8.48% Paper reports L2 (nm²); we report PVB (nm) — different metrics and layouts
curvyILT Yang & Ren, ISPD 2025 / arXiv 2411.07311 MSE avg 25 991 nm², 2.11 s/clip (RTX A6000) — (not yet integrated) External GPU tool; best published academic SOTA on ICCAD13

Optimization throughput (Table 4)

All timing measured with perf_counter_ns, gc.disable() during sampling, 100 samples (forward models / metrics) or 20 samples (full model predictions), median and P99 reported. CPU only (no GPU).

Benchmark Grid Median P99 Device
forward_gaussian 64×64 238 µs 549 µs AMD 5600G CPU
forward_gaussian 256×256 804 µs 1.2 ms AMD 5600G CPU
forward_hopkins 64×64 2.1 ms 2.7 ms AMD 5600G CPU
forward_hopkins 256×256 6.5 ms 9.5 ms AMD 5600G CPU
metric_epe 64×64 541 µs 941 µs AMD 5600G CPU
metric_pvband 64×64 1.4 ms 3.6 ms AMD 5600G CPU
metric_epe 256×256 2.0 ms 4.1 ms AMD 5600G CPU
metric_pvband 256×256 6.7 ms 7.5 ms AMD 5600G CPU
model_dummy-identity 64×64 4 µs 106 µs AMD 5600G CPU
model_rule-based-opc 64×64 632 µs 1.3 ms AMD 5600G CPU
model_levelset-ilt (10 iter) 64×64 17.9 ms 20.7 ms AMD 5600G CPU
  • Hopkins is ~8× slower than Gaussian (2.1 ms vs 238 µs at 64×64) — the SOCS SVD decomposition is the bottleneck.
  • levelset-ilt 10 iterations takes ~18 ms per 64×64 tile; 200 iterations would scale to ~360 ms. This is consistent with the iterative gradient-descent nature of the algorithm.
  • GPU timing is not reported — OpenLithoHub's models run on CPU by default. Neural-ILT (Jiang et al., ICCAD 2020) reports ~11 s on GPU for the same task; direct comparison is not meaningful without matching hardware.

Surrogate-ILT uses an on-the-fly trained surrogate forward model and reports 10–50× speedup relative to the full-physics Hopkins forward model — this is an internal relative measurement, not a wall-clock comparison with external tools.

How to reproduce

Hardware: AMD Ryzen 5 5600G (6C/12T), 13 GB DDR4, SATA SSD, Ubuntu 24.04 (kernel 6.8.0)

Software: CPython 3.10.12, PyTorch 2.12.0+cpu, OpenLithoHub 4c3a699 (main)

# Model quality (synthetic-8):
python3 scripts/generate_baselines.py --synthetic --limit 8 --output baselines/

# Model quality (ICCAD16 testcase1):
openlithohub eval run --model levelset-ilt --dataset iccad16 \
  --data-root data/iccad16 --node 7nm --pixel-nm 4.0

# Performance timing:
python3 scripts/benchmark_performance.py --json results_timing.json

# Generate comparison charts:
python3 scripts/plot_benchmarks.py --input baselines/results.json --output docs/images/

Methodology: Synthetic-8 numbers are averaged across 8 patterns per model, single run. ICCAD16 is a single testcase, single run. No statistical sampling across seeds. Timing benchmarks use perf_counter_ns, gc.disable() during measurement, and report median / P95 / P99 over 100 samples (forward models) or 20 samples (full model predictions).

All test data is obtained by actually running the above commands on the above hardware, without any subjective estimation. Readers can reproduce the results by running the same commands.

Visualization

python scripts/plot_benchmarks.py \
  --input baselines/results.json \
  --output docs/images/

Model quality comparison — synthetic-8

Charts use transparent-background SVG with neutral-gray (#888) axis labels for readability in both light and dark GitHub themes.


Optical forward models

OpenLithoHub ships two differentiable forward models, both written in pure PyTorch so the entire ILT loop is end-to-end auto-differentiable:

Model Module Notes
Gaussian PSF openlithohub._utils.forward_model.simulate_aerial_image Single-Gaussian convolution; cheap default for tests and small grids
Hopkins SOCS openlithohub._utils.hopkins.simulate_aerial_image_hopkins Partial-coherent imaging via SVD-truncated Sum-Of-Coherent-Systems; supports circular / annular / dipole illumination
Thick mask forward model openlithohub._utils.forward_model.simulate_aerial_image_thick_mask Multi-layer thick-mask diffraction model for 3D mask effects (O7.1)
DiffNano RCWA/FDTD/FDFD openlithohub.plugins.diffnano_em (opt-in) Rigorous EM solvers via the DiffNano plugin; registered as diffnano_rcwa, diffnano_fdtd2d, diffnano_fdfd2d backends

Built-in Hopkins remains the default and the only comparable path for leaderboard numbers. Plugin EM backends are opt-in and produce non-comparable scores.

Schwarz Domain Decomposition (Tiling)

schwarz_tiled_ilt() in openlithohub._utils.tiling implements alternating Schwarz domain decomposition for large-layout ILT. Adjacent tiles exchange overlap boundary data at each iteration, with convergence monitoring (residual norm). This replaces naive independent tiling with a solver that enforces inter-tile consistency:

from openlithohub._utils.tiling import schwarz_tiled_ilt

result = schwarz_tiled_ilt(
    mask, tile_size=512, overlap=64, max_schwarz_iter=10, tol=1e-4,
)

Differentiable Morphological Operators (O7.2)

Differentiable dilate/erode/open/close via structured-element max-pool soft approximations, usable as differentiable MRC/DRC proxies in the ILT autograd graph:

from openlithohub._utils.morphology import soft_dilate, soft_erode, soft_opening, soft_closing

# Differentiable morphological operations
opened = soft_opening(mask, kernel_size=3, temperature=0.1)
width_violation = soft_erode(mask, kernel_size=3).clamp(min=0).mean()  # proxy for min-width penalty

Warm-Start ILT Interface (O7.3)

The LevelSetILTModel and warm_start_ilt() support initializing ILT from a prior OPC result (rule-based, neural, or external), avoiding cold-start convergence issues:

from openlithohub._utils.warm_start import warm_start_ilt

result = warm_start_ilt(
    initial_mask=prior_opc_mask,   # from rule-based or neural OPC
    target=target_mask,
    iterations=100,
    forward_model="hopkins",
)

Tiling Residual Quantification (O7.4)

tiling_residual_report() quantifies inter-tile boundary consistency after tiling/stitching, reporting overlap L2 norm, max discontinuity, and per-tile residual maps:

from openlithohub._utils.tiling import tiling_residual_report

report = tiling_residual_report(stitched_mask, tile_size=512, overlap=64)
print(f"Overlap L2: {report['overlap_l2']:.4f}, Max discontinuity: {report['max_disc']:.2f} nm")

Born Scattering Forward Correction

simulate_aerial_image_born() in openlithohub._utils.forward_model extends the Hopkins Gaussian PSF forward model with higher-order Born scattering terms for thick-mask effects. This captures edge diffraction and sidewall scattering that the thin-mask (Hopkins-only) model misses:

from openlithohub._utils.forward_model import simulate_aerial_image_born

aerial = simulate_aerial_image_born(
    mask, sigma_nm=20.0, born_order=2,  # Hopkins + 2nd-order correction
)

Switch LevelSetILTModel to Hopkins:

from openlithohub._utils import HopkinsParams
from openlithohub.models.levelset_ilt import LevelSetILTModel

model = LevelSetILTModel(
    iterations=200,
    forward_model="hopkins",
    hopkins_params=HopkinsParams(
        wavelength_nm=193.0, na=1.35, sigma=0.7, num_kernels=24, pixel_size_nm=2.0,
    ),
)

Stochastic-aware ILT (O8.1)

Differentiable stochastic metrics — edge error and LCDU (local CD uniformity) — with CVaR (Conditional Value-at-Risk) and quantile risk measures. Enables stochastic process window evaluation that directly optimizes worst-case yield instead of nominal performance:

from openlithohub._utils.stochastic_ilt import StochasticILTLoss

stochastic_loss = StochasticILTLoss(
    edge_weight=1.0,
    lcdu_weight=0.5,
    risk_measure="cvar",      # or "quantile"
    alpha=0.05,                # tail fraction for CVaR
)
loss = stochastic_loss(predicted_contour, target_contour)

Posterior Warm-Start (O8.2)

PosteriorWarmStart uses a conditional VAE (CVAE) to sample diverse multi-candidate initializations from the learned posterior over OPC solutions. BatchILTScheduler performs batch refinement and selection across candidates, picking the best mask by a composite score (EPE + MRC + PVB):

from openlithohub._utils.posterior_warm_start import PosteriorWarmStart, BatchILTScheduler

warm_start = PosteriorWarmStart(latent_dim=64, n_candidates=8)
candidates = warm_start.sample(target_mask, n=8)  # diverse initial masks

scheduler = BatchILTScheduler(iterations=200, forward_model="hopkins")
best_mask = scheduler.refine_and_select(candidates, target=target_mask)

GPU Full-Chip Tiling (O8.3)

TileParallelProcessor enables GPU batch-parallel Schwarz tiling for full-chip ILT. SchwarzTilingSolver runs iterative Schwarz convergence with all tiles processed simultaneously on GPU, achieving near-linear scaling for large layouts:

from openlithohub._utils.tiling_gpu import TileParallelProcessor, SchwarzTilingSolver

processor = TileParallelProcessor(tile_size=512, overlap=64, device="cuda")
solver = SchwarzTilingSolver(max_iter=10, tol=1e-4)

result = solver.solve(mask, processor=processor)
# All tiles batched on GPU, overlap exchange at each Schwarz iteration

Physical Resist Model (O8.4)

PhysicalResistModel implements a differentiable CAR (chemically amplified resist) pipeline: acid generation from aerial image exposure, Gaussian acid diffusion during PEB, quencher kinetics, and sigmoid development. GradientFidelityGate verifies that the differentiable surrogate stays faithful to a high-fidelity resist simulation:

from openlithohub._utils.resist_physical import PhysicalResistModel, GradientFidelityGate

resist = PhysicalResistModel(
    acid_generation_rate=0.8,
    diffusion_length_nm=20.0,
    quencher_concentration=0.3,
    development_contrast=10.0,
)
resist_contour = resist(aerial_image)

# Verify surrogate fidelity
gate = GradientFidelityGate(atol=1e-3, rtol=1e-2)
fidelity_report = gate.check(resist, high_fidelity_resist, sample_input)

GRPO Generative Warm Start (O9.1)

GRPOWarmStart applies Group Relative Policy Optimization (GRPO) fine-tuning on the CVAE posterior, producing higher-quality and more diverse warm-start candidates than the V8 posterior sampler. StyleConditioning injects layer-purpose awareness (metal, via, cut) into the VAE encoder via LayerPurpose embeddings, so the generative model adapts its initialization strategy per mask layer:

from openlithohub.models.grpo_warm_start import GRPOWarmStart, GRPOConfig, StyleConditioning
from openlithohub._constants import LayerPurpose

config = GRPOConfig(
    latent_dim=64,
    grpo_steps=50,
    group_size=8,
    clip_ratio=0.2,
    style_conditioning=StyleConditioning(layer_purpose=LayerPurpose.METAL),
)
warm_start = GRPOWarmStart(config)
candidates = warm_start.sample(target_mask, n=8)

Reference: arXiv:2602.19027 (clean-room implementation).

Stochastic ILT Coverage Gate (O9.3)

StochasticAcceptanceGate replaces the deterministic pass/fail MRC check with a conformal-calibrated stochastic process window. StochasticSampler draws photon-noise and dose/focus perturbation samples; ThroughFocusCoverageCalibrator fits a conformal prediction band so the acceptance probability is statistically calibrated. ProcessWindowPlotter produces through-focus coverage visualizations:

from openlithohub.benchmark.metrics.coverage_gate import (
    StochasticSampler,
    ThroughFocusCoverageCalibrator,
    StochasticAcceptanceGate,
    ProcessWindowPlotter,
)

sampler = StochasticSampler(n_samples=512, dose_sigma=0.02, focus_range_nm=40.0)
calibrator = ThroughFocusCoverageCalibrator(alpha=0.05)  # 95% conformal band
gate = StochasticAcceptanceGate(sampler=sampler, calibrator=calibrator)

result = gate.evaluate(predicted_mask, target_mask)
print(f"Coverage probability: {result.coverage_prob:.3f}, Accepted: {result.accepted}")

ProcessWindowPlotter().plot(result, save_path="process_window.pdf")

Reference: arXiv:2402.01960.

GPU Tile-Batch Benchmark (O9.2)

GPUTileBatchProcessor wraps GPU batch-parallel Schwarz tiling in a reproducible benchmark harness. ICCAD13Benchmark provides the ICCAD'13 contest end-to-end pipeline (10 clips, gauges, scoring). TilingResidualRegression fits a lightweight regression model that predicts tiling residual from tile geometry, enabling adaptive overlap selection:

from openlithohub.workflow.gpu_tiling_benchmark import (
    GPUTileBatchProcessor,
    ICCAD13Benchmark,
    TilingResidualRegression,
)

processor = GPUTileBatchProcessor(tile_size=1024, overlap=128, device="cuda")
benchmark = ICCAD13Benchmark(processor=processor, data_root="data/iccad13")
results = benchmark.run(model="levelset-ilt")
print(f"Median L2: {results['l2_median_nm2']:.0f} nm2, TAT: {results['tat_s']:.1f} s")

regression = TilingResidualRegression()
regression.fit(tile geometries, measured_residuals)
predicted_residual = regression.predict(new_tile_geometry)

References: arXiv:2411.07311, Light: Sci. Appl. 2025-07.

Flagship Evidence Status

Claim Code Tests Data Status
Schwarz domain decomposition tiling (schwarz_tiled_ilt) openlithohub/workflow/tiling.py tests/test_workflow/test_schwarz_born.py (5 tests) Internal Verified
Born scattering forward correction (simulate_aerial_image_born) openlithohub/_utils/forward_model.py tests/test_workflow/test_schwarz_born.py (4 tests) Internal Verified
Hopkins SOCS forward model openlithohub/_utils/hopkins.py tests/test_utils/test_hopkins.py docs/benchmarks.md (measured timing) Verified
EPE / PV Band / MRC / DRC metrics openlithohub/benchmark/metrics/ tests/test_benchmark/test_metrics.py Baseline tables in README Verified
LevelSet-ILT model openlithohub/models/levelset_ilt.py tests/test_models/test_levelset_ilt.py Synthetic-8 and ICCAD16 tables Verified
GAN-OPC model (GanOpcModel) openlithohub/models/gan_opc.py tests/test_models/test_gan_opc.py ICCAD16 table Aspirational — generator-only, no GAN discriminator, predictions near-random without pretrained weights
Neural-ILT model (NeuralILTModel) openlithohub/models/neural_ilt.py tests/test_models/test_neural_ilt.py ICCAD16 table Aspirational — NOT paper-faithful re-implementation of Jiang2020; differentiable ILT correction layer unimplemented; degenerate on out-of-distribution inputs
Layout-MAE (LayoutMAE) openlithohub/models/layout_mae.py tests/test_models/test_layout_mae.py N/A Aspirational — ViT-S MAE prototype with no pretrained weights, no fine-tune adapter, no Hub release
Stochastic-aware ILT (O8.1) openlithohub/_utils/stochastic_ilt.py tests/test_utils/test_stochastic_ilt.py Internal Verified
Posterior warm-start (O8.2) openlithohub/_utils/posterior_warm_start.py tests/test_utils/test_posterior_warm_start.py Internal Verified
GPU full-chip tiling (O8.3) openlithohub/_utils/tiling_gpu.py tests/test_utils/test_tiling_gpu.py Internal Verified
Physical resist model (O8.4) openlithohub/_utils/resist_physical.py tests/test_utils/test_resist_physical.py Internal Verified
GRPO generative warm start (O9.1) openlithohub/models/grpo_warm_start.py tests/test_models/test_grpo_warm_start.py Internal Verified
GPU tile-batch benchmark (O9.2) openlithohub/workflow/gpu_tiling_benchmark.py tests/test_workflow/test_gpu_tiling_benchmark.py Internal Verified
Stochastic ILT coverage gate (O9.3) openlithohub/benchmark/metrics/coverage_gate.py tests/test_benchmark/test_coverage_gate.py Internal Verified

Compatibility

Dependency Version
Python 3.10+ (< 3.13)
PyTorch 2.12+

Sister projects: DiffCFD (differentiable CFD, optional plugin), DiffNano (nanophotonics, optional plugin), diff-surrogate (shared surrogate framework).

Commercial simulator adapters

OpenLithoHub ships adapters for Calibre nmOPC and ASML Brion Tachyon. Both fall back to a deterministic mock when the commercial toolchain is not installed, so tests pass on any machine:

from openlithohub.simulators import CalibreSimulator, TachyonSimulator
from openlithohub.simulators import SimulatorConfig

# Calibre nmOPC (requires calibre on PATH; mock_mode=True otherwise)
calibre = CalibreSimulator(SimulatorConfig(pixel_size_nm=4.0, mock_mode=True))
result = calibre.simulate(mask_tensor)

# ASML Brion Tachyon (requires TACHYON_HOME; mock_mode=True otherwise)
tachyon = TachyonSimulator(SimulatorConfig(pixel_size_nm=4.0, mock_mode=True))
result = tachyon.simulate(mask_tensor)

Development

# Run tests
pytest tests/ -v

# Lint
ruff check src/ tests/

# Type check
mypy src/

# Format
ruff format src/ tests/

# Check plugin infrastructure health
make check-plugins

Multi-worker batch inference

For production-scale scoring, multiproc_predict distributes tiles across worker processes with shared model weights via SharedMemory:

from openlithohub.inference import multiproc_predict
from openlithohub.models import get_model

model = get_model("neural-ilt")
tiles = [mask_tile_1, mask_tile_2, mask_tile_3, mask_tile_4]

results = multiproc_predict(model, tiles, n_workers=2)

Roadmap

  • Milestone 1: Unified data adapters, EPE metric, eval CLI
  • Milestone 2: MRC compliance, Manhattan contour extraction, tiling, shot count
  • Milestone 3: OASIS workflow, PV Band, stochastic robustness, DRC, B-spline fitting, optimize CLI
  • Milestone 4: Public leaderboard, MkDocs documentation site, CI/CD for docs
  • Milestone 5: Web playground (HuggingFace Spaces)
  • Milestone 6: Real ILT models (LevelSet-ILT, Neural-ILT U-Net), DTCO process nodes, resist simulation, model hub, Jupyter integration, PyPI/Docker CI/CD
  • Milestone 7: Paper-ready visualization, dummy layout generator, EDA bridge templates, Colab quickstart
  • Milestone 8: Multi-stage KLayout Docker, AI-engineer terminology guide, Auto-Leaderboard CI, community charter (Discord), v0.1 launch announcement
  • Milestone 9: PDK-aware synthetic layout generator, vendor-neutral simulator hook API, EUV 3D-mask shadow proxy, Monte Carlo failure metric, Mini-Hackathon (2026-Q3), RFC 0001 (Layout-MAE) + RFC 0002 (Layout Tokens)
  • Milestone 10: Real PDK rollout — ASAP7 standard cells, FreePDK45 + NanGate OCL, ORFS-routed RISC-V mock-alu (issue #4)
  • Milestone 11: Standard MRC rule-deck schema (RFC 0003), measured-source / Zernike-pupil I/O, Calibre/CSV gauge parser, openlithohub export CLI (ONNX / TorchScript / TensorRT-ready), --compile on by default, first PyPI release (openlithohub-0.1.0a2)
  • Milestone 12: Opt-in diffusion resist (--resist-diffusion-nm), openlithohub flow run closed-loop CLI (design→litho→DFM), configurable per-PDK layer maps, optional DiffNano/DiffCFD plugin ecosystem
  • Milestone 13: Thick mask forward model (O7.1), differentiable morphological operators (O7.2), warm-start ILT interface (O7.3), tiling residual quantification (O7.4)
  • Milestone 14: Stochastic-aware ILT (O8.1), posterior warm-start with conditional VAE (O8.2), GPU batch-parallel Schwarz tiling (O8.3), physical resist model with gradient fidelity gate (O8.4)
  • Milestone 15: GRPO generative warm start with style-aware conditioning (O9.1), GPU tile-batch benchmark with ICCAD13 pipeline (O9.2), stochastic ILT coverage gate with conformal calibration (O9.3)

Note: Milestones above reflect feature integration completeness (adapters, CLI commands, CI pipelines), not industrial validation. The alpha version (0.1.0a2) runs on synthetic layouts — real industrial-scale benchmarking is planned for the v1.0 milestone.


Competitive Positioning

What it is: An open-source computational lithography benchmarking and workflow toolkit — ILT, OPC, mask optimization, and process window analysis with honest self-measurement.

Where it leads:

  • Open ILT benchmark with honest baselines: The only open-source project providing standardized ILT benchmarks with SARIF export, morphological MRC, tile-consistency metrics, and stochastic-aware loss. Commercial tools (Calibre MML, cuLitho) are closed-source with no public benchmarks.
  • Variation-aware ILT: CVaR and quantile risk measures integrated directly into ILT loss — stochastic-aware optimization that goes beyond deterministic nominal-point optimization.
  • Full-chip tiling with Schwarz decomposition: GPU batch-parallel Schwarz tiling for full-chip ILT with tile-consistency residual quantification.
  • Physical resist model: Acid generation → diffusion → quencher neutralization → sigmoid development — fully differentiable for end-to-end mask-to-resist optimization.

Where it lags (honest assessment):

  • Scale: Benchmark subsets, tile-level, GPU stitching. Orders of magnitude behind Calibre MML and cuLitho (full-chip, GPU production-grade).
  • Validation: Self-tests + numerical cross-validation against LithoBench/ICCAD13 references. No fab validation, no production tapeout.
  • Maturity: Research prototype. No foundry integration, no PDK sign-off flow.

Bottom line: Uniquely positioned as the honest open-source lithography benchmark — what it lacks in scale it compensates with transparency, reproducibility, and methodological currency (2024-2026 stochastic ILT, conformal UQ, physical resist). Not a replacement for production OPC tools, but a research and benchmarking platform they don't provide.


Related Projects

Project Venue Role in Ecosystem
LithoSim NeurIPS'25 Sub-28nm industrial dataset
LithoBench NeurIPS'23 45nm evaluation framework
TorchLitho 2.0 ASICON'25 Differentiable lithography simulator
curvyILT NVIDIA arXiv'24 GPU-accelerated curvilinear ILT
EasyMRC TODAES'25 MRC reference implementation
ILT challenges survey Light: Sci. Appl. 2025 Comprehensive survey of ILT challenges and solutions
B-spline + Delaunay curvilinear mask arXiv:2504.11962, 2025 Curvilinear mask optimization via B-spline and Delaunay triangulation
Full-chip EUV curvilinear mask optimization Light: Advanced Manufacturing, 2026, doi:10.37188/lam.2026.049 Full-chip EUV curvilinear mask optimization
Schwarz Neural Inference arXiv:2504.00510 v2, 2026-02 Local→global domain decomposition operator learning — applicable to ILT solver acceleration
ML4PS optical diffraction convolution NeurIPS 2025 ML for physical simulation: optical diffraction convolution
DiffNano Optional plugin: PyTorch-native nanophotonics (RCWA / FDTD / FDFD + calibratable resist). Early-stage research, no third-party validation.
DiffCFD Optional plugin: PyTorch-native steady-state CFD for lithography (Dill/Mack solver, spin-coating solver, joint process optimization). Early-stage research, no third-party validation.

Contributing

See CONTRIBUTING.md for guidelines.


Community

Status

A Discord server for OpenLithoHub is launching 2026-Q3 — channels for model discussion, physics simulation, help, and showcase. The place to debate model design, reproducibility, and benchmarks.

Want to be notified when the invite goes live? Open an issue with the community label or watch this repo. Charter, channel structure, etiquette, and onboarding flow are documented in docs/community.md.

📣 Read the launch announcement: v0.1 release post — includes paste-ready copy for X / LinkedIn / 知乎 / HuggingFace Forum.

🏆 Mini-hackathon launching 2026-Q3charter & rules. EPE target, frozen test split, hard MRC/DRC gate, separate leaderboard track.


Disclaimer

OpenLithoHub is a purely academic, open-source project for fundamental research in computational physics and machine learning. It relies solely on publicly available datasets and published algorithms. It does not contain, nor does it seek to reverse-engineer, any proprietary commercial EDA tools or export-controlled manufacturing processes.

Plugin validation: DiffNano and DiffCFD are optional plugins that self-describe as early-stage personal research projects with no external users and no third-party validation. Do not rely on them for production decisions.

Leaderboard comparability: The scored default is CTR (constant-threshold resist) without diffusion, at threshold 0.225. Enabling acid diffusion (--resist-diffusion-nm > 0) or switching to a plugin EM/resist backend produces non-comparable metric values and is disabled for leaderboard submission.

License

OpenLithoHub uses a layered licensing model:

You may freely use OpenLithoHub commercially under the open-source license (attribution and the NOTICE file are the only requirements). For commercial licensing options without attribution or with SLA-backed support, see COMMERCIAL-USE.md.

To cite OpenLithoHub in academic work, see CITATION.cff. Contributors: please review CONTRIBUTING.md and the Contributor License Agreement. Security issues: SECURITY.md.

About

Open-source computational lithography workflow, manufacturability benchmarking, and foundation model data engine for advanced EUV/curvilinear mask processes

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages