iclayout-bench 0.4.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. iclayout_bench-0.4.0a1/.dockerignore +8 -0
  2. iclayout_bench-0.4.0a1/.gitattributes +2 -0
  3. iclayout_bench-0.4.0a1/.github/workflows/cd.yml +134 -0
  4. iclayout_bench-0.4.0a1/.github/workflows/checks.yml +98 -0
  5. iclayout_bench-0.4.0a1/.github/workflows/eda.yml +39 -0
  6. iclayout_bench-0.4.0a1/.github/workflows/image.yml +77 -0
  7. iclayout_bench-0.4.0a1/.github/workflows/pages.yml +58 -0
  8. iclayout_bench-0.4.0a1/.gitignore +23 -0
  9. iclayout_bench-0.4.0a1/AGENTS.md +56 -0
  10. iclayout_bench-0.4.0a1/CONTRIBUTING.md +299 -0
  11. iclayout_bench-0.4.0a1/Dockerfile +131 -0
  12. iclayout_bench-0.4.0a1/Dockerfile.dev +11 -0
  13. iclayout_bench-0.4.0a1/LICENSE +21 -0
  14. iclayout_bench-0.4.0a1/MANIFEST.in +1 -0
  15. iclayout_bench-0.4.0a1/PKG-INFO +100 -0
  16. iclayout_bench-0.4.0a1/README.md +81 -0
  17. iclayout_bench-0.4.0a1/README_CN.md +25 -0
  18. iclayout_bench-0.4.0a1/benchmarking/__init__.py +1 -0
  19. iclayout_bench-0.4.0a1/benchmarking/_build.json +1 -0
  20. iclayout_bench-0.4.0a1/benchmarking/analysis.py +185 -0
  21. iclayout_bench-0.4.0a1/benchmarking/analyze.py +29 -0
  22. iclayout_bench-0.4.0a1/benchmarking/bundles.py +89 -0
  23. iclayout_bench-0.4.0a1/benchmarking/client.py +289 -0
  24. iclayout_bench-0.4.0a1/benchmarking/dataset.py +136 -0
  25. iclayout_bench-0.4.0a1/benchmarking/dataset_index.py +133 -0
  26. iclayout_bench-0.4.0a1/benchmarking/engine/__init__.py +1 -0
  27. iclayout_bench-0.4.0a1/benchmarking/engine/benchmark_feedback.py +60 -0
  28. iclayout_bench-0.4.0a1/benchmarking/engine/cli.py +129 -0
  29. iclayout_bench-0.4.0a1/benchmarking/engine/docker.py +122 -0
  30. iclayout_bench-0.4.0a1/benchmarking/engine/environment.py +42 -0
  31. iclayout_bench-0.4.0a1/benchmarking/engine/evaluate.py +267 -0
  32. iclayout_bench-0.4.0a1/benchmarking/engine/execution.py +183 -0
  33. iclayout_bench-0.4.0a1/benchmarking/engine/geometry.py +123 -0
  34. iclayout_bench-0.4.0a1/benchmarking/engine/geometry_runner.py +115 -0
  35. iclayout_bench-0.4.0a1/benchmarking/engine/hbt.py +1718 -0
  36. iclayout_bench-0.4.0a1/benchmarking/engine/hbt_runner.py +63 -0
  37. iclayout_bench-0.4.0a1/benchmarking/engine/identity.py +19 -0
  38. iclayout_bench-0.4.0a1/benchmarking/engine/inference.py +675 -0
  39. iclayout_bench-0.4.0a1/benchmarking/engine/klayout.py +195 -0
  40. iclayout_bench-0.4.0a1/benchmarking/engine/klayout_runner.py +265 -0
  41. iclayout_bench-0.4.0a1/benchmarking/engine/kpex.py +93 -0
  42. iclayout_bench-0.4.0a1/benchmarking/engine/kpex_runner.py +150 -0
  43. iclayout_bench-0.4.0a1/benchmarking/engine/layout_image.py +42 -0
  44. iclayout_bench-0.4.0a1/benchmarking/engine/magic.py +204 -0
  45. iclayout_bench-0.4.0a1/benchmarking/engine/magic_netlist.py +80 -0
  46. iclayout_bench-0.4.0a1/benchmarking/engine/magic_ports.py +50 -0
  47. iclayout_bench-0.4.0a1/benchmarking/engine/messages.py +155 -0
  48. iclayout_bench-0.4.0a1/benchmarking/engine/model_config.py +77 -0
  49. iclayout_bench-0.4.0a1/benchmarking/engine/ngspice.py +159 -0
  50. iclayout_bench-0.4.0a1/benchmarking/engine/pdk_installation.py +68 -0
  51. iclayout_bench-0.4.0a1/benchmarking/engine/pdk_probe.py +42 -0
  52. iclayout_bench-0.4.0a1/benchmarking/engine/pdk_resources.py +151 -0
  53. iclayout_bench-0.4.0a1/benchmarking/engine/preparation.py +48 -0
  54. iclayout_bench-0.4.0a1/benchmarking/engine/prepare_support.py +111 -0
  55. iclayout_bench-0.4.0a1/benchmarking/engine/preview.py +284 -0
  56. iclayout_bench-0.4.0a1/benchmarking/engine/process_check.py +12 -0
  57. iclayout_bench-0.4.0a1/benchmarking/engine/qualification.py +285 -0
  58. iclayout_bench-0.4.0a1/benchmarking/engine/recorder.py +187 -0
  59. iclayout_bench-0.4.0a1/benchmarking/engine/recording.py +20 -0
  60. iclayout_bench-0.4.0a1/benchmarking/engine/resource_cache.py +34 -0
  61. iclayout_bench-0.4.0a1/benchmarking/engine/runtime.py +61 -0
  62. iclayout_bench-0.4.0a1/benchmarking/engine/session.py +611 -0
  63. iclayout_bench-0.4.0a1/benchmarking/engine/snapshot.py +41 -0
  64. iclayout_bench-0.4.0a1/benchmarking/engine/source.py +29 -0
  65. iclayout_bench-0.4.0a1/benchmarking/engine/submit.py +12 -0
  66. iclayout_bench-0.4.0a1/benchmarking/engine/toolchains.py +88 -0
  67. iclayout_bench-0.4.0a1/benchmarking/engine/workspace.py +101 -0
  68. iclayout_bench-0.4.0a1/benchmarking/evaluation.py +421 -0
  69. iclayout_bench-0.4.0a1/benchmarking/files.py +126 -0
  70. iclayout_bench-0.4.0a1/benchmarking/harnesses.py +89 -0
  71. iclayout_bench-0.4.0a1/benchmarking/layout_preview.py +104 -0
  72. iclayout_bench-0.4.0a1/benchmarking/model_configs.yaml +2 -0
  73. iclayout_bench-0.4.0a1/benchmarking/observe.py +72 -0
  74. iclayout_bench-0.4.0a1/benchmarking/participants/__init__.py +1 -0
  75. iclayout_bench-0.4.0a1/benchmarking/participants/archive.py +57 -0
  76. iclayout_bench-0.4.0a1/benchmarking/participants/bridge.py +176 -0
  77. iclayout_bench-0.4.0a1/benchmarking/participants/config.py +202 -0
  78. iclayout_bench-0.4.0a1/benchmarking/participants/dsh.py +102 -0
  79. iclayout_bench-0.4.0a1/benchmarking/participants/process.py +31 -0
  80. iclayout_bench-0.4.0a1/benchmarking/participants/recovery.py +106 -0
  81. iclayout_bench-0.4.0a1/benchmarking/participants/results.py +285 -0
  82. iclayout_bench-0.4.0a1/benchmarking/participants/runner.py +402 -0
  83. iclayout_bench-0.4.0a1/benchmarking/participants/scheme.py +85 -0
  84. iclayout_bench-0.4.0a1/benchmarking/participants/storage.py +20 -0
  85. iclayout_bench-0.4.0a1/benchmarking/plotting.py +149 -0
  86. iclayout_bench-0.4.0a1/benchmarking/protocol.py +42 -0
  87. iclayout_bench-0.4.0a1/benchmarking/results/__init__.py +5 -0
  88. iclayout_bench-0.4.0a1/benchmarking/results/__main__.py +81 -0
  89. iclayout_bench-0.4.0a1/benchmarking/results/geometry.py +142 -0
  90. iclayout_bench-0.4.0a1/benchmarking/results/presentation.py +333 -0
  91. iclayout_bench-0.4.0a1/benchmarking/results/schema.py +105 -0
  92. iclayout_bench-0.4.0a1/benchmarking/results/store.py +788 -0
  93. iclayout_bench-0.4.0a1/benchmarking/run.py +348 -0
  94. iclayout_bench-0.4.0a1/benchmarking/scoring.py +201 -0
  95. iclayout_bench-0.4.0a1/benchmarking/service/__init__.py +1 -0
  96. iclayout_bench-0.4.0a1/benchmarking/service/__main__.py +45 -0
  97. iclayout_bench-0.4.0a1/benchmarking/service/server.py +545 -0
  98. iclayout_bench-0.4.0a1/benchmarking/tasks.py +307 -0
  99. iclayout_bench-0.4.0a1/benchmarking/transfer.py +256 -0
  100. iclayout_bench-0.4.0a1/benchmarking/version.py +17 -0
  101. iclayout_bench-0.4.0a1/docs/architecture.md +497 -0
  102. iclayout_bench-0.4.0a1/docs/running.md +968 -0
  103. iclayout_bench-0.4.0a1/docs/tasks.md +373 -0
  104. iclayout_bench-0.4.0a1/docs/tools.md +653 -0
  105. iclayout_bench-0.4.0a1/iclayout_bench.egg-info/PKG-INFO +100 -0
  106. iclayout_bench-0.4.0a1/iclayout_bench.egg-info/SOURCES.txt +203 -0
  107. iclayout_bench-0.4.0a1/iclayout_bench.egg-info/dependency_links.txt +1 -0
  108. iclayout_bench-0.4.0a1/iclayout_bench.egg-info/requires.txt +11 -0
  109. iclayout_bench-0.4.0a1/iclayout_bench.egg-info/scm_file_list.json +206 -0
  110. iclayout_bench-0.4.0a1/iclayout_bench.egg-info/scm_version.json +8 -0
  111. iclayout_bench-0.4.0a1/iclayout_bench.egg-info/top_level.txt +1 -0
  112. iclayout_bench-0.4.0a1/pyproject.toml +51 -0
  113. iclayout_bench-0.4.0a1/pytest.ini +11 -0
  114. iclayout_bench-0.4.0a1/scripts/build_magic.sh +16 -0
  115. iclayout_bench-0.4.0a1/scripts/build_ngspice.sh +16 -0
  116. iclayout_bench-0.4.0a1/scripts/check_docs.py +59 -0
  117. iclayout_bench-0.4.0a1/scripts/check_repository.py +56 -0
  118. iclayout_bench-0.4.0a1/scripts/patches/magic-stable-device-order.patch +286 -0
  119. iclayout_bench-0.4.0a1/setup.cfg +4 -0
  120. iclayout_bench-0.4.0a1/setup.py +33 -0
  121. iclayout_bench-0.4.0a1/tests/AGENTS.md +80 -0
  122. iclayout_bench-0.4.0a1/tests/fixtures/characterization/divider.spice +5 -0
  123. iclayout_bench-0.4.0a1/tests/fixtures/characterization/divider.toml +28 -0
  124. iclayout_bench-0.4.0a1/tests/fixtures/characterization/divider_dc.spice +12 -0
  125. iclayout_bench-0.4.0a1/tests/fixtures/characterization/rc.spice +5 -0
  126. iclayout_bench-0.4.0a1/tests/fixtures/characterization/rc.toml +58 -0
  127. iclayout_bench-0.4.0a1/tests/fixtures/characterization/rc_ac.spice +12 -0
  128. iclayout_bench-0.4.0a1/tests/fixtures/characterization/rc_transient.spice +12 -0
  129. iclayout_bench-0.4.0a1/tests/fixtures/characterization/toolchain.toml +8 -0
  130. iclayout_bench-0.4.0a1/tests/fixtures/gf180-isolated-body/README.md +23 -0
  131. iclayout_bench-0.4.0a1/tests/fixtures/gf180-isolated-body/deep-well.gds +0 -0
  132. iclayout_bench-0.4.0a1/tests/fixtures/gf180-isolated-body/nwell-ring.gds +0 -0
  133. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/generate.py +54 -0
  134. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/make_plate.py +31 -0
  135. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/make_series_switch.py +40 -0
  136. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/make_switch.py +46 -0
  137. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/mos.toml +35 -0
  138. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/mos_dc.spice +13 -0
  139. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/plate.toml +24 -0
  140. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/plate_ac.spice +11 -0
  141. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/switch.toml +25 -0
  142. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/switch_transient.spice +14 -0
  143. iclayout_bench-0.4.0a1/tests/fixtures/sg13g2/toolchain.toml +22 -0
  144. iclayout_bench-0.4.0a1/tests/helpers/__init__.py +0 -0
  145. iclayout_bench-0.4.0a1/tests/helpers/case_config.py +32 -0
  146. iclayout_bench-0.4.0a1/tests/helpers/catalog.py +12 -0
  147. iclayout_bench-0.4.0a1/tests/helpers/protocol.py +89 -0
  148. iclayout_bench-0.4.0a1/tests/helpers/scoring.py +62 -0
  149. iclayout_bench-0.4.0a1/tests/helpers/service.py +131 -0
  150. iclayout_bench-0.4.0a1/tests/helpers/spice_raw.py +21 -0
  151. iclayout_bench-0.4.0a1/tests/helpers/stimuli.py +57 -0
  152. iclayout_bench-0.4.0a1/tests/integration/test_build_context.sh +44 -0
  153. iclayout_bench-0.4.0a1/tests/integration/test_characterization.py +191 -0
  154. iclayout_bench-0.4.0a1/tests/integration/test_comparator.py +533 -0
  155. iclayout_bench-0.4.0a1/tests/integration/test_full_ota.py +436 -0
  156. iclayout_bench-0.4.0a1/tests/integration/test_inference_https.py +140 -0
  157. iclayout_bench-0.4.0a1/tests/integration/test_input_pair_netlists.py +77 -0
  158. iclayout_bench-0.4.0a1/tests/integration/test_input_pair_postlayout.py +379 -0
  159. iclayout_bench-0.4.0a1/tests/integration/test_lna160_postlayout.py +326 -0
  160. iclayout_bench-0.4.0a1/tests/integration/test_magic_rc.py +255 -0
  161. iclayout_bench-0.4.0a1/tests/integration/test_maintained_netlists.py +84 -0
  162. iclayout_bench-0.4.0a1/tests/integration/test_output_stage_postlayout.py +373 -0
  163. iclayout_bench-0.4.0a1/tests/integration/test_pdk_view.sh +34 -0
  164. iclayout_bench-0.4.0a1/tests/integration/test_public_references.py +96 -0
  165. iclayout_bench-0.4.0a1/tests/integration/test_session.py +475 -0
  166. iclayout_bench-0.4.0a1/tests/integration/test_sg13g2.py +127 -0
  167. iclayout_bench-0.4.0a1/tests/integration/test_sg13g2_model_calls.py +91 -0
  168. iclayout_bench-0.4.0a1/tests/integration/test_tia130_postlayout.py +247 -0
  169. iclayout_bench-0.4.0a1/tests/integration/test_tia97_postlayout.py +408 -0
  170. iclayout_bench-0.4.0a1/tests/integration/test_to_apr2025_40ghz.py +460 -0
  171. iclayout_bench-0.4.0a1/tests/integration/test_to_apr2025_schematic.py +194 -0
  172. iclayout_bench-0.4.0a1/tests/integration/test_toolchain.sh +37 -0
  173. iclayout_bench-0.4.0a1/tests/test_http.py +321 -0
  174. iclayout_bench-0.4.0a1/tests/unit/.gitkeep +0 -0
  175. iclayout_bench-0.4.0a1/tests/unit/conftest.py +64 -0
  176. iclayout_bench-0.4.0a1/tests/unit/test_bundles.py +176 -0
  177. iclayout_bench-0.4.0a1/tests/unit/test_catalogs.py +299 -0
  178. iclayout_bench-0.4.0a1/tests/unit/test_client.py +129 -0
  179. iclayout_bench-0.4.0a1/tests/unit/test_comparator_contract.py +23 -0
  180. iclayout_bench-0.4.0a1/tests/unit/test_documentation.py +64 -0
  181. iclayout_bench-0.4.0a1/tests/unit/test_environment.py +86 -0
  182. iclayout_bench-0.4.0a1/tests/unit/test_evaluate.py +436 -0
  183. iclayout_bench-0.4.0a1/tests/unit/test_geometry.py +34 -0
  184. iclayout_bench-0.4.0a1/tests/unit/test_hbt_extraction.py +593 -0
  185. iclayout_bench-0.4.0a1/tests/unit/test_hbt_tap_scope.py +55 -0
  186. iclayout_bench-0.4.0a1/tests/unit/test_inference.py +336 -0
  187. iclayout_bench-0.4.0a1/tests/unit/test_klayout.py +68 -0
  188. iclayout_bench-0.4.0a1/tests/unit/test_layout_preview.py +234 -0
  189. iclayout_bench-0.4.0a1/tests/unit/test_magic_configuration.py +51 -0
  190. iclayout_bench-0.4.0a1/tests/unit/test_main.py +81 -0
  191. iclayout_bench-0.4.0a1/tests/unit/test_model_config.py +118 -0
  192. iclayout_bench-0.4.0a1/tests/unit/test_participant_config.py +321 -0
  193. iclayout_bench-0.4.0a1/tests/unit/test_participant_dsh.py +51 -0
  194. iclayout_bench-0.4.0a1/tests/unit/test_participant_runner.py +873 -0
  195. iclayout_bench-0.4.0a1/tests/unit/test_public_preview.py +177 -0
  196. iclayout_bench-0.4.0a1/tests/unit/test_qualification.py +72 -0
  197. iclayout_bench-0.4.0a1/tests/unit/test_recorder.py +135 -0
  198. iclayout_bench-0.4.0a1/tests/unit/test_results_archive.py +522 -0
  199. iclayout_bench-0.4.0a1/tests/unit/test_scoring.py +279 -0
  200. iclayout_bench-0.4.0a1/tests/unit/test_service_analysis.py +97 -0
  201. iclayout_bench-0.4.0a1/tests/unit/test_session_resources.py +96 -0
  202. iclayout_bench-0.4.0a1/tests/unit/test_submission.py +69 -0
  203. iclayout_bench-0.4.0a1/tests/unit/test_task_sources.py +77 -0
  204. iclayout_bench-0.4.0a1/tests/unit/test_tasks.py +326 -0
  205. iclayout_bench-0.4.0a1/tests/unit/test_toolchains.py +102 -0
  206. iclayout_bench-0.4.0a1/uv.lock +3701 -0
@@ -0,0 +1,8 @@
1
+ **
2
+ !pyproject.toml
3
+ !uv.lock
4
+ !scripts/
5
+ !scripts/build_ngspice.sh
6
+ !scripts/build_magic.sh
7
+ !scripts/patches/
8
+ !scripts/patches/magic-stable-device-order.patch
@@ -0,0 +1,2 @@
1
+ # Unified patches retain upstream context prefixes and tab indentation.
2
+ scripts/patches/*.patch whitespace=-blank-at-eol,-space-before-tab
@@ -0,0 +1,134 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*.*.*'
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: release-${{ github.ref }}
11
+ cancel-in-progress: false
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ package:
18
+ name: Build Python distributions
19
+ runs-on: ubuntu-24.04
20
+ timeout-minutes: 15
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+ with:
24
+ persist-credentials: false
25
+ fetch-depth: 0
26
+ - uses: astral-sh/setup-uv@v7
27
+ with:
28
+ version: '0.11.2'
29
+ python-version: '3.12'
30
+ enable-cache: true
31
+ - run: uv sync --locked --extra results
32
+ - run: uv run --locked ruff check .
33
+ - run: uv run --locked python scripts/check_docs.py
34
+ - run: uv run --locked python scripts/check_repository.py
35
+ - run: uv run --locked pytest -m unit
36
+ - name: Check release tag
37
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
38
+ run: |
39
+ version="$(uv run --locked python -c 'from importlib.metadata import version; print(version("iclayout-bench"))')"
40
+ test "$GITHUB_REF_NAME" = "v${version}" || {
41
+ echo "Tag $GITHUB_REF_NAME does not match project version $version" >&2
42
+ exit 1
43
+ }
44
+ - name: Build distributions
45
+ run: uv build --out-dir build/dist
46
+ - name: Install wheel smoke test
47
+ run: |
48
+ package_venv="$RUNNER_TEMP/iclayout-bench-package"
49
+ python -m venv "$package_venv"
50
+ for bench_wheel in build/dist/*.whl; do
51
+ "$package_venv/bin/python" -m pip install "${bench_wheel}[results]"
52
+ done
53
+ "$package_venv/bin/python" -I - <<'PY'
54
+ import importlib.util
55
+ import subprocess
56
+ import sys
57
+ from importlib.resources import files
58
+ from pathlib import Path
59
+
60
+ for name in ("benchmarking", "benchmarking.engine", "benchmarking.service", "benchmarking.participants"):
61
+ module = importlib.import_module(name)
62
+ assert Path(module.__file__).resolve().is_relative_to(Path(sys.prefix).resolve())
63
+ assert importlib.util.find_spec("iclayout_bench_private") is None
64
+ assert files("benchmarking").joinpath("model_configs.yaml").is_file()
65
+ from importlib.metadata import version
66
+ from benchmarking.version import package_version
67
+ identity = package_version()
68
+ assert identity["version"] == version("iclayout-bench")
69
+ assert identity["commit"] == subprocess.check_output(
70
+ ["git", "rev-parse", "HEAD"], text=True).strip()
71
+ assert importlib.util.find_spec("layout_eval") is None
72
+ assert importlib.util.find_spec("layout_service") is None
73
+ from benchmarking.dataset import Dataset, process_manifest
74
+ from benchmarking.engine.qualification import acceptance_summary
75
+ assert importlib.util.find_spec("benchmarking.web") is None
76
+ from benchmarking.engine.source import implementation_identity
77
+ assert implementation_identity().startswith("sha256:")
78
+ for name in ("benchmarking.client", "benchmarking.observe", "benchmarking.run", "benchmarking.engine.cli",
79
+ "benchmarking.engine.preview", "benchmarking.service", "benchmarking.results"):
80
+ subprocess.run([sys.executable, "-I", "-m", name, "--help"], check=True)
81
+ PY
82
+ - name: Upload distributions
83
+ uses: actions/upload-artifact@v4
84
+ with:
85
+ name: iclayout-bench-release-${{ github.sha }}
86
+ path: build/dist/*
87
+ if-no-files-found: error
88
+ retention-days: 14
89
+
90
+ pypi:
91
+ name: Publish Python distributions to PyPI
92
+ needs: package
93
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
94
+ runs-on: ubuntu-24.04
95
+ timeout-minutes: 15
96
+ environment:
97
+ name: pypi
98
+ url: https://pypi.org/project/iclayout-bench/
99
+ permissions:
100
+ id-token: write
101
+ steps:
102
+ - name: Download checked distributions
103
+ uses: actions/download-artifact@v4
104
+ with:
105
+ name: iclayout-bench-release-${{ github.sha }}
106
+ path: build/dist
107
+ - name: Publish with Trusted Publishing
108
+ uses: pypa/gh-action-pypi-publish@release/v1
109
+ with:
110
+ packages-dir: build/dist/
111
+ skip-existing: true
112
+
113
+ publish:
114
+ name: Publish GitHub release
115
+ needs: [package, pypi]
116
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
117
+ runs-on: ubuntu-24.04
118
+ timeout-minutes: 90
119
+ permissions:
120
+ contents: write
121
+ steps:
122
+ - uses: actions/checkout@v6
123
+ with:
124
+ persist-credentials: false
125
+ fetch-depth: 0
126
+ - name: Download distributions
127
+ uses: actions/download-artifact@v4
128
+ with:
129
+ name: iclayout-bench-release-${{ github.sha }}
130
+ path: build/dist
131
+ - name: Create GitHub release
132
+ env:
133
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
134
+ run: gh release create "$GITHUB_REF_NAME" build/dist/* --verify-tag --generate-notes
@@ -0,0 +1,98 @@
1
+ name: Framework checks
2
+ on:
3
+ push:
4
+ pull_request:
5
+ workflow_dispatch:
6
+
7
+ concurrency:
8
+ group: checks-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
9
+ cancel-in-progress: true
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ checks:
16
+ runs-on: ubuntu-24.04
17
+ timeout-minutes: 15
18
+ strategy:
19
+ matrix:
20
+ python: ['3.12', '3.13']
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+ with:
24
+ persist-credentials: false
25
+ fetch-depth: 0
26
+ - uses: astral-sh/setup-uv@v7
27
+ with:
28
+ version: '0.11.2'
29
+ python-version: ${{ matrix.python }}
30
+ enable-cache: true
31
+ - run: uv sync --locked --extra results --group analysis
32
+ - run: uv run --locked ruff check .
33
+ - run: uv run --locked python scripts/check_docs.py
34
+ - run: uv run --locked python scripts/check_repository.py
35
+ - run: uv run --locked --group analysis pytest -m unit
36
+ - run: git diff --exit-code
37
+
38
+ package:
39
+ name: Build package
40
+ needs: checks
41
+ runs-on: ubuntu-24.04
42
+ timeout-minutes: 15
43
+ steps:
44
+ - uses: actions/checkout@v6
45
+ with:
46
+ persist-credentials: false
47
+ fetch-depth: 0
48
+ - uses: astral-sh/setup-uv@v7
49
+ with:
50
+ version: '0.11.2'
51
+ python-version: '3.12'
52
+ enable-cache: true
53
+ - run: uv sync --locked --extra results
54
+ - name: Build distributions
55
+ run: uv build --out-dir build/dist
56
+ - name: Install wheel smoke test
57
+ run: |
58
+ package_venv="$RUNNER_TEMP/iclayout-bench-package"
59
+ python -m venv "$package_venv"
60
+ for bench_wheel in build/dist/*.whl; do
61
+ "$package_venv/bin/python" -m pip install "${bench_wheel}[results]"
62
+ done
63
+ "$package_venv/bin/python" -I - <<'PY'
64
+ import importlib.util
65
+ import subprocess
66
+ import sys
67
+ from importlib.resources import files
68
+ from pathlib import Path
69
+
70
+ for name in ("benchmarking", "benchmarking.engine", "benchmarking.service", "benchmarking.participants"):
71
+ module = importlib.import_module(name)
72
+ assert Path(module.__file__).resolve().is_relative_to(Path(sys.prefix).resolve())
73
+ assert importlib.util.find_spec("iclayout_bench_private") is None
74
+ assert files("benchmarking").joinpath("model_configs.yaml").is_file()
75
+ from importlib.metadata import version
76
+ from benchmarking.version import package_version
77
+ identity = package_version()
78
+ assert identity["version"] == version("iclayout-bench")
79
+ assert identity["commit"] == subprocess.check_output(
80
+ ["git", "rev-parse", "HEAD"], text=True).strip()
81
+ assert importlib.util.find_spec("layout_eval") is None
82
+ assert importlib.util.find_spec("layout_service") is None
83
+ from benchmarking.dataset import Dataset, process_manifest
84
+ from benchmarking.engine.qualification import acceptance_summary
85
+ assert importlib.util.find_spec("benchmarking.web") is None
86
+ from benchmarking.engine.source import implementation_identity
87
+ assert implementation_identity().startswith("sha256:")
88
+ for name in ("benchmarking.client", "benchmarking.observe", "benchmarking.run", "benchmarking.engine.cli",
89
+ "benchmarking.engine.preview", "benchmarking.service", "benchmarking.results"):
90
+ subprocess.run([sys.executable, "-I", "-m", name, "--help"], check=True)
91
+ PY
92
+ - name: Upload distributions
93
+ uses: actions/upload-artifact@v4
94
+ with:
95
+ name: iclayout-bench-distributions-${{ github.sha }}
96
+ path: build/dist/*
97
+ if-no-files-found: error
98
+ retention-days: 14
@@ -0,0 +1,39 @@
1
+ name: Public evaluator checks
2
+ on:
3
+ workflow_dispatch:
4
+ inputs:
5
+ dataset:
6
+ description: Hugging Face Dataset repository ID
7
+ required: true
8
+ type: string
9
+ revision:
10
+ description: Dataset Git commit
11
+ required: true
12
+ type: string
13
+ permissions:
14
+ contents: read
15
+ jobs:
16
+ evaluator:
17
+ runs-on: ubuntu-24.04
18
+ timeout-minutes: 180
19
+ steps:
20
+ - uses: actions/checkout@v6
21
+ with:
22
+ persist-credentials: false
23
+ fetch-depth: 0
24
+ - uses: astral-sh/setup-uv@v7
25
+ with:
26
+ version: '0.11.2'
27
+ python-version: '3.12'
28
+ - run: uv sync --locked --group analysis --group eda
29
+ - run: docker build -t iclayout-bench-tools:dev .
30
+ - env:
31
+ ICLAYOUT_BENCH_TEST_IMAGE: iclayout-bench-tools:dev
32
+ DATASET_REPO: ${{ inputs.dataset }}
33
+ DATASET_REVISION: ${{ inputs.revision }}
34
+ run: |
35
+ export ICLAYOUT_BENCH_DATASET="$(uv run --locked python -c 'import os; from huggingface_hub import snapshot_download; print(snapshot_download(repo_id=os.environ["DATASET_REPO"], repo_type="dataset", revision=os.environ["DATASET_REVISION"]))')"
36
+ uv run --locked pytest tests/unit/test_catalogs.py
37
+ uv run --locked pytest -m acceptance_container
38
+ uv run --locked pytest tests/test_http.py
39
+ uv run --locked --group eda pytest tests/integration/test_public_references.py -k 'cell_6t or NAND2_X1'
@@ -0,0 +1,77 @@
1
+ name: Tools image
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags: ['v*.*.*']
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: tools-image-publish
14
+ cancel-in-progress: false
15
+
16
+ jobs:
17
+ image:
18
+ if: vars.DOCKERHUB_IMAGE != ''
19
+ runs-on: ubuntu-24.04
20
+ timeout-minutes: 120
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+ with:
24
+ persist-credentials: false
25
+ - name: Validate Docker build context
26
+ run: bash tests/integration/test_build_context.sh
27
+ - uses: docker/setup-buildx-action@v4
28
+ - name: Extract image metadata
29
+ id: meta
30
+ uses: docker/metadata-action@v6
31
+ with:
32
+ images: ${{ vars.DOCKERHUB_IMAGE }}
33
+ flavor: latest=false
34
+ tags: |
35
+ type=sha,format=long
36
+ type=ref,event=tag
37
+ type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
38
+ - name: Build candidate
39
+ uses: docker/build-push-action@v7
40
+ with:
41
+ context: .
42
+ target: tools
43
+ platforms: linux/amd64
44
+ load: true
45
+ tags: iclayout-bench-tools:ci
46
+ labels: ${{ steps.meta.outputs.labels }}
47
+ cache-from: type=gha,scope=tools
48
+ cache-to: type=gha,scope=tools,mode=max,ignore-error=true
49
+ - name: Check installed tools
50
+ run: |
51
+ docker run --rm --network none iclayout-bench-tools:ci bash -euc '
52
+ test "$(id -u)" != 0
53
+ klayout -v
54
+ ngspice --version
55
+ magic --version
56
+ openvaf --version
57
+ for tool in xschem qucs-s qucsator qucsator_rf qucsconv; do
58
+ command -v "$tool"
59
+ done
60
+ python -I -c "import klayout.db, klayout_pex, gdsfactory, psutil"
61
+ '
62
+ - name: Log in to Docker Hub
63
+ uses: docker/login-action@v4
64
+ with:
65
+ username: ${{ vars.DOCKERHUB_USERNAME }}
66
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
67
+ - name: Publish checked image
68
+ uses: docker/build-push-action@v7
69
+ with:
70
+ context: .
71
+ target: tools
72
+ platforms: linux/amd64
73
+ push: true
74
+ tags: ${{ steps.meta.outputs.tags }}
75
+ labels: ${{ steps.meta.outputs.labels }}
76
+ provenance: mode=min
77
+ sbom: true
@@ -0,0 +1,58 @@
1
+ name: Publish reviewed website
2
+
3
+ # The site is built and reviewed externally. This workflow never imports an
4
+ # operator checkout, builds website sources, or participates in Python package CI.
5
+ on:
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ concurrency:
12
+ group: github-pages
13
+ cancel-in-progress: false
14
+
15
+ jobs:
16
+ upload:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v6
20
+ with:
21
+ ref: gh-pages
22
+ persist-credentials: false
23
+ - name: Verify the reviewed artifact
24
+ run: |
25
+ python - <<'PY'
26
+ import hashlib
27
+ import json
28
+ from pathlib import Path
29
+ root = Path('.')
30
+ manifest = json.loads(Path('release-manifest.json').read_text())
31
+ paths = [p for p in root.rglob('*') if '.git' not in p.parts]
32
+ assert not any(p.is_symlink() for p in paths), 'Symlinks are not publishable'
33
+ files = {p.as_posix() for p in paths if p.is_file()}
34
+ assert files == set(manifest['files']) | {'release-manifest.json'}, 'Unexpected release files'
35
+ assert {'index.html', '404.html', '.nojekyll', 'site-data/snapshot.json'} <= files
36
+ assert not any(p.split('/')[0] in {'admin', 'account', 'api', '.github'} for p in files)
37
+ assert sum(Path(p).stat().st_size for p in files) <= 1024 ** 3
38
+ for name, digest in manifest['files'].items():
39
+ path = Path(name)
40
+ assert not path.is_absolute() and '..' not in path.parts
41
+ assert hashlib.sha256(path.read_bytes()).hexdigest() == digest, name
42
+ PY
43
+ - uses: actions/upload-pages-artifact@v4
44
+ with:
45
+ path: .
46
+ deploy:
47
+ needs: upload
48
+ runs-on: ubuntu-latest
49
+ permissions:
50
+ pages: write
51
+ id-token: write
52
+ environment:
53
+ name: github-pages
54
+ url: ${{ steps.deployment.outputs.page_url }}
55
+ steps:
56
+ - name: Deploy Pages
57
+ id: deployment
58
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,23 @@
1
+ # Python environments and repository-local generated outputs
2
+ .venv/
3
+ __pycache__/
4
+ *.py[cod]
5
+ *.egg-info/
6
+ /build/
7
+ /dist/
8
+
9
+ # Legacy and tool caches
10
+ /.cache/
11
+ .pytest_cache/
12
+ .ruff_cache/
13
+ .mypy_cache/
14
+ .coverage
15
+ htmlcov/
16
+
17
+ # Local credentials and settings
18
+ .env
19
+ .env.*
20
+ auth.json
21
+
22
+ # Generated run artifacts
23
+ /results/
@@ -0,0 +1,56 @@
1
+ # ICLayout-Bench Repository Conventions
2
+
3
+ This repository owns the evaluation observation layer, generic client, public protocol, scoring specifications, Dataset loading, result archives/visualization and portable result delivery. It also owns the shared evaluation engine and local HTTP service. Operators own operator-controlled admission, frozen reruns, the official website and publication (one-way dependency operator applications → Public). See the architecture guide for the current package boundary. Write all repository Markdown in English, except `README_CN.md`.
4
+
5
+ ## Starting Work
6
+
7
+ Run `git status --short --branch` and preserve unrelated changes. Use the [README](README.md) as the entry point and [CONTRIBUTING](CONTRIBUTING.md) for verification rules. Read the guide matching the change:
8
+
9
+ | Work | Read first |
10
+ |---|---|
11
+ | Module boundaries and extension interfaces | [Architecture](docs/architecture.md) |
12
+ | Tasks, inputs, sources, constraints, metrics, or judges | [Task contract](docs/tasks.md) and [qualification](CONTRIBUTING.md#task-qualification); [input isolation](docs/tasks.md#input-isolation) defines solver visibility |
13
+ | Agents, submissions, events, batches, or statistics | [Running guide](docs/running.md) |
14
+ | Result archives or presentation data | [Result storage](docs/running.md#result-archive), [task presentation bindings](docs/running.md#task-presentations-and-interactive-layouts), and [archive verification](CONTRIBUTING.md#result-archive-verification) |
15
+ | Result packaging or website delivery | [Handoff boundaries](docs/architecture.md#result-handoff-and-storage-ownership) and [delivery contract](docs/running.md#website-result-delivery) |
16
+ | Images, dependencies, PDKs, EDA backends, or support bundles | [Tools guide](docs/tools.md); dependencies are declared in `pyproject.toml`, synchronized in `uv.lock` |
17
+ | Qualification admission, resource or endpoint approval, or report export | [Admission and export](docs/architecture.md#verified-reruns-and-disclosure) |
18
+
19
+ PDK implementation and signoff rules belong to the upstream PDK. Resource manifests
20
+ identify pinned sources; the framework resolves installations and derived resources
21
+ through the external cache described in the tools guide.
22
+
23
+ ## Execution and Completion
24
+
25
+ - Keep protocol, client, observation and analysis in `benchmarking/`, shared preparation/execution/EDA in `benchmarking/engine/`, the local HTTP adapter in `benchmarking/service/`, and reusable participant launch/configuration/MCP adapters in `benchmarking/participants/`. `benchmarking.run` schedules experiments; Agent harnesses retain their own decision loops. External applications consume the installed public interfaces; the package must not import consumer code. Static tasks and reference solutions belong in the independent Dataset repository; design sources, acceptance summaries and full retained validation belong in the design authoring workspace. Read local directories or Hugging Face snapshots directly; do not generate prepared case copies. Public installation and CI must not depend on operator applications.
26
+ - Shared archive/import/query/presentation code belongs in `benchmarking.results`, and portable packaging/upload in `benchmarking.transfer`. Operators own the unified Web frontend and HTTP routes, website accounts, storage integration, publication permissions and leaderboard policy. Keep the local archive separate from the operator database; importing or publishing never changes recorded scores or verification levels.
27
+ - Maintained case schematics and their provenance follow the presentation contract above. Keep solver inputs explicit; drawings and a later presentation revision do not rewrite a historical task or attest its evaluation.
28
+ - Default to a compatible existing tool image or a thin derived image for development validation. Keep the public recipe/lock current and run affected checks; passing these checks completes development validation without a full rebuild. Before changing container dependencies or starting a full build, apply the triggers in [image development](docs/tools.md#image-development). Report the image used and actual checks.
29
+ - A standard solve materializes only declared inputs and reviewed resource bundles. Public reference solutions may be downloaded for debugging but are never mounted for a standard solver Agent. Follow the [task guide](docs/tasks.md#asset-rights) for sources and distribution.
30
+ - Evaluate frozen candidates independently with trusted materials, without Agent credentials or writable directories. DRC/LVS establishes physical validity; task success also requires the declared geometry and post-layout metrics.
31
+ - Rerun affected case validation and shared evaluator regressions when the judge, rules, or task changes; use the task guide to determine calibration scope. Deterministic protocol tests are not model scores.
32
+ - Update the owning guide as the single source of truth when behavior changes; keep onboarding in the README and verification guidance in CONTRIBUTING. Do not create `CONTEXT.md` or duplicate protocol documents.
33
+
34
+ When complete: select the affected checks from the [verification matrix](CONTRIBUTING.md#verification), check documentation links against the commands they describe, and report actual test scope and Git status. Verify and commit cross-repository changes separately; retain reviewable evidence for architecture and upstream-reference changes.
35
+
36
+ ## Website publication branch
37
+
38
+ The `gh-pages` branch may hold reviewed, generated website artifacts. Keep the
39
+ main branch limited to package sources, documentation and the optional Pages
40
+ workflow. Website authoring and export stay with the operator. Follow
41
+ [static hosting](docs/architecture.md#static-website-hosting) for publication;
42
+ package builds and CI remain independent of website artifacts.
43
+
44
+ ## Standalone boundary
45
+
46
+ Participant usage examples are documented in [examples/README.md](examples/README.md).
47
+ They run the installed public wheel in an isolated environment. Reusable configs
48
+ and documentation are tracked; local dotenv files, environments, repository
49
+ archives and persistent experiment results remain ignored and outside releases.
50
+
51
+ Ship a reusable installed package and public interface documentation. Accept data
52
+ through explicit Dataset paths/IDs and operator/participant integrations through
53
+ public interfaces. The checkout, wheel, tests and CI must work with no sibling
54
+ repositories present. Keep concrete case catalogs, design recipes, experiment
55
+ results, website code and internal operating policies with their respective owners.
56
+ Run the repository boundary check and isolated wheel checks before completion.