From 29958d314ce2bb5408858ced5fd513497ebb6884 Mon Sep 17 00:00:00 2001 From: Tong Cheng Date: Tue, 21 Jul 2026 15:56:04 +0800 Subject: [PATCH] fix: harden v1.0.1 release --- .github/workflows/ci.yml | 9 + README.md | 13 +- README.zh-CN.md | 10 +- VERSION | 2 +- docs/compatibility.md | 19 +- docs/getting-started.md | 6 +- docs/knowledge-and-research.md | 2 +- docs/long-running-optimization.md | 15 +- docs/validation.md | 13 +- skills/cuda-kernel-optimizer/LICENSE | 21 ++ skills/cuda-kernel-optimizer/NOTICE | 20 ++ .../examples/walkthrough.md | 4 +- .../examples/workload-controller.md | 4 +- .../references/compatibility.md | 9 +- .../scripts/orchestrate.py | 144 ++++++++++- .../templates/candidate_proposal.schema.json | 2 +- .../templates/capability.schema.json | 2 +- .../templates/change_set.schema.json | 2 +- .../templates/diagnostic_evidence.schema.json | 2 +- .../diagnostic_measurement.schema.json | 2 +- .../templates/gate_evidence.schema.json | 2 +- .../templates/gate_measurement.schema.json | 2 +- .../templates/observation_summary.schema.json | 2 +- .../templates/planner_admission.schema.json | 2 +- .../templates/readiness_contract.schema.json | 2 +- .../templates/readiness_probe.schema.json | 2 +- .../templates/readiness_report.schema.json | 2 +- .../templates/run_control.schema.json | 2 +- .../templates/run_event.schema.json | 3 +- .../templates/stability_audit.schema.json | 2 +- .../stability_calibration.schema.json | 2 +- .../templates/workload_contract.schema.json | 2 +- .../templates/workload_control.schema.json | 2 +- tests/gpu/sm120/README.md | 42 ++-- tests/gpu/sm120/remote/run_lane.sh | 50 ++-- tests/gpu/sm120/test_sm120_acceptance.py | 42 +++- tests/test_orchestrate.py | 236 ++++++++++++++++++ tests/test_public_docs.py | 19 +- tests/test_standalone_project.py | 50 +++- 39 files changed, 668 insertions(+), 99 deletions(-) create mode 100644 skills/cuda-kernel-optimizer/LICENSE create mode 100644 skills/cuda-kernel-optimizer/NOTICE diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e36d942..fb345b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,15 @@ jobs: run: python -m unittest discover -s tests -p 'test_*.py' - name: Installed-skill tests run: python -m unittest discover -s skills/cuda-kernel-optimizer/tests -p 'test_*.py' + - name: Staged installation smoke + run: | + stage="$(mktemp -d)" + cp -R skills/cuda-kernel-optimizer "$stage/cuda-kernel-optimizer" + cd "$stage/cuda-kernel-optimizer" + test -f LICENSE + test -f NOTICE + python -m unittest discover -s tests -p 'test_*.py' + python scripts/self_check.py - name: Compile Python sources run: python -m compileall -q skills/cuda-kernel-optimizer/scripts tests - name: Skill self-check diff --git a/README.md b/README.md index c47423d..02327eb 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,9 @@ recommendations unless the user separately authorizes them. Installation is performed by Codex. Ask Codex to install or update `skills/cuda-kernel-optimizer` from [troycheng/cuda-kernel-optimizer](https://github.com/troycheng/cuda-kernel-optimizer), -then start a new session so the instructions are reloaded. +using the latest published release tag. Use the moving `main` branch only when +deliberately testing unreleased changes. Start a new session after installation +so the instructions are reloaded. Provide a runnable target, correctness reference, target environment, performance goal, constraints, and allowed modification scope. A real workload must be supplied by the user; the skill does not download or invent one. When a @@ -127,7 +129,7 @@ fast number cannot repair an invalid experiment. The installed `self_check` is CPU/static only and does not validate a GPU environment. See [Evidence & Safety](docs/evidence-and-safety.md), the -[formal V2.5 reference](skills/cuda-kernel-optimizer/references/evidence_automation.md), +[pre-V1 protocol 2.5 reference](skills/cuda-kernel-optimizer/references/evidence_automation.md), and the [long-run control reference](skills/cuda-kernel-optimizer/references/long_running_control.md). ## Validation status @@ -139,6 +141,13 @@ separate. Neither page predicts the speedup of a new project. ## Release notes +### V1.0.1 + +- Include `LICENSE` and `NOTICE` in the installable skill artifact. +- Make the physical GPU lane configurable instead of binding it to maintainer paths. +- Apply the hard deadline and durable elapsed-time accounting to `open-iter`. +- Separate standalone release numbers from retained pre-V1 protocol identities. + ### V1.0.0 The first standalone release combines environment readiness, active diagnosis, diff --git a/README.zh-CN.md b/README.zh-CN.md index e39d109..99fb661 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -41,7 +41,8 @@ Skill 不会自动修改宿主机配置。驱动、counter 权限、频率、功 安装由 Codex 完成。让 Codex 从 [troycheng/cuda-kernel-optimizer](https://github.com/troycheng/cuda-kernel-optimizer) -安装或更新 `skills/cuda-kernel-optimizer`,然后开启新会话,让新指令生效。 +按最新发布标签安装或更新 `skills/cuda-kernel-optimizer`。只有需要试用尚未发布的修改时, +才使用持续变化的 `main` 分支。安装完成后开启新会话,让新指令生效。 请提供可运行目标、正确性 reference、目标环境、性能目标、约束和允许修改的范围。 真实 workload 必须由用户提供;skill 不会自行下载或编造。缺少基础条件时,它会先说明 @@ -123,6 +124,13 @@ workload 结果。两者都不承诺新项目能获得相同提速。 ## 版本记录 +### V1.0.1 + +- 安装后的 skill 现在包含 `LICENSE` 与 `NOTICE`。 +- 物理 GPU 验收路径改为参数配置,不再绑定维护者目录。 +- `open-iter` 统一使用 hard deadline,并持久记录实际耗时。 +- 明确区分独立项目版本和保留的 pre-V1 协议标识。 + ### V1.0.0 首个独立公开版本整合了环境准备、主动诊断、限定范围的代码修改、分阶段的 diff --git a/VERSION b/VERSION index 3eefcb9..7dea76e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 +1.0.1 diff --git a/docs/compatibility.md b/docs/compatibility.md index bf72bb9..6531d56 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -1,7 +1,13 @@ # Compatibility -Kernel optimization needs Python 3.10+, a working CUDA GPU and driver, and the -toolchain required by the target implementation. +The CPU/static suite is tested with Python 3.10 and 3.12 on Linux CI. Core +Controller scripts use POSIX facilities such as file locks, resource limits, +signals, and process groups. Linux is the supported GPU execution environment; +macOS can run CPU/static checks, while native Windows is not supported. Windows +users should use a Linux or WSL environment. + +Kernel optimization also needs a working CUDA GPU and driver and the toolchain +required by the target implementation. | Path | Requirement | Boundary | |---|---|---| @@ -29,3 +35,12 @@ routing, and primary upstream sources are maintained in the The physical GPU fixture and opt-in commands are documented in the [RTX 5090 test guide](https://github.com/troycheng/cuda-kernel-optimizer/blob/main/tests/gpu/sm120/README.md). + +## Schema identities + +New unversioned schemas use the standalone repository namespace. Existing +versioned pre-V1 schema IDs under the archived `cuda-optimized-skill/schema/v*` and +`cuda-optimized-skill/schemas/v*` namespaces remain unchanged because they are +stable protocol identifiers, not installation URLs. Future incompatible schemas +must use a new versioned namespace in this repository instead of rewriting those +legacy IDs. diff --git a/docs/getting-started.md b/docs/getting-started.md index 696c273..8b6c832 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -4,8 +4,10 @@ Installation is performed by Codex. Ask Codex to install or update `skills/cuda-kernel-optimizer` from -[troycheng/cuda-optimized-skill](https://github.com/troycheng/cuda-kernel-optimizer), -then start a new session so Codex reloads the skill instructions. +[troycheng/cuda-kernel-optimizer](https://github.com/troycheng/cuda-kernel-optimizer) +at the latest published release tag. Use the moving `main` branch only when +deliberately testing unreleased changes. Start a new session after installation +so Codex reloads the skill instructions. ## Prepare the task diff --git a/docs/knowledge-and-research.md b/docs/knowledge-and-research.md index 1688aab..c888611 100644 --- a/docs/knowledge-and-research.md +++ b/docs/knowledge-and-research.md @@ -24,7 +24,7 @@ Each card names counter-signals, required gates, verification steps, and stop conditions. A hard UTF-8 byte budget limits the loaded playbooks; the complete catalog never enters the Planner context. -During V3.1 active diagnosis, a smaller routing catalog supplies at most three +During active diagnosis, a smaller routing catalog supplies at most three diagnostic cards for the current layer and bottleneck. The cards name likely signals, counter-signals, and the next evidence family; they contain no commands and have `promotion_authority: none`. They help the model read the context without loading the diff --git a/docs/long-running-optimization.md b/docs/long-running-optimization.md index 66c90a1..647366e 100644 --- a/docs/long-running-optimization.md +++ b/docs/long-running-optimization.md @@ -1,8 +1,13 @@ # Long-running optimization -Version 3.0 is designed for optimization work that may take hours, cross many -candidates, or resume after interruption. The AI still analyzes profiles and -writes code, but it does not control the rules of the experiment. +The long-running Controller is designed for optimization work that may take +hours, cross many candidates, or resume after interruption. The AI still +analyzes profiles and writes code, but it does not control the rules of the +experiment. + +The project release starts at V1.0.0. Labels such as 2.5, 3.0, and 3.1 in +schemas and validation records identify pre-V1 protocol generations retained +for compatibility; they are not project release versions. ## The control loop @@ -38,8 +43,8 @@ match exact architecture, task, observed signals, and available evidence before loading a playbook. A card can suggest what to try and how to disprove it; it cannot authorize execution or promotion. -V3.1 adds the active-diagnosis loop between the first global scan and candidate -admission. The Controller freezes user-owned evidence adapters, obtains available +Protocol generation 3.1 introduced the active-diagnosis loop between the first +global scan and candidate admission. The Controller freezes user-owned evidence adapters, obtains available capabilities from the current readiness report, and deterministically chooses one request from the AI's competing hypotheses. The selected outcome has predefined support and opposition effects. Those effects, the artifact digest, equivalent-request diff --git a/docs/validation.md b/docs/validation.md index 7191594..b4b9863 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -5,9 +5,10 @@ predict the speedup of a new workload. ## Automated checks -The local CPU/static suite ran 1,111 tests on 2026-07-21: 1,102 passed, nine physical RTX 5090 opt-in tests were skipped, and none failed. It covers input +The local CPU/static suite ran 1,122 tests on 2026-07-21: 1,113 passed, nine physical RTX 5090 opt-in tests were skipped, and none failed. It covers input validation, state recovery, evidence binding, shared-host guards, timeouts, restoration, capability retrieval, -stability calibration, audit cadence, and deterministic decision logic. V3.1 adds +stability calibration, audit cadence, and deterministic decision logic. Pre-V1 +protocol generation 3.1 added closed-loop adapter execution, outcome-bound support/opposition, cross-round request history, content-based project identity, frozen launcher identity, result and artifact tamper detection, interruption handling, concurrent start/resume, readiness-capability @@ -16,7 +17,7 @@ validate the reader's CUDA environment. ## Physical GPU lane -The final V3.1 completion lane passed 20 of 20 checks in 58.876 seconds on a physical +The final protocol-generation 3.1 completion lane passed 20 of 20 checks in 58.876 seconds on a physical RTX 5090 on 2026-07-20. It used immutable image `sha256:a2d9d89bc4394eab3fadc62c6b5b3f739b6494c1f64c56f5ba5e6c008252a0e5`. The new active-diagnosis test executed a real PyTorch CPU/CUDA profile action, @@ -24,7 +25,7 @@ sealed its 14,341-byte Chrome trace and observed outcome, bound the outcome's support/opposition effects, and returned to the next hypothesis round. No host setting or package was changed. -The V3.1 readiness lane completed 18 of 18 checks in 52.141 seconds +The protocol-generation 3.1 readiness lane completed 18 of 18 checks in 52.141 seconds on 2026-07-20 with the same immutable image listed below. Readiness itself took 8.793 seconds; the first baseline artifact appeared 9.297 seconds after the run started. CUDA 13.3 target compilation, SM120 execution and SASS, Compute @@ -33,9 +34,9 @@ recorded as diagnostic degradation. A real NCU target range returned `ERR_NVGPUCTRPERM`, so the report requested user action without changing host policy. All required capabilities passed and the baseline ran afterward. -The historical V3.0 controller produced its first baseline artifact in about +The historical protocol-generation 3.0 Controller produced its first baseline artifact in about 0.014 seconds because it had no readiness stage. The added 9-second startup cost -is not evidence that V3.1 finds a useful direction faster. That claim still +is not evidence that protocol generation 3.1 finds a useful direction faster. That claim still requires a long user workload showing fewer tool repairs, repeated probes, and unproductive profiling rounds. diff --git a/skills/cuda-kernel-optimizer/LICENSE b/skills/cuda-kernel-optimizer/LICENSE new file mode 100644 index 0000000..115702a --- /dev/null +++ b/skills/cuda-kernel-optimizer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 aa24aa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/skills/cuda-kernel-optimizer/NOTICE b/skills/cuda-kernel-optimizer/NOTICE new file mode 100644 index 0000000..272366b --- /dev/null +++ b/skills/cuda-kernel-optimizer/NOTICE @@ -0,0 +1,20 @@ +CUDA Kernel Optimizer is distributed under the MIT License in this repository. + +The project began from KernelFlow-ops/cuda-optimized-skill and was developed +through the historical repositories below before its standalone V1.0.0 release: + +- https://github.com/KernelFlow-ops/cuda-optimized-skill +- https://github.com/troycheng/cuda-optimized-skill +- https://git.yukework.com/mlsys/cuda-optimized-skill + +The historical repositories remain the source for pre-V1 development history. + +Acknowledgements + +CUDA Kernel Optimizer builds on the original cuda-optimized-skill created and +published by KernelFlow-ops. We thank Mark Liu and all upstream contributors +for the validation, benchmarking, profiling, and iterative optimization work +that provided the foundation for this standalone project. + +- KernelFlow-ops: https://github.com/KernelFlow-ops +- Mark Liu: https://github.com/mark-liu diff --git a/skills/cuda-kernel-optimizer/examples/walkthrough.md b/skills/cuda-kernel-optimizer/examples/walkthrough.md index 24ec833..e892743 100644 --- a/skills/cuda-kernel-optimizer/examples/walkthrough.md +++ b/skills/cuda-kernel-optimizer/examples/walkthrough.md @@ -1,8 +1,8 @@ -# V2.2 dual-loop walkthrough +# Dual-loop walkthrough This example optimizes `gemm.cu` against `ref.py` and then validates the shortlisted kernel on a user-provided inference workload. Values are illustrative; -the verdict rules and artifact names match V2.2. +the verdict rules and artifact names follow the retained pre-V1 protocol. Commands run from the installed skill root: diff --git a/skills/cuda-kernel-optimizer/examples/workload-controller.md b/skills/cuda-kernel-optimizer/examples/workload-controller.md index 9c6faeb..ce70eaf 100644 --- a/skills/cuda-kernel-optimizer/examples/workload-controller.md +++ b/skills/cuda-kernel-optimizer/examples/workload-controller.md @@ -1,6 +1,8 @@ # Workload Controller example -This page shows what the AI and Controller exchange during a V3.1 workload run. +This page shows what the AI and Controller exchange during an active-diagnosis +workload run. The underlying 3.1 label is a pre-V1 protocol generation, not the +project release version. It is not a command list for the user. The user supplies the runnable workload, reference, target environment, objective, constraints, and allowed project paths; the AI prepares and operates the contracts. diff --git a/skills/cuda-kernel-optimizer/references/compatibility.md b/skills/cuda-kernel-optimizer/references/compatibility.md index e751f91..c93387f 100644 --- a/skills/cuda-kernel-optimizer/references/compatibility.md +++ b/skills/cuda-kernel-optimizer/references/compatibility.md @@ -12,7 +12,7 @@ Probe the installed environment before selecting an optimization path. ## Observed RTX 5090 lanes -Both isolated lanes passed the same V2.2 SM120 acceptance matrix on 2026-07-17: +Both isolated lanes passed the same pre-V1 SM120 acceptance matrix on 2026-07-17: seven safety/helper tests and four real-GPU tests for Triton, native CUDA, CUTLASS, randomized identical paired timing, the production outer-workload evaluator, and target-bounded NCU. @@ -48,10 +48,9 @@ degradation. The adapter compared prebuilt baseline/optimized binaries; the captured dispatch headers were byte-identical, so the result is binary A/B evidence rather than source-level promotion proof. No source tree was modified. -Durable evidence is under -`/data/tcheng/cuda-skill-e2e/v2.2/artifacts/{current,compatibility,real}`. The -real run directory is -`real/orchestrator/run_20260717_043610_569950525`. +The validation records were captured in an isolated artifact lane. Maintainer +filesystem paths are intentionally omitted because they are not part of the +portable evidence contract. ## Architecture capability rules diff --git a/skills/cuda-kernel-optimizer/scripts/orchestrate.py b/skills/cuda-kernel-optimizer/scripts/orchestrate.py index 812e139..0b35a7e 100644 --- a/skills/cuda-kernel-optimizer/scripts/orchestrate.py +++ b/skills/cuda-kernel-optimizer/scripts/orchestrate.py @@ -1971,30 +1971,159 @@ def cmd_setup(args): # open-iter — profile + roofline for iteration N (if not done by setup) # --------------------------------------------------------------------------- +def _open_iter_budget_context(state: Mapping, run_dir: Path): + if state.get("budget") is None: + policy = resolve_budget("quick") + else: + policy = _policy_from_state(state) + + store = ArtifactStore(run_dir) + checkpoint = None + elapsed_seconds = 0.0 + checkpoint_path = run_dir / "checkpoint.json" + if checkpoint_path.exists() or checkpoint_path.is_symlink(): + input_hash = state.get("input_hash") + if not isinstance(input_hash, str) or not input_hash: + raise ValueError("checkpointed open-iter requires state input_hash") + checkpoint = _validate_checkpoint( + store.load_checkpoint(expected_input_hash=input_hash), + input_hash=input_hash, + ) + elapsed_seconds = _finite_real( + checkpoint["budget"]["elapsed_seconds"], + "checkpoint budget.elapsed_seconds", + minimum=0.0, + ) + else: + started_at = state.get("started_at") + if ( + isinstance(started_at, (int, float)) + and not isinstance(started_at, bool) + and math.isfinite(float(started_at)) + ): + elapsed_seconds = max(0.0, time.time() - float(started_at)) + + return ( + BudgetClock( + policy, + started_at=time.monotonic(), + elapsed_seconds=elapsed_seconds, + ), + store, + checkpoint, + ) + + +def _persist_open_iter_budget(store, checkpoint, clock): + if checkpoint is None: + return None + now = time.monotonic() + updated = copy.deepcopy(checkpoint) + updated["budget"] = _checkpoint_budget(clock, now) + updated["updated_at"] = now + return _persist_checkpoint( + store, updated, input_hash=updated["input_hash"] + ) + + +def _stop_open_iter_at_deadline(args, *, clock, store, checkpoint, command): + if checkpoint is not None: + checkpoint = _persist_hard_timeout( + checkpoint, + "candidate_correctness", + store=store, + clock=clock, + ) + elapsed_seconds = ( + checkpoint["budget"]["elapsed_seconds"] + if checkpoint is not None + else clock.elapsed(now=time.monotonic()) + ) + payload = { + "iter": args.iter, + "status": "budget_exhausted", + "stop_reason": "hard_execution_deadline", + "command": command, + "elapsed_seconds": elapsed_seconds, + "skipped_expensive_stages": ( + ["roofline", "branch_seed"] + if command == "profile_ncu" + else ["branch_seed"] + ), + } + store.write_json( + Path(f"iterv{args.iter}") / "open_iter_terminal.json", payload + ) + print(json.dumps(payload, indent=2)) + + def cmd_open_iter(args): - state_path = os.path.join(args.run_dir, "state.json") + run_dir = Path(args.run_dir).expanduser().resolve(strict=True) + state_path = str(run_dir / "state.json") if not os.path.isfile(state_path): sys.exit(f"state.json missing: {state_path}") state = _read(state_path) + clock, store, checkpoint = _open_iter_budget_context(state, run_dir) # Profile best_input for this iter - rc = _run([ + profile_timeout = _hard_timeout_seconds(clock) + if profile_timeout <= 0.0: + _stop_open_iter_at_deadline( + args, + clock=clock, + store=store, + checkpoint=checkpoint, + command="profile_ncu", + ) + return + profile_result = _run([ sys.executable, str(SCRIPT_DIR / "profile_ncu.py"), "--state", state_path, "--iter", str(args.iter), "--which", "best_input", "--benchmark", os.path.abspath(args.benchmark), - ]).returncode + ], hard_timeout=profile_timeout) + if getattr(profile_result, "timed_out", False): + _stop_open_iter_at_deadline( + args, + clock=clock, + store=store, + checkpoint=checkpoint, + command="profile_ncu", + ) + return + checkpoint = _persist_open_iter_budget(store, checkpoint, clock) + rc = profile_result.returncode if rc != 0: print("[warn] ncu profiling failed or degraded", file=sys.stderr) # Roofline - rc = _run([ + roofline_timeout = _hard_timeout_seconds(clock) + if roofline_timeout <= 0.0: + _stop_open_iter_at_deadline( + args, + clock=clock, + store=store, + checkpoint=checkpoint, + command="roofline", + ) + return + roofline_result = _run([ sys.executable, str(SCRIPT_DIR / "roofline.py"), "--state", state_path, "--iter", str(args.iter), - ]).returncode + ], hard_timeout=roofline_timeout) + if getattr(roofline_result, "timed_out", False): + _stop_open_iter_at_deadline( + args, + clock=clock, + store=store, + checkpoint=checkpoint, + command="roofline", + ) + return + checkpoint = _persist_open_iter_budget(store, checkpoint, clock) # Check early stop iter_dir = os.path.join(args.run_dir, f"iterv{args.iter}") @@ -2042,6 +2171,11 @@ def cmd_open_iter(args): print(json.dumps({ "iter": args.iter, "early_stop": early_stop, + "elapsed_seconds": ( + checkpoint["budget"]["elapsed_seconds"] + if checkpoint is not None + else clock.elapsed(now=time.monotonic()) + ), "branches_dir": branches_dir, "num_branches": num_branches, "next_step": ( diff --git a/skills/cuda-kernel-optimizer/templates/candidate_proposal.schema.json b/skills/cuda-kernel-optimizer/templates/candidate_proposal.schema.json index dc3eee9..a6b7af7 100644 --- a/skills/cuda-kernel-optimizer/templates/candidate_proposal.schema.json +++ b/skills/cuda-kernel-optimizer/templates/candidate_proposal.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/candidate_proposal.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/candidate_proposal.schema.json", "title": "CUDA optimizer candidate proposal v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/capability.schema.json b/skills/cuda-kernel-optimizer/templates/capability.schema.json index 287a7e8..3bcd89e 100644 --- a/skills/cuda-kernel-optimizer/templates/capability.schema.json +++ b/skills/cuda-kernel-optimizer/templates/capability.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/capability.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/capability.schema.json", "title": "CUDA optimizer capability metadata v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/change_set.schema.json b/skills/cuda-kernel-optimizer/templates/change_set.schema.json index bd1dbac..c85e345 100644 --- a/skills/cuda-kernel-optimizer/templates/change_set.schema.json +++ b/skills/cuda-kernel-optimizer/templates/change_set.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/change_set.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/change_set.schema.json", "title": "CUDA Workload Optimizer ChangeSet v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/diagnostic_evidence.schema.json b/skills/cuda-kernel-optimizer/templates/diagnostic_evidence.schema.json index 8824f32..d3432aa 100644 --- a/skills/cuda-kernel-optimizer/templates/diagnostic_evidence.schema.json +++ b/skills/cuda-kernel-optimizer/templates/diagnostic_evidence.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/diagnostic_evidence.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/diagnostic_evidence.schema.json", "title": "CUDA optimizer Controller-derived diagnostic evidence v1", "$comment": "Runtime validation additionally enforces the exact producer and signal vocabulary for each diagnostic kind.", "type": "object", diff --git a/skills/cuda-kernel-optimizer/templates/diagnostic_measurement.schema.json b/skills/cuda-kernel-optimizer/templates/diagnostic_measurement.schema.json index 1244a68..b3fc367 100644 --- a/skills/cuda-kernel-optimizer/templates/diagnostic_measurement.schema.json +++ b/skills/cuda-kernel-optimizer/templates/diagnostic_measurement.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/diagnostic_measurement.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/diagnostic_measurement.schema.json", "title": "CUDA optimizer diagnostic adapter measurement v1", "$comment": "The Controller supplies the diagnostic kind. Runtime validation enforces the kind-specific subset of this closed signal vocabulary.", "type": "object", diff --git a/skills/cuda-kernel-optimizer/templates/gate_evidence.schema.json b/skills/cuda-kernel-optimizer/templates/gate_evidence.schema.json index b82309c..3716c96 100644 --- a/skills/cuda-kernel-optimizer/templates/gate_evidence.schema.json +++ b/skills/cuda-kernel-optimizer/templates/gate_evidence.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/gate_evidence.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/gate_evidence.schema.json", "title": "CUDA optimizer adapter-specific gate evidence v1", "$comment": "cases_passed == cases_total is enforced by gate_evidence.py because standard JSON Schema cannot express this equality without non-portable extensions.", "type": "object", diff --git a/skills/cuda-kernel-optimizer/templates/gate_measurement.schema.json b/skills/cuda-kernel-optimizer/templates/gate_measurement.schema.json index 03e3728..2788f58 100644 --- a/skills/cuda-kernel-optimizer/templates/gate_measurement.schema.json +++ b/skills/cuda-kernel-optimizer/templates/gate_measurement.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/gate_measurement.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/gate_measurement.schema.json", "title": "CUDA optimizer raw gate adapter measurement v1", "$comment": "Controller selects the adapter kind outside this document. oneOf infers the closed shape from kind-specific subject/result fields. Cross-field equality such as cases_passed == cases_total remains a runtime-only invariant.", "type": "object", diff --git a/skills/cuda-kernel-optimizer/templates/observation_summary.schema.json b/skills/cuda-kernel-optimizer/templates/observation_summary.schema.json index 69bf77a..a8504f3 100644 --- a/skills/cuda-kernel-optimizer/templates/observation_summary.schema.json +++ b/skills/cuda-kernel-optimizer/templates/observation_summary.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/observation_summary.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/observation_summary.schema.json", "title": "CUDA optimizer bounded observation summary v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/planner_admission.schema.json b/skills/cuda-kernel-optimizer/templates/planner_admission.schema.json index bed4c76..795875c 100644 --- a/skills/cuda-kernel-optimizer/templates/planner_admission.schema.json +++ b/skills/cuda-kernel-optimizer/templates/planner_admission.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/planner_admission.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/planner_admission.schema.json", "title": "CUDA optimizer Planner admission v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/readiness_contract.schema.json b/skills/cuda-kernel-optimizer/templates/readiness_contract.schema.json index a6a3ab0..7c4a4e1 100644 --- a/skills/cuda-kernel-optimizer/templates/readiness_contract.schema.json +++ b/skills/cuda-kernel-optimizer/templates/readiness_contract.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/readiness_contract.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/readiness_contract.schema.json", "title": "CUDA workload optimizer readiness contract v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/readiness_probe.schema.json b/skills/cuda-kernel-optimizer/templates/readiness_probe.schema.json index 99ba273..d7d15e9 100644 --- a/skills/cuda-kernel-optimizer/templates/readiness_probe.schema.json +++ b/skills/cuda-kernel-optimizer/templates/readiness_probe.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/readiness_probe.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/readiness_probe.schema.json", "title": "CUDA workload optimizer readiness probe v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/readiness_report.schema.json b/skills/cuda-kernel-optimizer/templates/readiness_report.schema.json index 1fe7c60..f9f4e95 100644 --- a/skills/cuda-kernel-optimizer/templates/readiness_report.schema.json +++ b/skills/cuda-kernel-optimizer/templates/readiness_report.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/readiness_report.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/readiness_report.schema.json", "title": "CUDA workload optimizer readiness report v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/run_control.schema.json b/skills/cuda-kernel-optimizer/templates/run_control.schema.json index 37651ba..3e4d7b5 100644 --- a/skills/cuda-kernel-optimizer/templates/run_control.schema.json +++ b/skills/cuda-kernel-optimizer/templates/run_control.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/run_control.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/run_control.schema.json", "title": "CUDA optimizer deterministic run-control state v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/run_event.schema.json b/skills/cuda-kernel-optimizer/templates/run_event.schema.json index 2fb95d6..9506e96 100644 --- a/skills/cuda-kernel-optimizer/templates/run_event.schema.json +++ b/skills/cuda-kernel-optimizer/templates/run_event.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/run_event.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/run_event.schema.json", "title": "CUDA optimizer hash-chained run event v1", "type": "object", "additionalProperties": false, @@ -23,4 +23,3 @@ "record_sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"} } } - diff --git a/skills/cuda-kernel-optimizer/templates/stability_audit.schema.json b/skills/cuda-kernel-optimizer/templates/stability_audit.schema.json index 4f8ea2b..7f70666 100644 --- a/skills/cuda-kernel-optimizer/templates/stability_audit.schema.json +++ b/skills/cuda-kernel-optimizer/templates/stability_audit.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/stability_audit.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/stability_audit.schema.json", "title": "CUDA optimizer periodic stability audit v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/stability_calibration.schema.json b/skills/cuda-kernel-optimizer/templates/stability_calibration.schema.json index 32afa21..9a52afd 100644 --- a/skills/cuda-kernel-optimizer/templates/stability_calibration.schema.json +++ b/skills/cuda-kernel-optimizer/templates/stability_calibration.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/stability_calibration.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/stability_calibration.schema.json", "title": "CUDA optimizer stability calibration v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/workload_contract.schema.json b/skills/cuda-kernel-optimizer/templates/workload_contract.schema.json index 42763cb..0299325 100644 --- a/skills/cuda-kernel-optimizer/templates/workload_contract.schema.json +++ b/skills/cuda-kernel-optimizer/templates/workload_contract.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/workload_contract.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/workload_contract.schema.json", "title": "CUDA optimizer frozen workload contract v1", "type": "object", "additionalProperties": false, diff --git a/skills/cuda-kernel-optimizer/templates/workload_control.schema.json b/skills/cuda-kernel-optimizer/templates/workload_control.schema.json index 22193df..d51f669 100644 --- a/skills/cuda-kernel-optimizer/templates/workload_control.schema.json +++ b/skills/cuda-kernel-optimizer/templates/workload_control.schema.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://github.com/troycheng/cuda-optimized-skill/workload_control.schema.json", + "$id": "https://github.com/troycheng/cuda-kernel-optimizer/workload_control.schema.json", "title": "CUDA Workload Optimizer Control Manifest v1/v2", "type": "object", "additionalProperties": false, diff --git a/tests/gpu/sm120/README.md b/tests/gpu/sm120/README.md index 9883378..ad76bd4 100644 --- a/tests/gpu/sm120/README.md +++ b/tests/gpu/sm120/README.md @@ -20,10 +20,10 @@ set. It covers: eight real identical-kernel pairs, binds the calibration to source, environment, and contract identities, and refuses to leave `CALIBRATING` when noise or minimum detectable effect is too high; -- a V3.1 readiness round that inventories required and diagnostic capabilities, +- a protocol-generation 3.1 readiness round that inventories required and diagnostic capabilities, runs a user-workload smoke test, and blocks baseline collection when a required check, dependency identity, or time budget fails; -- a V3.1 active-diagnosis round that runs a real PyTorch CPU/CUDA profile action, +- a protocol-generation 3.1 active-diagnosis round that runs a real PyTorch CPU/CUDA profile action, seals its trace and outcome, and returns to the next hypothesis round; - a target-bounded Nsight Compute attempt. It must either collect real metrics with readable counters or record exactly `ERR_NVGPUCTRPERM`; no other @@ -44,26 +44,26 @@ reported as skipped: python3 -m unittest tests.gpu.sm120.test_sm120_acceptance -v ``` -On the isolated checkout, a current host environment can run the same suite -directly: +On an isolated checkout, a current host environment can run the same suite +directly. The example locations are placeholders owned by the operator: ```bash -cd /data/tcheng/cuda-skill-e2e/v3.1/repo +cd /srv/cuda-skill-e2e/repo CUDA_VISIBLE_DEVICES=7 \ CUDA_SM120_E2E=1 \ -CUDA_E2E_ARTIFACTS=/data/tcheng/cuda-skill-e2e/v3.1/artifacts/current-host \ -CUTLASS_PATH=/data/tcheng/cuda-skill-e2e/deps/cutlass \ +CUDA_E2E_ARTIFACTS=/srv/cuda-skill-e2e/artifacts/current-host \ +CUTLASS_PATH=/opt/cutlass-4.6.1 \ python3 -m unittest tests.gpu.sm120.test_sm120_acceptance -v ``` ## Disposable current and compatibility containers -`remote/run_lane.sh` accepts `current` or `compat` (default). It requires the -exact repository path `/data/tcheng/cuda-skill-e2e/v3.1/repo`, an artifact lane -below `/data/tcheng/cuda-skill-e2e/v3.1/artifacts`, and the physical CUTLASS -checkout `/data/tcheng/cuda-skill-e2e/deps/cutlass` with both +`remote/run_lane.sh` accepts `current` or `compat` (default). Set +`CUDA_E2E_ROOT` to an isolated root containing the repository, put each artifact +lane below `$CUDA_E2E_ROOT/artifacts`, and set `CUTLASS_PATH` to a dedicated +physical CUTLASS checkout with both `include/cutlass/cutlass.h` and `include/cutlass/version.h`. CUTLASS must not -overlap the repository or `/data/vllm-opt`, and the version header must report +overlap the repository or a `vllm-opt` tree, and the version header must report the validated `4.6.1` release. The artifact lane must be fresh; only a regular `run.log` created by an outer `tee` is allowed to pre-exist. @@ -76,15 +76,17 @@ remain available while compiler binaries and evidence stay out of the repository. ```bash -cd /data/tcheng/cuda-skill-e2e/v3.1/repo +cd /srv/cuda-skill-e2e/repo CUDA_E2E_GPU=7 \ -CUDA_E2E_ARTIFACTS=/data/tcheng/cuda-skill-e2e/v3.1/artifacts/current \ -CUTLASS_PATH=/data/tcheng/cuda-skill-e2e/deps/cutlass \ +CUDA_E2E_ROOT=/srv/cuda-skill-e2e \ +CUDA_E2E_ARTIFACTS=/srv/cuda-skill-e2e/artifacts/current \ +CUTLASS_PATH=/opt/cutlass-4.6.1 \ tests/gpu/sm120/remote/run_lane.sh current CUDA_E2E_GPU=7 \ -CUDA_E2E_ARTIFACTS=/data/tcheng/cuda-skill-e2e/v3.1/artifacts/compatibility \ -CUTLASS_PATH=/data/tcheng/cuda-skill-e2e/deps/cutlass \ +CUDA_E2E_ROOT=/srv/cuda-skill-e2e \ +CUDA_E2E_ARTIFACTS=/srv/cuda-skill-e2e/artifacts/compatibility \ +CUTLASS_PATH=/opt/cutlass-4.6.1 \ tests/gpu/sm120/remote/run_lane.sh compat ``` @@ -160,7 +162,7 @@ controller detected that the environment could not support the requested claim and did not begin candidate exploration. NCU again returned `ERR_NVGPUCTRPERM`; no host permission or driver policy was changed. -The V3.1 readiness lane ran on an idle physical RTX 5090 on +The protocol-generation 3.1 readiness lane ran on an idle physical RTX 5090 on 2026-07-20. A fresh lane passed 18/18 checks in 52.141 seconds with the same immutable image. Readiness took 8.793 seconds and the first baseline artifact appeared after 9.297 seconds. CUDA 13.3 target compilation, SM120 execution and @@ -168,10 +170,10 @@ SASS, Compute Sanitizer, and the user-workload smoke passed. Nsys was absent and NCU returned `ERR_NVGPUCTRPERM`; both were recorded as diagnostic limitations, with no package, host-policy, or driver change. Injected timeout, workload failure, and requirements-identity drift each blocked the baseline as designed. -The historical V3.0 path had no readiness stage, so this run proves admission +The historical protocol-generation 3.0 path had no readiness stage, so this run proves admission behavior, not faster diagnosis or optimization. -The V3.1 completion lane ran on 2026-07-20 using the same immutable image and +The protocol-generation 3.1 completion lane ran on 2026-07-20 using the same immutable image and passed 20/20 checks in 58.876 seconds. Its new active-diagnosis check executed a real PyTorch CPU/CUDA profile action on the RTX 5090, sealed a 14,341-byte Chrome trace and an observed outcome, bound the outcome as support for the framework-gap diff --git a/tests/gpu/sm120/remote/run_lane.sh b/tests/gpu/sm120/remote/run_lane.sh index 140eb96..14fae6d 100755 --- a/tests/gpu/sm120/remote/run_lane.sh +++ b/tests/gpu/sm120/remote/run_lane.sh @@ -15,32 +15,58 @@ case "$lane" in ;; esac -readonly allowed_root="/data/tcheng/cuda-skill-e2e/v3.1" -readonly allowed_cutlass="/data/tcheng/cuda-skill-e2e/deps/cutlass" readonly expected_cutlass_version="4.6.1" script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" repo_root="$(cd -- "$script_dir/../../../.." && pwd -P)" -if [[ "$repo_root" != "$allowed_root/repo" ]]; then - echo "refusing repository outside $allowed_root/repo: $repo_root" >&2 + +: "${CUDA_E2E_ROOT:?set CUDA_E2E_ROOT to the isolated lane root}" +: "${CUDA_E2E_ARTIFACTS:?set CUDA_E2E_ARTIFACTS below CUDA_E2E_ROOT/artifacts}" +: "${CUTLASS_PATH:?set CUTLASS_PATH to a dedicated CUTLASS 4.6.1 checkout}" +e2e_root="$(cd -- "$CUDA_E2E_ROOT" && pwd -P)" +case "$repo_root/" in + "$e2e_root/"*) ;; + *) + echo "refusing repository outside CUDA_E2E_ROOT: $repo_root" >&2 + exit 2 + ;; +esac +if [[ "$repo_root" == "$e2e_root" ]]; then + echo "repository must be a child of CUDA_E2E_ROOT: $repo_root" >&2 exit 2 fi +case "$repo_root/" in + "$e2e_root/artifacts/"*) + echo "repository and writable artifact root must not overlap: $repo_root" >&2 + exit 2 + ;; +esac -: "${CUDA_E2E_ARTIFACTS:?set CUDA_E2E_ARTIFACTS below $allowed_root/artifacts}" -: "${CUTLASS_PATH:?set CUTLASS_PATH to $allowed_cutlass}" artifacts="$(python3 -c 'import pathlib, sys; print(pathlib.Path(sys.argv[1]).expanduser().resolve(strict=False))' "$CUDA_E2E_ARTIFACTS")" case "$artifacts/" in - "$allowed_root/artifacts/"*) ;; + "$e2e_root/artifacts/"*) ;; *) - echo "refusing artifact path outside $allowed_root/artifacts: $artifacts" >&2 + echo "refusing artifact path outside $e2e_root/artifacts: $artifacts" >&2 exit 2 ;; esac mkdir -p -- "$artifacts" artifacts="$(cd -- "$artifacts" && pwd -P)" case "$artifacts/" in - "$allowed_root/artifacts/"*) ;; + "$e2e_root/artifacts/"*) ;; *) - echo "refusing resolved artifact path outside $allowed_root/artifacts: $artifacts" >&2 + echo "refusing resolved artifact path outside $e2e_root/artifacts: $artifacts" >&2 + exit 2 + ;; +esac +case "$artifacts/" in + "$repo_root/"*) + echo "repository and writable artifact lane must not overlap: $artifacts" >&2 + exit 2 + ;; +esac +case "$repo_root/" in + "$artifacts/"*) + echo "repository and writable artifact lane must not overlap: $repo_root" >&2 exit 2 ;; esac @@ -62,10 +88,6 @@ case "$CUTLASS_PATH" in ;; esac cutlass_path="$(cd -- "$CUTLASS_PATH" && pwd -P)" -if [[ "$cutlass_path" != "$allowed_cutlass" ]]; then - echo "CUTLASS physical path must equal $allowed_cutlass: $cutlass_path" >&2 - exit 2 -fi case "$cutlass_path/" in "$repo_root/"*) echo "CUTLASS checkout must not overlap the test repository" >&2 diff --git a/tests/gpu/sm120/test_sm120_acceptance.py b/tests/gpu/sm120/test_sm120_acceptance.py index 11d647f..24475bb 100644 --- a/tests/gpu/sm120/test_sm120_acceptance.py +++ b/tests/gpu/sm120/test_sm120_acceptance.py @@ -252,15 +252,51 @@ def test_runner_contract_is_fail_closed_and_uses_immutable_image(self) -> None: def test_runner_restricts_cutlass_to_the_dedicated_checkout(self) -> None: source = RUNNER.read_text(encoding="utf-8") - self.assertIn( - '/data/tcheng/cuda-skill-e2e/deps/cutlass', source - ) + self.assertIn("CUDA_E2E_ROOT", source) + self.assertIn("CUTLASS_PATH", source) + self.assertNotIn("/data/tcheng", source) self.assertIn("include/cutlass/cutlass.h", source) self.assertIn("include/cutlass/version.h", source) self.assertIn('expected_cutlass_version="4.6.1"', source) self.assertIn("vllm-opt", source) self.assertIn('-v "$repo_root:$repo_root:ro"', source) + def test_runner_rejects_a_writable_artifact_mount_inside_the_repository(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + repository = root / "artifacts" / "repo" + runner = repository / "tests" / "gpu" / "sm120" / "remote" / "run_lane.sh" + runner.parent.mkdir(parents=True) + shutil.copy2(RUNNER, runner) + cutlass = root / "cutlass" + include = cutlass / "include" / "cutlass" + include.mkdir(parents=True) + (include / "cutlass.h").write_text("// fixture\n", encoding="utf-8") + (include / "version.h").write_text( + "#define CUTLASS_MAJOR 4\n" + "#define CUTLASS_MINOR 6\n" + "#define CUTLASS_PATCH 1\n", + encoding="utf-8", + ) + environment = os.environ.copy() + environment.update( + { + "CUDA_E2E_ROOT": str(root), + "CUDA_E2E_ARTIFACTS": str(repository / "writable"), + "CUTLASS_PATH": str(cutlass), + } + ) + + completed = subprocess.run( + [str(runner), "compat"], + text=True, + capture_output=True, + env=environment, + ) + + self.assertEqual(completed.returncode, 2, completed.stderr) + self.assertIn("must not overlap", completed.stderr) + def test_v2_4_lane_uses_the_production_workload_controller(self) -> None: source = inspect.getsource( Sm120AcceptanceTests.test_workload_controller_promotes_real_gpu_candidate diff --git a/tests/test_orchestrate.py b/tests/test_orchestrate.py index 246316b..1bc6e74 100644 --- a/tests/test_orchestrate.py +++ b/tests/test_orchestrate.py @@ -36,6 +36,51 @@ def _load_orchestrate(): return module +def _open_iter_lifecycle_fixture(orchestrate, root: Path, *, elapsed_seconds: float): + run_dir = root / "run" + run_dir.mkdir() + champion = root / "champion.py" + champion.write_text("# champion\n", encoding="utf-8") + policy = orchestrate.resolve_budget("quick") + input_hash = "a" * 64 + state = { + "schema_version": orchestrate.CURRENT_SCHEMA_VERSION, + "run_dir": str(run_dir), + "input_hash": input_hash, + "budget": orchestrate._budget_payload(policy), + "best_file": str(champion), + "branches": 1, + "effective_methods": [], + } + (run_dir / "state.json").write_text(json.dumps(state), encoding="utf-8") + store = orchestrate.ArtifactStore(run_dir) + store.write_checkpoint( + { + "schema_version": orchestrate.CURRENT_SCHEMA_VERSION, + "input_hash": input_hash, + "run_dir": str(run_dir), + "iteration": 0, + "stage": "baseline", + "stage_index": 0, + "status": "stage_complete", + "candidate_id": None, + "candidate_status": None, + "budget": { + "elapsed_seconds": elapsed_seconds, + "remaining_seconds": max( + 0.0, policy.max_seconds - elapsed_seconds + ), + }, + "updated_at": 1.0, + "stage_evidence": {"baseline": {"status": "passed"}}, + } + ) + args = SimpleNamespace( + run_dir=str(run_dir), iter=1, benchmark="benchmark.py" + ) + return args, store, input_hash, policy + + class CloseIterationDecisionTests(unittest.TestCase): def _fixture(self, root: Path) -> tuple[SimpleNamespace, Path, Path]: run_dir = root / "run" @@ -904,6 +949,197 @@ def test_open_iteration_rejects_a_preexisting_unseeded_branch(self) -> None: with self.assertRaisesRegex(ValueError, "not seeded"): self.orchestrate.cmd_open_iter(args) + def test_open_iteration_timeout_stops_before_roofline_and_branch_work(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + run_dir = root / "run" + run_dir.mkdir() + champion = root / "champion.py" + champion.write_text("# champion\n", encoding="utf-8") + (run_dir / "state.json").write_text( + json.dumps( + { + "best_file": str(champion), + "branches": 1, + "effective_methods": [], + } + ), + encoding="utf-8", + ) + args = SimpleNamespace( + run_dir=str(run_dir), iter=1, benchmark="benchmark.py" + ) + timed_out = SimpleNamespace( + returncode=-15, + stdout="", + stderr="", + timed_out=True, + elapsed_seconds=0.2, + ) + runner = mock.Mock(return_value=timed_out) + + with mock.patch.object(self.orchestrate, "_run", runner): + with contextlib.redirect_stdout(io.StringIO()) as stdout: + self.orchestrate.cmd_open_iter(args) + + output = json.loads(stdout.getvalue()) + self.assertEqual(runner.call_count, 1) + self.assertGreater(runner.call_args.kwargs["hard_timeout"], 0.0) + self.assertEqual(output["status"], "budget_exhausted") + self.assertEqual(output["stop_reason"], "hard_execution_deadline") + self.assertFalse((run_dir / "iterv1" / "branches").exists()) + terminal = json.loads( + (run_dir / "iterv1" / "open_iter_terminal.json").read_text("utf-8") + ) + self.assertEqual(terminal["stop_reason"], "hard_execution_deadline") + + def test_open_iteration_charges_elapsed_time_to_the_checkpoint(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + args, store, input_hash, _policy = _open_iter_lifecycle_fixture( + self.orchestrate, root, elapsed_seconds=10.0 + ) + completed = SimpleNamespace( + returncode=0, stdout="", stderr="", timed_out=False + ) + + with mock.patch.object( + self.orchestrate, "_run", return_value=completed + ): + self.orchestrate.cmd_open_iter(args) + + checkpoint = store.load_checkpoint(expected_input_hash=input_hash) + self.assertGreater(checkpoint["budget"]["elapsed_seconds"], 10.0) + self.assertEqual(checkpoint["stage"], "baseline") + self.assertEqual(checkpoint["status"], "stage_complete") + + def test_open_iteration_preexhausted_budget_stops_before_spawning(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + policy_limit = 2400.0 + args, store, input_hash, policy = _open_iter_lifecycle_fixture( + self.orchestrate, + root, + elapsed_seconds=policy_limit, + ) + self.assertEqual( + policy_limit, policy.max_seconds - policy.reserve_seconds + ) + runner = mock.Mock() + + with mock.patch.object(self.orchestrate, "_run", runner): + with contextlib.redirect_stdout(io.StringIO()) as stdout: + self.orchestrate.cmd_open_iter(args) + + output = json.loads(stdout.getvalue()) + checkpoint = store.load_checkpoint(expected_input_hash=input_hash) + runner.assert_not_called() + self.assertEqual(output["stop_reason"], "hard_execution_deadline") + self.assertEqual(checkpoint["status"], "budget_exhausted") + self.assertEqual(checkpoint["candidate_status"], "inconclusive") + + def test_open_iteration_timeout_is_terminal_in_the_checkpoint(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + args, store, input_hash, _policy = _open_iter_lifecycle_fixture( + self.orchestrate, root, elapsed_seconds=10.0 + ) + timed_out = SimpleNamespace( + returncode=-15, + stdout="", + stderr="", + timed_out=True, + elapsed_seconds=0.2, + ) + + with mock.patch.object( + self.orchestrate, "_run", return_value=timed_out + ): + with contextlib.redirect_stdout(io.StringIO()): + self.orchestrate.cmd_open_iter(args) + + checkpoint = store.load_checkpoint(expected_input_hash=input_hash) + self.assertEqual(checkpoint["stage"], "candidate_correctness") + self.assertEqual(checkpoint["status"], "budget_exhausted") + self.assertEqual(checkpoint["candidate_status"], "inconclusive") + self.assertEqual( + checkpoint["stage_evidence"]["candidate_correctness"]["reason"], + "hard execution deadline expired", + ) + + def test_open_iteration_roofline_timeout_reports_only_unstarted_work(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + run_dir = root / "run" + run_dir.mkdir() + champion = root / "champion.py" + champion.write_text("# champion\n", encoding="utf-8") + (run_dir / "state.json").write_text( + json.dumps( + { + "best_file": str(champion), + "branches": 1, + "effective_methods": [], + } + ), + encoding="utf-8", + ) + args = SimpleNamespace( + run_dir=str(run_dir), iter=1, benchmark="benchmark.py" + ) + completed = SimpleNamespace( + returncode=0, stdout="", stderr="", timed_out=False + ) + timed_out = SimpleNamespace( + returncode=-15, + stdout="", + stderr="", + timed_out=True, + elapsed_seconds=0.2, + ) + + with mock.patch.object( + self.orchestrate, + "_run", + side_effect=(completed, timed_out), + ) as runner: + with contextlib.redirect_stdout(io.StringIO()) as stdout: + self.orchestrate.cmd_open_iter(args) + + output = json.loads(stdout.getvalue()) + self.assertEqual(runner.call_count, 2) + self.assertEqual(output["command"], "roofline") + self.assertEqual(output["skipped_expensive_stages"], ["branch_seed"]) + + def test_open_iteration_rejects_a_dangling_checkpoint_symlink(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + run_dir = root / "run" + run_dir.mkdir() + champion = root / "champion.py" + champion.write_text("# champion\n", encoding="utf-8") + (run_dir / "state.json").write_text( + json.dumps( + { + "input_hash": "a" * 64, + "best_file": str(champion), + "branches": 1, + "effective_methods": [], + } + ), + encoding="utf-8", + ) + try: + (run_dir / "checkpoint.json").symlink_to(root / "missing.json") + except OSError: + self.skipTest("symlinks are unavailable") + args = SimpleNamespace( + run_dir=str(run_dir), iter=1, benchmark="benchmark.py" + ) + + with self.assertRaisesRegex(ValueError, "symlink|unsafe|missing|escapes"): + self.orchestrate.cmd_open_iter(args) + def test_setup_keeps_secret_workload_snapshot_out_of_argv(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) diff --git a/tests/test_public_docs.py b/tests/test_public_docs.py index 70751b0..9fa436e 100644 --- a/tests/test_public_docs.py +++ b/tests/test_public_docs.py @@ -194,6 +194,10 @@ def test_compatibility_routes_to_canonical_reference(self) -> None: "Nsight Compute", "references/compatibility.md", "ERR_NVGPUCTRPERM", + "Python 3.10 and 3.12", + "POSIX", + "native Windows", + "Schema identities", ): self.assertIn(marker, text) @@ -206,10 +210,23 @@ def test_validation_records_v3_1_readiness_without_speed_claim(self) -> None: "9.297", "Nsys", "ERR_NVGPUCTRPERM", - "not evidence that V3.1 finds a useful direction faster", + "not evidence that protocol generation 3.1 finds a useful direction faster", ): self.assertIn(marker, text) + def test_public_docs_distinguish_release_and_protocol_versions(self) -> None: + getting_started = (ROOT / "docs/getting-started.md").read_text("utf-8") + self.assertIn("troycheng/cuda-kernel-optimizer", getting_started) + self.assertNotIn("[troycheng/cuda-optimized-skill]", getting_started) + self.assertIn("published release tag", getting_started) + self.assertIn("moving `main` branch", getting_started) + + long_running = (ROOT / "docs/long-running-optimization.md").read_text("utf-8") + self.assertIn("project release", long_running) + self.assertIn("protocol generation", long_running) + self.assertNotIn("Version 3.0 is designed", long_running) + self.assertNotIn("V3.1 adds", long_running) + def test_internal_history_is_not_shipped_as_public_documentation(self) -> None: self.assertFalse((ROOT / "maintainers").exists()) self.assertFalse((ROOT / "docs/superpowers").exists()) diff --git a/tests/test_standalone_project.py b/tests/test_standalone_project.py index 2198a1d..4b2eac4 100644 --- a/tests/test_standalone_project.py +++ b/tests/test_standalone_project.py @@ -1,5 +1,6 @@ from __future__ import annotations +import json import unittest from pathlib import Path @@ -10,14 +11,12 @@ class StandaloneProjectTests(unittest.TestCase): - def test_public_version_starts_at_v1(self) -> None: - self.assertEqual((ROOT / "VERSION").read_text("utf-8").strip(), "1.0.0") - for name, heading in ( - ("README.md", "### V1.0.0"), - ("README.zh-CN.md", "### V1.0.0"), - ): + def test_public_version_uses_the_v1_release_line(self) -> None: + self.assertEqual((ROOT / "VERSION").read_text("utf-8").strip(), "1.0.1") + for name in ("README.md", "README.zh-CN.md"): text = (ROOT / name).read_text("utf-8") - self.assertIn(heading, text) + self.assertIn("### V1.0.1", text) + self.assertIn("### V1.0.0", text) self.assertNotRegex(text, r"(?m)^### V(?:2|3)\.") def test_readmes_install_from_the_standalone_repository(self) -> None: @@ -37,6 +36,39 @@ def test_origin_notice_preserves_provenance(self) -> None: self.assertIn("Mark Liu", notice) self.assertIn("https://github.com/mark-liu", notice) + def test_installed_skill_carries_license_and_notice(self) -> None: + skill = ROOT / "skills" / "cuda-kernel-optimizer" + for name in ("LICENSE", "NOTICE"): + distributed = skill / name + self.assertTrue(distributed.is_file(), name) + self.assertEqual( + distributed.read_text("utf-8"), + (ROOT / name).read_text("utf-8"), + ) + + def test_public_files_do_not_expose_maintainer_storage_paths(self) -> None: + paths = ( + ROOT / "skills" / "cuda-kernel-optimizer" / "references" / "compatibility.md", + ROOT / "tests" / "gpu" / "sm120" / "README.md", + ROOT / "tests" / "gpu" / "sm120" / "remote" / "run_lane.sh", + ) + for path in paths: + self.assertNotIn("/data/tcheng", path.read_text("utf-8"), str(path)) + + def test_schema_identity_policy_keeps_only_versioned_legacy_ids(self) -> None: + old_prefix = "https://github.com/troycheng/cuda-optimized-skill/" + versioned_prefixes = (old_prefix + "schema/v", old_prefix + "schemas/v") + legacy_ids = [] + for path in sorted((ROOT / "skills/cuda-kernel-optimizer/templates").glob("*.schema.json")): + schema_id = json.loads(path.read_text("utf-8")).get("$id", "") + if schema_id.startswith(old_prefix): + self.assertTrue(schema_id.startswith(versioned_prefixes), path.name) + legacy_ids.append(schema_id) + self.assertTrue(legacy_ids) + compatibility = (ROOT / "docs" / "compatibility.md").read_text("utf-8") + self.assertIn("Schema identities", compatibility) + self.assertIn("versioned pre-V1", compatibility) + def test_public_tree_excludes_maintainer_history_and_dual_publisher(self) -> None: self.assertFalse((ROOT / "maintainers").exists()) self.assertFalse((ROOT / "tools" / "publish_dual_remote.py").exists()) @@ -72,8 +104,8 @@ def test_ci_runs_static_suite_on_supported_python_versions(self) -> None: def test_validation_count_matches_the_release_gate(self) -> None: validation = (ROOT / "docs" / "validation.md").read_text("utf-8") - self.assertIn("1,111 tests", validation) - self.assertIn("1,102 passed", validation) + self.assertIn("1,122 tests", validation) + self.assertIn("1,113 passed", validation) self.assertIn("nine physical RTX 5090 opt-in tests were skipped", validation)