build: drop the CUDA toolkit dependency - #1
Merged
Conversation
This was referenced Sep 1, 2026
richardkiene
force-pushed
the
build/drop-cuda-toolkit-dependency
branch
from
September 1, 2026 16:15
0550899 to
ced66b6
Compare
nvfd only needs NVML, and NVML ships with every NVIDIA driver as libnvidia-ml.so.1. The only reason the CUDA toolkit was required was nvml.h, and installing the toolkit through a distribution package (nvidia-cuda-toolkit on Debian/Ubuntu) can replace or pin the driver on the host. On Ubuntu 22.04 the packaged header is also CUDA 11.5, which predates nvmlDeviceSetFanControlPolicy, so the #ifdef in fan.c silently compiled the auto-restore path out. - Add include/nvml_api.h declaring the 17 NVML entry points nvfd calls, with the enum values and struct layouts from nvml.h. Signatures are part of the versioned ABI (_v2 suffixes), so this is stable. - Link by SONAME (-l:libnvidia-ml.so.1) so no libnvidia-ml.so dev symlink is needed either. Compile with -Werror=implicit-function-declaration so an undeclared NVML call is a build error, not a silent implicit int. - nvmlDeviceSetFanControlPolicy is always compiled in and its result checked. Minimum driver is R520: the first branch exporting every symbol (Set*FanSpeed_v2 are R515; SetFanControlPolicy is 520.61.05, backported to 515.105.01). - install.sh: stop installing nvidia-cuda-toolkit. Preflight libnvidia-ml.so.1 via ldconfig before installing anything, build, probe NVML with the fresh build/nvfd list (which also runs the v1.x migration), and only then stop the old service, install and start, so an NVML failure leaves the host untouched instead of half-upgraded. The link directory comes from the same ldconfig line, so the linker searches where ld.so actually resolves the library. - CI: build without the toolkit, and link against a stub libnvidia-ml.so.1 built from tests/nvml_stub.c, which defines every declared entry point with the same signature. This exercises the -l: link line and the symbol set, and fails to compile if nvml_api.h drifts.
richardkiene
force-pushed
the
build/drop-cuda-toolkit-dependency
branch
from
September 1, 2026 16:30
ced66b6 to
fa27c20
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
nvfd only needs NVML, and NVML ships with every NVIDIA driver as
libnvidia-ml.so.1. The only reason the CUDA toolkit was required wasnvml.h— and installing the toolkit through a distribution package (apt-get install nvidia-cuda-toolkitininstall.sh) can replace or pin the NVIDIA driver on the host. On Ubuntu 22.04 the packaged header is also CUDA 11.5, which predatesnvmlDeviceSetFanControlPolicy, so the#ifdefinfan.csilently compiled the auto-restore path out.What
include/nvml_api.hdeclares the 17 NVML entry points nvfd calls, with the enum values and struct layouts fromnvml.h. These are part of the versioned ABI (_v2suffixes) and do not change.-l:libnvidia-ml.so.1) so nolibnvidia-ml.sodev symlink is needed either.-Werror=implicit-function-declaration, so an NVML call that is not declared is a build error rather than an implicitint.nvmlDeviceSetFanControlPolicyis always compiled in and its result is checked. Minimum driver is R520 (first branch exporting every symbol;Set*FanSpeed_v2are R515,SetFanControlPolicyis 520.61.05 / backported to 515.105.01).install.sh: no longer installsnvidia-cuda-toolkit. Preflightslibnvidia-ml.so.1vialdconfig -pbefore installing anything, builds, probes NVML with the freshbuild/nvfd list(which also runs the v1.x migration), and only then stops the old service, installs and starts — an NVML failure leaves the host untouched. The link directory is taken from the sameldconfigline.libnvidia-ml.so.1built fromtests/nvml_stub.c, which defines every declared entry point with the same signature — so both the link line and the symbol set are exercised, and the stub fails to compile ifnvml_api.hdrifts.Verified
All 17 symbols resolve in driver 595.84's
libnvidia-ml.so.1(nm -D /lib/x86_64-linux-gnu/libnvidia-ml.so.1, Ubuntu 22.04.5). Code review mechanically checked every prototype, enum value, struct layout and unversioned→_v2macro against nvml.h from CUDA 12.0 and the current API-13 header (function-pointer_Static_assertequivalence), confirmednvmlDeviceGetMemoryInfois not auto-upgraded to_v2, and verified the-l:link with ld.lld against a.so.1-only directory.