Repository navigation
[CI] Windows: drop test-stage devcontainer + use static CRT - #127
Conversation
PR NVIDIA#81 introduced devcontainer-based execution for both the build and test stages of Windows CI. The build stage needs the devcontainer for MSVC, but the test stage doesn't: the wheel is already built, GPU access works through the host driver, and pip install + the wheel's bundled DLL-search patch handle runtime DLL discovery. The devcontainer adds ~6-8 min per matrix entry to pull the rapidsai/devcontainers image, repeated across all entries. This change removes the devcontainer from test-wheel-windows.yml in favor of host execution, mirroring cuda-python's pattern and the existing Linux job: - Drop the `Resolve devcontainer image`, `Pull devcontainer image`, and `Run numba-cuda-mlir tests in devcontainer` steps. - Add a single `Run numba-cuda-mlir tests` step that exports NUMBA_CUDA_MLIR*_TEST_WHEEL_ONLY when LOCAL_CTK=0 (matching the Linux job) and invokes the test script directly under the workflow's default bash shell. - Delete ci/windows-run-tests-container.ps1 (no longer used). Also re-enable the TCC driver-mode combinations in ci/test-matrix.yml that PR NVIDIA#81 commented out as "untested." With host-side execution they should work, and the entries match cuda-python's Windows TCC coverage (py3.12 @ 13.0.2/13.2.1, py3.13 @ 12.9.1, py3.14 @ 12.9.1, py3.14t @ 12.9.1). ci/windows-common.ps1 and ci/windows-devcontainer.env are left in place; the build stage still uses them.
The cuSIMT wheel bundles libMLIRPythonCAPI.so / libMLIRToLLVM70.so / libMLIRPythonSupport-numba_cuda_mlir.so / libLLVM-7.so under numba_cuda_mlir/_mlir/_mlir_libs and numba_cuda_mlir/lib (via setup.py's manual staging plus auditwheel-exclude on Linux). The LLVM install dirs that the test jobs were restoring contain the same libs that the wheel already ships. Python tests don't invoke any external LLVM CLI tools either: PR NVIDIA#81 moved FileCheck-style assertions to an in-process parser/matcher, and there are no subprocess calls to mlir-opt / mlir-translate / llc / FileCheck / llvm-dis anywhere under tests/ or src/. If the wheel's RPATH (or DLL-search patch on Windows) is set up correctly, the restore + LD_LIBRARY_PATH steps are dead weight. Drop them from: - test-wheel-linux.yml - test-expensive-linux.yml - test-wheel-windows.yml test-numbast-mlir-linux.yml is left alone: it builds numbast-mlir C++ against the LLVM install dirs inside a conda env, so it may genuinely need them. Treat separately if confirmed unnecessary. If CI fails after this change with import/load errors, the fix is to correct the wheel's RPATH / DLL-search setup in setup.py rather than to restore these workflow steps.
|
/ok to test 7769cbe |
This comment has been minimized.
This comment has been minimized.
The first round of CI on PR NVIDIA#127 showed all Windows test entries failing with: ImportError: DLL load failed while importing _mlir: A dynamic link library (DLL) initialization routine failed. Investigation of the wheel showed: - All bundled DLLs are present (MLIRPythonCAPI, MLIRPythonSupport, MLIRModernToNVVM, MLIRToLLVM70, nanobind, LLVM-C, and the _mlir.*.pyd). - The DLL-search patch in _mlir_libs/__init__.py is correctly applied. - _mlir.pyd's static imports are all resolvable (next-to-pyd DLLs, python311.dll, and Windows system DLLs). - The "LLVM install dir on PATH" trick the devcontainer used wasn't actually providing missing user-mode DLLs — only MLIR DLLs that the wheel already bundles. So the failure is a DllMain / static-initializer error in one of the bundled DLLs, not a missing-file issue. Two changes to make progress: 1. Add CIBW_REPAIR_WHEEL_COMMAND_WINDOWS using delvewheel, matching what auditwheel does on Linux. cibuildwheel's Windows default is no-op (unlike Linux/macOS), so the wheel had only setup.py's manual staging — no transitive dep walk, no DLL search-path init shim from delvewheel, no MSVC redist consideration. --add-path points delvewheel at the LLVM install bins so it can find anything that may live outside the wheel during the dependency walk. 2. Add a continue-on-error "Diagnose DLL loading" step to the Windows test job that, before the test run, ctypes.WinDLL-loads each bundled DLL in dependency order and reports which one fails first with the Windows error code. The bare ImportError doesn't say which DLL initialization actually failed; this pins it down. If delvewheel repair fixes the import on its own, great. If not, the diagnostic step tells us which specific DLL's init routine is failing, and we can target the fix there.
|
/ok to test 3b889a5 |
Setting CIBW_REPAIR_WHEEL_COMMAND_WINDOWS breaks the build because
cibuildwheel only auto-installs delvewheel when the *default* repair
runs; when you override the command, delvewheel isn't on PATH and the
build fails with "'delvewheel' is not recognized".
cibuildwheel v3.4.1's default Windows repair is already
`delvewheel repair -w {dest_dir} -v {wheel}` with delvewheel
auto-installed — that's what was running on PR NVIDIA#81's wheels. The
diagnostic step on the test side stays, since that's what'll tell us
which specific DLL init is failing.
This also matches cuda-python and numba-cuda, which both leave the
Windows repair command unset and rely on cibuildwheel's default.
cibuildwheel's Windows default repair-wheel-command is a no-op, so the wheel that PR NVIDIA#81 produced was never run through delvewheel. setup.py's manual DLL staging is real, but it doesn't walk the transitive dependency tree the way auditwheel does on Linux. cuda-python (cuda_bindings, cuda_core) and numba-cuda both configure delvewheel through pyproject.toml's [tool.cibuildwheel.windows] block. Mirror that pattern here (without --namespace-pkg, since numba_cuda_mlir isn't a namespace package).
|
/ok to test 110aefa |
First delvewheel attempt failed with "FileNotFoundError: Unable to find library: nanobind-numba_cuda_mlir.dll". Per delvewheel docs, it only inspects .pyd import tables and resolves each dependency against PATH or --add-path; it does NOT look at DLLs already bundled inside the wheel. setup.py manually stages the MLIR / nanobind / LLVM7 DLLs into _mlir_libs/ and lib/, but delvewheel needs the on-disk source path to find them during dependency walking. Add --add-path entries for the LLVM modern install's MLIR Python libs dir (which has MLIRPythonCAPI.dll, nanobind-numba_cuda_mlir.dll, MLIRPythonSupport-numba_cuda_mlir.dll, MLIRModernToNVVM.dll), the LLVM modern install's bin dir, and the LLVM 7 install's bin dir (LLVM-C.dll). cibuildwheel invokes repair-wheel-command via Git Bash on Windows (the earlier failure log shows `+ delvewheel ...` -- bash's set -x prefix), so $LLVM_MODERN_INSTALL_DIR / $LLVM7_INSTALL_DIR expansion works.
|
/ok to test 33eba60 |
…and \$VAR) The previous attempt used bash-style \$LLVM_MODERN_INSTALL_DIR in the delvewheel command, but cibuildwheel runs repair-wheel-command via cmd.exe on Windows, which doesn't expand \$VAR. The variable appeared literally in the command and delvewheel still failed to find nanobind-numba_cuda_mlir.dll. Switch to repo-relative paths: cibuildwheel runs the command from the package directory (repo root), and llvm-modern-install/ and llvm7-install/ are restored there earlier in the workflow. No shell variable expansion needed.
Per design feedback: Linux's auditwheel command already lives in the
workflow's CIBW_REPAIR_WHEEL_COMMAND_LINUX. Putting Windows's delvewheel
config in pyproject.toml created an inconsistent split. Move it back to
the workflow so both platforms' repair configurations sit together.
Benefits:
- One place to read/edit wheel-repair logic.
- ${{ env.LLVM_MODERN_INSTALL_DIR }} / ${{ env.LLVM7_INSTALL_DIR }} are
GitHub Actions expressions substituted at workflow render time,
before cibuildwheel/cmd.exe ever sees the string. No reliance on
shell variable expansion (which differs between cmd.exe and bash).
- CIBW_BEFORE_BUILD_WINDOWS handles installing delvewheel — the piece
the original commit 3b889a5 was missing.
|
/ok to test 8918c6d |
REPO_DIR=\$(pwd) returns MSYS-style paths under Git Bash on Windows (e.g. /d/a/.../llvm-modern-install). Downstream tools that run as Windows-native processes -- cibuildwheel, delvewheel, the wheel's Python imports -- can't resolve these paths. The most recent build failure shows delvewheel receiving the MSYS path verbatim and raising FileNotFoundError on nanobind-numba_cuda_mlir.dll, even though the .dll exists at the equivalent Windows path. Match cuda-python's pattern: on Windows, run REPO_DIR (and the derived TOOLS_PATH) through cygpath -w so the value is D:\\a\\... rather than /d/a/... . LLVM_MODERN_INSTALL_DIR and LLVM7_INSTALL_DIR (set later in this script as REPO_DIR/...) inherit the Windows-native style automatically, so the delvewheel command's --add-path entries finally point at paths Windows can resolve.
|
/ok to test e6c987f |
Commit e6c987f converted REPO_DIR to Windows-native (D:\a\...) in env-vars on Windows. That broke the build because LLVM_MODERN_INSTALL_DIR (derived from REPO_DIR) ended up containing backslashes, and the existing CIBW_ENVIRONMENT_WINDOWS uses cygpath -w on the value as an unquoted argument. Bash strips backslashes from unquoted args (\a -> a, \n -> n, etc.), corrupting the path to nonsense before cygpath sees it. cygpath then produces a garbage Windows path, MLIR_DIR points nowhere real, and CMake find_package(MLIR) fails. cuda-python sidesteps this by double-escaping backslashes via a normpath() helper, but only on CUDA_PATH (which IS used in CIBW_ENVIRONMENT_WINDOWS); their REPO_DIR isn't piped back through unquoted bash. cuSIMT's LLVM_*_INSTALL_DIR is derived from REPO_DIR and *is* used in CIBW_ENVIRONMENT_WINDOWS, so the bash backslash-eating applies. Smallest fix: revert env-vars to the MSYS-style REPO_DIR that worked before, and add an inline cygpath -w in CIBW_REPAIR_WHEEL_COMMAND_WINDOWS specifically for delvewheel's --add-path entries (delvewheel is the only consumer that needs Windows-native paths; everything else either already does its own cygpath conversion or is happy with MSYS form). cibuildwheel runs the repair command via Git Bash on Windows, so \$(cygpath -w ...) works inline.
…wrap
Implements option B from the design discussion: restore cygpath -w on
REPO_DIR (matching cuda-python and numba-cuda), wrap the derived
LLVM_*_INSTALL_DIR exports in realpath so the backslashes from
cygpath -w are normalized out of the env value, and revert the inline
$(cygpath -w ...) from CIBW_REPAIR_WHEEL_COMMAND_WINDOWS.
The reason cuSIMT hit the backslash-eating bug while cuda-python /
numba-cuda don't: cuda-python's env-vars pipes all its REPO_DIR-derived
paths through realpath before exporting them to $GITHUB_ENV (e.g.
CUDA_CORE_ARTIFACTS_DIR=\$(realpath "\${REPO_DIR}/cuda_core/dist"));
cuSIMT was concatenating REPO_DIR with /llvm-modern-install directly,
which left raw backslashes in the env value. Downstream
cygpath -w \${{ env.VAR }} calls then fed those backslashes to bash as
an unquoted argument, where bash silently strips them (\\a → a, \\n →
n, etc.), corrupting the path before cygpath sees it.
Move the env-vars BUILD step to run AFTER Restore LLVM artifacts so
realpath doesn't need -m (the LLVM install dirs exist by then in both
cold-cache and warm-cache flows; the composite action either restores
from actions/cache or falls back to actions/download-artifact, and
either produces the directories). No other step between checkout and
Build numba-cuda-mlir wheel needs env-vars output, so the reorder is
safe.
|
/ok to test bad8b94 |
The previous delvewheel-repaired wheel ended up with two physical
copies of each project DLL:
- numba_cuda_mlir/_mlir/_mlir_libs/MLIRPythonCAPI.dll
(un-mangled, from setup.py staging)
- numba_cuda_mlir.libs/MLIRPythonCAPI-<hash>.dll
(mangled, from delvewheel)
delvewheel patched _mlir.pyd's import table to the mangled name, but
MLIRToLLVM70.dll (loaded later via ctypes.CDLL, not visited by
delvewheel) still imports the un-mangled name and resolves to the
copy in _mlir_libs/. The process winds up with two distinct
MLIRPythonCAPI images, each with its own static state / LLVM
registries. When MLIRToLLVM70 calls into MLIR state that _mlir.pyd
set up via the OTHER copy, the registries are missing -> access
violation in the test job.
setup.py already manages staging of MLIRPythonCAPI / MLIRPythonSupport
/ nanobind into the wheel for uniform Linux/Windows treatment. Tell
delvewheel via --exclude not to bundle a second mangled copy of these.
delvewheel still gets to bundle the real missing pieces (msvcp140
etc.) that setup.py doesn't stage.
Mirrors how cuda_core/pyproject.toml does --exclude for torch DLLs.
|
/ok to test 1162b16 |
Per design discussion: we want the project DLLs (MLIRPythonCAPI etc.)
un-mangled because setup.py already stages them into _mlir_libs/ and
because other in-wheel DLLs (MLIRToLLVM70 in particular, loaded later
via ctypes.CDLL) import them under their original names. But we want
msvcp140 (and other transitive system deps) mangled to preserve
isolation from other wheels in the same process.
delvewheel exposes exactly this:
--ignore-existing -> don't re-bundle DLLs already in the wheel
(so no duplicate MLIRPythonCAPI copies)
--analyze-existing -> walk the in-wheel DLLs for their transitive
deps anyway (so msvcp140 still gets discovered)
--with-mangle -> mangle those deps for isolation (default is
no-mangle when combined with --ignore-existing)
delvewheel then patches the existing in-wheel DLLs' import tables to
reference msvcp140-<hash>.dll, so the un-mangled MLIRPythonCAPI in
_mlir_libs/ correctly resolves to our bundled mangled msvcp140 at
runtime. Other wheels in the same process keep using their own
mangled copies. No name collisions, no duplicate images.
|
/ok to test 3c87a7d |
Stepping back from the delvewheel-repair rabbit hole. The whole reason delvewheel was wired in was to bundle a matching msvcp140.dll for our Windows DLLs, because they were built with the default MSVC CRT linkage (/MD, dynamic). On the build devcontainer the right redist version was on PATH; on the bare runner the system msvcp140 didn't match and init routines failed. Building with the static CRT (/MT) links the C++ runtime *into* each DLL, removing the msvcp140 / vcruntime140 import dependency entirely. The wheel is then genuinely self-contained -- nothing for delvewheel to bundle. This also dissolves the "two competing bundling mechanisms" problem (setup.py's manual staging + delvewheel's repair-with-mangling) we kept tripping over. Changes: - ci/build-windows.sh: add `-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded` and `-DLLVM_USE_CRT_RELEASE=MT` to the LLVM7, modern LLVM/MLIR, and MLIRModernToNVVM bridge cmake invocations. - ci/build-windows.sh: change the llvm-c-stub.c manual `cl` compile from `-MD` to `-MT` so it matches the static LLVM static libs it links against (mixing /MT and /MD within the same DLL is a link error). - setup.py: pass `-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded` to the cmake invocation for our _cext / _helperlib / _typeconv / _mviewbuf and MLIRToLLVM70 builds on Windows. - .github/workflows/build-wheel.yml: drop CIBW_BEFORE_BUILD_WINDOWS (the `pip install delvewheel` line) and CIBW_REPAIR_WHEEL_COMMAND_WINDOWS. cibuildwheel's Windows default is no-op, which is what we want now. The ci/llvm-cache-key.sh hash already includes ci/build-windows.sh, so editing this file automatically invalidates the existing LLVM cache keys and triggers a clean rebuild. Trade-offs of /MT: - Larger DLLs (each carries its own CRT). MLIRPythonCAPI is already ~100 MB; an extra 1-2 MB of CRT code is in the noise. - C++ stdlib types are unsafe to pass across DLL boundaries (different heaps per CRT instance). Our boundary is MLIRPythonCAPI's C API plus nanobind/Python-object handoffs through the .pyd files -- no C++ stdlib types cross the wire. - LLVM/MLIR officially supports /MT builds via LLVM_USE_CRT_RELEASE=MT.
Per design feedback: the previous comment in setup.py conflated "/MT everywhere" with "same CRT everywhere". These are different constraints. /MT only requires per-binary consistency (all .objs and statically-linked .libs feeding a single DLL must agree on /MT vs /MD). Across DLLs each /MT binary has its own embedded CRT instance with its own heap; that's safe as long as no C++ stdlib types cross the DLL boundary, which holds here because MLIRPythonCAPI exposes a C API and our cext modules call into that API via the import lib only.
|
/ok to test c757877 |
The "Install numba-cuda-mlir for diagnostics" + "Diagnose DLL loading" steps were added in 3b889a5 to pinpoint which bundled DLL was failing to initialize. Now that /MT static CRT (commit 99d354c) eliminates the underlying msvcp140 mismatch and Windows tests pass, the diagnostic step has no purpose -- it's pure debug code that prepends 30+ seconds to every test job and re-installs the wheel.
|
/ok to test 972cf8f |
atmnp
left a comment
There was a problem hiding this comment.
Looks great! Thank you for handling it/fixing the bugs inadvertently introduced by me. Surprised that it was just the /MT / multithreading option that I had overlooked to get it working.
Journey to the final solutionThe simple change in this PR — drop the devcontainer at the Windows test stage — immediately exposed that the wheel wasn't actually self-contained on Windows: DLL init failures ( The canonical pip-ecosystem fix for this is wheel repair — auditwheel on Linux, delvewheel on Windows. Repair tools walk the .pyd import tables, find the missing redistributable DLLs (msvcp140, libstdc++, etc.), bundle them into the wheel with content-hash-mangled names for cross-wheel isolation, and patch the .pyd's import table to use the mangled name. Most native-Python projects ship Windows wheels this way (cuda-bindings, cuda-core, numpy, scipy, etc.). It seemed like the obvious lever to reach for, so that's where we started. Ten iterations of trying to make delvewheel work before pivoting to fix the root cause:
The pivot: stepped back, asked why delvewheel was needed at all. Answer: only to bundle Lessons:
|
|
cibuildwheel v4 made `delvewheel repair -w {dest_dir} -v {wheel}` the
default for `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS`; v3.x had no default. We
intentionally do not need wheel repair on Windows because the wheel is
built with `/MT` (static CRT) per NVIDIA#127 -- it is self-contained and has
no DLL dependencies for delvewheel to bundle.
Without this opt-out, the default delvewheel invocation discovers an
unresolvable reference to the project's own internal nanobind module
and fails wheel build for every win-64 matrix entry. This regression
re-surfaced when the cibuildwheel v3.4.1 -> v4.1.0 bump from NVIDIA#125 was
cherry-picked into this branch to validate the new aggregator catches
it. With the opt-out, the build succeeds again.
Refs: NVIDIA#127 (static-CRT Windows wheel design), NVIDIA#125 / NVIDIA#134 (original
cibuildwheel bump + revert).
* ci: adopt CCCL check_result aggregator and add [doc-only] PR mode Mirrors the gating-check fix in NVIDIA/cuda-python#2210 (root-cause analysis: NVIDIA/cuda-python#2208) and bundles in cuda-python's `[doc-only]` PR-mode feature, which had not been propagated to this repo. Changes: * should-skip: emit both `skip` (existing `[no-ci]` gate) and a new `doc_only` output, computed from PR title containing `[doc-only]`. Single `gh pr view` call now drives both, matching cuda-python's pattern. * `[doc-only]` gating on non-doc-chain jobs: build-llvm-linux-aarch64, build-llvm-windows, build-linux-aarch64, build-windows, and all 11 test-* jobs now have `&& \!fromJSON(needs.should-skip.outputs.doc-only)` in their `if:`. The linux-64 chain (build-llvm-linux-64, build-linux-64) and build-docs are intentionally NOT `[doc-only]`-gated because build-docs needs the linux-64 wheel. * checks: aggregator rewritten to CCCL's `check_result` pattern: explicit `expected="success"` per dependency, anything else (including `'skipped'` from a failed upstream) fails the gate. `[no-ci]` short-circuits at the top; `[doc-only]` flips `expected` to `"skipped"` for every test-* dep. `should-skip` itself is now in `needs:` and checked, so a crash in the gating job can't masquerade as a green CI run. Verified the aggregator script with a local simulation across 8 scenarios: normal-green, build-fail-cascade, `[no-ci]`, `[doc-only]`-OK, `[doc-only]`-doc-fails, build-windows-fail-cascade, single-test-fail, should-skip-itself-fails. All behave correctly. Reference: CCCL gate, https://github.com/NVIDIA/cccl/blob/8c0e6cb1b6412d7bd0070f9ac3f55fa80231961a/.github/workflows/ci-workflow-pull-request.yml#L463-L526 Refs: NVIDIA/cuda-python#2208, NVIDIA/cuda-python#2210 * Bump the actions-monthly group across 1 directory with 5 updates (#125) Bumps the actions-monthly group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) | `8.1.0` | `8.2.0` | | [github/codeql-action](https://github.com/github/codeql-action) | `4.35.3` | `4.36.2` | | [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) | `3.4.1` | `4.1.0` | | [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) | `0.9.5` | `0.9.6` | | [test-summary/action](https://github.com/test-summary/action) | `2.4` | `2.6` | Updates `astral-sh/setup-uv` from 8.1.0 to 8.2.0 - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](astral-sh/setup-uv@0880764...fac544c) Updates `github/codeql-action` from 4.35.3 to 4.36.2 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@e46ed2c...8aad20d) Updates `pypa/cibuildwheel` from 3.4.1 to 4.1.0 - [Release notes](https://github.com/pypa/cibuildwheel/releases) - [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md) - [Commits](pypa/cibuildwheel@8d2b08b...2947353) Updates `prefix-dev/setup-pixi` from 0.9.5 to 0.9.6 - [Release notes](https://github.com/prefix-dev/setup-pixi/releases) - [Commits](prefix-dev/setup-pixi@1b2de7f...5185adf) Updates `test-summary/action` from 2.4 to 2.6 - [Release notes](https://github.com/test-summary/action/releases) - [Commits](test-summary/action@v2.4...v2.6) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: 8.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-monthly - dependency-name: github/codeql-action dependency-version: 4.36.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-monthly - dependency-name: prefix-dev/setup-pixi dependency-version: 0.9.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-monthly - dependency-name: pypa/cibuildwheel dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-monthly - dependency-name: test-summary/action dependency-version: '2.6' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-monthly ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci: opt out of delvewheel repair on Windows (cibuildwheel v4 default) cibuildwheel v4 made `delvewheel repair -w {dest_dir} -v {wheel}` the default for `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS`; v3.x had no default. We intentionally do not need wheel repair on Windows because the wheel is built with `/MT` (static CRT) per #127 -- it is self-contained and has no DLL dependencies for delvewheel to bundle. Without this opt-out, the default delvewheel invocation discovers an unresolvable reference to the project's own internal nanobind module and fails wheel build for every win-64 matrix entry. This regression re-surfaced when the cibuildwheel v3.4.1 -> v4.1.0 bump from #125 was cherry-picked into this branch to validate the new aggregator catches it. With the opt-out, the build succeeds again. Refs: #127 (static-CRT Windows wheel design), #125 / #134 (original cibuildwheel bump + revert). --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Atmn Patel <[email protected]>
Summary
docker pullof the devcontainer per matrix entry./MT(static CRT) so the wheel has nomsvcp140runtime dependency. No delvewheel repair needed; wheel is self-contained.Other cleanups
ci/tools/env-varsWindows path handling now matches cuda-python (cygpath -wREPO_DIR+realpathwrap on derived exports).restore_llvm_artifacts+LD_LIBRARY_PATHfrom wheel-test jobs on both Linux and Windows; verified the wheel is self-contained (Linux pass/skip counts identical to main).ci/windows-run-tests-container.ps1.Test plan