Recently i got my hands on a nvidia GPU. I wanted to use my integrated AMD GPU for display and the nvidia GPU for computing only. This seems like a fairly reasonable setup, but the wiki doesn’t have any information on how to do it.
The wiki suggests
services.xserver.videoDrivers = [ "nvidia" ]; which is incompatible with the above setup. Suprisingly,
services.xserver.videoDrivers = [ "nvidia" "amdgpu" ]; also doesn’t work because my compositor could no longer find the required mesa libraries.
Anyway, ignoring the attribute
services.xserver.videoDrivers, I got it working fairly painlessly, so I thought I would describe how here, so maybe we can add it to the wiki.
Firstly I had to set integrated graphics as default in the UEFI bios. Without this, I couldn’t even even get to the motherboard splash screen without the external GPU plugged in to a monitor.
Here are the relevent parts of
nixpkgs.config.allowUnfree = true;
boot.extraModulePackages = [ pkgs.linuxPackages.nvidia_x11 ];
boot.blacklistedKernelModules = [ "nouveau" "nvidia_drm" "nvidia_modeset" "nvidia" ];
packages = [ pkgs.linuxPackages.nvidia_x11 ];
nixpkgs.config.allowUnfree is self explanatory: nvidia drivers are not open source.
boot.extraModulePackages adds the nvidia drivers to the list of available linux modules.
boot.blacklistedKernelModules is the list of modules blacklisted from being loaded automatically on startup. We need to blacklist the open source nvidia driver and all the modules from the propitiatory driver because if any one of them gets loaded, it somehow loads all the other ones .
Now, if you try
sudo modprobe nvidia, the module gets loaded, but there is some other system initialization which is needed for the GPU to function correctly. I read on the nvidia forums that
nvidia-smi will initialize the device if you run it as root, and this is why we include the driver in
packages as it puts
nvidia-smi into scope.
When you want to initialize the GPU, just run
sudo nvidia-smi rather than loading the kernel modules directly, and you should be good to go!