Windows owned-CUDA worker: delay-loaded cuBLASLt + sidecar packaging gate - #18
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 9 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
Verified on a dispatched run of the manual gate against 10ec3fc8: archive hashes, no-DLL --version, the missing-DLL refusal naming the library, and side-by-side runtime resolution all pass on a real Windows runner. The new gate is stronger than the one it replaces — the hollow-green discriminator is now a named DLL rather than a status code. 4620d1b's -RequireGpu floor enforcement and license-path preservation read correctly.
One thing before merge: this branch is not rebased on #17's current head. ce87e1be on #17 fixed a vacuous real-worker test and bounded the probe's pipe reads by the deadline, and #18 still carries the earlier versions of those hunks in crates/synapse-module/src/lib.rs. Merging #17 then #18 in that state would either conflict or regress the fix. Please rebase #18 onto #17's head (and, as noted on #17, keep Cargo.lock at origin/master's bytes). I will re-dispatch the packaging gate on the rebased head before landing; the earlier dispatch already proves the packaging half, so that is a confirmation run, not a new question.
Merge order once both are ready: #17, then #18, then #16, on one train.
4620d1b to
d558d3e
Compare
|
Rebased onto PR #17 head 3e47fa9; PR #18 is now d558d3e. Cargo.lock is restored to origin/master bytes in both branches. The corrected probe deadline and explicit real-worker regression are included. Windows worker builds now explicitly reject non-CUDA-13 toolkits because the package uses CUDA 13 DLL names; the CUDA 13 build passed locally. Ready for your packaging-gate confirmation run. |
|
Pushed 6ee5494: hardware probe results and failure evidence are now keyed by canonical worker path. The regression runs two separate worker commands, verifies a failed package cannot contaminate a working package, and verifies failure caching stays scoped to that worker. Targeted regression passed locally. PR ancestry still includes #17 head 3e47fa9; catalog model.load repair is on a separate branch. |
There was a problem hiding this comment.
2 issues found across 1 file (changes from recent commits).
You’re at about 92% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="crates/synapse-module/src/lib.rs">
<violation number="1" location="crates/synapse-module/src/lib.rs:6050">
P2: When probes for different worker binaries overlap, this global mutex remains locked for the child-process timeout, serializing unrelated probes and synchronously blocking async probe tasks for up to ten seconds. Release the mutex before running the child, or use per-worker in-flight state so only callers for the same path wait.</violation>
<violation number="2" location="crates/synapse-module/src/lib.rs:6167">
P2: When a CUDA model specifies an explicit `worker_bin` and the sibling or environment worker differs or is absent, certification evidence probes that other path instead of the worker that was loaded. Preserve the worker path or successful reading from model loading and use it when generating CUDA evidence.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| fn owned_cuda_floor_observed(decision: &CudaFloorDecision, worker: Option<&Path>) -> Value { | ||
| let error = match decision { | ||
| CudaFloorDecision::Unsupported { observed: None, .. } => { | ||
| owned_cuda_probe_floor(worker).err() |
There was a problem hiding this comment.
P2: When a CUDA model specifies an explicit worker_bin and the sibling or environment worker differs or is absent, certification evidence probes that other path instead of the worker that was loaded. Preserve the worker path or successful reading from model loading and use it when generating CUDA evidence.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/synapse-module/src/lib.rs, line 6167:
<comment>When a CUDA model specifies an explicit `worker_bin` and the sibling or environment worker differs or is absent, certification evidence probes that other path instead of the worker that was loaded. Preserve the worker path or successful reading from model loading and use it when generating CUDA evidence.</comment>
<file context>
@@ -6151,14 +6161,14 @@ fn parse_compute_capability(value: &str) -> Option<(u32, u32)> {
+fn owned_cuda_floor_observed(decision: &CudaFloorDecision, worker: Option<&Path>) -> Value {
+ let error = match decision {
+ CudaFloorDecision::Unsupported { observed: None, .. } => {
+ owned_cuda_probe_floor(worker).err()
+ }
+ _ => None,
</file context>
| .or_else(|| resolve_worker_binary_sibling(CUDA_WORKER_ENGINE)) | ||
| .ok_or_else(|| "CUDA floor probe worker binary not found".to_string())?; | ||
| let worker = fs::canonicalize(&worker).unwrap_or(worker); | ||
| let mut cache = OWNED_CUDA_PROBE |
There was a problem hiding this comment.
P2: When probes for different worker binaries overlap, this global mutex remains locked for the child-process timeout, serializing unrelated probes and synchronously blocking async probe tasks for up to ten seconds. Release the mutex before running the child, or use per-worker in-flight state so only callers for the same path wait.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/synapse-module/src/lib.rs, line 6050:
<comment>When probes for different worker binaries overlap, this global mutex remains locked for the child-process timeout, serializing unrelated probes and synchronously blocking async probe tasks for up to ten seconds. Release the mutex before running the child, or use per-worker in-flight state so only callers for the same path wait.</comment>
<file context>
@@ -6035,20 +6035,30 @@ struct OwnedCudaFloorReading {
+ .or_else(|| resolve_worker_binary_sibling(CUDA_WORKER_ENGINE))
+ .ok_or_else(|| "CUDA floor probe worker binary not found".to_string())?;
+ let worker = fs::canonicalize(&worker).unwrap_or(worker);
+ let mut cache = OWNED_CUDA_PROBE
+ .lock()
+ .unwrap_or_else(|poisoned| poisoned.into_inner());
</file context>
|
All three are merged locally on one branch in the order #17 → #18 → #16, verified with
Thanks for the lock restore and the rebase — both landed exactly as asked, and the two extra commits on #18 (per-worker-path probe cache, CUDA-13 toolkit guard) read correctly. The packaging gate was re-dispatched on the rebased head as a confirmation run. |
Closes #14 (item 1: delay-load + sidecar packaging).
What changed
ck-synapse-worker-cuda(MSVC+CUDA only,crates/synapse-worker-cuda/build.rs):/DELAYLOAD:cublasLt64_13.dll+delayimp. Verified withdumpbin /dependentsthat cudart/cublas are statically linked and cuBLASLt is the only delay-loaded DLL.nvcuda.dll/cudart64_13.dll/cublas64_13.dllwere dropped from the DELOAD list after the linker reported "no imports found".crates/synapse-engine-cuda/src/cuda.rs): beforecuInit/cudaGetDevice,LoadLibraryWthe four CUDA DLLs (LazyLock, MSVC-only). A missing library is now a Rust error naming the DLL instead of an unhandled loader exception (exit 53, no output).scripts/package-owned-cuda.ps1: worker EXE + runtime DLLs at ZIP root, component licenses,manifest.jsonwith SHA-256 hashes and source component attribution. Driver deliberately not bundled.scripts/test-owned-cuda-package.ps1: extracts a fresh copy, verifies hashes, then asserts no-sidecar--versionexit 0, missing-DLL--probe-floornon-zero with a named-DLL error, and side-by-side resolution with CUDA removed from PATH.-RequireGpuadditionally requires a real floor JSON.tests.yml,windows-owned-cuda-manual): derives sidecars from the same pinnedcuda_cudart/libcublasarchives used for compilation (no independently maintained DLL manifest) and runs the verifier. GPU execution itself requires a GPU runner; the gate asserts loader correctness, not model execution.Verification (local RTX 4050, CUDA removed from PATH)
--version→ exit 0;--probe-floor→ exit 1,Error: cannot load CUDA library cublasLt64_13.dll: The specified module could not be found. (os error 126).--probe-floor→ exit 0,{"driver_api":13030,"compute_capability":{"major":8,"minor":9}}.cargo clippy -p synapse-engine-cuda -p synapse-worker-cuda --all-targets -D warningsclean;cargo fmt --checkclean.Non-goals
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Closes #14 (item 1). Windows CUDA workers now delay-load cuBLASLt and run with packaged runtime sidecars, so
--versionworks without CUDA onPATHwhile CUDA failures report the missing library instead of crashing during load. The module probes the worker for its hardware floor before creation, unless a complete environment override is available.Packaging
PATH;-RequireGpuadditionally enforces the driver and compute-capability floor.Hardware probe
Written for commit 6ee5494. Summary will update on new commits.