cudaPackages: name and consolidate use of fixups pattern

Signed-off-by: Connor Baker <ConnorBaker01@gmail.com>
This commit is contained in:
Connor Baker 2025-05-07 16:13:32 +00:00 committed by SomeoneSerge
parent b03feee1ee
commit ab39a0fffa
32 changed files with 835 additions and 812 deletions

View file

@ -27,6 +27,12 @@ scope. These are typically required for the creation of the finalized
to `cudaPackages` scope.
- `cudnn`: NVIDIA cuDNN library.
- `cutensor`: NVIDIA cuTENSOR library.
- `fixups`: Each file or directory (excluding `default.nix`) should contain a
`callPackage`-able expression to be provided to the `overrideAttrs` attribute
of a package produced by the generic manifest builder.
These fixups are applied by `pname`, so packages with multiple versions
(e.g., `cudnn`, `cudnn_8_9`, etc.) all share a single fixup function
(i.e., `fixups/cudnn.nix`).
- `generic-builders`:
- Contains a builder `manifest.nix` which operates on the `Manifest` type
defined in `modules/generic/manifests`. Most packages are built using this

View file

@ -1,36 +1,33 @@
{
lib,
backendStdenv,
fetchFromGitHub,
cmake,
addDriverRunpath,
autoAddDriverRunpath,
cudatoolkit,
cutensor,
cusparselt,
cudaPackages,
setupCudaHook,
autoPatchelfHook,
backendStdenv,
cmake,
cuda_cccl ? null,
cuda_cudart ? null,
cuda_nvcc ? null,
cudaAtLeast,
cudaOlder,
cudatoolkit,
cusparselt ? null,
cutensor ? null,
fetchFromGitHub,
lib,
libcusparse ? null,
setupCudaHook,
}:
let
inherit (cudaPackages)
cuda_cccl
cuda_cudart
cuda_nvcc
libcusparse
cudaAtLeast
cudaOlder
;
rev = "e57b9c483c5384b7b97b7d129457e5a9bdcdb5e1";
src = fetchFromGitHub {
owner = "NVIDIA";
repo = "CUDALibrarySamples";
inherit rev;
sha256 = "0g17afsmb8am0darxchqgjz1lmkaihmnn7k1x4ahg5gllcmw8k3l";
};
commonAttrs = {
version = lib.strings.substring 0 7 rev + "-" + lib.versions.majorMinor cudatoolkit.version;
base = backendStdenv.mkDerivation (finalAttrs: {
src = fetchFromGitHub {
owner = "NVIDIA";
repo = "CUDALibrarySamples";
rev = "e57b9c483c5384b7b97b7d129457e5a9bdcdb5e1";
sha256 = "0g17afsmb8am0darxchqgjz1lmkaihmnn7k1x4ahg5gllcmw8k3l";
};
version =
lib.strings.substring 0 7 finalAttrs.src.rev + "-" + lib.versions.majorMinor cudatoolkit.version;
nativeBuildInputs = [
cmake
addDriverRunpath
@ -53,64 +50,63 @@ let
maintainers = with lib.maintainers; [ obsidian-systems-maintenance ];
teams = [ lib.teams.cuda ];
};
};
});
in
{
cublas = backendStdenv.mkDerivation (
commonAttrs
// {
cublas = base.overrideAttrs (
finalAttrs: _: {
pname = "cuda-library-samples-cublas";
src = "${src}/cuBLASLt";
sourceRoot = "${finalAttrs.src.name}/cuBLASLt";
}
);
cusolver = backendStdenv.mkDerivation (
commonAttrs
// {
cusolver = base.overrideAttrs (
finalAttrs: _: {
pname = "cuda-library-samples-cusolver";
src = "${src}/cuSOLVER";
sourceRoot = "cuSOLVER/gesv";
sourceRoot = "${finalAttrs.src.name}/cuSOLVER/gesv";
}
);
cutensor = backendStdenv.mkDerivation (
commonAttrs
// {
cutensor = base.overrideAttrs (
finalAttrs: prevAttrs: {
pname = "cuda-library-samples-cutensor";
src = "${src}/cuTENSOR";
sourceRoot = "${finalAttrs.src.name}/cuTENSOR";
buildInputs = [ cutensor ];
buildInputs = prevAttrs.buildInputs or [ ] ++ [ cutensor ];
cmakeFlags = [ "-DCUTENSOR_EXAMPLE_BINARY_INSTALL_DIR=${builtins.placeholder "out"}/bin" ];
cmakeFlags = prevAttrs.cmakeFlags or [ ] ++ [
"-DCUTENSOR_EXAMPLE_BINARY_INSTALL_DIR=${builtins.placeholder "out"}/bin"
];
# CUTENSOR_ROOT is double escaped
postPatch = ''
substituteInPlace CMakeLists.txt \
--replace-fail "\''${CUTENSOR_ROOT}/include" "${cutensor.dev}/include"
'';
postPatch =
prevAttrs.postPatch or ""
+ ''
substituteInPlace CMakeLists.txt \
--replace-fail "\''${CUTENSOR_ROOT}/include" "${lib.getDev cutensor}/include"
'';
CUTENSOR_ROOT = cutensor;
meta = prevAttrs.meta or { } // {
broken = cutensor == null;
};
}
);
cusparselt = backendStdenv.mkDerivation (
commonAttrs
// {
cusparselt = base.overrideAttrs (
finalAttrs: prevAttrs: {
pname = "cuda-library-samples-cusparselt";
src = "${src}/cuSPARSELt";
sourceRoot = "${finalAttrs.src.name}/cuSPARSELt/matmul";
sourceRoot = "cuSPARSELt/matmul";
buildInputs = lib.optionals (cudaOlder "11.4") [ cudatoolkit ];
buildInputs = prevAttrs.buildInputs or [ ] ++ lib.optionals (cudaOlder "11.4") [ cudatoolkit ];
nativeBuildInputs =
[
prevAttrs.nativeBuildInputs or [ ]
++ [
cmake
addDriverRunpath
(lib.getDev cusparselt)
@ -125,22 +121,34 @@ in
cuda_cccl # <nv/target>
];
postPatch = ''
substituteInPlace CMakeLists.txt \
--replace-fail "''${CUSPARSELT_ROOT}/lib64/libcusparseLt.so" "${lib.getLib cusparselt}/lib/libcusparseLt.so" \
--replace-fail "''${CUSPARSELT_ROOT}/lib64/libcusparseLt_static.a" "${lib.getStatic cusparselt}/lib/libcusparseLt_static.a"
'';
postPatch =
prevAttrs.postPatch or ""
+ ''
substituteInPlace CMakeLists.txt \
--replace-fail "''${CUSPARSELT_ROOT}/lib64/libcusparseLt.so" "${lib.getLib cusparselt}/lib/libcusparseLt.so" \
--replace-fail "''${CUSPARSELT_ROOT}/lib64/libcusparseLt_static.a" "${lib.getStatic cusparselt}/lib/libcusparseLt_static.a"
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp matmul_example $out/bin/
cp matmul_example_static $out/bin/
runHook postInstall
'';
postInstall =
prevAttrs.postInstall or ""
+ ''
mkdir -p $out/bin
cp matmul_example $out/bin/
cp matmul_example_static $out/bin/
'';
CUDA_TOOLKIT_PATH = lib.getLib cudatoolkit;
CUSPARSELT_PATH = lib.getLib cusparselt;
meta = prevAttrs.meta or { } // {
broken =
# Base dependencies
(cusparselt == null || libcusparse == null)
# CUDA 11.4+ dependencies
|| (cudaAtLeast "11.4" && (cuda_nvcc == null || cuda_cudart == null))
# CUDA 12.0+ dependencies
|| (cudaAtLeast "12.0" && cuda_cccl == null);
};
}
);
}

View file

@ -53,42 +53,13 @@ let
# buildRedistPackage : callPackage -> PackageName -> Derivation
buildRedistPackage =
callPackage: pname:
let
callPackage ../generic-builders/manifest.nix {
inherit pname redistName;
# We pass the whole release to the builder because it has logic to handle
# the case we're trying to build on an unsupported platform.
redistribRelease = redistribManifest.${pname};
featureRelease = featureManifest.${pname};
drv =
let
# get `autoAddDriverRunpath` from pkgs instead of cudaPackages' alias to avoid warning
inherit (callPackage ({ pkgs }: pkgs) { }) autoAddDriverRunpath;
in
(callPackage ../generic-builders/manifest.nix {
# We pass the whole release to the builder because it has logic to handle
# the case we're trying to build on an unsupported platform.
inherit
pname
redistName
redistribRelease
featureRelease
autoAddDriverRunpath
;
}).overrideAttrs
(prevAttrs: {
# Add the package-specific license.
meta = prevAttrs.meta // {
license =
let
licensePath =
if redistribRelease.license_path != null then
redistribRelease.license_path
else
"${pname}/LICENSE.txt";
url = "https://developer.download.nvidia.com/compute/cuda/redist/${licensePath}";
in
lib.licenses.nvidiaCudaRedist // { inherit url; };
};
});
in
drv;
};
# Build all the redist packages given final and prev.
redistPackages =

View file

@ -1,490 +0,0 @@
let
filterAndCreateOverrides =
createOverrideAttrs: final: prev:
let
# It is imperative that we use `final.callPackage` to perform overrides,
# so the final package set is available to the override functions.
inherit (final) callPackage;
# NOTE(@connorbaker): We MUST use `lib` from `prev` because the attribute
# names CAN NOT depend on `final`.
inherit (prev.lib.attrsets) filterAttrs mapAttrs;
inherit (prev.lib.trivial) pipe;
# NOTE: Filter out attributes that are not present in the previous version of
# the package set. This is necessary to prevent the appearance of attributes
# like `cuda_nvcc` in `cudaPackages_10_0, which predates redistributables.
filterOutNewAttrs = filterAttrs (name: _: prev ? ${name});
# Apply callPackage to each attribute value, yielding a value to be passed
# to overrideAttrs.
callPackageThenOverrideAttrs = mapAttrs (
name: value: prev.${name}.overrideAttrs (callPackage value { })
);
in
pipe createOverrideAttrs [
filterOutNewAttrs
callPackageThenOverrideAttrs
];
in
# Each attribute name is the name of an existing package in the previous version
# of the package set.
# The value is a function (to be provided to callPackage), which yields a value
# to be provided to overrideAttrs. This allows us to override the attributes of
# a package without losing access to the fixed point of the package set --
# especially useful given that some packages may depend on each other!
filterAndCreateOverrides {
libcufile =
{
cudaOlder,
lib,
libcublas,
numactl,
rdma-core,
}:
prevAttrs: {
buildInputs = prevAttrs.buildInputs ++ [
libcublas
numactl
rdma-core
];
# Before 11.7 libcufile depends on itself for some reason.
autoPatchelfIgnoreMissingDeps =
prevAttrs.autoPatchelfIgnoreMissingDeps
++ lib.lists.optionals (cudaOlder "11.7") [ "libcufile.so.0" ];
};
libcusolver =
{
cudaAtLeast,
lib,
libcublas,
libcusparse ? null,
libnvjitlink ? null,
}:
prevAttrs: {
buildInputs =
prevAttrs.buildInputs
# Always depends on this
++ [ libcublas ]
# Dependency from 12.0 and on
++ lib.lists.optionals (cudaAtLeast "12.0") [ libnvjitlink ]
# Dependency from 12.1 and on
++ lib.lists.optionals (cudaAtLeast "12.1") [ libcusparse ];
brokenConditions = prevAttrs.brokenConditions // {
"libnvjitlink missing (CUDA >= 12.0)" =
!(cudaAtLeast "12.0" -> (libnvjitlink != null && libnvjitlink != null));
"libcusparse missing (CUDA >= 12.1)" =
!(cudaAtLeast "12.1" -> (libcusparse != null && libcusparse != null));
};
};
libcusparse =
{
cudaAtLeast,
lib,
libnvjitlink ? null,
}:
prevAttrs: {
buildInputs =
prevAttrs.buildInputs
# Dependency from 12.0 and on
++ lib.lists.optionals (cudaAtLeast "12.0") [ libnvjitlink ];
brokenConditions = prevAttrs.brokenConditions // {
"libnvjitlink missing (CUDA >= 12.0)" =
!(cudaAtLeast "12.0" -> (libnvjitlink != null && libnvjitlink != null));
};
};
# TODO(@connorbaker): cuda_cudart.dev depends on crt/host_config.h, which is from
# (getDev cuda_nvcc). It would be nice to be able to encode that.
cuda_cudart =
{ addDriverRunpath, lib }:
prevAttrs: {
# Remove once cuda-find-redist-features has a special case for libcuda
outputs =
prevAttrs.outputs
++ lib.lists.optionals (!(builtins.elem "stubs" prevAttrs.outputs)) [ "stubs" ];
allowFHSReferences = false;
# The libcuda stub's pkg-config doesn't follow the general pattern:
postPatch =
prevAttrs.postPatch or ""
+ ''
while IFS= read -r -d $'\0' path; do
sed -i \
-e "s|^libdir\s*=.*/lib\$|libdir=''${!outputLib}/lib/stubs|" \
-e "s|^Libs\s*:\(.*\)\$|Libs: \1 -Wl,-rpath,${addDriverRunpath.driverLink}/lib|" \
"$path"
done < <(find -iname 'cuda-*.pc' -print0)
''
# Namelink may not be enough, add a soname.
# Cf. https://gitlab.kitware.com/cmake/cmake/-/issues/25536
+ ''
if [[ -f lib/stubs/libcuda.so && ! -f lib/stubs/libcuda.so.1 ]]; then
ln -s libcuda.so lib/stubs/libcuda.so.1
fi
'';
postFixup =
prevAttrs.postFixup or ""
+ ''
moveToOutput lib/stubs "$stubs"
ln -s "$stubs"/lib/stubs/* "$stubs"/lib/
ln -s "$stubs"/lib/stubs "''${!outputLib}/lib/stubs"
'';
};
cuda_compat =
{ flags, lib }:
prevAttrs: {
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps ++ [
"libnvrm_gpu.so"
"libnvrm_mem.so"
"libnvdla_runtime.so"
];
# `cuda_compat` only works on aarch64-linux, and only when building for Jetson devices.
badPlatformsConditions = prevAttrs.badPlatformsConditions // {
"Trying to use cuda_compat on aarch64-linux targeting non-Jetson devices" = !flags.isJetsonBuild;
};
};
cuda_gdb =
{
cudaAtLeast,
gmp,
expat,
libxcrypt-legacy,
ncurses6,
python310,
python311,
python312,
stdenv,
lib,
}:
prevAttrs: {
buildInputs =
prevAttrs.buildInputs
# x86_64 only needs gmp from 12.0 and on
++ lib.lists.optionals (cudaAtLeast "12.0") [ gmp ]
# Additional dependencies for CUDA 12.5 and later, which
# support multiple Python versions.
++ lib.lists.optionals (cudaAtLeast "12.5") [
libxcrypt-legacy
ncurses6
python310
python311
python312
]
# aarch64,sbsa needs expat
++ lib.lists.optionals (stdenv.hostPlatform.isAarch64) [ expat ];
installPhase =
prevAttrs.installPhase
# Python 3.8 is not in nixpkgs anymore, delete Python 3.8 cuda-gdb support
# to avoid autopatchelf failing to find libpython3.8.so.
+ lib.optionalString (cudaAtLeast "12.5") ''
find $bin -name '*python3.8*' -delete
find $bin -name '*python3.9*' -delete
'';
};
cuda_nvcc =
{
lib,
backendStdenv,
cudaOlder,
setupCudaHook,
}:
prevAttrs: {
# Merge "bin" and "dev" into "out" to avoid circular references
outputs = builtins.filter (
x:
!(builtins.elem x [
"dev"
"bin"
])
) prevAttrs.outputs;
# Patch the nvcc.profile.
# Syntax:
# - `=` for assignment,
# - `?=` for conditional assignment,
# - `+=` to "prepend",
# - `=+` to "append".
# Cf. https://web.archive.org/web/20230308044351/https://arcb.csc.ncsu.edu/~mueller/cluster/nvidia/2.0/nvcc_2.0.pdf
# We set all variables with the lowest priority (=+), but we do force
# nvcc to use the fixed backend toolchain. Cf. comments in
# backend-stdenv.nix
postPatch =
let
nvvmReplace = lib.optionalString (cudaOlder "12.5") ''
--replace-fail \
'$(TOP)/$(_NVVM_BRANCH_)' \
"''${!outputBin}/nvvm" \
'';
in
(prevAttrs.postPatch or "")
+ ''
substituteInPlace bin/nvcc.profile \
--replace-fail \
'$(TOP)/$(_TARGET_DIR_)/include' \
"''${!outputDev}/include" \
${nvvmReplace}
cat << EOF >> bin/nvcc.profile
# Fix a compatible backend compiler
PATH += "${backendStdenv.cc}/bin":
# Expose the split-out nvvm
LIBRARIES =+ "-L''${!outputBin}/nvvm/lib"
INCLUDES =+ "-I''${!outputBin}/nvvm/include"
EOF
'';
# NOTE(@connorbaker):
# Though it might seem odd or counter-intuitive to add the setup hook to `propagatedBuildInputs` instead of
# `propagatedNativeBuildInputs`, it is necessary! If you move the setup hook from `propagatedBuildInputs` to
# `propagatedNativeBuildInputs`, it stops being propagated to downstream packages during their build because
# setup hooks in `propagatedNativeBuildInputs` are not designed to affect the runtime or build environment of
# dependencies; they are only meant to affect the build environment of the package that directly includes them.
propagatedBuildInputs = (prevAttrs.propagatedBuildInputs or [ ]) ++ [ setupCudaHook ];
postInstall =
(prevAttrs.postInstall or "")
+ ''
moveToOutput "nvvm" "''${!outputBin}"
'';
# The nvcc and cicc binaries contain hard-coded references to /usr
allowFHSReferences = true;
meta = (prevAttrs.meta or { }) // {
mainProgram = "nvcc";
};
};
cuda_nvprof = { cuda_cupti }: prevAttrs: { buildInputs = prevAttrs.buildInputs ++ [ cuda_cupti ]; };
cuda_demo_suite =
{
libglut,
libcufft,
libcurand,
libGLU,
libglvnd,
libgbm,
}:
prevAttrs: {
buildInputs = prevAttrs.buildInputs ++ [
libglut
libcufft
libcurand
libGLU
libglvnd
libgbm
];
};
cuda_sanitizer_api = _: _: { outputs = [ "out" ]; };
fabricmanager = { zlib }: prevAttrs: { buildInputs = prevAttrs.buildInputs ++ [ zlib ]; };
imex = { zlib }: prevAttrs: { buildInputs = prevAttrs.buildInputs ++ [ zlib ]; };
nsight_compute =
{
lib,
qt5 ? null,
qt6 ? null,
rdma-core,
stdenv,
}:
prevAttrs:
let
inherit (lib.strings) versionOlder versionAtLeast;
inherit (prevAttrs) version;
qt = if versionOlder version "2022.2.0" then qt5 else qt6;
qtwayland =
if lib.versions.major qt.qtbase.version == "5" then
lib.getBin qt.qtwayland
else
lib.getLib qt.qtwayland;
inherit (qt) wrapQtAppsHook qtwebview;
archDir =
{
aarch64-linux = "linux-desktop-t210-a64";
x86_64-linux = "linux-desktop-glibc_2_11_3-x64";
}
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
in
{
nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ wrapQtAppsHook ];
buildInputs = prevAttrs.buildInputs ++ [
qtwayland
qtwebview
(qt.qtwebengine or qt.full)
rdma-core
];
dontWrapQtApps = true;
preInstall = ''
rm -rf host/${archDir}/Mesa/
'';
postInstall = ''
moveToOutput 'ncu' "''${!outputBin}/bin"
moveToOutput 'ncu-ui' "''${!outputBin}/bin"
moveToOutput 'host/${archDir}' "''${!outputBin}/bin"
moveToOutput 'target/${archDir}' "''${!outputBin}/bin"
wrapQtApp "''${!outputBin}/bin/host/${archDir}/ncu-ui.bin"
'';
preFixup = ''
# lib needs libtiff.so.5, but nixpkgs provides libtiff.so.6
patchelf --replace-needed libtiff.so.5 libtiff.so "''${!outputBin}/bin/host/${archDir}/Plugins/imageformats/libqtiff.so"
'';
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps ++ [
"libnvidia-ml.so.1"
];
brokenConditions = prevAttrs.brokenConditions // {
"Qt 5 missing (<2022.2.0)" = !(versionOlder version "2022.2.0" -> qt5 != null);
"Qt 6 missing (>=2022.2.0)" = !(versionAtLeast version "2022.2.0" -> qt6 != null);
};
};
nsight_systems =
{
boost178,
cuda_cudart,
cudaOlder,
gst_all_1,
lib,
nss,
numactl,
pulseaudio,
qt5 ? null,
qt6 ? null,
rdma-core,
stdenv,
ucx,
wayland,
xorg,
}:
prevAttrs:
let
inherit (lib.strings) versionOlder versionAtLeast;
inherit (prevAttrs) version;
qt = if lib.strings.versionOlder prevAttrs.version "2022.4.2.1" then qt5 else qt6;
qtwayland =
if lib.versions.major qt.qtbase.version == "5" then
lib.getBin qt.qtwayland
else
lib.getLib qt.qtwayland;
qtWaylandPlugins = "${qtwayland}/${qt.qtbase.qtPluginPrefix}";
hostDir =
{
aarch64-linux = "host-linux-armv8";
x86_64-linux = "host-linux-x64";
}
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
targetDir =
{
aarch64-linux = "target-linux-sbsa-armv8";
x86_64-linux = "target-linux-x64";
}
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
versionString = with lib.versions; "${majorMinor version}.${patch version}";
in
{
# An ad hoc replacement for
# https://github.com/ConnorBaker/cuda-redist-find-features/issues/11
env.rmPatterns = toString [
"nsight-systems/${versionString}/${hostDir}/lib{arrow,jpeg}*"
"nsight-systems/${versionString}/${hostDir}/lib{ssl,ssh,crypto}*"
"nsight-systems/${versionString}/${hostDir}/libboost*"
"nsight-systems/${versionString}/${hostDir}/libexec"
"nsight-systems/${versionString}/${hostDir}/libstdc*"
"nsight-systems/${versionString}/${hostDir}/python/bin/python"
"nsight-systems/${versionString}/${hostDir}/Mesa"
];
postPatch =
prevAttrs.postPatch or ""
+ ''
for path in $rmPatterns; do
rm -r "$path"
done
patchShebangs nsight-systems
'';
nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ qt.wrapQtAppsHook ];
dontWrapQtApps = true;
buildInputs = prevAttrs.buildInputs ++ [
(qt.qtdeclarative or qt.full)
(qt.qtsvg or qt.full)
(qt.qtimageformats or qt.full)
(qt.qtpositioning or qt.full)
(qt.qtscxml or qt.full)
(qt.qttools or qt.full)
(qt.qtwebengine or qt.full)
(qt.qtwayland or qt.full)
boost178
cuda_cudart.stubs
gst_all_1.gst-plugins-base
gst_all_1.gstreamer
nss
numactl
pulseaudio
qt.qtbase
qtWaylandPlugins
rdma-core
ucx
wayland
xorg.libXcursor
xorg.libXdamage
xorg.libXrandr
xorg.libXtst
];
postInstall =
# 1. Move dependencies of nsys, nsys-ui binaries to bin output
# 2. Fix paths in wrapper scripts
''
moveToOutput 'nsight-systems/${versionString}/${hostDir}' "''${!outputBin}"
moveToOutput 'nsight-systems/${versionString}/${targetDir}' "''${!outputBin}"
moveToOutput 'nsight-systems/${versionString}/bin' "''${!outputBin}"
substituteInPlace $bin/bin/nsys $bin/bin/nsys-ui \
--replace-fail 'nsight-systems-#VERSION_RSPLIT#' nsight-systems/${versionString}
wrapQtApp "$bin/nsight-systems/${versionString}/${hostDir}/nsys-ui.bin"
'';
preFixup = ''
# lib needs libtiff.so.5, but nixpkgs provides libtiff.so.6
patchelf --replace-needed libtiff.so.5 libtiff.so $bin/nsight-systems/${versionString}/${hostDir}/Plugins/imageformats/libqtiff.so
'';
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps ++ [
"libnvidia-ml.so.1"
];
brokenConditions = prevAttrs.brokenConditions // {
"Qt 5 missing (<2022.4.2.1)" = !(versionOlder version "2022.4.2.1" -> qt5 != null);
"Qt 6 missing (>=2022.4.2.1)" = !(versionAtLeast version "2022.4.2.1" -> qt6 != null);
};
badPlatformsConditions = prevAttrs.badPlatformsConditions // {
# Older releases require boost 1.70, which is deprecated in Nixpkgs
"CUDA too old (<11.8)" = cudaOlder "11.8";
};
};
nvidia_driver =
{ }:
prevAttrs: {
badPlatformsConditions = prevAttrs.badPlatformsConditions // {
"Package is not supported; use drivers from linuxPackages" = true;
};
};
}

View file

@ -1,75 +0,0 @@
{
cudaVersion,
fetchurl,
final,
lib,
package,
patchelf,
zlib,
...
}:
let
inherit (lib)
lists
maintainers
meta
strings
;
in
finalAttrs: prevAttrs: {
src = fetchurl { inherit (package) url hash; };
# Useful for inspecting why something went wrong.
badPlatformsConditions =
let
cudaTooOld = strings.versionOlder cudaVersion package.minCudaVersion;
cudaTooNew =
(package.maxCudaVersion != null) && strings.versionOlder package.maxCudaVersion cudaVersion;
in
prevAttrs.badPlatformsConditions
// {
"CUDA version is too old" = cudaTooOld;
"CUDA version is too new" = cudaTooNew;
};
buildInputs =
prevAttrs.buildInputs
++ [ zlib ]
++ lists.optionals finalAttrs.passthru.useCudatoolkitRunfile [ final.cudatoolkit ]
++ lists.optionals (!finalAttrs.passthru.useCudatoolkitRunfile) [ final.libcublas.lib ];
# Tell autoPatchelf about runtime dependencies. *_infer* libraries only
# exist in CuDNN 8.
# NOTE: Versions from CUDNN releases have four components.
postFixup =
strings.optionalString
(
strings.versionAtLeast finalAttrs.version "8.0.5.0"
&& strings.versionOlder finalAttrs.version "9.0.0.0"
)
''
${meta.getExe patchelf} $lib/lib/libcudnn.so --add-needed libcudnn_cnn_infer.so
${meta.getExe patchelf} $lib/lib/libcudnn_ops_infer.so --add-needed libcublas.so --add-needed libcublasLt.so
'';
passthru.useCudatoolkitRunfile = strings.versionOlder cudaVersion "11.3.999";
meta = prevAttrs.meta // {
homepage = "https://developer.nvidia.com/cudnn";
maintainers =
prevAttrs.meta.maintainers or [ ]
++ (with maintainers; [
mdaiter
samuela
connorbaker
]);
teams = prevAttrs.meta.teams or [ ];
license = {
shortName = "cuDNN EULA";
fullName = "NVIDIA cuDNN Software License Agreement (EULA)";
url = "https://docs.nvidia.com/deeplearning/sdk/cudnn-sla/index.html#supplement";
free = false;
redistributable = !finalAttrs.passthru.useCudatoolkitRunfile;
};
};
}

View file

@ -8,6 +8,7 @@
}:
{
featureRelease = lib.optionalAttrs (redistArch != "unsupported") {
inherit (package) minCudaVersion maxCudaVersion;
${redistArch}.outputs = {
lib = true;
static = true;
@ -16,6 +17,6 @@
};
redistribRelease = {
name = "NVIDIA CUDA Deep Neural Network library (cuDNN)";
inherit (package) version;
inherit (package) hash url version;
};
}

View file

@ -12,8 +12,6 @@ let
attrsets
lists
modules
versions
strings
trivial
;
@ -65,14 +63,6 @@ let
# - 11.0
# - 12
# libPath :: String
libPath =
let
cudaMajorMinor = versions.majorMinor cudaVersion;
cudaMajor = versions.major cudaVersion;
in
if cudaMajorMinor == "10.2" then cudaMajorMinor else cudaMajor;
# A release is supported if it has a libPath that matches our CUDA version for our platform.
# LibPath are not constant across the same release -- one platform may support fewer
# CUDA versions than another.
@ -109,30 +99,8 @@ let
redistribRelease = redistrib.${pname};
featureRelease = feature.${pname};
};
fixedDrv = drv.overrideAttrs (prevAttrs: {
buildInputs =
prevAttrs.buildInputs
++ lists.optionals (strings.versionOlder cudaVersion "11.4") [ final.cudatoolkit ]
++ lists.optionals (strings.versionAtLeast cudaVersion "11.4") (
[ final.libcublas.lib ]
# For some reason, the 1.4.x release of cusparselt requires the cudart library.
++ lists.optionals (strings.hasPrefix "1.4" redistrib.${pname}.version) [ final.cuda_cudart.lib ]
);
meta = prevAttrs.meta // {
description = "cuSPARSELt: A High-Performance CUDA Library for Sparse Matrix-Matrix Multiplication";
homepage = "https://developer.nvidia.com/cusparselt-downloads";
maintainers = prevAttrs.meta.maintainers or [ ] ++ [ lib.maintainers.sepiabrown ];
teams = prevAttrs.meta.teams or [ ];
license = lib.licenses.unfreeRedistributable // {
shortName = "cuSPARSELt EULA";
fullName = "cuSPARSELt SUPPLEMENT TO SOFTWARE LICENSE AGREEMENT FOR NVIDIA SOFTWARE DEVELOPMENT KITS";
url = "https://docs.nvidia.com/cuda/cusparselt/license.html";
};
};
});
in
attrsets.nameValuePair (computeName redistrib.${pname}) fixedDrv;
attrsets.nameValuePair (computeName redistrib.${pname}) drv;
extension =
let

View file

@ -25,7 +25,6 @@ let
lists
modules
versions
strings
trivial
;
@ -127,29 +126,8 @@ let
redistribRelease = redistrib.${pname};
featureRelease = feature.${pname};
};
fixedDrv = drv.overrideAttrs (prevAttrs: {
buildInputs =
prevAttrs.buildInputs
++ lists.optionals (strings.versionOlder cudaVersion "11.4") [ final.cudatoolkit ]
++ lists.optionals (strings.versionAtLeast cudaVersion "11.4") (
[ final.libcublas.lib ]
# For some reason, the 1.4.x release of cuTENSOR requires the cudart library.
++ lists.optionals (strings.hasPrefix "1.4" redistrib.${pname}.version) [ final.cuda_cudart.lib ]
);
meta = prevAttrs.meta // {
description = "cuTENSOR: A High-Performance CUDA Library For Tensor Primitives";
homepage = "https://developer.nvidia.com/cutensor";
maintainers = prevAttrs.meta.maintainers or [ ] ++ [ lib.maintainers.obsidian-systems-maintenance ];
teams = prevAttrs.meta.teams;
license = lib.licenses.unfreeRedistributable // {
shortName = "cuTENSOR EULA";
fullName = "cuTENSOR SUPPLEMENT TO SOFTWARE LICENSE AGREEMENT FOR NVIDIA SOFTWARE DEVELOPMENT KITS";
url = "https://docs.nvidia.com/cuda/cutensor/license.html";
};
};
});
in
attrsets.nameValuePair (computeName redistrib.${pname}) fixedDrv;
attrsets.nameValuePair (computeName redistrib.${pname}) drv;
extension =
let

View file

@ -0,0 +1,12 @@
{ flags, lib }:
prevAttrs: {
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps or [ ] ++ [
"libnvrm_gpu.so"
"libnvrm_mem.so"
"libnvdla_runtime.so"
];
# `cuda_compat` only works on aarch64-linux, and only when building for Jetson devices.
badPlatformsConditions = prevAttrs.badPlatformsConditions or { } // {
"Trying to use cuda_compat on aarch64-linux targeting non-Jetson devices" = !flags.isJetsonBuild;
};
}

View file

@ -0,0 +1,38 @@
# TODO(@connorbaker): cuda_cudart.dev depends on crt/host_config.h, which is from
# (getDev cuda_nvcc). It would be nice to be able to encode that.
{ addDriverRunpath, lib }:
prevAttrs: {
# Remove once cuda-find-redist-features has a special case for libcuda
outputs =
prevAttrs.outputs or [ ]
++ lib.lists.optionals (!(builtins.elem "stubs" prevAttrs.outputs)) [ "stubs" ];
allowFHSReferences = false;
# The libcuda stub's pkg-config doesn't follow the general pattern:
postPatch =
prevAttrs.postPatch or ""
+ ''
while IFS= read -r -d $'\0' path; do
sed -i \
-e "s|^libdir\s*=.*/lib\$|libdir=''${!outputLib}/lib/stubs|" \
-e "s|^Libs\s*:\(.*\)\$|Libs: \1 -Wl,-rpath,${addDriverRunpath.driverLink}/lib|" \
"$path"
done < <(find -iname 'cuda-*.pc' -print0)
''
# Namelink may not be enough, add a soname.
# Cf. https://gitlab.kitware.com/cmake/cmake/-/issues/25536
+ ''
if [[ -f lib/stubs/libcuda.so && ! -f lib/stubs/libcuda.so.1 ]]; then
ln -s libcuda.so lib/stubs/libcuda.so.1
fi
'';
postFixup =
prevAttrs.postFixup or ""
+ ''
moveToOutput lib/stubs "$stubs"
ln -s "$stubs"/lib/stubs/* "$stubs"/lib/
ln -s "$stubs"/lib/stubs "''${!outputLib}/lib/stubs"
'';
}

View file

@ -0,0 +1,18 @@
{
libglut,
libcufft,
libcurand,
libGLU,
libglvnd,
libgbm,
}:
prevAttrs: {
buildInputs = prevAttrs.buildInputs or [ ] ++ [
libglut
libcufft
libcurand
libGLU
libglvnd
libgbm
];
}

View file

@ -0,0 +1,38 @@
{
cudaAtLeast,
gmp,
expat,
libxcrypt-legacy,
ncurses6,
python310,
python311,
python312,
stdenv,
lib,
}:
prevAttrs: {
buildInputs =
prevAttrs.buildInputs or [ ]
# x86_64 only needs gmp from 12.0 and on
++ lib.lists.optionals (cudaAtLeast "12.0") [ gmp ]
# Additional dependencies for CUDA 12.5 and later, which
# support multiple Python versions.
++ lib.lists.optionals (cudaAtLeast "12.5") [
libxcrypt-legacy
ncurses6
python310
python311
python312
]
# aarch64,sbsa needs expat
++ lib.lists.optionals (stdenv.hostPlatform.isAarch64) [ expat ];
installPhase =
prevAttrs.installPhase or ""
# Python 3.8 is not in nixpkgs anymore, delete Python 3.8 cuda-gdb support
# to avoid autopatchelf failing to find libpython3.8.so.
+ lib.optionalString (cudaAtLeast "12.5") ''
find $bin -name '*python3.8*' -delete
find $bin -name '*python3.9*' -delete
'';
}

View file

@ -0,0 +1,72 @@
{
lib,
backendStdenv,
cudaOlder,
setupCudaHook,
}:
prevAttrs: {
# Merge "bin" and "dev" into "out" to avoid circular references
outputs = builtins.filter (
x:
!(builtins.elem x [
"dev"
"bin"
])
) prevAttrs.outputs or [ ];
# Patch the nvcc.profile.
# Syntax:
# - `=` for assignment,
# - `?=` for conditional assignment,
# - `+=` to "prepend",
# - `=+` to "append".
# Cf. https://web.archive.org/web/20230308044351/https://arcb.csc.ncsu.edu/~mueller/cluster/nvidia/2.0/nvcc_2.0.pdf
# We set all variables with the lowest priority (=+), but we do force
# nvcc to use the fixed backend toolchain. Cf. comments in
# backend-stdenv.nix
postPatch =
prevAttrs.postPatch or ""
+ ''
substituteInPlace bin/nvcc.profile \
--replace-fail \
'$(TOP)/$(_TARGET_DIR_)/include' \
"''${!outputDev}/include"
''
# Additional patching required pre-CUDA 12.5.
+ lib.optionalString (cudaOlder "12.5") ''
substituteInPlace bin/nvcc.profile \
--replace-fail \
'$(TOP)/$(_NVVM_BRANCH_)' \
"''${!outputBin}/nvvm" \
''
+ ''
cat << EOF >> bin/nvcc.profile
# Fix a compatible backend compiler
PATH += "${backendStdenv.cc}/bin":
# Expose the split-out nvvm
LIBRARIES =+ "-L''${!outputBin}/nvvm/lib"
INCLUDES =+ "-I''${!outputBin}/nvvm/include"
EOF
'';
# Entries here will be in nativeBuildInputs when cuda_nvcc is in nativeBuildInputs.
propagatedBuildInputs = prevAttrs.propagatedBuildInputs or [ ] ++ [ setupCudaHook ];
postInstall =
prevAttrs.postInstall or ""
+ ''
moveToOutput "nvvm" "''${!outputBin}"
'';
# The nvcc and cicc binaries contain hard-coded references to /usr
allowFHSReferences = true;
meta = prevAttrs.meta or { } // {
mainProgram = "nvcc";
};
}

View file

@ -0,0 +1 @@
{ cuda_cupti }: prevAttrs: { buildInputs = prevAttrs.buildInputs or [ ] ++ [ cuda_cupti ]; }

View file

@ -0,0 +1 @@
_: _: { outputs = [ "out" ]; }

View file

@ -0,0 +1,84 @@
{
cudaOlder,
cudatoolkit,
cudaVersion,
fetchurl,
lib,
libcublas ? null, # cuDNN uses CUDA Toolkit on old releases, where libcublas is not available.
patchelf,
zlib,
}:
let
inherit (lib)
lists
maintainers
meta
strings
;
in
finalAttrs: prevAttrs: {
src = fetchurl { inherit (finalAttrs.passthru.redistribRelease) hash url; };
# Useful for inspecting why something went wrong.
badPlatformsConditions =
let
cudaTooOld = cudaOlder finalAttrs.passthru.featureRelease.minCudaVersion;
cudaTooNew =
(finalAttrs.passthru.featureRelease.maxCudaVersion != null)
&& strings.versionOlder finalAttrs.passthru.featureRelease.maxCudaVersion cudaVersion;
in
prevAttrs.badPlatformsConditions or { }
// {
"CUDA version is too old" = cudaTooOld;
"CUDA version is too new" = cudaTooNew;
};
buildInputs =
prevAttrs.buildInputs or [ ]
++ [ zlib ]
++ lists.optionals finalAttrs.passthru.useCudatoolkitRunfile [ cudatoolkit ]
++ lists.optionals (!finalAttrs.passthru.useCudatoolkitRunfile) [ (libcublas.lib or null) ];
# Tell autoPatchelf about runtime dependencies. *_infer* libraries only
# exist in CuDNN 8.
# NOTE: Versions from CUDNN releases have four components.
postFixup =
prevAttrs.postFixup or ""
+
strings.optionalString
(
strings.versionAtLeast finalAttrs.version "8.0.5.0"
&& strings.versionOlder finalAttrs.version "9.0.0.0"
)
''
${meta.getExe patchelf} $lib/lib/libcudnn.so --add-needed libcudnn_cnn_infer.so
${meta.getExe patchelf} $lib/lib/libcudnn_ops_infer.so --add-needed libcublas.so --add-needed libcublasLt.so
'';
passthru = prevAttrs.passthru or { } // {
useCudatoolkitRunfile = cudaOlder "11.3.999";
};
meta = prevAttrs.meta or { } // {
homepage = "https://developer.nvidia.com/cudnn";
maintainers =
prevAttrs.meta.maintainers or [ ]
++ (with maintainers; [
mdaiter
samuela
connorbaker
]);
# TODO(@connorbaker): Temporary workaround to avoid changing the derivation hash since introducing more
# brokenConditions would change the derivation as they're top-level and __structuredAttrs is set.
broken =
prevAttrs.meta.broken or false || (finalAttrs.passthru.useCudatoolkitRunfile && libcublas == null);
teams = prevAttrs.meta.teams or [ ];
license = {
shortName = "cuDNN EULA";
fullName = "NVIDIA cuDNN Software License Agreement (EULA)";
url = "https://docs.nvidia.com/deeplearning/sdk/cudnn-sla/index.html#supplement";
free = false;
redistributable = !finalAttrs.passthru.useCudatoolkitRunfile;
};
};
}

View file

@ -0,0 +1,12 @@
{ lib }:
lib.concatMapAttrs (
fileName: _type:
let
# Fixup is in `./${attrName}.nix` or in `./${fileName}/default.nix`:
attrName = lib.removeSuffix ".nix" fileName;
fixup = import (./. + "/${fileName}");
isFixup = fileName != "default.nix";
in
lib.optionalAttrs isFixup { ${attrName} = fixup; }
) (builtins.readDir ./.)

View file

@ -0,0 +1 @@
{ zlib }: prevAttrs: { buildInputs = prevAttrs.buildInputs or [ ] ++ [ zlib ]; }

View file

@ -0,0 +1 @@
{ zlib }: prevAttrs: { buildInputs = prevAttrs.buildInputs or [ ] ++ [ zlib ]; }

View file

@ -0,0 +1,18 @@
{
cudaOlder,
lib,
libcublas,
numactl,
rdma-core,
}:
prevAttrs: {
buildInputs = prevAttrs.buildInputs or [ ] ++ [
libcublas
numactl
rdma-core
];
# Before 11.7 libcufile depends on itself for some reason.
autoPatchelfIgnoreMissingDeps =
prevAttrs.autoPatchelfIgnoreMissingDeps or [ ]
++ lib.lists.optionals (cudaOlder "11.7") [ "libcufile.so.0" ];
}

View file

@ -0,0 +1,24 @@
{
cudaAtLeast,
lib,
libcublas,
libcusparse ? null,
libnvjitlink ? null,
}:
prevAttrs: {
buildInputs =
prevAttrs.buildInputs or [ ]
# Always depends on this
++ [ libcublas ]
# Dependency from 12.0 and on
++ lib.lists.optionals (cudaAtLeast "12.0") [ libnvjitlink ]
# Dependency from 12.1 and on
++ lib.lists.optionals (cudaAtLeast "12.1") [ libcusparse ];
brokenConditions = prevAttrs.brokenConditions or { } // {
"libnvjitlink missing (CUDA >= 12.0)" =
!(cudaAtLeast "12.0" -> (libnvjitlink != null && libnvjitlink != null));
"libcusparse missing (CUDA >= 12.1)" =
!(cudaAtLeast "12.1" -> (libcusparse != null && libcusparse != null));
};
}

View file

@ -0,0 +1,16 @@
{
cudaAtLeast,
lib,
libnvjitlink ? null,
}:
prevAttrs: {
buildInputs =
prevAttrs.buildInputs or [ ]
# Dependency from 12.0 and on
++ lib.lists.optionals (cudaAtLeast "12.0") [ libnvjitlink ];
brokenConditions = prevAttrs.brokenConditions or { } // {
"libnvjitlink missing (CUDA >= 12.0)" =
!(cudaAtLeast "12.0" -> (libnvjitlink != null && libnvjitlink != null));
};
}

View file

@ -0,0 +1,37 @@
{
cuda_cudart ? null,
cudaAtLeast,
cudaOlder,
cudatoolkit,
lib,
libcublas ? null,
}:
finalAttrs: prevAttrs: {
buildInputs =
prevAttrs.buildInputs or [ ]
++ lib.optionals (cudaOlder "11.4") [ cudatoolkit ]
++ lib.optionals (cudaAtLeast "11.4") (
[ (libcublas.lib or null) ]
# For some reason, the 1.4.x release of cusparselt requires the cudart library.
++ lib.optionals (lib.hasPrefix "1.4" finalAttrs.version) [ (cuda_cudart.lib or null) ]
);
meta = prevAttrs.meta or { } // {
description = "cuSPARSELt: A High-Performance CUDA Library for Sparse Matrix-Matrix Multiplication";
homepage = "https://developer.nvidia.com/cusparselt-downloads";
# TODO(@connorbaker): Temporary workaround to avoid changing the derivation hash since introducing more
# brokenConditions would change the derivation as they're top-level and __structuredAttrs is set.
broken =
prevAttrs.meta.broken or false
|| (
cudaAtLeast "11.4"
&& (libcublas == null || (lib.hasPrefix "1.4" finalAttrs.version && cuda_cudart == null))
);
maintainers = prevAttrs.meta.maintainers or [ ] ++ [ lib.maintainers.sepiabrown ];
teams = prevAttrs.meta.teams or [ ];
license = lib.licenses.unfreeRedistributable // {
shortName = "cuSPARSELt EULA";
fullName = "cuSPARSELt SUPPLEMENT TO SOFTWARE LICENSE AGREEMENT FOR NVIDIA SOFTWARE DEVELOPMENT KITS";
url = "https://docs.nvidia.com/cuda/cusparselt/license.html";
};
};
}

View file

@ -0,0 +1,37 @@
{
cuda_cudart ? null,
cudaAtLeast,
cudaOlder,
cudatoolkit,
lib,
libcublas ? null,
}:
finalAttrs: prevAttrs: {
buildInputs =
prevAttrs.buildInputs or [ ]
++ lib.optionals (cudaOlder "11.4") [ cudatoolkit ]
++ lib.optionals (cudaAtLeast "11.4") (
[ (libcublas.lib or null) ]
# For some reason, the 1.4.x release of cuTENSOR requires the cudart library.
++ lib.optionals (lib.hasPrefix "1.4" finalAttrs.version) [ (cuda_cudart.lib or null) ]
);
meta = prevAttrs.meta or { } // {
description = "cuTENSOR: A High-Performance CUDA Library For Tensor Primitives";
homepage = "https://developer.nvidia.com/cutensor";
# TODO(@connorbaker): Temporary workaround to avoid changing the derivation hash since introducing more
# brokenConditions would change the derivation as they're top-level and __structuredAttrs is set.
broken =
prevAttrs.meta.broken or false
|| (
cudaAtLeast "11.4"
&& (libcublas == null || (lib.hasPrefix "1.4" finalAttrs.version && cuda_cudart == null))
);
maintainers = prevAttrs.meta.maintainers or [ ] ++ [ lib.maintainers.obsidian-systems-maintenance ];
teams = prevAttrs.meta.teams;
license = lib.licenses.unfreeRedistributable // {
shortName = "cuTENSOR EULA";
fullName = "cuTENSOR SUPPLEMENT TO SOFTWARE LICENSE AGREEMENT FOR NVIDIA SOFTWARE DEVELOPMENT KITS";
url = "https://docs.nvidia.com/cuda/cutensor/license.html";
};
};
}

View file

@ -0,0 +1,62 @@
{
lib,
qt5 ? null,
qt6 ? null,
rdma-core,
stdenv,
}:
prevAttrs:
let
inherit (lib.strings) versionOlder versionAtLeast;
inherit (prevAttrs) version;
qt = if versionOlder version "2022.2.0" then qt5 else qt6;
qtwayland =
if lib.versions.major qt.qtbase.version == "5" then
lib.getBin qt.qtwayland
else
lib.getLib qt.qtwayland;
inherit (qt) wrapQtAppsHook qtwebview;
archDir =
{
aarch64-linux = "linux-desktop-t210-a64";
x86_64-linux = "linux-desktop-glibc_2_11_3-x64";
}
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
in
{
nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [ wrapQtAppsHook ];
buildInputs = prevAttrs.buildInputs or [ ] ++ [
qtwayland
qtwebview
(qt.qtwebengine or qt.full)
rdma-core
];
dontWrapQtApps = true;
preInstall =
prevAttrs.preInstall or ""
+ ''
rm -rf host/${archDir}/Mesa/
'';
postInstall =
prevAttrs.postInstall or ""
+ ''
moveToOutput 'ncu' "''${!outputBin}/bin"
moveToOutput 'ncu-ui' "''${!outputBin}/bin"
moveToOutput 'host/${archDir}' "''${!outputBin}/bin"
moveToOutput 'target/${archDir}' "''${!outputBin}/bin"
wrapQtApp "''${!outputBin}/bin/host/${archDir}/ncu-ui.bin"
'';
preFixup =
prevAttrs.preFixup or ""
+ ''
# lib needs libtiff.so.5, but nixpkgs provides libtiff.so.6
patchelf --replace-needed libtiff.so.5 libtiff.so "''${!outputBin}/bin/host/${archDir}/Plugins/imageformats/libqtiff.so"
'';
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps or [ ] ++ [
"libnvidia-ml.so.1"
];
brokenConditions = prevAttrs.brokenConditions or { } // {
"Qt 5 missing (<2022.2.0)" = !(versionOlder version "2022.2.0" -> qt5 != null);
"Qt 6 missing (>=2022.2.0)" = !(versionAtLeast version "2022.2.0" -> qt6 != null);
};
}

View file

@ -0,0 +1,128 @@
{
boost178,
cuda_cudart,
cudaOlder,
gst_all_1,
lib,
nss,
numactl,
pulseaudio,
qt5 ? null,
qt6 ? null,
rdma-core,
stdenv,
ucx,
wayland,
xorg,
}:
prevAttrs:
let
inherit (lib.strings) versionOlder versionAtLeast;
inherit (prevAttrs) version;
qt = if lib.strings.versionOlder prevAttrs.version "2022.4.2.1" then qt5 else qt6;
qtwayland =
if lib.versions.major qt.qtbase.version == "5" then
lib.getBin qt.qtwayland
else
lib.getLib qt.qtwayland;
qtWaylandPlugins = "${qtwayland}/${qt.qtbase.qtPluginPrefix}";
hostDir =
{
aarch64-linux = "host-linux-armv8";
x86_64-linux = "host-linux-x64";
}
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
targetDir =
{
aarch64-linux = "target-linux-sbsa-armv8";
x86_64-linux = "target-linux-x64";
}
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
versionString = with lib.versions; "${majorMinor version}.${patch version}";
in
{
# An ad hoc replacement for
# https://github.com/ConnorBaker/cuda-redist-find-features/issues/11
env = prevAttrs.env or { } // {
rmPatterns =
prevAttrs.env.rmPatterns or ""
+ toString [
"nsight-systems/${versionString}/${hostDir}/lib{arrow,jpeg}*"
"nsight-systems/${versionString}/${hostDir}/lib{ssl,ssh,crypto}*"
"nsight-systems/${versionString}/${hostDir}/libboost*"
"nsight-systems/${versionString}/${hostDir}/libexec"
"nsight-systems/${versionString}/${hostDir}/libstdc*"
"nsight-systems/${versionString}/${hostDir}/python/bin/python"
"nsight-systems/${versionString}/${hostDir}/Mesa"
];
};
postPatch =
prevAttrs.postPatch or ""
+ ''
for path in $rmPatterns; do
rm -r "$path"
done
patchShebangs nsight-systems
'';
nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [ qt.wrapQtAppsHook ];
dontWrapQtApps = true;
buildInputs = prevAttrs.buildInputs or [ ] ++ [
(qt.qtdeclarative or qt.full)
(qt.qtsvg or qt.full)
(qt.qtimageformats or qt.full)
(qt.qtpositioning or qt.full)
(qt.qtscxml or qt.full)
(qt.qttools or qt.full)
(qt.qtwebengine or qt.full)
(qt.qtwayland or qt.full)
boost178
cuda_cudart.stubs
gst_all_1.gst-plugins-base
gst_all_1.gstreamer
nss
numactl
pulseaudio
qt.qtbase
qtWaylandPlugins
rdma-core
ucx
wayland
xorg.libXcursor
xorg.libXdamage
xorg.libXrandr
xorg.libXtst
];
postInstall =
prevAttrs.postInstall or ""
# 1. Move dependencies of nsys, nsys-ui binaries to bin output
# 2. Fix paths in wrapper scripts
+ ''
moveToOutput 'nsight-systems/${versionString}/${hostDir}' "''${!outputBin}"
moveToOutput 'nsight-systems/${versionString}/${targetDir}' "''${!outputBin}"
moveToOutput 'nsight-systems/${versionString}/bin' "''${!outputBin}"
substituteInPlace $bin/bin/nsys $bin/bin/nsys-ui \
--replace-fail 'nsight-systems-#VERSION_RSPLIT#' nsight-systems/${versionString}
wrapQtApp "$bin/nsight-systems/${versionString}/${hostDir}/nsys-ui.bin"
'';
preFixup =
prevAttrs.preFixup or ""
+ ''
# lib needs libtiff.so.5, but nixpkgs provides libtiff.so.6
patchelf --replace-needed libtiff.so.5 libtiff.so $bin/nsight-systems/${versionString}/${hostDir}/Plugins/imageformats/libqtiff.so
'';
autoPatchelfIgnoreMissingDeps = prevAttrs.autoPatchelfIgnoreMissingDeps or [ ] ++ [
"libnvidia-ml.so.1"
];
brokenConditions = prevAttrs.brokenConditions or { } // {
"Qt 5 missing (<2022.4.2.1)" = !(versionOlder version "2022.4.2.1" -> qt5 != null);
"Qt 6 missing (>=2022.4.2.1)" = !(versionAtLeast version "2022.4.2.1" -> qt6 != null);
};
badPlatformsConditions = prevAttrs.badPlatformsConditions or { } // {
# Older releases require boost 1.70, which is deprecated in Nixpkgs
"CUDA too old (<11.8)" = cudaOlder "11.8";
};
}

View file

@ -0,0 +1,5 @@
_: prevAttrs: {
badPlatformsConditions = prevAttrs.badPlatformsConditions or { } // {
"Package is not supported; use drivers from linuxPackages" = true;
};
}

View file

@ -1,13 +1,12 @@
{
cudaOlder,
cudaPackages,
cudaVersion,
final,
lib,
mkVersionedPackageName,
package,
patchelf,
requireFile,
stdenv,
...
}:
let
inherit (lib)
@ -28,18 +27,19 @@ finalAttrs: prevAttrs: {
# Useful for inspecting why something went wrong.
brokenConditions =
let
cudaTooOld = strings.versionOlder cudaVersion package.minCudaVersion;
cudaTooOld = cudaOlder finalAttrs.passthru.featureRelease.minCudaVersion;
cudaTooNew =
(package.maxCudaVersion != null) && strings.versionOlder package.maxCudaVersion cudaVersion;
cudnnVersionIsSpecified = package.cudnnVersion != null;
cudnnVersionSpecified = versions.majorMinor package.cudnnVersion;
(finalAttrs.passthru.featureRelease.maxCudaVersion != null)
&& strings.versionOlder finalAttrs.passthru.featureRelease.maxCudaVersion cudaVersion;
cudnnVersionIsSpecified = finalAttrs.passthru.featureRelease.cudnnVersion != null;
cudnnVersionSpecified = versions.majorMinor finalAttrs.passthru.featureRelease.cudnnVersion;
cudnnVersionProvided = versions.majorMinor finalAttrs.passthru.cudnn.version;
cudnnTooOld =
cudnnVersionIsSpecified && (strings.versionOlder cudnnVersionProvided cudnnVersionSpecified);
cudnnTooNew =
cudnnVersionIsSpecified && (strings.versionOlder cudnnVersionSpecified cudnnVersionProvided);
in
prevAttrs.brokenConditions
prevAttrs.brokenConditions or { }
// {
"CUDA version is too old" = cudaTooOld;
"CUDA version is too new" = cudaTooNew;
@ -48,27 +48,27 @@ finalAttrs: prevAttrs: {
};
src = requireFile {
name = package.filename;
inherit (package) hash;
name = finalAttrs.passthru.redistribRelease.filename;
inherit (finalAttrs.passthru.redistribRelease) hash;
message = ''
To use the TensorRT derivation, you must join the NVIDIA Developer Program and
download the ${package.version} TAR package for CUDA ${cudaVersion} from
download the ${finalAttrs.version} TAR package for CUDA ${cudaVersion} from
${finalAttrs.meta.homepage}.
Once you have downloaded the file, add it to the store with the following
command, and try building this derivation again.
$ nix-store --add-fixed sha256 ${package.filename}
$ nix-store --add-fixed sha256 ${finalAttrs.passthru.redistribRelease.filename}
'';
};
# We need to look inside the extracted output to get the files we need.
sourceRoot = "TensorRT-${finalAttrs.version}";
buildInputs = prevAttrs.buildInputs ++ [ (finalAttrs.passthru.cudnn.lib or null) ];
buildInputs = prevAttrs.buildInputs or [ ] ++ [ (finalAttrs.passthru.cudnn.lib or null) ];
preInstall =
(prevAttrs.preInstall or "")
prevAttrs.preInstall or ""
+ strings.optionalString (targetArch != "unsupported") ''
# Replace symlinks to bin and lib with the actual directories from targets.
for dir in bin lib; do
@ -87,7 +87,7 @@ finalAttrs: prevAttrs: {
let
versionTriple = "${versions.majorMinor finalAttrs.version}.${versions.patch finalAttrs.version}";
in
(prevAttrs.postFixup or "")
prevAttrs.postFixup or ""
+ ''
${meta.getExe' patchelf "patchelf"} --add-needed libnvinfer.so \
"$lib/lib/libnvinfer.so.${versionTriple}" \
@ -95,7 +95,7 @@ finalAttrs: prevAttrs: {
"$lib/lib/libnvinfer_builder_resource.so.${versionTriple}"
'';
passthru = {
passthru = prevAttrs.passthru or { } // {
useCudatoolkitRunfile = strings.versionOlder cudaVersion "11.3.999";
# The CUDNN used with TensorRT.
# If null, the default cudnn derivation will be used.
@ -103,12 +103,15 @@ finalAttrs: prevAttrs: {
# unless it is not available, in which case the default cudnn derivation will be used.
cudnn =
let
desiredName = mkVersionedPackageName "cudnn" package.cudnnVersion;
desiredName = mkVersionedPackageName "cudnn" finalAttrs.passthru.featureRelease.cudnnVersion;
in
if package.cudnnVersion == null || (final ? desiredName) then final.cudnn else final.${desiredName};
if finalAttrs.passthru.featureRelease.cudnnVersion == null || (cudaPackages ? desiredName) then
cudaPackages.cudnn
else
cudaPackages.${desiredName};
};
meta = prevAttrs.meta // {
meta = prevAttrs.meta or { } // {
badPlatforms =
prevAttrs.meta.badPlatforms or [ ]
++ lib.optionals (targetArch == "unsupported") [ hostPlatform.system ];

View file

@ -4,7 +4,9 @@
autoAddCudaCompatRunpath,
autoPatchelfHook,
backendStdenv,
callPackage,
fetchurl,
fixups,
lib,
markForCudatoolkitRootHook,
flags,
@ -30,7 +32,6 @@ let
inherit (lib)
attrsets
lists
meta
strings
trivial
licenses
@ -40,6 +41,12 @@ let
inherit (stdenv) hostPlatform;
# Last step before returning control to `callPackage` (adds the `.override` method)
# we'll apply (`overrideAttrs`) necessary package-specific "fixup" functions.
# Order is significant.
maybeFixup = fixups.${pname} or null;
fixup = if maybeFixup != null then callPackage maybeFixup { } else { };
# Get the redist architectures for which package provides distributables.
# These are used by meta.platforms.
supportedRedistArchs = builtins.attrNames featureRelease;
@ -50,7 +57,7 @@ let
sourceMatchesHost = flags.getNixSystem redistArch == hostPlatform.system;
in
backendStdenv.mkDerivation (finalAttrs: {
(backendStdenv.mkDerivation (finalAttrs: {
# NOTE: Even though there's no actual buildPhase going on here, the derivations of the
# redistributables are sensitive to the compiler flags provided to stdenv. The patchelf package
# is sensitive to the compiler flags provided to stdenv, and we depend on it. As such, we are
@ -303,8 +310,12 @@ backendStdenv.mkDerivation (finalAttrs: {
true
'';
# Make the CUDA-patched stdenv available
passthru.stdenv = backendStdenv;
passthru = {
# Provide access to the release information for fixup functions.
inherit redistribRelease featureRelease;
# Make the CUDA-patched stdenv available
stdenv = backendStdenv;
};
meta = {
description = "${redistribRelease.name}. By downloading and using the packages you accept the terms and conditions of the ${finalAttrs.meta.license.shortName}";
@ -321,7 +332,21 @@ backendStdenv.mkDerivation (finalAttrs: {
isBadPlatform = lists.any trivial.id (attrsets.attrValues finalAttrs.badPlatformsConditions);
in
lists.optionals isBadPlatform finalAttrs.meta.platforms;
license = licenses.unfree;
license =
if redistName == "cuda" then
# Add the package-specific license.
let
licensePath =
if redistribRelease.license_path != null then
redistribRelease.license_path
else
"${pname}/LICENSE.txt";
url = "https://developer.download.nvidia.com/compute/cuda/redist/${licensePath}";
in
lib.licenses.nvidiaCudaRedist // { inherit url; }
else
licenses.unfree;
teams = [ teams.cuda ];
};
})
})).overrideAttrs
fixup

View file

@ -6,8 +6,14 @@
stdenv,
# Expected to be passed by the caller
mkVersionedPackageName,
# pname :: String
# Builder-specific arguments
# Short package name (e.g., "cuda_cccl")
# pname : String
pname,
# Common name (e.g., "cutensor" or "cudnn") -- used in the URL.
# Also known as the Redistributable Name.
# redistName : String,
redistName,
# releasesModule :: Path
# A path to a module which provides a `releases` attribute
releasesModule,
@ -17,20 +23,11 @@
# and the package description (which NVIDIA's manifest calls the "name").
# It's also used for fetching the source, but we override that since we can't
# re-use that portion of the functionality (different URLs, etc.).
# The featureRelease is used to populate meta.platforms (by way of looking at the attribute names)
# and to determine the outputs of the package.
# The featureRelease is used to populate meta.platforms (by way of looking at the attribute names), determine the
# outputs of the package, and provide additional package-specific constraints (e.g., min/max supported CUDA versions,
# required versions of other packages, etc.).
# shimFn :: {package, redistArch} -> AttrSet
shimsFn ? (throw "shimsFn must be provided"),
# fixupFn :: Path
# A path (or nix expression) to be evaluated with callPackage and then
# provided to the package's overrideAttrs function.
# It must accept at least the following arguments:
# - final
# - cudaVersion
# - mkVersionedPackageName
# - package
# - ...
fixupFn ? (throw "fixupFn must be provided"),
}:
let
inherit (lib)
@ -97,19 +94,6 @@ let
newest = builtins.head (builtins.sort preferable allReleases);
# A function which takes the `final` overlay and the `package` being built and returns
# a function to be consumed via `overrideAttrs`.
overrideAttrsFixupFn =
final: package:
final.callPackage fixupFn {
inherit
final
cudaVersion
mkVersionedPackageName
package
;
};
extension =
final: _:
let
@ -124,13 +108,11 @@ let
};
name = computeName package;
drv = final.callPackage ./manifest.nix {
inherit pname;
redistName = pname;
inherit pname redistName;
inherit (shims) redistribRelease featureRelease;
};
fixedDrv = drv.overrideAttrs (overrideAttrsFixupFn final package);
in
attrsets.nameValuePair name fixedDrv;
attrsets.nameValuePair name drv;
# versionedDerivations :: AttrSet Derivation
versionedDerivations = builtins.listToAttrs (lists.map buildPackage allReleases);

View file

@ -8,6 +8,7 @@
}:
{
featureRelease = lib.optionalAttrs (redistArch != "unsupported") {
inherit (package) cudnnVersion minCudaVersion maxCudaVersion;
${redistArch}.outputs = {
bin = true;
lib = true;
@ -19,6 +20,6 @@
};
redistribRelease = {
name = "TensorRT: a high-performance deep learning interface";
inherit (package) version;
inherit (package) hash filename version;
};
}

View file

@ -13,20 +13,20 @@
#
# - `prev` should only be used to access attributes which are going to be overridden.
# - `final` should only be used to access `callPackage` to build new packages.
# - Attribute names should be computable without relying on `final`.
# - Extensions should take arguments to build attribute names before relying on `final`.
# - Attribute names are evaluated eagerly ("NAMESET STRICTNESS").
# - Extensions must not depend on `final` when computing names and count of new attributes.
#
# Silvan's recommendation then is to explicitly use `callPackage` to provide everything our
# extensions need to compute the attribute names, without relying on `final`.
#
# I've (@connorbaker) attempted to do that, though I'm unsure of how this will interact with overrides.
{
callPackage,
config,
cudaVersion,
lib,
newScope,
pkgs,
config,
stdenv,
}:
let
inherit (lib)
@ -37,18 +37,42 @@ let
strings
versions
;
# Backbone
gpus = builtins.import ../development/cuda-modules/gpus.nix;
nvccCompatibilities = builtins.import ../development/cuda-modules/nvcc-compatibilities.nix;
flags = callPackage ../development/cuda-modules/flags.nix { inherit cudaVersion gpus; };
# MUST be defined outside fix-point (cf. "NAMESET STRICTNESS" above)
fixups = import ../development/cuda-modules/fixups { inherit lib; };
gpus = import ../development/cuda-modules/gpus.nix;
nvccCompatibilities = import ../development/cuda-modules/nvcc-compatibilities.nix;
flags = import ../development/cuda-modules/flags.nix {
inherit
config
cudaVersion
gpus
lib
stdenv
;
};
mkVersionedPackageName =
name: version: name + "_" + strings.replaceStrings [ "." ] [ "_" ] (versions.majorMinor version);
passthruFunction = final: {
inherit cudaVersion lib pkgs;
inherit gpus nvccCompatibilities flags;
inherit
cudaVersion
fixups
flags
gpus
lib
nvccCompatibilities
pkgs
;
cudaMajorVersion = versions.major cudaVersion;
cudaMajorMinorVersion = versions.majorMinor cudaVersion;
cudaOlder = strings.versionOlder cudaVersion;
cudaAtLeast = strings.versionAtLeast cudaVersion;
# NOTE: mkVersionedPackageName is an internal, implementation detail and should not be relied on by outside consumers.
# It may be removed in the future.
inherit mkVersionedPackageName;
# Maintain a reference to the final cudaPackages.
# Without this, if we use `final.callPackage` and a package accepts `cudaPackages` as an
# argument, it's provided with `cudaPackages` from the top-level scope, which is not what we
@ -111,13 +135,6 @@ let
attrsets.listToAttrs (attrsets.mapCartesianProduct builder configs);
};
mkVersionedPackageName =
name: version:
strings.concatStringsSep "_" [
name
(strings.replaceStrings [ "." ] [ "_" ] (versions.majorMinor version))
];
composedExtension = fixedPoints.composeManyExtensions (
[
(
@ -127,30 +144,53 @@ let
directory = ../development/cuda-modules/packages;
}
)
(callPackage ../development/cuda-modules/cuda/extension.nix { inherit cudaVersion; })
(import ../development/cuda-modules/cuda/overrides.nix)
(callPackage ../development/cuda-modules/generic-builders/multiplex.nix {
inherit cudaVersion flags mkVersionedPackageName;
(import ../development/cuda-modules/cuda/extension.nix { inherit cudaVersion lib; })
(import ../development/cuda-modules/generic-builders/multiplex.nix {
inherit
cudaVersion
flags
lib
mkVersionedPackageName
stdenv
;
pname = "cudnn";
redistName = "cudnn";
releasesModule = ../development/cuda-modules/cudnn/releases.nix;
shimsFn = ../development/cuda-modules/cudnn/shims.nix;
fixupFn = ../development/cuda-modules/cudnn/fixup.nix;
})
(callPackage ../development/cuda-modules/cutensor/extension.nix {
inherit cudaVersion flags mkVersionedPackageName;
(import ../development/cuda-modules/cutensor/extension.nix {
inherit
cudaVersion
flags
lib
mkVersionedPackageName
stdenv
;
})
(callPackage ../development/cuda-modules/cusparselt/extension.nix {
inherit cudaVersion flags mkVersionedPackageName;
(import ../development/cuda-modules/cusparselt/extension.nix {
inherit
cudaVersion
flags
lib
mkVersionedPackageName
stdenv
;
})
(callPackage ../development/cuda-modules/generic-builders/multiplex.nix {
inherit cudaVersion flags mkVersionedPackageName;
(import ../development/cuda-modules/generic-builders/multiplex.nix {
inherit
cudaVersion
flags
lib
mkVersionedPackageName
stdenv
;
pname = "tensorrt";
redistName = "tensorrt";
releasesModule = ../development/cuda-modules/tensorrt/releases.nix;
shimsFn = ../development/cuda-modules/tensorrt/shims.nix;
fixupFn = ../development/cuda-modules/tensorrt/fixup.nix;
})
(callPackage ../development/cuda-modules/cuda-samples/extension.nix { inherit cudaVersion; })
(callPackage ../development/cuda-modules/cuda-library-samples/extension.nix { })
(import ../development/cuda-modules/cuda-samples/extension.nix { inherit cudaVersion lib stdenv; })
(import ../development/cuda-modules/cuda-library-samples/extension.nix { inherit lib stdenv; })
]
++ lib.optionals config.allowAliases [ (import ../development/cuda-modules/aliases.nix) ]
);