Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# charly local state — never commit
#
# `.build/` is the build cache: generated candy checkouts (`_candy/`) of THIS
# repo's dependencies, recreated by every `charly box validate`/`generate`/`build`.
# `.containerignore` and `.dockerignore` are generated context-ignore files
# (gitignored org-wide by the shared ignore rules).
#
# Without this file a `git add -A` silently lands all of it in a PR — which is
# exactly what happened in opencharly/layer-cuda#10, where 18 of 19 changed files
# were this cache rather than the change.
.build/
.containerignore
.dockerignore
70 changes: 64 additions & 6 deletions charly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,22 @@ cuda:
# Headers — cudnn*.h live in /opt/cuda/targets/x86_64-linux/include
# on the cudnn package, while CUDA's own headers live in
# /opt/cuda/include. Symlink both into /usr/include.
for inc in /opt/cuda/include/*.h /opt/cuda/targets/x86_64-linux/include/*.h; do
[ -e "$inc" ] && ln -sf "$inc" /usr/include/$(basename "$inc")
# Headers — link EVERY ENTRY of each toolkit include root, not a guessed subset.
# nvcc computes its default include root RELATIVE to its own executable, and
# /usr/bin/nvcc is a symlink, so all CUDA headers must be reachable under
# /usr/include. Enumerating by pattern is what broke this: a `*.h` glob linked the
# top-level headers but silently dropped (a) the SUBTREES crt/ and cccl/, which
# killed every build at CMake's enable_language(CUDA) with "crt/host_config.h: No
# such file or directory", and then (b) the `.hpp` half of the `_functions` family
# (`vector_functions.hpp` and friends), which killed the very next stage -- both
# reported on opencharly/layer-cuda#9. Linking every entry needs no extension list
# to keep in sync and cannot silently miss a file or a subtree again.
for root in /opt/cuda/include /opt/cuda/targets/x86_64-linux/include; do
[ -d "$root" ] || continue
for entry in "$root"/*; do
[ -e "$entry" ] || continue
ln -sfn "$entry" /usr/include/"$(basename "$entry")"
done
done
# Libraries: libcudart, libcudnn, libcurand, etc.
mkdir -p /usr/lib64
Expand All @@ -159,8 +173,22 @@ cuda:
# Headers — cudnn*.h live in /opt/cuda/targets/x86_64-linux/include
# on the cudnn package, while CUDA's own headers live in
# /opt/cuda/include. Symlink both into /usr/include.
for inc in /opt/cuda/include/*.h /opt/cuda/targets/x86_64-linux/include/*.h; do
[ -e "$inc" ] && ln -sf "$inc" /usr/include/$(basename "$inc")
# Headers — link EVERY ENTRY of each toolkit include root, not a guessed subset.
# nvcc computes its default include root RELATIVE to its own executable, and
# /usr/bin/nvcc is a symlink, so all CUDA headers must be reachable under
# /usr/include. Enumerating by pattern is what broke this: a `*.h` glob linked the
# top-level headers but silently dropped (a) the SUBTREES crt/ and cccl/, which
# killed every build at CMake's enable_language(CUDA) with "crt/host_config.h: No
# such file or directory", and then (b) the `.hpp` half of the `_functions` family
# (`vector_functions.hpp` and friends), which killed the very next stage -- both
# reported on opencharly/layer-cuda#9. Linking every entry needs no extension list
# to keep in sync and cannot silently miss a file or a subtree again.
for root in /opt/cuda/include /opt/cuda/targets/x86_64-linux/include; do
[ -d "$root" ] || continue
for entry in "$root"/*; do
[ -e "$entry" ] || continue
ln -sfn "$entry" /usr/include/"$(basename "$entry")"
done
done
# Libraries: libcudart, libcudnn, libcurand, etc.
mkdir -p /usr/lib64
Expand All @@ -180,6 +208,25 @@ cuda:
file:
file: /usr/include/cudnn.h
exists: true
- check: "a CUDA translation unit PREPROCESSES against the stitched /usr layout (Arch: the header subtrees are linked, not only the top-level files)"
id: cuda-arch-header-root
# Scoped IN THE COMMAND deliberately: the check runner does not honour runner-level
# exclude-distro fields, and Fedora's RPMs land in /usr directly so its layout differs.
#
# This is the probe the plan was missing. `nvcc --version` proves nvcc RUNS and the
# cuDNN probe proves one top-level header arrived -- but neither can FAIL on a layout
# that cannot compile, which is how `crt/` stayed unlinked while every probe passed:
# nvcc computes its include root relative to its own (symlinked) executable, so
# cuda_runtime.h's `#include "crt/host_config.h"` resolved under /usr/include and was
# not there. Reproduced end to end on real Arch hardware (opencharly/layer-cuda#9).
command: |
[ -f /etc/arch-release ] || exit 0
test -f /usr/include/crt/host_config.h || exit 1
printf 'int main(void){return 0;}\n' > /tmp/chkcuda.cu
nvcc -E -x cu /tmp/chkcuda.cu > /dev/null
rc=$?
rm -f /tmp/chkcuda.cu
exit $rc
- check: the CUDA runtime library is linkable from the canonical /usr/lib64 path
exit_status: 0
command: ls /usr/lib64/libcudart.so*
Expand Down Expand Up @@ -244,8 +291,19 @@ cuda-skill:

The candy is multi-distro. The `distro.arch` section installs `cuda`, `cudnn`,
and `python-onnxruntime-cpu` from the Arch repos. Arch installs CUDA under
`/opt/cuda`, while `CUDA_HOME` is `/usr`, so the Arch path symlinks
`/opt/cuda/*` into `/usr/*` to stitch the Arch layout into the Fedora layout.
`/opt/cuda` — its toolkit headers under `/opt/cuda/targets/x86_64-linux/include/` —
while `CUDA_HOME` is `/usr`, so the Arch path links **every entry of those trees into
`/usr`** — files of any extension and subtrees alike, enumerated rather than
pattern-matched. `nvcc` computes its include root *relative to its own executable*, and
`/usr/bin/nvcc` is a symlink, so anything not reachable under `/usr/include` cannot be
found: `cuda_runtime.h`'s own `#include` fails and every CUDA build dies at CMake's
`enable_language(CUDA)` with "No such file or directory". Matching on patterns produced
both of those failures, on both Arch arms, while every probe in this plan still passed
(opencharly/layer-cuda#9): first a `*.h` glob that linked the top-level headers but not
the `crt/` and `cccl/` subtrees, then the same glob missing the `.hpp` half of the
`_functions` family once the subtrees were linked. The check `cuda-arch-header-root`
preprocesses a real CUDA translation unit to prove the whole header root resolves.

With that stitch in place, the same `nvcc`, header, and library paths resolve
identically on Fedora and on Arch/CachyOS.

Expand Down
Loading