fix(build): repair the macOS conda build and the CUDA wheel toolchain - #1185
Conversation
vec_intersect.cpp calls std::back_inserter in vec2d_intersect,
vec_intersect and both vec_intersect_ overloads, and std::distance in
vec_intersect_, but includes only <algorithm> and <vector>. Both names
are declared in <iterator>.
libstdc++ reaches them anyway because <vector> and <algorithm> pull in
<bits/stl_iterator.h>, so the missing include is invisible on Linux.
libc++ drops those transitive includes in C++20 mode, which is the mode
this project builds in (CMAKE_CXX_STANDARD 20), so the file does not
compile on macOS:
src/utils/vec_intersect.cpp:18:76: error: no member named
'back_inserter' in namespace 'std'
Include <iterator> directly. This is the only file under src/ or
include/ that names back_inserter or std::distance without it.
Co-Authored-By: Claude <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1185 +/- ##
=======================================
Coverage 68.89% 68.89%
=======================================
Files 208 208
Lines 22411 22411
Branches 72 72
=======================================
Hits 15439 15439
Misses 6950 6950
Partials 22 22
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
CUDA_BUILD_TOOLCHAIN in tools/prepare_cuda_release.py pins
nvidia-cuda-nvcc, which supplies ptxas, but not nvidia-nvvm, which
supplies cicc. nvcc splits the device compile between them: cicc emits
the PTX and ptxas assembles it, and ptxas rejects a PTX ISA newer than
its own.
Neither nvidia-nvvm nor nvidia-cuda-crt is named in the list today. They
reach the toolchain through nvidia-cuda-nvcc, whose requires_dist is
["nvidia-nvvm", "nvidia-cuda-runtime", "nvidia-cuda-crt"] with no
version bounds, so pip resolves them to the newest CUDA minor version
available while ptxas stays on the pinned one. Resolving the current
list shows the split:
nvidia-cuda-nvcc 13.3.73 <- ptxas
nvidia-nvvm 13.4.92 <- cicc
nvidia-cuda-crt 13.4.92
A 13.4 cicc emits PTX ISA 9.4, which the 13.3 ptxas cannot assemble, so
the CUDA wheel build fails at enable_language(CUDA) in
CMakeLists.txt:270, before any project source is compiled:
ptxas tmp/CMakeCUDACompilerId.ptx, line 9; fatal : Unsupported
.version 9.4; current version is '9.3'
Pin both to nvcc's own version so the whole compiler comes from one
CUDA minor release. Re-resolving with the pins puts nvidia-cuda-nvcc,
nvidia-nvvm and nvidia-cuda-crt all on 13.3.73.
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 71402fc6e7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
pixi.toml's [target.linux-64.pypi-dependencies] block states that its version ranges must match CUDA_BUILD_TOOLCHAIN and CUDA_RUNTIME_DEPENDENCIES in tools/prepare_cuda_release.py. It pinned nvidia-cuda-nvcc but not nvidia-nvvm or nvidia-cuda-crt, which nvidia-cuda-nvcc requires without version bounds. pixi.lock currently holds all three at 13.3.73, so existing environments are unaffected. A re-resolve, however, was free to pick a 13.4 cicc (nvidia-nvvm) against the pinned 13.3 ptxas (nvidia-cuda-nvcc), which reproduces locally the unsupported-PTX-ISA failure the release path now guards against. Add the two constraints so both paths hold the whole compiler to one CUDA minor release. `pixi lock` reports the lock file already up to date -- the locked versions satisfy the new ranges -- so pixi.lock is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
The "only file" claim is wrong for |
| # dropped here since this only ever runs inside the Linux manylinux container. | ||
| CUDA_BUILD_TOOLCHAIN = [ | ||
| "nvidia-cuda-nvcc ~=13.3.73", | ||
| # nvidia-nvvm and nvidia-cuda-crt are not listed here because the build |
There was a problem hiding this comment.
This contradicts the code it sits on. "nvidia-nvvm and nvidia-cuda-crt are not listed here because the build calls them directly" is claimed directly above lines that do list them. The intended meaning (listed because of unpinned resolution, not direct use) only emerges on a third read. The pixi.toml version of the same comment ("Named although nvidia-cuda-nvcc already depends on them: …") is clear; the script comment should be reworded to match.
There was a problem hiding this comment.
Agreed — reworded in 194a42f. The sentence parsed first as "these are not listed here", two lines above the entries that list them; the intended reading (direct use is not the reason they appear) only arrived on re-reading. It now matches the pixi.toml wording:
# Named although nvidia-cuda-nvcc already depends on them: it does so
# without version bounds, which lets pip resolve a newer CUDA minor
# version for cicc (nvidia-nvvm) than for ptxas (nvidia-cuda-nvcc), and
# ptxas rejects a PTX ISA newer than its own. Must match the
# nvidia-cuda-nvcc version above.Comment text only; CUDA_BUILD_TOOLCHAIN is unchanged, and both CPU presets still build and pass (1839/1839 and 1873/1873).
Generated by Claude Code
The comment opened "nvidia-nvvm and nvidia-cuda-crt are not listed here because the build calls them directly", two lines above the entries that list them. The intended reading is that direct use is not the reason they appear, but the sentence parses first as a claim that they are absent. Restate it the way the equivalent comment in pixi.toml already does -- named despite nvidia-cuda-nvcc depending on them, because that dependency carries no version bound -- so both copies read the same way. Comment text only; CUDA_BUILD_TOOLCHAIN is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
|
You're right, and the scope is wider than two files. Checked against the tree:
So The PR description has been corrected — it no longer claims On where to fix it: leaving it out of this PR for now. This one is two build repairs that are both red on Generated by Claude Code |
Two independent build breakages, both latent problems that surfaced when an external toolchain moved. Neither is caused by a source change in this repository.
1. Missing
<iterator>breaks the macOS conda buildProblem
src/utils/vec_intersect.cppcallsstd::back_inserterinvec2d_intersect,vec_intersectand bothvec_intersect_overloads, andstd::distanceinvec_intersect_, but includes only<algorithm>and<vector>. Both names are declared in<iterator>.libstdc++ reaches them anyway, because
<vector>and<algorithm>pull in<bits/stl_iterator.h>— so the missing include is invisible on Linux andci-cmake_tests(Ubuntu/GCC) stays green. libc++ drops those transitive includes in C++20 mode, which is the mode this project builds in (CMAKE_CXX_STANDARD 20), so the file does not compile on macOS:Both macOS jobs of Conda Build (Test build) die there at 56%, taking the wheel build with them;
ubuntu-latestpasses.masteris affected too. The file last changed on 2026-06-30 in43fd1fd, and the same code still built on master as recently as run 32725171357 (2026-08-24,32d5d82); the conda-forge macOS toolchain has since moved to a libc++ that no longer supplies the transitive include.Fix
Add
#include <iterator>.Scope of that claim, narrowed after review: it holds for
back_inserter— the only other two users,include/utils/vec_clone.hppandsrc/backend/linalg_internal_cpu/Gemm_Batch_internal.hpp, include<iterator>directly. It does not hold forstd::distance, which nine files name without a direct include:src/utils/vec_unique.cpp,src/utils/vec_where.cpp,src/Bond.cpp,src/BlockUniTensor.cpp,src/BlockFermionicUniTensor.cpp,src/UniTensor_base.cpp,src/DenseUniTensor.cpp,include/UniTensor.hppandinclude/LinOp.hpp. All of them compile today: seven reach<iterator>through the chainutils.hpp→vec_clone.hpp(which includes it at line 5), andvec_unique.cpp/vec_where.cpponly because libc++'s<algorithm>still suppliesstd::distance. That last pair is the same fragility class as the bug fixed here, but is not a current breakage and is not addressed by this PR.2. Unpinned nvcc siblings break the CUDA wheel build
Problem
CUDA_BUILD_TOOLCHAINintools/prepare_cuda_release.pypinsnvidia-cuda-nvcc, which suppliesptxas, but notnvidia-nvvm, which suppliescicc. nvcc splits the device compile between them:ciccemits the PTX andptxasassembles it, andptxasrejects a PTX ISA newer than its own.Neither
nvidia-nvvmnornvidia-cuda-crtis named in the list. They arrive throughnvidia-cuda-nvcc, whoserequires_distis["nvidia-nvvm", "nvidia-cuda-runtime", "nvidia-cuda-crt"]with no version bounds, so pip resolves them to the newest CUDA minor version whileptxasstays pinned. Resolving the current list shows the split:A 13.4
ciccemits PTX ISA 9.4, which the 13.3ptxascannot assemble, so the build fails atenable_language(CUDA)(CMakeLists.txt:270) before any project source is compiled:nvidia-nvvm13.4.59 was published 2026-09-09 at 18:02 UTC, under four hours after the last green Release CUDA wheels run. The build has no lockfile, so every run since re-resolves to 13.4.Fix
Pin
nvidia-nvvmandnvidia-cuda-crtto nvcc's own version so the whole compiler comes from one CUDA minor release. Re-resolving with the pins puts all three on 13.3.73.pixi.toml's[target.linux-64.pypi-dependencies]block states that its ranges must matchCUDA_BUILD_TOOLCHAIN, and it pinnednvidia-cuda-nvcconly, so the same two constraints are added there.pixi.lockalready held all three at 13.3.73, so no environment was broken in practice and the lock is unchanged —pixi lockreports it already up to date. The exposure was a future re-resolve.This keeps the toolchain on 13.3 rather than bumping to 13.4; it does not change what the published wheel links against or the driver it requires.
Testing
Neither failure reproduces on Linux/GCC, so both fixes were verified by CI on this PR, on the toolchains that actually rejected the code:
BuildAndTest-macos-latestandBuildAndTest-macos-15-intel(Conda Build) — both pass. These are the jobs that were dying at 56% onback_inserter.BuildWheel-ubuntu-24.04(Release CUDA wheels) — passes, taking 2h02m to build; before the pin it failed after about 2 minutes at CMake's CUDA compiler-ID probe.Formatting Check,BuildAndTest(ctest + pytest),DownstreamFindPackage,check(version consistency), every CPU wheel leg, Codecov.Local runs, which confirm no regression rather than demonstrating either fix:
debug-openblas-cpu— build +ctest: 1839/1839 passeddebug-mkl-cpu— build +ctest: 1873/1873 passedpre-commiton all changed files: clean (clang-format v14;.clang-formatsetsSortIncludes: false, so the new include stays where it is written)nvidia-nvvm/nvidia-cuda-crtcome back 13.4.92 against a 13.3.73ptxas; with them all three resolve to 13.3.73Remaining scope note: the CUDA wheel job builds on a GPU-less runner and only asserts
cytnx.Device.Ngpus == 0, so it proves the toolchain compiles and links, not that device code runs correctly.