CUDA 12.8 support in nixpkgs

so this will take a little bit explanation, for any of you who run nixos-rebuild switch with latest kernel built/nvidia-driver, you will be using CUDA version 12.8 globally, you will be mostly fine if you are only developing python as this is explained quite well by claude:

This is because libraries like PyTorch and Numba are built to handle CUDA version compatibility more gracefully:

  1. PyTorch and Numba use the CUDA Runtime API in a more abstracted way:
  • They don’t directly initialize CUDA devices like our raw CUDA C code

  • They include version compatibility layers

  • They dynamically load CUDA libraries at runtime

However, if you are developing in raw C, you will have some sort of unknown cuda errors, that is mostly caused by cuda version mismatch, within a shell environment.

And the reason is the latest CUDA/cudapackages/toolkits nixpkgs can give you is 12.4.

AND THERE YOU HAVE IT PEOPLE. If i am forced to do the c development using a container like docker on nixos, that would be very silly people, that would be very silly.

worse yet, the CUDA wiki wrote by whoever is just large incompetent and very annoying with little useful information to say the least.

and when i find out arch linux has already updated their repo to include cuda 12.8, i genuinely felt sad for NixOS.

https://archlinux.org/packages/extra/x86_64/cuda/

is it anything I have done wrong?

this is my shell code

with import (fetchTarball "https://github.com/NixOS/nixpkgs/tarball/9aed71348bff9c6e142cc3f64206a128388494b9") {
  config = {
    allowUnfree = true;
  };
};

mkShell {
  buildInputs = [
    # CUDA 12.4 and matching NVIDIA drivers
    cudaPackages.cuda_cudart
    cudaPackages.cuda_nvcc
    cudaPackages.cuda_cccl
    linuxPackages.nvidia_x11

    # Other development tools
    gcc12
    gdb
    cmake
    gnumake
    ninja
    clang-tools
    valgrind
    libGLU libGL
    xorg.libXi xorg.libXmu freeglut
    xorg.libXext xorg.libX11 xorg.libXv xorg.libXrandr zlib
    pkg-config
    binutils
  ];

  shellHook = ''
    # NVIDIA Driver and CUDA setup
    export NVIDIA_VISIBLE_DEVICES=all
    export NVIDIA_DRIVER_CAPABILITIES=compute,utility
    export CUDA_VISIBLE_DEVICES=0

    # Path setup
    export PATH="${pkgs.gcc12}/bin:$PATH"
    export PATH=${pkgs.cudaPackages.cuda_nvcc}/bin:$PATH

    # CUDA setup
    export CUDAHOSTCXX="${pkgs.gcc12}/bin/g++"
    export CUDA_HOST_COMPILER="${pkgs.gcc12}/bin/gcc"
    export CUDA_HOME=${pkgs.cudaPackages.cuda_cudart}
    export CUDA_PATH=${pkgs.cudaPackages.cuda_cudart}

    # Library paths with specific NVIDIA driver
    export LD_LIBRARY_PATH=${pkgs.linuxPackages.nvidia_x11}/lib
    export LD_LIBRARY_PATH=${pkgs.cudaPackages.cuda_cudart}/lib64:${pkgs.cudaPackages.cuda_cudart}/lib:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=${stdenv.cc.cc.lib}/lib:$LD_LIBRARY_PATH

    export LIBRARY_PATH=${pkgs.cudaPackages.cuda_cudart}/lib64:${pkgs.cudaPackages.cuda_cudart}/lib:$LIBRARY_PATH

    # OpenGL driver path
    export LD_LIBRARY_PATH=${pkgs.linuxPackages.nvidia_x11}/lib:$LD_LIBRARY_PATH

    echo "CUDA C/C++ development environment ready"
    echo "GCC version in use:"
    gcc --version
    echo "NVCC version:"
    nvcc --version
    echo "SHELL NVIDIA driver version:"
    cat ${pkgs.linuxPackages.nvidia_x11}/lib/nvidia/version
  '';
}

and this is the c code for testing purpose:

#include <stdio.h>

int main() {
    int deviceCount;
    cudaError_t error = cudaGetDeviceCount(&deviceCount);

    if (error != cudaSuccess) {
        printf("cudaGetDeviceCount failed: %s\n", cudaGetErrorString(error));
        return -1;
    }

    printf("Number of CUDA devices: %d\n", deviceCount);

    for (int i = 0; i < deviceCount; i++) {
        cudaDeviceProp prop;
        error = cudaGetDeviceProperties(&prop, i);

        if (error != cudaSuccess) {
            printf("Failed to get properties for device %d: %s\n",
                   i, cudaGetErrorString(error));
            continue;
        }

        printf("Device %d: %s\n", i, prop.name);
        printf("  Compute Capability: %d.%d\n",
               prop.major, prop.minor);
        printf("  Total Global Memory: %lu MB\n",
               prop.totalGlobalMem / (1024*1024));
    }

    return 0;
}

// compile with: nvcc -I${CUDA_PATH}/include -L${CUDA_PATH}/lib64 -L${CUDA_PATH}/lib hello.cu -o hello

I really wish i made some silly mistakes and i am very wrong about nixos. If anyone can point me to the right direction and free me out of this frustration, that would be great.

I want to hear your opinion on this, thank you.

1 Like

Most likely your fetchurl is pinning your shell’s nixpkgs to an ancient version which is way behind your system, so you get an old cuda version in the shell.

Edit: Nope, you’re correct, nixpkgs doesn’t currently package that version. The latest currently available is 12.6, you could do the legwork of adding the new version upstream.

2 Likes

before I change my shell code, how do i even verify that nixpkgs already include the latest CUDA version, which is 12.8?

i went on google for ‘nix search’, I sure do not find anything.

Is there, by any chance, that an unstable channel would include CUDA 12.8? and an overlay to the cuda package will come into rescue?

tbh, it would be my honor to do so other than one small problem:

I dont know how.

And i thought there is a dedicated CUDA team of nix to be doing this, no?

https://search.nixos.org/packages

Well, good time to learn! Create a fork, make a feature branch, follow the docs, depend on your feature branch and see if you can get it to work. If you do you can try to upstream a PR; there are contributing docs in the repo root.

This is an open source project, if you’re paid to maintain the cuda ecosystem you’re lucky. Mostly it’ll be volunteers who need it for something, and clearly until now most people have been ok with slightly older versions for their use cases, or presumably been using cuda_compat. The cuda team is also just a few people who decided to get together to build some tooling they needed - if you’re experienced with cuda and its packaging, and have an interest in maintaining it, you’re probably welcome to join.

You might not entirely appreciate how much legwork is being done by a comparatively small number of people here. We’re all working together on a really complex project largely for the fun of it (though you will find the occasional commercial interest), demanding stuff be done for you without putting in at least the effort to understand what needs to be done - or paying someone to do that for you - is a quick way to burn any community goodwill you may have and not get any of what you want.

12 Likes

Otherwise i could do downgrade nvidia driver to 550 with cuda 12.6 instead. just so there is no conflicts.

But at the moment i cant think of any better alernatives

12.6 was merged yesterday: cudaPackages_12_6: init at 12.6.0 by danieldk · Pull Request #377991 · NixOS/nixpkgs · GitHub

No PR yet for 12.8

1 Like

Hey @lucassong3000 ,

This is not an appropriate way to communicate on this forum. Generally speaking, try to keep in mind open source maintainers don’t owe you anything.

The wiki is edited by the NixOS community. That includes you. If you feel like something is incorrect, it’s up to you to correct it.

Calling out people for being “incompetent” on public forums without contributing yourself is bad looks for you. Please refrain yourself from doing that again.

Let’s manage your expectations there.

As for most NixOS teams, the members are mostly nerds doing volunteer work on their sparetime.

You’re free to help them through bumping the CUDA packages yourself. Or, alternatively, feel free to try to contract some of them to bump the packages for you.

I removed some subthreads escalating the discussion in hope to keep the conversation constructive. I’ll close the thread if it continues to escalate.

22 Likes

Much of the dedicated team is busy securing resources to fix more CUDA issues in Nixpkgs

Generally speaking, pkgs.linuxPackages from a random Nixpkgs instance pkgs is not compatible with the running kernel. The userspace driver libcuda.so has to match the version string in the kernel module (.ko) exactly, otherwise the driver short circuits into an error. You never want to reference pkgs.linuxPackages.nvidia_x11, except as config.boot.kernelPackages.nvidia_x11 in a NixOS configuration. On NixOS CUDA programs load the kernel-compatible driver from /run/opengl-driver/lib/libcuda.so (grep Nixpkgs for usages of autoAddDriverRunpath). Outside NixOS the current status quo is to use wrappers (nixglhost or nixGL).

Note that LD_LIBRARY_PATH takes priority over DT_RUNPATH. Setting LD_LIBRARY_PATH means you disable the deterministic/“static” dynamic loading as configured by Nixpkgs, and force the program instead to load a potentially incompatible library from elsewhere.

To best of my knowledge they do not.

To the best of my knowledge they do, they either dlopen("cudart", ...) or even directly dlopen("cuda", ...) (not sure why, possibly linking pieces of static cudart); please link if there’s something I’m not aware of.

To the best of my knowledge they do not, they rely on the same compatibility guarantees promised by nvidia: cudart version at runtime >= cudart at build time && cudart at runtime <= cudaDriverGetVersion() && libcuda.so version == nvidia.ko (or equivalent) version unless using cuda_compat. EDIT(2025-02-24): the original message had the wrong sign for cudaRuntimeGetVersion vs cudaDriverGetVersion

Likely caused by LD_LIBRARY_PATH but hard to tell without logs

The wiki article hasn’t been updated in years, recent contributors have been mostly putting stuff in the Nixpkgs manual (which would still benefit from more work).

There’s instructions for updating the package set in the Nixpkgs manual (admittedly the current process is more involved and cumbersome than it should be)

This can be helped: it takes time, search, engagement with other users and contributors. Among other places, conversations in https://matrix.to/#/#cuda:nixos.org may be relevant

9 Likes

hello thank you for this break down of my original post here, I want to start by posting the shell.nix that i currently use for python development. please realize that this shell code will build a virtual environment for cuda 12.4, which is older than the cuda version of the nvidia driver, which is 12.8. without addressing any of your forward mentioned concerns, all gpu related python tests has passed flawlessly without returning any errors, I have tested pytorch with cuda, vllm, and numba with cuda so far.


with import (fetchTarball "https://github.com/NixOS/nixpkgs/tarball/9aed71348bff9c6e142cc3f64206a128388494b9") {
  config = {
    allowUnfree = true;
  };
};

let
  py-pkgs = python312Packages;
in pkgs.mkShell rec {
  name = "impurePythonEnv";
  venvDir = "./.venv";
  buildInputs = [
    # Python and venv
    py-pkgs.python
    py-pkgs.venvShellHook
    py-pkgs.zlib-ng

    # System tools
    gitRepo
    gnupg
    autoconf
    curl
    procps
    gnumake
    util-linux
    m4
    gperf
    unzip

    # CUDA and OpenGL
    cudatoolkit
    libGLU libGL
    xorg.libXi xorg.libXmu freeglut
    xorg.libXext xorg.libX11 xorg.libXv xorg.libXrandr zlib
    ncurses5
    stdenv.cc
    binutils
  ];

  # Run this command, only after creating the virtual environment
  postVenvCreation = ''
    unset SOURCE_DATE_EPOCH
    pip install -r requirements.txt
  '';

  # Now we can execute any commands within the virtual environment.
  postShellHook = ''
    # allow pip to install wheels
    unset SOURCE_DATE_EPOCH

    # CUDA setup
    export CUDA_HOME=${pkgs.cudatoolkit}
    export CUDA_PATH=${pkgs.cudatoolkit}

    # Library path setup - using system NVIDIA drivers
    export LD_LIBRARY_PATH=${stdenv.cc.cc.lib}/lib:/run/opengl-driver/lib
    export LD_LIBRARY_PATH="${pkgs.cudatoolkit}/lib64:${pkgs.cudatoolkit}/lib:$LD_LIBRARY_PATH"
    export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH"

    # Add CUDA bins to PATH
    export PATH=${pkgs.cudatoolkit}/bin:$PATH

    # CUDA specific flags
    export EXTRA_LDFLAGS="-L/lib -L${pkgs.cudatoolkit}/lib64 -L${pkgs.cudatoolkit}/lib"
    export EXTRA_CCFLAGS="-I/usr/include -I${pkgs.cudatoolkit}/include"
  '';
}


the troubles comes in soon as i want to convert this shell file into c language compatible, that i am unable to proper enable a cuda run environment for c.

If logs can help identify the exact problem i am willing to try, but at the moment, i think best way to solve the problem is either,

learn how to package the source and upstream PR to nixpkgs

or,

wait until cuda 12.8 to be merged.

with that said, I DO want to tell you that the source of this cuda package that i found from this official nvidia website download, does not support nixos.

fedora and ubuntu people can be laughing at us.

with that said,

It will be my honor to do anything to help merge cuda 12.8 into official nixpkgs. I will try to learn how to get started.

and thanks again for such detailed break down.

I do want to apology for my very inappropriate attitude towards OSS contributors and I am not in any position to judge their work let along the fact i have benefited from their work.

I hope i can contact the nix cuda team to get some more professional advices as to solve this cuda version compatibility issue.

it is my honor to be this part of the community because nixos has given me a completely different , yet very elegant in its own unique way, experience in the linux world, and i am loving it. I will be learning from people and from my own mistakes, and hopefully become a contributor myself.

thank you again for pointing out my bad acts and I shall refrain from doing again in this community.

good day.

10 Likes

So it has been a crazy night for me so far, the local cuda 12.8 built with success at last, this is the approach and shell.nix:


# shell.nix
let
  pkgs = import <nixpkgs> { config.allowUnfree = true; };
  cuda128 = pkgs.stdenv.mkDerivation rec {
    name = "cudatoolkit-12.8.0";
    version = "12.8.0";
    src = /home/alice7/.dev/test-cuda_with_C/cuda_12.8.0_570.86.10_linux.run;
    nativeBuildInputs = [ pkgs.autoPatchelfHook pkgs.makeWrapper pkgs.coreutils pkgs.bash ];
    buildInputs = [
      pkgs.stdenv.cc.cc.lib  # libgcc_s, libc
      pkgs.libxml2           # libxml2.so.2
      pkgs.cudaPackages.cuda_cupti  # libcupti.so.12 (from nixpkgs, might be 12.4, but should work)
      pkgs.rdma-core         # libibverbs.so.1, librdmacm.so.1
      # libmlx5.so.1 not directly in nixpkgs; part of Mellanox OFED, ignore for now
    ];
    autoPatchelfIgnoreMissingDeps = [
      "libmlx5.so.1"       # RDMA-specific, optional
      "libcuda.so.1"       # Driver stub, provided by NVIDIA driver at runtime
    ];
    unpackPhase = ''
      echo "Unpacking Makeself CUDA 12.8.0 archive from $src"
      cp $src cuda.run
      chmod +x cuda.run
      mkdir -p $out
      ./cuda.run --tar xvf -C $out
      echo "Extracted contents before rearrangement:"
      ls -lh $out/builds
      mkdir -p $out/bin $out/lib64 $out/include
      mv $out/builds/cuda_nvcc/bin/* $out/bin/ 2>/dev/null || true
      mv $out/builds/*/lib64/* $out/lib64/ 2>/dev/null || true
      mv $out/builds/*/include/* $out/include/ 2>/dev/null || true
      rm -rf $out/builds
      echo "Final extracted contents:"
      ls -lh $out/bin $out/lib64 $out/include
    '';
    installPhase = ''
      echo "Installing CUDA 12.8.0"
      ls -lh $out/bin
      for bin in $out/bin/*; do
        if [ -f "$bin" ] && [ -x "$bin" ]; then
          wrapProgram "$bin" --prefix LD_LIBRARY_PATH : "$out/lib64"
        fi
      done
    '';
    postFixup = ''
      echo "Patching libraries:"
      ls -lh $out/lib64
      for lib in $out/lib64/*.so; do
        patchelf --set-rpath "$out/lib64" $lib
      done
    '';
  };
in
pkgs.mkShell {
  buildInputs = [ cuda128 ];
}


and this is the running result for a quick testing within the shell:


alice7@nixos ~/.d/test-cuda_with_C> nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2025 NVIDIA Corporation
Built on Wed_Jan_15_19:20:09_PST_2025
Cuda compilation tools, release 12.8, V12.8.61
Build cuda_12.8.r12.8/compiler.35404655_0
alice7@nixos ~/.d/test-cuda_with_C> nvidia-smi
Sat Feb 22 11:15:52 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.86.16              Driver Version: 570.86.16      CUDA Version: 12.8     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4060 ...    Off |   00000000:01:00.0 Off |                  N/A |
| N/A   44C    P8              2W /   80W |      15MiB /   8188MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A            1877      G   ...me-shell-47.2/bin/gnome-shell          2MiB |
+-----------------------------------------------------------------------------------------+



I am very close to make this to work:


// hello.cu
#include <stdio.h>
__global__ void kernel() { printf("Hello from GPU!\n"); }
int main() {
  kernel<<<1,1>>>();
  cudaDeviceSynchronize();
  printf("Hello from CPU!\n");
  return 0;
}

// compile with: nvcc -I{$CUDA_PATH}/include -L{$CUDA_PATH}/lib64 -L{$CUDA_PATH}/lib hello.cu -o hello


it returns:


alice7@nixos ~/.d/test-cuda_with_C> nvcc -I{$CUDA_PATH}/include -L{$CUDA_PATH}/lib64 -L{$CUDA_PATH}/lib hello.cu -o hello
nvcc warning : Support for offline compilation for architectures prior to '<compute/sm/lto>_75' will be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
sh: line 1: /nix/store/1wvizkjikwvzdy8ni3gxqifflnlmjdw4-cudatoolkit-12.8.0/bin/../nvvm/bin/cicc: No such file or directory


1 Like

Perhaps the info on Cuda in this video might be helpfull also?

1 Like

Then let that carry onto all platforms, seems like your poor attitude persists over at reddit. Very sad.

1 Like

Well, OP has gotten one of the “dedicated” CUDA members defending themself from OP’s unwarranted criticism - that I dislike but OP has issued an apology and if it’s sincere than fine if not whatever. Let bygones be bygones as they say.

Changed post title (previous was “NixOS has no love for CUDA”) to reflect the new discussion.

And, yeah, the CUDA maintainers are pretty cool folks. :slight_smile:

6 Likes

thanks for the edit, so much to learn :hugs:

1 Like