1
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-06-29 20:45:29 +03:00

[Backport release-25.05] cudaPackages: introduce and use cudaLib (#411445)

This commit is contained in:
Connor Baker 2025-06-17 07:48:31 -07:00 committed by GitHub
commit a0e85c9a08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 2143 additions and 929 deletions

View file

@ -115,8 +115,8 @@ All new projects should use the CUDA redistributables available in [`cudaPackage
### Updating supported compilers and GPUs {#updating-supported-compilers-and-gpus} ### Updating supported compilers and GPUs {#updating-supported-compilers-and-gpus}
1. Update `nvcc-compatibilities.nix` in `pkgs/development/cuda-modules/` to include the newest release of NVCC, as well as any newly supported host compilers. 1. Update `nvccCompatibilities` in `pkgs/development/cuda-modules/_cuda/db/bootstrap/nvcc.nix` to include the newest release of NVCC, as well as any newly supported host compilers.
2. Update `gpus.nix` in `pkgs/development/cuda-modules/` to include any new GPUs supported by the new release of CUDA. 2. Update `cudaCapabilityToInfo` in `pkgs/development/cuda-modules/_cuda/db/bootstrap/cuda.nix` to include any new GPUs supported by the new release of CUDA.
### Updating the CUDA Toolkit runfile installer {#updating-the-cuda-toolkit} ### Updating the CUDA Toolkit runfile installer {#updating-the-cuda-toolkit}

View file

@ -46,7 +46,7 @@ stdenv'.mkDerivation rec {
cmakeFlags = lib.optionals cudaSupport [ cmakeFlags = lib.optionals cudaSupport [
(lib.cmakeBool "CUDA_ENABLED" true) (lib.cmakeBool "CUDA_ENABLED" true)
(lib.cmakeFeature "CMAKE_CUDA_ARCHITECTURES" ( (lib.cmakeFeature "CMAKE_CUDA_ARCHITECTURES" (
lib.strings.concatStringsSep ";" (map cudaPackages.flags.dropDot cudaCapabilities) lib.strings.concatStringsSep ";" (map cudaPackages.flags.dropDots cudaCapabilities)
)) ))
]; ];

View file

@ -42,7 +42,7 @@
] ]
++ lib.optionals cudaSupport [ ++ lib.optionals cudaSupport [
(lib.cmakeFeature "DLIB_USE_CUDA_COMPUTE_CAPABILITIES" ( (lib.cmakeFeature "DLIB_USE_CUDA_COMPUTE_CAPABILITIES" (
builtins.concatStringsSep "," (with cudaPackages.flags; map dropDot cudaCapabilities) builtins.concatStringsSep "," (with cudaPackages.flags; map dropDots cudaCapabilities)
)) ))
]; ];

View file

@ -17,7 +17,7 @@ let
cuda_nvcc cuda_nvcc
libcublas libcublas
; ;
inherit (cudaPackages.flags) cudaCapabilities dropDot isJetsonBuild; inherit (cudaPackages.flags) cudaCapabilities dropDots isJetsonBuild;
in in
backendStdenv.mkDerivation { backendStdenv.mkDerivation {
pname = "gpu-burn"; pname = "gpu-burn";
@ -53,7 +53,7 @@ backendStdenv.mkDerivation {
makeFlags = [ makeFlags = [
"CUDAPATH=${getBin cuda_nvcc}" "CUDAPATH=${getBin cuda_nvcc}"
"COMPUTE=${last (map dropDot cudaCapabilities)}" "COMPUTE=${last (map dropDots cudaCapabilities)}"
"IS_JETSON=${boolToString isJetsonBuild}" "IS_JETSON=${boolToString isJetsonBuild}"
]; ];

View file

@ -60,7 +60,7 @@ let
)) ))
else else
cudaCapability; cudaCapability;
cudaCapability' = lib.toInt (cudaPackages.flags.dropDot cudaCapabilityString); cudaCapability' = lib.toInt (cudaPackages.flags.dropDots cudaCapabilityString);
mklSupport = mklSupport =
assert accelIsValid; assert accelIsValid;

View file

@ -38,7 +38,7 @@ let
)) ))
else else
cudaCapability; cudaCapability;
cudaCapability' = lib.toInt (cudaPackages.flags.dropDot cudaCapabilityString); cudaCapability' = lib.toInt (cudaPackages.flags.dropDots cudaCapabilityString);
in in
rustPlatform.buildRustPackage (finalAttrs: { rustPlatform.buildRustPackage (finalAttrs: {
pname = "moshi"; pname = "moshi";

View file

@ -43,7 +43,7 @@ let
cudaCapabilities = lists.subtractLists unsupportedCudaCapabilities flags.cudaCapabilities; cudaCapabilities = lists.subtractLists unsupportedCudaCapabilities flags.cudaCapabilities;
cudaArchitecturesString = strings.concatMapStringsSep ";" flags.dropDot cudaCapabilities; cudaArchitecturesString = strings.concatMapStringsSep ";" flags.dropDots cudaCapabilities;
in in
stdenv.mkDerivation (finalAttrs: { stdenv.mkDerivation (finalAttrs: {
pname = "tiny-cuda-nn"; pname = "tiny-cuda-nn";

View file

@ -8,18 +8,6 @@
The files in this directory are added (in some way) to the `cudaPackages` The files in this directory are added (in some way) to the `cudaPackages`
package set by [cuda-packages.nix](../../top-level/cuda-packages.nix). package set by [cuda-packages.nix](../../top-level/cuda-packages.nix).
## Top-level files
Top-level nix files are included in the initial creation of the `cudaPackages`
scope. These are typically required for the creation of the finalized
`cudaPackages` scope:
- `backend-stdenv.nix`: Standard environment for CUDA packages.
- `flags.nix`: Flags set, or consumed by, NVCC in order to build packages.
- `gpus.nix`: A list of supported NVIDIA GPUs.
- `nvcc-compatibilities.nix`: NVCC releases and the version range of GCC/Clang
they support.
## Top-level directories ## Top-level directories
- `cuda`: CUDA redistributables! Provides extension to `cudaPackages` scope. - `cuda`: CUDA redistributables! Provides extension to `cudaPackages` scope.
@ -48,9 +36,8 @@ scope. These are typically required for the creation of the finalized
own. `cudnn` and `tensorrt` are examples of packages which provide such own. `cudnn` and `tensorrt` are examples of packages which provide such
shims. These modules are further described in the shims. These modules are further described in the
[Modules](./modules/README.md) documentation. [Modules](./modules/README.md) documentation.
- `nccl`: NVIDIA NCCL library. - `packages`: Contains packages which exist in every instance of the CUDA
- `nccl-tests`: NVIDIA NCCL tests. package set. These packages are built in a `by-name` fashion.
- `saxpy`: Example CMake project that uses CUDA.
- `setup-hooks`: Nixpkgs setup hooks for CUDA. - `setup-hooks`: Nixpkgs setup hooks for CUDA.
- `tensorrt`: NVIDIA TensorRT library. - `tensorrt`: NVIDIA TensorRT library.

View file

@ -0,0 +1,299 @@
{ lib }:
{
/**
Attribute set of supported CUDA capability mapped to information about that capability.
NOTE: For more on baseline, architecture-specific, and family-specific feature sets, see
https://developer.nvidia.com/blog/nvidia-blackwell-and-nvidia-cuda-12-9-introduce-family-specific-architecture-features.
NOTE: For information on when support for a given architecture was added, see
https://docs.nvidia.com/cuda/parallel-thread-execution/#release-notes
NOTE: For baseline feature sets, `dontDefaultAfterCudaMajorMinorVersion` is generally set to the CUDA release
immediately prior to TensorRT removing support for that architecture.
Many thanks to Arnon Shimoni for maintaining a list of these architectures and capabilities.
Without your work, this would have been much more difficult.
https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/
# Type
```
cudaCapabilityToInfo ::
AttrSet
CudaCapability
{ archName :: String
, cudaCapability :: CudaCapability
, isJetson :: Bool
, isArchitectureSpecific :: Bool
, isFamilySpecific :: Bool
, minCudaMajorMinorVersion :: MajorMinorVersion
, maxCudaMajorMinorVersion :: MajorMinorVersion
, dontDefaultAfterCudaMajorMinorVersion :: Null | MajorMinorVersion
}
```
`archName`
: The name of the microarchitecture
`cudaCapability`
: The CUDA capability
`isJetson`
: Whether this capability is part of NVIDIA's line of Jetson embedded computers. This field is notable
because it tells us what architecture to build for (as Jetson devices are aarch64).
More on Jetson devices here: https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/
NOTE: These architectures are only built upon request.
`isArchitectureSpecific`
: Whether this capability is an architecture-specific feature set.
NOTE: These architectures are only built upon request.
`isFamilySpecific`
: Whether this capability is a family-specific feature set.
NOTE: These architectures are only built upon request.
`minCudaMajorMinorVersion`
: The minimum (inclusive) CUDA version that supports this capability.
`maxCudaMajorMinorVersion`
: The maximum (exclusive) CUDA version that supports this capability.
`null` means there is no maximum.
`dontDefaultAfterCudaMajorMinorVersion`
: The CUDA version after which to exclude this capability from the list of default capabilities we build.
*/
cudaCapabilityToInfo =
lib.mapAttrs
(
cudaCapability:
# Supplies default values.
{
archName,
isJetson ? false,
isArchitectureSpecific ? (lib.hasSuffix "a" cudaCapability),
isFamilySpecific ? (lib.hasSuffix "f" cudaCapability),
minCudaMajorMinorVersion,
maxCudaMajorMinorVersion ? null,
dontDefaultAfterCudaMajorMinorVersion ? null,
}:
{
inherit
archName
cudaCapability
isJetson
isArchitectureSpecific
isFamilySpecific
minCudaMajorMinorVersion
maxCudaMajorMinorVersion
dontDefaultAfterCudaMajorMinorVersion
;
}
)
{
# Tesla K40
"3.5" = {
archName = "Kepler";
minCudaMajorMinorVersion = "10.0";
dontDefaultAfterCudaMajorMinorVersion = "11.0";
maxCudaMajorMinorVersion = "11.8";
};
# Tesla K80
"3.7" = {
archName = "Kepler";
minCudaMajorMinorVersion = "10.0";
dontDefaultAfterCudaMajorMinorVersion = "11.0";
maxCudaMajorMinorVersion = "11.8";
};
# Tesla/Quadro M series
"5.0" = {
archName = "Maxwell";
minCudaMajorMinorVersion = "10.0";
dontDefaultAfterCudaMajorMinorVersion = "11.0";
};
# Quadro M6000 , GeForce 900, GTX-970, GTX-980, GTX Titan X
"5.2" = {
archName = "Maxwell";
minCudaMajorMinorVersion = "10.0";
dontDefaultAfterCudaMajorMinorVersion = "11.0";
};
# Quadro GP100, Tesla P100, DGX-1 (Generic Pascal)
"6.0" = {
archName = "Pascal";
minCudaMajorMinorVersion = "10.0";
# Removed from TensorRT 10.0, which corresponds to CUDA 12.4 release.
# https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-1001/support-matrix/index.html
dontDefaultAfterCudaMajorMinorVersion = "12.3";
};
# GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030 (GP108), GT 1010 (GP108) Titan Xp, Tesla
# P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2
"6.1" = {
archName = "Pascal";
minCudaMajorMinorVersion = "10.0";
# Removed from TensorRT 10.0, which corresponds to CUDA 12.4 release.
# https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-1001/support-matrix/index.html
dontDefaultAfterCudaMajorMinorVersion = "12.3";
};
# DGX-1 with Volta, Tesla V100, GTX 1180 (GV104), Titan V, Quadro GV100
"7.0" = {
archName = "Volta";
minCudaMajorMinorVersion = "10.0";
# Removed from TensorRT 10.5, which corresponds to CUDA 12.6 release.
# https://docs.nvidia.com/deeplearning/tensorrt/archives/tensorrt-1050/support-matrix/index.html
dontDefaultAfterCudaMajorMinorVersion = "12.5";
};
# Jetson AGX Xavier, Drive AGX Pegasus, Xavier NX
"7.2" = {
archName = "Volta";
minCudaMajorMinorVersion = "10.0";
# Note: without `cuda_compat`, maxCudaMajorMinorVersion is 11.8
# https://docs.nvidia.com/cuda/cuda-for-tegra-appnote/index.html#deployment-considerations-for-cuda-upgrade-package
maxCudaMajorMinorVersion = "12.2";
isJetson = true;
};
# GTX/RTX Turing GTX 1660 Ti, RTX 2060, RTX 2070, RTX 2080, Titan RTX, Quadro RTX 4000,
# Quadro RTX 5000, Quadro RTX 6000, Quadro RTX 8000, Quadro T1000/T2000, Tesla T4
"7.5" = {
archName = "Turing";
minCudaMajorMinorVersion = "10.0";
};
# NVIDIA A100 (the name “Tesla” has been dropped GA100), NVIDIA DGX-A100
"8.0" = {
archName = "Ampere";
minCudaMajorMinorVersion = "11.2";
};
# Tesla GA10x cards, RTX Ampere RTX 3080, GA102 RTX 3090, RTX A2000, A3000, RTX A4000,
# A5000, A6000, NVIDIA A40, GA106 RTX 3060, GA104 RTX 3070, GA107 RTX 3050, RTX A10, RTX
# A16, RTX A40, A2 Tensor Core GPU
"8.6" = {
archName = "Ampere";
minCudaMajorMinorVersion = "11.2";
};
# Jetson AGX Orin and Drive AGX Orin only
"8.7" = {
archName = "Ampere";
minCudaMajorMinorVersion = "11.5";
isJetson = true;
};
# NVIDIA GeForce RTX 4090, RTX 4080, RTX 6000, Tesla L40
"8.9" = {
archName = "Ada";
minCudaMajorMinorVersion = "11.8";
};
# NVIDIA H100 (GH100)
"9.0" = {
archName = "Hopper";
minCudaMajorMinorVersion = "11.8";
};
"9.0a" = {
archName = "Hopper";
minCudaMajorMinorVersion = "12.0";
};
# NVIDIA B100
"10.0" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.7";
};
"10.0a" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.7";
};
"10.0f" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
# NVIDIA Jetson Thor Blackwell
"10.1" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.7";
isJetson = true;
};
"10.1a" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.7";
isJetson = true;
};
"10.1f" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
isJetson = true;
};
# NVIDIA ???
"10.3" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
"10.3a" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
"10.3f" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
# NVIDIA GeForce RTX 5090 (GB202) etc.
"12.0" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.8";
};
"12.0a" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.8";
};
"12.0f" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
# NVIDIA ???
"12.1" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
"12.1a" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
"12.1f" = {
archName = "Blackwell";
minCudaMajorMinorVersion = "12.9";
};
};
}

View file

@ -0,0 +1,30 @@
{ lib }:
{
# See ./cuda.nix for documentation.
inherit (import ./cuda.nix { inherit lib; })
cudaCapabilityToInfo
;
# See ./nvcc.nix for documentation.
inherit (import ./nvcc.nix)
nvccCompatibilities
;
# See ./redist.nix for documentation.
inherit (import ./redist.nix)
redistNames
redistSystems
redistUrlPrefix
;
/**
The path to the CUDA packages root directory, for use with `callPackage` to create new package sets.
# Type
```
cudaPackagesPath :: Path
```
*/
cudaPackagesPath = ./../../..;
}

View file

@ -0,0 +1,268 @@
{
/**
Mapping of CUDA versions to NVCC compatibilities
Taken from
https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#host-compiler-support-policy
NVCC performs a version check on the host compiler's major version and so newer minor versions
of the compilers listed below will be supported, but major versions falling outside the range
will not be supported.
NOTE: These constraints don't apply to Jetson, which uses something else.
NOTE: NVIDIA can and will add support for newer compilers even during patch releases.
E.g.: CUDA 12.2.1 maxxed out with support for Clang 15.0; 12.2.2 added support for Clang 16.0.
NOTE: Because all platforms NVIDIA supports use GCC and Clang, we omit the architectures here.
# Type
```
nvccCompatibilities ::
AttrSet
String
{ clang :: { maxMajorVersion :: String, minMajorVersion :: String }
, gcc :: { maxMajorVersion :: String, minMajorVersion :: String }
}
```
*/
nvccCompatibilities = {
# Our baseline
# https://docs.nvidia.com/cuda/archive/11.0/cuda-toolkit-release-notes/index.html#cuda-compiler-new-features
"11.0" = {
clang = {
maxMajorVersion = "9";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "9";
minMajorVersion = "6";
};
};
# Added support for Clang 10 and GCC 10
# https://docs.nvidia.com/cuda/archive/11.1.1/cuda-toolkit-release-notes/index.html#cuda-compiler-new-features
"11.1" = {
clang = {
maxMajorVersion = "10";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "10";
minMajorVersion = "6";
};
};
# Added support for Clang 11
# https://docs.nvidia.com/cuda/archive/11.2.2/cuda-installation-guide-linux/index.html#system-requirements
"11.2" = {
clang = {
maxMajorVersion = "11";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "10";
minMajorVersion = "6";
};
};
# No changes from 11.2 to 11.3
"11.3" = {
clang = {
maxMajorVersion = "11";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "10";
minMajorVersion = "6";
};
};
# Added support for Clang 12 and GCC 11
# https://docs.nvidia.com/cuda/archive/11.4.4/cuda-toolkit-release-notes/index.html#cuda-general-new-features
# NOTE: There is a bug in the version of GLIBC that GCC 11 uses which causes it to fail to compile some CUDA
# code. As such, we skip it for this release, and do the bump in 11.6 (skipping 11.5).
# https://forums.developer.nvidia.com/t/cuda-11-5-samples-throw-multiple-error-attribute-malloc-does-not-take-arguments/192750/15
"11.4" = {
clang = {
maxMajorVersion = "12";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "10";
minMajorVersion = "6";
};
};
# No changes from 11.4 to 11.5
"11.5" = {
clang = {
maxMajorVersion = "12";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "10";
minMajorVersion = "6";
};
};
# No changes from 11.5 to 11.6
# However, as mentioned above, we add GCC 11 this release.
"11.6" = {
clang = {
maxMajorVersion = "12";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "11";
minMajorVersion = "6";
};
};
# Added support for Clang 13
# https://docs.nvidia.com/cuda/archive/11.7.1/cuda-toolkit-release-notes/index.html#cuda-compiler-new-features
"11.7" = {
clang = {
maxMajorVersion = "13";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "11";
minMajorVersion = "6";
};
};
# Added support for Clang 14
# https://docs.nvidia.com/cuda/archive/11.8.0/cuda-installation-guide-linux/index.html#system-requirements
"11.8" = {
clang = {
maxMajorVersion = "14";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "11";
minMajorVersion = "6";
};
};
# Added support for GCC 12
# https://docs.nvidia.com/cuda/archive/12.0.1/cuda-installation-guide-linux/index.html#system-requirements
"12.0" = {
clang = {
maxMajorVersion = "14";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "12";
minMajorVersion = "6";
};
};
# Added support for Clang 15
# https://docs.nvidia.com/cuda/archive/12.1.1/cuda-toolkit-release-notes/index.html#cuda-compilers-new-features
"12.1" = {
clang = {
maxMajorVersion = "15";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "12";
minMajorVersion = "6";
};
};
# Added support for Clang 16
# https://docs.nvidia.com/cuda/archive/12.2.2/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.2" = {
clang = {
maxMajorVersion = "16";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "12";
minMajorVersion = "6";
};
};
# No changes from 12.2 to 12.3
# https://docs.nvidia.com/cuda/archive/12.3.2/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.3" = {
clang = {
maxMajorVersion = "16";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "12";
minMajorVersion = "6";
};
};
# Maximum Clang version is 17
# Minimum GCC version is still 6, but all versions prior to GCC 7.3 are deprecated.
# Maximum GCC version is 13.2
# https://docs.nvidia.com/cuda/archive/12.4.1/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.4" = {
clang = {
maxMajorVersion = "17";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "13";
minMajorVersion = "6";
};
};
# No changes from 12.4 to 12.5
# https://docs.nvidia.com/cuda/archive/12.5.1/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.5" = {
clang = {
maxMajorVersion = "17";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "13";
minMajorVersion = "6";
};
};
# Maximum Clang version is 18
# https://docs.nvidia.com/cuda/archive/12.6.0/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.6" = {
clang = {
maxMajorVersion = "18";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "13";
minMajorVersion = "6";
};
};
# Maximum Clang version is 19, maximum GCC version is 14
# https://docs.nvidia.com/cuda/archive/12.8.1/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.8" = {
clang = {
maxMajorVersion = "19";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "14";
minMajorVersion = "6";
};
};
# No changes from 12.8 to 12.9
# https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.9" = {
clang = {
maxMajorVersion = "19";
minMajorVersion = "7";
};
gcc = {
maxMajorVersion = "14";
minMajorVersion = "6";
};
};
};
}

View file

@ -0,0 +1,56 @@
{
/**
A list of redistributable names to use in creation of the `redistName` option type.
# Type
```
redistNames :: [String]
```
*/
redistNames = [
"cublasmp"
"cuda"
"cudnn"
"cudss"
"cuquantum"
"cusolvermp"
"cusparselt"
"cutensor"
"nppplus"
"nvcomp"
# "nvidia-driver", # NOTE: Some of the earlier manifests don't follow our scheme.
"nvjpeg2000"
"nvpl"
"nvtiff"
"tensorrt" # NOTE: not truly a redist; uses different naming convention
];
/**
A list of redistributable systems to use in creation of the `redistSystem` option type.
# Type
```
redistSystems :: [String]
```
*/
redistSystems = [
"linux-aarch64"
"linux-all" # Taken to mean all other linux systems
"linux-sbsa"
"linux-x86_64"
"source" # Source-agnostic platform
];
/**
The prefix of the URL for redistributable files.
# Type
```
redistUrlPrefix :: String
```
*/
redistUrlPrefix = "https://developer.download.nvidia.com/compute";
}

View file

@ -0,0 +1,65 @@
{
lib,
bootstrapData,
db,
}:
bootstrapData
// {
/**
All CUDA capabilities, sorted by version.
NOTE: Since the capabilities are sorted by version and architecture/family-specific features are
appended to the minor version component, the sorted list groups capabilities by baseline feature
set.
# Type
```
allSortedCudaCapabilities :: [CudaCapability]
```
# Example
```
allSortedCudaCapabilities = [
"5.0"
"5.2"
"6.0"
"6.1"
"7.0"
"7.2"
"7.5"
"8.0"
"8.6"
"8.7"
"8.9"
"9.0"
"9.0a"
"10.0"
"10.0a"
"10.0f"
"10.1"
"10.1a"
"10.1f"
"10.3"
"10.3a"
"10.3f"
];
```
*/
allSortedCudaCapabilities = lib.sort lib.versionOlder (lib.attrNames db.cudaCapabilityToInfo);
/**
Mapping of CUDA micro-architecture name to capabilities belonging to that micro-architecture.
# Type
```
cudaArchNameToCapabilities :: AttrSet NonEmptyStr (NonEmptyListOf CudaCapability)
```
*/
cudaArchNameToCapabilities = lib.groupBy (
cudaCapability: db.cudaCapabilityToInfo.${cudaCapability}.archName
) db.allSortedCudaCapabilities;
}

View file

@ -0,0 +1,30 @@
# The _cuda attribute set is a fixed-point which contains the static functionality required to construct CUDA package
# sets. For example, `_cuda.bootstrapData` includes information about NVIDIA's redistributables (such as the names
# NVIDIA uses for different systems), `_cuda.lib` contains utility functions like `formatCapabilities` (which generate
# common arguments passed to NVCC and `cmakeFlags`), and `_cuda.fixups` contains `callPackage`-able functions which
# are provided to the corresponding package's `overrideAttrs` attribute to provide package-specific fixups
# out of scope of the generic redistributable builder.
#
# Since this attribute set is used to construct the CUDA package sets, it must exist outside the fixed point of the
# package sets. Make these attributes available directly in the package set construction could cause confusion if
# users override the attribute set with the expection that changes will be reflected in the enclosing CUDA package
# set. To avoid this, we declare `_cuda` and inherit its members here, at top-level. (This also allows us to benefit
# from import caching, as it should be evaluated once per system, rather than per-system and CUDA package set.)
let
lib = import ../../../../lib;
in
lib.fixedPoints.makeExtensible (final: {
bootstrapData = import ./db/bootstrap {
inherit lib;
};
db = import ./db {
inherit (final) bootstrapData db;
inherit lib;
};
fixups = import ./fixups { inherit lib; };
lib = import ./lib {
_cuda = final;
inherit lib;
};
})

View file

@ -1,5 +1,4 @@
{ lib }: { lib }:
lib.concatMapAttrs ( lib.concatMapAttrs (
fileName: _type: fileName: _type:
let let

View file

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

View file

@ -1,9 +1,9 @@
{ {
_cuda,
cudaOlder, cudaOlder,
cudaPackages, cudaPackages,
cudaMajorMinorVersion, cudaMajorMinorVersion,
lib, lib,
mkVersionedPackageName,
patchelf, patchelf,
requireFile, requireFile,
stdenv, stdenv,
@ -103,7 +103,9 @@ finalAttrs: prevAttrs: {
# unless it is not available, in which case the default cudnn derivation will be used. # unless it is not available, in which case the default cudnn derivation will be used.
cudnn = cudnn =
let let
desiredName = mkVersionedPackageName "cudnn" finalAttrs.passthru.featureRelease.cudnnVersion; desiredName = _cuda.lib.mkVersionedName "cudnn" (
lib.versions.majorMinor finalAttrs.passthru.featureRelease.cudnnVersion
);
in in
if finalAttrs.passthru.featureRelease.cudnnVersion == null || (cudaPackages ? desiredName) then if finalAttrs.passthru.featureRelease.cudnnVersion == null || (cudaPackages ? desiredName) then
cudaPackages.cudnn cudaPackages.cudnn

View file

@ -0,0 +1,139 @@
{ _cuda, lib }:
{
/**
Evaluate assertions and add error context to return value.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
# Type
```
_evaluateAssertions
:: (assertions :: List { assertion :: Bool, message :: String })
-> Bool
```
*/
_evaluateAssertions =
assertions:
let
failedAssertionsString = _cuda.lib._mkFailedAssertionsString assertions;
in
if failedAssertionsString == "" then
true
else
lib.addErrorContext "with failed assertions:${failedAssertionsString}" false;
/**
Function to generate a string of failed assertions.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
# Type
```
_mkFailedAssertionsString
:: (assertions :: List { assertion :: Bool, message :: String })
-> String
```
# Inputs
`assertions`
: A list of assertions to evaluate
# Examples
:::{.example}
## `_cuda.lib._mkFailedAssertionsString` usage examples
```nix
_mkFailedAssertionsString [
{ assertion = false; message = "Assertion 1 failed"; }
{ assertion = true; message = "Assertion 2 failed"; }
]
=> "\n- Assertion 1 failed"
```
```nix
_mkFailedAssertionsString [
{ assertion = false; message = "Assertion 1 failed"; }
{ assertion = false; message = "Assertion 2 failed"; }
]
=> "\n- Assertion 1 failed\n- Assertion 2 failed"
```
:::
*/
_mkFailedAssertionsString = lib.foldl' (
failedAssertionsString:
{ assertion, message }:
failedAssertionsString + lib.optionalString (!assertion) ("\n- " + message)
) "";
/**
Utility function to generate assertions for missing packages.
Used to mark a package as unsupported if any of its required packages are missing (null).
Expects a set of attributes.
Most commonly used in overrides files on a callPackage-provided attribute set of packages.
NOTE: We typically use platfromAssertions instead of brokenAssertions because the presence of packages set to null
means evaluation will fail if package attributes are accessed without checking for null first. OfBorg evaluation
sets allowBroken to true, which means we can't rely on brokenAssertions to prevent evaluation of a package with
missing dependencies.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
# Type
```
_mkMissingPackagesAssertions
:: (attrs :: AttrSet)
-> (assertions :: List { assertion :: Bool, message :: String })
```
# Inputs
`attrs`
: The attributes to check for null
# Examples
:::{.example}
## `_cuda.lib._mkMissingPackagesAssertions` usage examples
```nix
{
lib,
libcal ? null,
libcublas,
utils,
}:
let
inherit (lib.attrsets) recursiveUpdate;
inherit (_cuda.lib) _mkMissingPackagesAssertions;
in
prevAttrs: {
passthru = prevAttrs.passthru or { } // {
platformAssertions =
prevAttrs.passthru.platformAssertions or [ ]
++ _mkMissingPackagesAssertions { inherit libcal; };
};
}
```
:::
*/
_mkMissingPackagesAssertions = lib.flip lib.pipe [
# Take the attributes that are null.
(lib.filterAttrs (_: value: value == null))
lib.attrNames
# Map them to assertions.
(lib.map (name: {
message = "${name} is available";
assertion = false;
}))
];
}

View file

@ -0,0 +1,129 @@
{ lib }:
{
/**
Returns whether a capability should be built by default for a particular CUDA version.
Capabilities built by default are baseline, non-Jetson capabilities with relatively recent CUDA support.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
# Type
```
_cudaCapabilityIsDefault
:: (cudaMajorMinorVersion :: Version)
-> (cudaCapabilityInfo :: CudaCapabilityInfo)
-> Bool
```
# Inputs
`cudaMajorMinorVersion`
: The CUDA version to check
`cudaCapabilityInfo`
: The capability information to check
*/
_cudaCapabilityIsDefault =
cudaMajorMinorVersion: cudaCapabilityInfo:
let
recentCapability =
cudaCapabilityInfo.dontDefaultAfterCudaMajorMinorVersion == null
|| lib.versionAtLeast cudaCapabilityInfo.dontDefaultAfterCudaMajorMinorVersion cudaMajorMinorVersion;
in
recentCapability
&& !cudaCapabilityInfo.isJetson
&& !cudaCapabilityInfo.isArchitectureSpecific
&& !cudaCapabilityInfo.isFamilySpecific;
/**
Returns whether a capability is supported for a particular CUDA version.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
# Type
```
_cudaCapabilityIsSupported
:: (cudaMajorMinorVersion :: Version)
-> (cudaCapabilityInfo :: CudaCapabilityInfo)
-> Bool
```
# Inputs
`cudaMajorMinorVersion`
: The CUDA version to check
`cudaCapabilityInfo`
: The capability information to check
*/
_cudaCapabilityIsSupported =
cudaMajorMinorVersion: cudaCapabilityInfo:
let
lowerBoundSatisfied = lib.versionAtLeast cudaMajorMinorVersion cudaCapabilityInfo.minCudaMajorMinorVersion;
upperBoundSatisfied =
cudaCapabilityInfo.maxCudaMajorMinorVersion == null
|| lib.versionAtLeast cudaCapabilityInfo.maxCudaMajorMinorVersion cudaMajorMinorVersion;
in
lowerBoundSatisfied && upperBoundSatisfied;
/**
Generates a CUDA variant name from a version.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
# Type
```
_mkCudaVariant :: (version :: String) -> String
```
# Inputs
`version`
: The version string
# Examples
:::{.example}
## `_cuda.lib._mkCudaVariant` usage examples
```nix
_mkCudaVariant "11.0"
=> "cuda11"
```
:::
*/
_mkCudaVariant = version: "cuda${lib.versions.major version}";
/**
A predicate which, given a package, returns true if the package has a free license or one of NVIDIA's licenses.
This function is intended to be provided as `config.allowUnfreePredicate` when `import`-ing Nixpkgs.
# Type
```
allowUnfreeCudaPredicate :: (package :: Package) -> Bool
```
*/
allowUnfreeCudaPredicate =
package:
lib.all (
license:
license.free
|| lib.elem license.shortName [
"CUDA EULA"
"cuDNN EULA"
"cuSPARSELt EULA"
"cuTENSOR EULA"
"NVidia OptiX EULA"
]
) (lib.toList package.meta.license);
}

View file

@ -0,0 +1,52 @@
{
_cuda,
lib,
}:
{
# See ./assertions.nix for documentation.
inherit (import ./assertions.nix { inherit _cuda lib; })
_evaluateAssertions
_mkFailedAssertionsString
_mkMissingPackagesAssertions
;
# See ./cuda.nix for documentation.
inherit (import ./cuda.nix { inherit lib; })
_cudaCapabilityIsDefault
_cudaCapabilityIsSupported
_mkCudaVariant
allowUnfreeCudaPredicate
;
# See ./meta.nix for documentation.
inherit (import ./meta.nix { inherit _cuda lib; })
_mkMetaBadPlatforms
_mkMetaBroken
;
# See ./redist.nix for documentation.
inherit (import ./redist.nix { inherit _cuda lib; })
_redistSystemIsSupported
getNixSystems
getRedistSystem
mkRedistUrl
;
# See ./strings.nix for documentation.
inherit (import ./strings.nix { inherit _cuda lib; })
dotsToUnderscores
dropDots
formatCapabilities
mkCmakeCudaArchitecturesString
mkGencodeFlag
mkRealArchitecture
mkVersionedName
mkVirtualArchitecture
;
# See ./versions.nix for documentation.
inherit (import ./versions.nix { inherit _cuda lib; })
majorMinorPatch
trimComponents
;
}

View file

@ -0,0 +1,71 @@
{ _cuda, lib }:
{
/**
Returns a list of bad platforms for a given package if assertsions in `finalAttrs.passthru.platformAssertions`
fail, optionally logging evaluation warnings for each reason.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
NOTE: This function requires `finalAttrs.passthru.platformAssertions` to be a list of assertions and
`finalAttrs.finalPackage.name` and `finalAttrs.finalPackage.stdenv` to be available.
# Type
```
_mkMetaBadPlatforms :: (warn :: Bool) -> (finalAttrs :: AttrSet) -> List String
```
*/
_mkMetaBadPlatforms =
warn: finalAttrs:
let
failedAssertionsString = _cuda.lib._mkFailedAssertionsString finalAttrs.passthru.platformAssertions;
hasFailedAssertions = failedAssertionsString != "";
finalStdenv = finalAttrs.finalPackage.stdenv;
in
lib.warnIf (warn && hasFailedAssertions)
"Package ${finalAttrs.finalPackage.name} is unsupported on this platform due to the following failed assertions:${failedAssertionsString}"
(
lib.optionals hasFailedAssertions (
lib.unique [
finalStdenv.buildPlatform.system
finalStdenv.hostPlatform.system
finalStdenv.targetPlatform.system
]
)
);
/**
Returns a boolean indicating whether the package is broken as a result of `finalAttrs.passthru.brokenAssertions`,
optionally logging evaluation warnings for each reason.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
NOTE: This function requires `finalAttrs.passthru.brokenAssertions` to be a list of assertions and
`finalAttrs.finalPackage.name` to be available.
# Type
```
_mkMetaBroken :: (warn :: Bool) -> (finalAttrs :: AttrSet) -> Bool
```
# Inputs
`warn`
: A boolean indicating whether to log warnings
`finalAttrs`
: The final attributes of the package
*/
_mkMetaBroken =
warn: finalAttrs:
let
failedAssertionsString = _cuda.lib._mkFailedAssertionsString finalAttrs.passthru.brokenAssertions;
hasFailedAssertions = failedAssertionsString != "";
in
lib.warnIf (warn && hasFailedAssertions)
"Package ${finalAttrs.finalPackage.name} is marked as broken due to the following failed assertions:${failedAssertionsString}"
hasFailedAssertions;
}

View file

@ -0,0 +1,196 @@
{ _cuda, lib }:
{
/**
Returns a boolean indicating whether the provided redist system is supported by any of the provided redist systems.
NOTE: No guarantees are made about this function's stability. You may use it at your own risk.
# Type
```
_redistSystemIsSupported
:: (redistSystem :: RedistSystem)
-> (redistSystems :: List RedistSystem)
-> Bool
```
# Inputs
`redistSystem`
: The redist system to check
`redistSystems`
: The list of redist systems to check against
# Examples
:::{.example}
## `cudaLib._redistSystemIsSupported` usage examples
```nix
_redistSystemIsSupported "linux-x86_64" [ "linux-x86_64" ]
=> true
```
```nix
_redistSystemIsSupported "linux-x86_64" [ "linux-aarch64" ]
=> false
```
```nix
_redistSystemIsSupported "linux-x86_64" [ "linux-aarch64" "linux-x86_64" ]
=> true
```
```nix
_redistSystemIsSupported "linux-x86_64" [ "linux-aarch64" "linux-all" ]
=> true
```
:::
*/
_redistSystemIsSupported =
redistSystem: redistSystems:
lib.findFirst (
redistSystem':
redistSystem' == redistSystem || redistSystem' == "linux-all" || redistSystem' == "source"
) null redistSystems != null;
/**
Maps a NVIDIA redistributable system to Nix systems.
NOTE: This function returns a list of systems because the redistributable systems `"linux-all"` and `"source"` can
be built on multiple systems.
NOTE: This function *will* be called by unsupported systems because `cudaPackages` is evaluated on all systems. As
such, we need to handle unsupported systems gracefully.
# Type
```
getNixSystems :: (redistSystem :: RedistSystem) -> [String]
```
# Inputs
`redistSystem`
: The NVIDIA redistributable system
# Examples
:::{.example}
## `cudaLib.getNixSystems` usage examples
```nix
getNixSystems "linux-sbsa"
=> [ "aarch64-linux" ]
```
```nix
getNixSystems "linux-aarch64"
=> [ "aarch64-linux" ]
```
:::
*/
getNixSystems =
redistSystem:
if redistSystem == "linux-x86_64" then
[ "x86_64-linux" ]
else if redistSystem == "linux-sbsa" || redistSystem == "linux-aarch64" then
[ "aarch64-linux" ]
else if redistSystem == "linux-all" || redistSystem == "source" then
[
"aarch64-linux"
"x86_64-linux"
]
else
[ ];
/**
Maps a Nix system to a NVIDIA redistributable system.
NOTE: We swap out the default `linux-sbsa` redist (for server-grade ARM chips) with the `linux-aarch64` redist
(which is for Jetson devices) if we're building any Jetson devices. Since both are based on aarch64, we can only
have one or the other, otherwise there's an ambiguity as to which should be used.
NOTE: This function *will* be called by unsupported systems because `cudaPackages` is evaluated on all systems. As
such, we need to handle unsupported systems gracefully.
# Type
```
getRedistSystem :: (hasJetsonCudaCapability :: Bool) -> (nixSystem :: String) -> String
```
# Inputs
`hasJetsonCudaCapability`
: If configured for a Jetson device
`nixSystem`
: The Nix system
# Examples
:::{.example}
## `cudaLib.getRedistSystem` usage examples
```nix
getRedistSystem true "aarch64-linux"
=> "linux-aarch64"
```
```nix
getRedistSystem false "aarch64-linux"
=> "linux-sbsa"
```
:::
*/
getRedistSystem =
hasJetsonCudaCapability: nixSystem:
if nixSystem == "x86_64-linux" then
"linux-x86_64"
else if nixSystem == "aarch64-linux" then
if hasJetsonCudaCapability then "linux-aarch64" else "linux-sbsa"
else
"unsupported";
/**
Function to generate a URL for something in the redistributable tree.
# Type
```
mkRedistUrl :: (redistName :: RedistName) -> (relativePath :: NonEmptyStr) -> RedistUrl
```
# Inputs
`redistName`
: The name of the redistributable
`relativePath`
: The relative path to a file in the redistributable tree
*/
mkRedistUrl =
redistName: relativePath:
lib.concatStringsSep "/" (
[ _cuda.db.redistUrlPrefix ]
++ (
if redistName != "tensorrt" then
[
redistName
"redist"
]
else
[ "machine-learning" ]
)
++ [ relativePath ]
);
}

View file

@ -0,0 +1,382 @@
{ _cuda, lib }:
let
cudaLib = _cuda.lib;
in
{
/**
Replaces dots in a string with underscores.
# Type
```
dotsToUnderscores :: (str :: String) -> String
```
# Inputs
`str`
: The string for which dots shall be replaced by underscores
# Examples
:::{.example}
## `cudaLib.dotsToUnderscores` usage examples
```nix
dotsToUnderscores "1.2.3"
=> "1_2_3"
```
:::
*/
dotsToUnderscores = lib.replaceStrings [ "." ] [ "_" ];
/**
Removes the dots from a string.
# Type
```
dropDots :: (str :: String) -> String
```
# Inputs
`str`
: The string to remove dots from
# Examples
:::{.example}
## `cudaLib.dropDots` usage examples
```nix
dropDots "1.2.3"
=> "123"
```
:::
*/
dropDots = lib.replaceStrings [ "." ] [ "" ];
/**
Produces an attribute set of useful data and functionality for packaging CUDA software within Nixpkgs.
# Type
```
formatCapabilities
:: { cudaCapabilityToInfo :: AttrSet CudaCapability CudaCapabilityInfo
, cudaCapabilities :: List CudaCapability
, cudaForwardCompat :: Bool
}
-> { cudaCapabilities :: List CudaCapability
, cudaForwardCompat :: Bool
, gencode :: List String
, realArches :: List String
, virtualArches :: List String
, archNames :: List String
, arches :: List String
, gencodeString :: String
, cmakeCudaArchitecturesString :: String
}
```
# Inputs
`cudaCapabilityToInfo`
: A mapping of CUDA capabilities to their information
`cudaCapabilities`
: A list of CUDA capabilities to use
`cudaForwardCompat`
: A boolean indicating whether to include the forward compatibility gencode (+PTX) to support future GPU
generations
*/
formatCapabilities =
{
cudaCapabilityToInfo,
cudaCapabilities,
cudaForwardCompat,
}:
let
/**
The real architectures for the given CUDA capabilities.
# Type
```
realArches :: List String
```
*/
realArches = lib.map cudaLib.mkRealArchitecture cudaCapabilities;
/**
The virtual architectures for the given CUDA capabilities.
These are typically used for forward compatibility, when trying to support an architecture newer than the CUDA
version allows.
# Type
```
virtualArches :: List String
```
*/
virtualArches = lib.map cudaLib.mkVirtualArchitecture cudaCapabilities;
/**
The gencode flags for the given CUDA capabilities.
# Type
```
gencode :: List String
```
*/
gencode =
let
base = lib.map (cudaLib.mkGencodeFlag "sm") cudaCapabilities;
forward = cudaLib.mkGencodeFlag "compute" (lib.last cudaCapabilities);
in
base ++ lib.optionals cudaForwardCompat [ forward ];
in
{
inherit
cudaCapabilities
cudaForwardCompat
gencode
realArches
virtualArches
;
/**
The architecture names for the given CUDA capabilities.
# Type
```
archNames :: List String
```
*/
# E.g. [ "Ampere" "Turing" ]
archNames = lib.pipe cudaCapabilities [
(lib.map (cudaCapability: cudaCapabilityToInfo.${cudaCapability}.archName))
lib.unique
lib.naturalSort
];
/**
The architectures for the given CUDA capabilities, including both real and virtual architectures.
When `cudaForwardCompat` is enabled, the last architecture in the list is used as the forward compatibility architecture.
# Type
```
arches :: List String
```
*/
# E.g. [ "sm_75" "sm_86" "compute_86" ]
arches = realArches ++ lib.optionals cudaForwardCompat [ (lib.last virtualArches) ];
/**
The CMake-compatible CUDA architectures string for the given CUDA capabilities.
# Type
```
cmakeCudaArchitecturesString :: String
```
*/
cmakeCudaArchitecturesString = cudaLib.mkCmakeCudaArchitecturesString cudaCapabilities;
/**
The gencode string for the given CUDA capabilities.
# Type
```
gencodeString :: String
```
*/
gencodeString = lib.concatStringsSep " " gencode;
};
/**
Produces a CMake-compatible CUDA architecture string from a list of CUDA capabilities.
# Type
```
mkCmakeCudaArchitecturesString :: (cudaCapabilities :: List String) -> String
```
# Inputs
`cudaCapabilities`
: The CUDA capabilities to convert
# Examples
:::{.example}
## `cudaLib.mkCmakeCudaArchitecturesString` usage examples
```nix
mkCmakeCudaArchitecturesString [ "8.9" "10.0a" ]
=> "89;100a"
```
:::
*/
mkCmakeCudaArchitecturesString = lib.concatMapStringsSep ";" cudaLib.dropDots;
/**
Produces a gencode flag from a CUDA capability.
# Type
```
mkGencodeFlag :: (archPrefix :: String) -> (cudaCapability :: String) -> String
```
# Inputs
`archPrefix`
: The architecture prefix to use for the `code` field
`cudaCapability`
: The CUDA capability to convert
# Examples
:::{.example}
## `cudaLib.mkGencodeFlag` usage examples
```nix
mkGencodeFlag "sm" "8.9"
=> "-gencode=arch=compute_89,code=sm_89"
```
```nix
mkGencodeFlag "compute" "10.0a"
=> "-gencode=arch=compute_100a,code=compute_100a"
```
:::
*/
mkGencodeFlag =
archPrefix: cudaCapability:
let
cap = cudaLib.dropDots cudaCapability;
in
"-gencode=arch=compute_${cap},code=${archPrefix}_${cap}";
/**
Produces a real architecture string from a CUDA capability.
# Type
```
mkRealArchitecture :: (cudaCapability :: String) -> String
```
# Inputs
`cudaCapability`
: The CUDA capability to convert
# Examples
:::{.example}
## `cudaLib.mkRealArchitecture` usage examples
```nix
mkRealArchitecture "8.9"
=> "sm_89"
```
```nix
mkRealArchitecture "10.0a"
=> "sm_100a"
```
:::
*/
mkRealArchitecture = cudaCapability: "sm_" + cudaLib.dropDots cudaCapability;
/**
Create a versioned attribute name from a version by replacing dots with underscores.
# Type
```
mkVersionedName :: (name :: String) -> (version :: Version) -> String
```
# Inputs
`name`
: The name to use
`version`
: The version to use
# Examples
:::{.example}
## `cudaLib.mkVersionedName` usage examples
```nix
mkVersionedName "hello" "1.2.3"
=> "hello_1_2_3"
```
```nix
mkVersionedName "cudaPackages" "12.8"
=> "cudaPackages_12_8"
```
:::
*/
mkVersionedName = name: version: "${name}_${cudaLib.dotsToUnderscores version}";
/**
Produces a virtual architecture string from a CUDA capability.
# Type
```
mkVirtualArchitecture :: (cudaCapability :: String) -> String
```
# Inputs
`cudaCapability`
: The CUDA capability to convert
# Examples
:::{.example}
## `cudaLib.mkVirtualArchitecture` usage examples
```nix
mkVirtualArchitecture "8.9"
=> "compute_89"
```
```nix
mkVirtualArchitecture "10.0a"
=> "compute_100a"
```
:::
*/
mkVirtualArchitecture = cudaCapability: "compute_" + cudaLib.dropDots cudaCapability;
}

View file

@ -0,0 +1,79 @@
{ _cuda, lib }:
let
cudaLib = _cuda.lib;
in
{
/**
Extracts the major, minor, and patch version from a string.
# Type
```
majorMinorPatch :: (version :: String) -> String
```
# Inputs
`version`
: The version string
# Examples
:::{.example}
## `_cuda.lib.majorMinorPatch` usage examples
```nix
majorMinorPatch "11.0.3.4"
=> "11.0.3"
```
:::
*/
majorMinorPatch = cudaLib.trimComponents 3;
/**
Get a version string with no more than than the specified number of components.
# Type
```
trimComponents :: (numComponents :: Integer) -> (version :: String) -> String
```
# Inputs
`numComponents`
: A positive integer corresponding to the maximum number of components to keep
`version`
: A version string
# Examples
:::{.example}
## `_cuda.lib.trimComponents` usage examples
```nix
trimComponents 1 "1.2.3.4"
=> "1"
```
```nix
trimComponents 3 "1.2.3.4"
=> "1.2.3"
```
```nix
trimComponents 9 "1.2.3.4"
=> "1.2.3.4"
```
:::
*/
trimComponents =
n: v:
lib.pipe v [
lib.splitVersion
(lib.take n)
(lib.concatStringsSep ".")
];
}

View file

@ -1,11 +1,12 @@
# Packages which have been deprecated or removed from cudaPackages # Packages which have been deprecated or removed from cudaPackages
final: _: { lib }:
let let
mkRenamed = mkRenamed =
oldName: oldName:
{ path, package }: { path, package }:
final.lib.warn "cudaPackages.${oldName} is deprecated, use ${path} instead" package; lib.warn "cudaPackages.${oldName} is deprecated, use ${path} instead" package;
in in
final: _:
builtins.mapAttrs mkRenamed { builtins.mapAttrs mkRenamed {
# A comment to prevent empty { } from collapsing into a single line # A comment to prevent empty { } from collapsing into a single line

View file

@ -43,7 +43,7 @@ let
}; };
# Generally we prefer to do things involving getting attribute names with feature_manifest instead # Generally we prefer to do things involving getting attribute names with feature_manifest instead
# of redistrib_manifest because the feature manifest will have *only* the redist architecture # of redistrib_manifest because the feature manifest will have *only* the redist system
# names as the keys, whereas the redistrib manifest will also have things like version, name, license, # names as the keys, whereas the redistrib manifest will also have things like version, name, license,
# and license_path. # and license_path.
featureManifest = evaluatedModules.config.cuda.manifests.feature; featureManifest = evaluatedModules.config.cuda.manifests.feature;

View file

@ -1,14 +1,14 @@
# Shims to mimic the shape of ../modules/generic/manifests/{feature,redistrib}/release.nix # Shims to mimic the shape of ../modules/generic/manifests/{feature,redistrib}/release.nix
{ {
package, package,
# redistArch :: String # redistSystem :: String
# String is "unsupported" if the given architecture is unsupported. # String is "unsupported" if the given architecture is unsupported.
redistArch, redistSystem,
}: }:
{ {
featureRelease = { featureRelease = {
inherit (package) minCudaVersion maxCudaVersion; inherit (package) minCudaVersion maxCudaVersion;
${redistArch}.outputs = { ${redistSystem}.outputs = {
lib = true; lib = true;
static = true; static = true;
dev = true; dev = true;

View file

@ -1,11 +1,9 @@
# Support matrix can be found at # Support matrix can be found at
# https://docs.nvidia.com/deeplearning/cudnn/archives/cudnn-880/support-matrix/index.html # https://docs.nvidia.com/deeplearning/cudnn/archives/cudnn-880/support-matrix/index.html
{ {
cudaLib,
lib, lib,
stdenv, redistSystem,
cudaMajorMinorVersion,
flags,
mkVersionedPackageName,
}: }:
let let
inherit (lib) inherit (lib)
@ -15,8 +13,6 @@ let
trivial trivial
; ;
inherit (stdenv) hostPlatform;
redistName = "cusparselt"; redistName = "cusparselt";
pname = "libcusparse_lt"; pname = "libcusparse_lt";
@ -54,17 +50,12 @@ let
releaseGrabber releaseGrabber
]) cusparseltVersions; ]) cusparseltVersions;
# 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.
# redistArch :: String
redistArch = flags.getRedistArch hostPlatform.system;
# platformIsSupported :: Manifests -> Boolean # platformIsSupported :: Manifests -> Boolean
platformIsSupported = platformIsSupported =
{ feature, redistrib, ... }: { feature, redistrib, ... }:
(attrsets.attrByPath [ (attrsets.attrByPath [
pname pname
redistArch redistSystem
] null feature) != null; ] null feature) != null;
# TODO(@connorbaker): With an auxiliary file keeping track of the CUDA versions each release supports, # TODO(@connorbaker): With an auxiliary file keeping track of the CUDA versions each release supports,
@ -77,7 +68,8 @@ let
# Compute versioned attribute name to be used in this package set # Compute versioned attribute name to be used in this package set
# Patch version changes should not break the build, so we only use major and minor # Patch version changes should not break the build, so we only use major and minor
# computeName :: RedistribRelease -> String # computeName :: RedistribRelease -> String
computeName = { version, ... }: mkVersionedPackageName redistName version; computeName =
{ version, ... }: cudaLib.mkVersionedName redistName (lib.versions.majorMinor version);
in in
final: _: final: _:
let let

View file

@ -13,11 +13,10 @@
# - Instead of providing different releases for each version of CUDA, CuTensor has multiple subdirectories in `lib` # - Instead of providing different releases for each version of CUDA, CuTensor has multiple subdirectories in `lib`
# -- one for each version of CUDA. # -- one for each version of CUDA.
{ {
cudaLib,
cudaMajorMinorVersion, cudaMajorMinorVersion,
flags,
lib, lib,
mkVersionedPackageName, redistSystem,
stdenv,
}: }:
let let
inherit (lib) inherit (lib)
@ -28,8 +27,6 @@ let
trivial trivial
; ;
inherit (stdenv) hostPlatform;
redistName = "cutensor"; redistName = "cutensor";
pname = "libcutensor"; pname = "libcutensor";
@ -92,14 +89,12 @@ let
# A release is supported if it has a libPath that matches our CUDA version for our platform. # 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 # LibPath are not constant across the same release -- one platform may support fewer
# CUDA versions than another. # CUDA versions than another.
# redistArch :: String
redistArch = flags.getRedistArch hostPlatform.system;
# platformIsSupported :: Manifests -> Boolean # platformIsSupported :: Manifests -> Boolean
platformIsSupported = platformIsSupported =
{ feature, redistrib, ... }: { feature, redistrib, ... }:
(attrsets.attrByPath [ (attrsets.attrByPath [
pname pname
redistArch redistSystem
] null feature) != null; ] null feature) != null;
# TODO(@connorbaker): With an auxiliary file keeping track of the CUDA versions each release supports, # TODO(@connorbaker): With an auxiliary file keeping track of the CUDA versions each release supports,
@ -112,7 +107,8 @@ let
# Compute versioned attribute name to be used in this package set # Compute versioned attribute name to be used in this package set
# Patch version changes should not break the build, so we only use major and minor # Patch version changes should not break the build, so we only use major and minor
# computeName :: RedistribRelease -> String # computeName :: RedistribRelease -> String
computeName = { version, ... }: mkVersionedPackageName redistName version; computeName =
{ version, ... }: cudaLib.mkVersionedName redistName (lib.versions.majorMinor version);
in in
final: _: final: _:
let let

View file

@ -1,399 +0,0 @@
# Type aliases
# Gpu :: AttrSet
# - See the documentation in ./gpus.nix.
{
config,
cudaCapabilities ? (config.cudaCapabilities or [ ]),
cudaForwardCompat ? (config.cudaForwardCompat or true),
lib,
cudaMajorMinorVersion,
stdenv,
# gpus :: List Gpu
gpus,
}:
let
inherit (lib)
asserts
attrsets
lists
strings
trivial
;
inherit (stdenv) hostPlatform;
# Flags are determined based on your CUDA toolkit by default. You may benefit
# from improved performance, reduced file size, or greater hardware support by
# passing a configuration based on your specific GPU environment.
#
# cudaCapabilities :: List Capability
# List of hardware generations to build.
# E.g. [ "8.0" ]
# Currently, the last item is considered the optional forward-compatibility arch,
# but this may change in the future.
#
# cudaForwardCompat :: Bool
# Whether to include the forward compatibility gencode (+PTX)
# to support future GPU generations.
# E.g. true
#
# Please see the accompanying documentation or https://github.com/NixOS/nixpkgs/pull/205351
# isSupported :: Gpu -> Bool
isSupported =
gpu:
let
inherit (gpu) minCudaVersion maxCudaVersion;
lowerBoundSatisfied = strings.versionAtLeast cudaMajorMinorVersion minCudaVersion;
upperBoundSatisfied =
(maxCudaVersion == null) || !(strings.versionOlder maxCudaVersion cudaMajorMinorVersion);
in
lowerBoundSatisfied && upperBoundSatisfied;
# NOTE: Jetson is never built by default.
# isDefault :: Gpu -> Bool
isDefault =
gpu:
let
inherit (gpu) dontDefaultAfter isJetson;
newGpu = dontDefaultAfter == null;
recentGpu = newGpu || strings.versionAtLeast dontDefaultAfter cudaMajorMinorVersion;
in
recentGpu && !isJetson;
# supportedGpus :: List Gpu
# GPUs which are supported by the provided CUDA version.
supportedGpus = builtins.filter isSupported gpus;
# defaultGpus :: List Gpu
# GPUs which are supported by the provided CUDA version and we want to build for by default.
defaultGpus = builtins.filter isDefault supportedGpus;
# supportedCapabilities :: List Capability
supportedCapabilities = lists.map (gpu: gpu.computeCapability) supportedGpus;
# defaultCapabilities :: List Capability
# The default capabilities to target, if not overridden by the user.
defaultCapabilities = lists.map (gpu: gpu.computeCapability) defaultGpus;
# cudaArchNameToVersions :: AttrSet String (List String)
# Maps the name of a GPU architecture to different versions of that architecture.
# For example, "Ampere" maps to [ "8.0" "8.6" "8.7" ].
cudaArchNameToVersions = lists.groupBy' (versions: gpu: versions ++ [ gpu.computeCapability ]) [ ] (
gpu: gpu.archName
) supportedGpus;
# cudaComputeCapabilityToName :: AttrSet String String
# Maps the version of a GPU architecture to the name of that architecture.
# For example, "8.0" maps to "Ampere".
cudaComputeCapabilityToName = builtins.listToAttrs (
lists.map (gpu: attrsets.nameValuePair gpu.computeCapability gpu.archName) supportedGpus
);
# cudaComputeCapabilityToIsJetson :: AttrSet String Boolean
cudaComputeCapabilityToIsJetson = builtins.listToAttrs (
lists.map (attrs: attrsets.nameValuePair attrs.computeCapability attrs.isJetson) supportedGpus
);
# jetsonComputeCapabilities :: List String
jetsonComputeCapabilities = trivial.pipe cudaComputeCapabilityToIsJetson [
(attrsets.filterAttrs (_: isJetson: isJetson))
builtins.attrNames
];
# Find the intersection with the user-specified list of cudaCapabilities.
# NOTE: Jetson devices are never built by default because they cannot be targeted along with
# non-Jetson devices and require an aarch64 host platform. As such, if they're present anywhere,
# they must be in the user-specified cudaCapabilities.
# NOTE: We don't need to worry about mixes of Jetson and non-Jetson devices here -- there's
# sanity-checking for all that in below.
jetsonTargets = lists.intersectLists jetsonComputeCapabilities cudaCapabilities;
# dropDot :: String -> String
dropDot = ver: builtins.replaceStrings [ "." ] [ "" ] ver;
# archMapper :: String -> List String -> List String
# Maps a feature across a list of architecture versions to produce a list of architectures.
# For example, "sm" and [ "8.0" "8.6" "8.7" ] produces [ "sm_80" "sm_86" "sm_87" ].
archMapper = feat: lists.map (computeCapability: "${feat}_${dropDot computeCapability}");
# gencodeMapper :: String -> List String -> List String
# Maps a feature across a list of architecture versions to produce a list of gencode arguments.
# For example, "sm" and [ "8.0" "8.6" "8.7" ] produces [ "-gencode=arch=compute_80,code=sm_80"
# "-gencode=arch=compute_86,code=sm_86" "-gencode=arch=compute_87,code=sm_87" ].
gencodeMapper =
feat:
lists.map (
computeCapability:
"-gencode=arch=compute_${dropDot computeCapability},code=${feat}_${dropDot computeCapability}"
);
# Maps Nix system to NVIDIA redist arch.
# NOTE: We swap out the default `linux-sbsa` redist (for server-grade ARM chips) with the
# `linux-aarch64` redist (which is for Jetson devices) if we're building any Jetson devices.
# Since both are based on aarch64, we can only have one or the other, otherwise there's an
# ambiguity as to which should be used.
# NOTE: This function *will* be called by unsupported systems because `cudaPackages` is part of
# `all-packages.nix`, which is evaluated on all systems. As such, we need to handle unsupported
# systems gracefully.
# getRedistArch :: String -> String
getRedistArch =
nixSystem:
attrsets.attrByPath [ nixSystem ] "unsupported" {
aarch64-linux = if jetsonTargets != [ ] then "linux-aarch64" else "linux-sbsa";
x86_64-linux = "linux-x86_64";
ppc64le-linux = "linux-ppc64le";
x86_64-windows = "windows-x86_64";
};
# Maps NVIDIA redist arch to Nix system.
# NOTE: This function *will* be called by unsupported systems because `cudaPackages` is part of
# `all-packages.nix`, which is evaluated on all systems. As such, we need to handle unsupported
# systems gracefully.
# getNixSystem :: String -> String
getNixSystem =
redistArch:
attrsets.attrByPath [ redistArch ] "unsupported-${redistArch}" {
linux-sbsa = "aarch64-linux";
linux-aarch64 = "aarch64-linux";
linux-x86_64 = "x86_64-linux";
linux-ppc64le = "ppc64le-linux";
windows-x86_64 = "x86_64-windows";
};
formatCapabilities =
{
cudaCapabilities,
enableForwardCompat ? true,
}:
rec {
inherit cudaCapabilities enableForwardCompat;
# archNames :: List String
# E.g. [ "Turing" "Ampere" ]
#
# Unknown architectures are rendered as sm_XX gencode flags.
archNames = lists.unique (
lists.map (cap: cudaComputeCapabilityToName.${cap} or "sm_${dropDot cap}") cudaCapabilities
);
# realArches :: List String
# The real architectures are physical architectures supported by the CUDA version.
# E.g. [ "sm_75" "sm_86" ]
realArches = archMapper "sm" cudaCapabilities;
# virtualArches :: List String
# The virtual architectures are typically used for forward compatibility, when trying to support
# an architecture newer than the CUDA version allows.
# E.g. [ "compute_75" "compute_86" ]
virtualArches = archMapper "compute" cudaCapabilities;
# arches :: List String
# By default, build for all supported architectures and forward compatibility via a virtual
# architecture for the newest supported architecture.
# E.g. [ "sm_75" "sm_86" "compute_86" ]
arches = realArches ++ lists.optional enableForwardCompat (lists.last virtualArches);
# gencode :: List String
# A list of CUDA gencode arguments to pass to NVCC.
# E.g. [ "-gencode=arch=compute_75,code=sm_75" ... "-gencode=arch=compute_86,code=compute_86" ]
gencode =
let
base = gencodeMapper "sm" cudaCapabilities;
forward = gencodeMapper "compute" [ (lists.last cudaCapabilities) ];
in
base ++ lib.optionals enableForwardCompat forward;
# gencodeString :: String
# A space-separated string of CUDA gencode arguments to pass to NVCC.
# E.g. "-gencode=arch=compute_75,code=sm_75 ... -gencode=arch=compute_86,code=compute_86"
gencodeString = strings.concatStringsSep " " gencode;
# cmakeCudaArchitecturesString :: String
# A semicolon-separated string of CUDA capabilities without dots, suitable for passing to CMake.
# E.g. "75;86"
cmakeCudaArchitecturesString = strings.concatMapStringsSep ";" dropDot cudaCapabilities;
# Jetson devices cannot be targeted by the same binaries which target non-Jetson devices. While
# NVIDIA provides both `linux-aarch64` and `linux-sbsa` packages, which both target `aarch64`,
# they are built with different settings and cannot be mixed.
# isJetsonBuild :: Boolean
isJetsonBuild =
let
requestedJetsonDevices = lists.filter (
cap: cudaComputeCapabilityToIsJetson.${cap} or false
) cudaCapabilities;
requestedNonJetsonDevices = lists.filter (
cap: !(builtins.elem cap requestedJetsonDevices)
) cudaCapabilities;
jetsonBuildSufficientCondition = requestedJetsonDevices != [ ];
jetsonBuildNecessaryCondition = requestedNonJetsonDevices == [ ] && hostPlatform.isAarch64;
in
trivial.throwIf (jetsonBuildSufficientCondition && !jetsonBuildNecessaryCondition) ''
Jetson devices cannot be targeted with non-Jetson devices. Additionally, they require hostPlatform to be aarch64.
You requested ${builtins.toJSON cudaCapabilities} for host platform ${hostPlatform.system}.
Requested Jetson devices: ${builtins.toJSON requestedJetsonDevices}.
Requested non-Jetson devices: ${builtins.toJSON requestedNonJetsonDevices}.
Exactly one of the following must be true:
- All CUDA capabilities belong to Jetson devices and hostPlatform is aarch64.
- No CUDA capabilities belong to Jetson devices.
See ${./gpus.nix} for a list of architectures supported by this version of Nixpkgs.
'' jetsonBuildSufficientCondition
&& jetsonBuildNecessaryCondition;
};
in
# When changing names or formats: pause, validate, and update the assert
assert
let
expected = {
cudaCapabilities = [
"7.5"
"8.6"
];
enableForwardCompat = true;
archNames = [
"Turing"
"Ampere"
];
realArches = [
"sm_75"
"sm_86"
];
virtualArches = [
"compute_75"
"compute_86"
];
arches = [
"sm_75"
"sm_86"
"compute_86"
];
gencode = [
"-gencode=arch=compute_75,code=sm_75"
"-gencode=arch=compute_86,code=sm_86"
"-gencode=arch=compute_86,code=compute_86"
];
gencodeString = "-gencode=arch=compute_75,code=sm_75 -gencode=arch=compute_86,code=sm_86 -gencode=arch=compute_86,code=compute_86";
cmakeCudaArchitecturesString = "75;86";
isJetsonBuild = false;
};
actual = formatCapabilities {
cudaCapabilities = [
"7.5"
"8.6"
];
};
actualWrapped = (builtins.tryEval (builtins.deepSeq actual actual)).value;
in
asserts.assertMsg
((strings.versionAtLeast cudaMajorMinorVersion "11.2") -> (expected == actualWrapped))
''
This test should only fail when using a version of CUDA older than 11.2, the first to support
8.6.
Expected: ${builtins.toJSON expected}
Actual: ${builtins.toJSON actualWrapped}
'';
# Check mixed Jetson and non-Jetson devices
assert
let
expected = false;
actual = formatCapabilities {
cudaCapabilities = [
"7.2"
"7.5"
];
};
actualWrapped = (builtins.tryEval (builtins.deepSeq actual actual)).value;
in
asserts.assertMsg (expected == actualWrapped) ''
Jetson devices capabilities cannot be mixed with non-jetson devices.
Capability 7.5 is non-Jetson and should not be allowed with Jetson 7.2.
Expected: ${builtins.toJSON expected}
Actual: ${builtins.toJSON actualWrapped}
'';
# Check Jetson-only
assert
let
expected = {
cudaCapabilities = [
"6.2"
"7.2"
];
enableForwardCompat = true;
archNames = [
"Pascal"
"Volta"
];
realArches = [
"sm_62"
"sm_72"
];
virtualArches = [
"compute_62"
"compute_72"
];
arches = [
"sm_62"
"sm_72"
"compute_72"
];
gencode = [
"-gencode=arch=compute_62,code=sm_62"
"-gencode=arch=compute_72,code=sm_72"
"-gencode=arch=compute_72,code=compute_72"
];
gencodeString = "-gencode=arch=compute_62,code=sm_62 -gencode=arch=compute_72,code=sm_72 -gencode=arch=compute_72,code=compute_72";
cmakeCudaArchitecturesString = "62;72";
isJetsonBuild = true;
};
actual = formatCapabilities {
cudaCapabilities = [
"6.2"
"7.2"
];
};
actualWrapped = (builtins.tryEval (builtins.deepSeq actual actual)).value;
in
asserts.assertMsg
# We can't do this test unless we're targeting aarch64
(hostPlatform.isAarch64 -> (expected == actualWrapped))
''
Jetson devices can only be built with other Jetson devices.
Both 6.2 and 7.2 are Jetson devices.
Expected: ${builtins.toJSON expected}
Actual: ${builtins.toJSON actualWrapped}
'';
{
# formatCapabilities :: { cudaCapabilities: List Capability, enableForwardCompat: Boolean } -> { ... }
inherit formatCapabilities;
# cudaArchNameToVersions :: String => String
inherit cudaArchNameToVersions;
# cudaComputeCapabilityToName :: String => String
inherit cudaComputeCapabilityToName;
# dropDot :: String -> String
inherit dropDot;
inherit
defaultCapabilities
supportedCapabilities
jetsonComputeCapabilities
jetsonTargets
getNixSystem
getRedistArch
;
}
// formatCapabilities {
cudaCapabilities = if cudaCapabilities == [ ] then defaultCapabilities else cudaCapabilities;
enableForwardCompat = cudaForwardCompat;
}

View file

@ -5,8 +5,8 @@
autoPatchelfHook, autoPatchelfHook,
backendStdenv, backendStdenv,
callPackage, callPackage,
_cuda,
fetchurl, fetchurl,
fixups,
lib, lib,
markForCudatoolkitRootHook, markForCudatoolkitRootHook,
flags, flags,
@ -44,18 +44,18 @@ let
# Last step before returning control to `callPackage` (adds the `.override` method) # Last step before returning control to `callPackage` (adds the `.override` method)
# we'll apply (`overrideAttrs`) necessary package-specific "fixup" functions. # we'll apply (`overrideAttrs`) necessary package-specific "fixup" functions.
# Order is significant. # Order is significant.
maybeFixup = fixups.${pname} or null; maybeFixup = _cuda.fixups.${pname} or null;
fixup = if maybeFixup != null then callPackage maybeFixup { } else { }; fixup = if maybeFixup != null then callPackage maybeFixup { } else { };
# Get the redist architectures for which package provides distributables. # Get the redist systems for which package provides distributables.
# These are used by meta.platforms. # These are used by meta.platforms.
supportedRedistArchs = builtins.attrNames featureRelease; supportedRedistSystems = builtins.attrNames featureRelease;
# redistArch :: String # redistSystem :: String
# The redistArch is the name of the architecture for which the redistributable is built. # The redistSystem is the name of the system for which the redistributable is built.
# It is `"unsupported"` if the redistributable is not supported on the target platform. # It is `"unsupported"` if the redistributable is not supported on the target system.
redistArch = flags.getRedistArch hostPlatform.system; redistSystem = _cuda.lib.getRedistSystem backendStdenv.hasJetsonCudaCapability hostPlatform.system;
sourceMatchesHost = flags.getNixSystem redistArch == hostPlatform.system; sourceMatchesHost = lib.elem hostPlatform.system (_cuda.lib.getNixSystems redistSystem);
in in
(backendStdenv.mkDerivation (finalAttrs: { (backendStdenv.mkDerivation (finalAttrs: {
# NOTE: Even though there's no actual buildPhase going on here, the derivations of the # NOTE: Even though there's no actual buildPhase going on here, the derivations of the
@ -81,7 +81,7 @@ in
hasOutput = hasOutput =
output: output:
attrsets.attrByPath [ attrsets.attrByPath [
redistArch redistSystem
"outputs" "outputs"
output output
] false featureRelease; ] false featureRelease;
@ -99,12 +99,15 @@ in
# NOTE: In the case the redistributable isn't supported on the target platform, # NOTE: In the case the redistributable isn't supported on the target platform,
# we will have `outputs = [ "out" ] ++ possibleOutputs`. This is of note because platforms which # we will have `outputs = [ "out" ] ++ possibleOutputs`. This is of note because platforms which
# aren't supported would otherwise have evaluation errors when trying to access outputs other than `out`. # aren't supported would otherwise have evaluation errors when trying to access outputs other than `out`.
# The alternative would be to have `outputs = [ "out" ]` when`redistArch = "unsupported"`, but that would # The alternative would be to have `outputs = [ "out" ]` when`redistSystem = "unsupported"`, but that would
# require adding guards throughout the entirety of the CUDA package set to ensure `cudaSupport` is true -- # require adding guards throughout the entirety of the CUDA package set to ensure `cudaSupport` is true --
# recall that OfBorg will evaluate packages marked as broken and that `cudaPackages` will be evaluated with # recall that OfBorg will evaluate packages marked as broken and that `cudaPackages` will be evaluated with
# `cudaSupport = false`! # `cudaSupport = false`!
additionalOutputs = additionalOutputs =
if redistArch == "unsupported" then possibleOutputs else builtins.filter hasOutput possibleOutputs; if redistSystem == "unsupported" then
possibleOutputs
else
builtins.filter hasOutput possibleOutputs;
# The out output is special -- it's the default output and we always include it. # The out output is special -- it's the default output and we always include it.
outputs = [ "out" ] ++ additionalOutputs; outputs = [ "out" ] ++ additionalOutputs;
in in
@ -155,14 +158,14 @@ in
}; };
# src :: Optional Derivation # src :: Optional Derivation
# If redistArch doesn't exist in redistribRelease, return null. # If redistSystem doesn't exist in redistribRelease, return null.
src = trivial.mapNullable ( src = trivial.mapNullable (
{ relative_path, sha256, ... }: { relative_path, sha256, ... }:
fetchurl { fetchurl {
url = "https://developer.download.nvidia.com/compute/${redistName}/redist/${relative_path}"; url = "https://developer.download.nvidia.com/compute/${redistName}/redist/${relative_path}";
inherit sha256; inherit sha256;
} }
) (redistribRelease.${redistArch} or null); ) (redistribRelease.${redistSystem} or null);
postPatch = postPatch =
# Pkg-config's setup hook expects configuration files in $out/share/pkgconfig # Pkg-config's setup hook expects configuration files in $out/share/pkgconfig
@ -321,11 +324,13 @@ in
description = "${redistribRelease.name}. By downloading and using the packages you accept the terms and conditions of the ${finalAttrs.meta.license.shortName}"; description = "${redistribRelease.name}. By downloading and using the packages you accept the terms and conditions of the ${finalAttrs.meta.license.shortName}";
sourceProvenance = [ sourceTypes.binaryNativeCode ]; sourceProvenance = [ sourceTypes.binaryNativeCode ];
broken = lists.any trivial.id (attrsets.attrValues finalAttrs.brokenConditions); broken = lists.any trivial.id (attrsets.attrValues finalAttrs.brokenConditions);
platforms = trivial.pipe supportedRedistArchs [ platforms = trivial.pipe supportedRedistSystems [
# Map each redist arch to the equivalent nix system or null if there is no equivalent. # Map each redist system to the equivalent nix systems.
(builtins.map flags.getNixSystem) (lib.concatMap _cuda.lib.getNixSystems)
# Filter out unsupported systems # Take all the unique values.
(builtins.filter (nixSystem: !(strings.hasPrefix "unsupported-" nixSystem))) lib.unique
# Sort the list.
lib.naturalSort
]; ];
badPlatforms = badPlatforms =
let let

View file

@ -1,11 +1,9 @@
{ {
# callPackage-provided arguments
lib, lib,
cudaLib,
cudaMajorMinorVersion, cudaMajorMinorVersion,
flags, redistSystem,
stdenv, stdenv,
# Expected to be passed by the caller
mkVersionedPackageName,
# Builder-specific arguments # Builder-specific arguments
# Short package name (e.g., "cuda_cccl") # Short package name (e.g., "cuda_cccl")
# pname : String # pname : String
@ -26,7 +24,7 @@
# The featureRelease is used to populate meta.platforms (by way of looking at the attribute names), determine the # 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, # outputs of the package, and provide additional package-specific constraints (e.g., min/max supported CUDA versions,
# required versions of other packages, etc.). # required versions of other packages, etc.).
# shimFn :: {package, redistArch} -> AttrSet # shimFn :: {package, redistSystem} -> AttrSet
shimsFn ? (throw "shimsFn must be provided"), shimsFn ? (throw "shimsFn must be provided"),
}: }:
let let
@ -41,10 +39,6 @@ let
# - Releases: ../modules/${pname}/releases/releases.nix # - Releases: ../modules/${pname}/releases/releases.nix
# - Package: ../modules/${pname}/releases/package.nix # - Package: ../modules/${pname}/releases/package.nix
# redistArch :: String
# Value is `"unsupported"` if the platform is not supported.
redistArch = flags.getRedistArch stdenv.hostPlatform.system;
# Check whether a package supports our CUDA version. # Check whether a package supports our CUDA version.
# satisfiesCudaVersion :: Package -> Bool # satisfiesCudaVersion :: Package -> Bool
satisfiesCudaVersion = satisfiesCudaVersion =
@ -53,7 +47,7 @@ let
&& lib.versionAtLeast package.maxCudaVersion cudaMajorMinorVersion; && lib.versionAtLeast package.maxCudaVersion cudaMajorMinorVersion;
# FIXME: do this at the module system level # FIXME: do this at the module system level
propagatePlatforms = lib.mapAttrs (redistArch: lib.map (p: { inherit redistArch; } // p)); propagatePlatforms = lib.mapAttrs (redistSystem: lib.map (p: { inherit redistSystem; } // p));
# Releases for all platforms and all CUDA versions. # Releases for all platforms and all CUDA versions.
allReleases = propagatePlatforms evaluatedModules.config.${pname}.releases; allReleases = propagatePlatforms evaluatedModules.config.${pname}.releases;
@ -65,12 +59,12 @@ let
allPackages = lib.concatLists (lib.attrValues allReleases'); allPackages = lib.concatLists (lib.attrValues allReleases');
packageOlder = p1: p2: lib.versionOlder p1.version p2.version; packageOlder = p1: p2: lib.versionOlder p1.version p2.version;
packageSupportedPlatform = p: p.redistArch == redistArch; packageSupportedPlatform = p: p.redistSystem == redistSystem;
# Compute versioned attribute name to be used in this package set # Compute versioned attribute name to be used in this package set
# Patch version changes should not break the build, so we only use major and minor # Patch version changes should not break the build, so we only use major and minor
# computeName :: Package -> String # computeName :: Package -> String
computeName = package: mkVersionedPackageName pname package.version; computeName = { version, ... }: cudaLib.mkVersionedName pname (lib.versions.majorMinor version);
# The newest package for each major-minor version, with newest first. # The newest package for each major-minor version, with newest first.
# newestPackages :: List Package # newestPackages :: List Package
@ -113,7 +107,7 @@ let
buildPackage = buildPackage =
package: package:
let let
shims = final.callPackage shimsFn { inherit package redistArch; }; shims = final.callPackage shimsFn { inherit package redistSystem; };
name = computeName package; name = computeName package;
drv = final.callPackage ./manifest.nix { drv = final.callPackage ./manifest.nix {
inherit pname redistName; inherit pname redistName;

View file

@ -1,244 +0,0 @@
# Type aliases
#
# Gpu = {
# archName: String
# - The name of the microarchitecture.
# computeCapability: String
# - The compute capability of the GPU.
# isJetson: Boolean
# - Whether a GPU is part of NVIDIA's line of Jetson embedded computers. This field is
# notable because it tells us what architecture to build for (as Jetson devices are
# aarch64).
# More on Jetson devices here:
# https://www.nvidia.com/en-us/autonomous-machines/embedded-systems/
# NOTE: These architectures are only built upon request.
# minCudaVersion: String
# - The minimum (inclusive) CUDA version that supports this GPU.
# dontDefaultAfter: null | String
# - The CUDA version after which to exclude this GPU from the list of default capabilities
# we build. null means we always include this GPU in the default capabilities if it is
# supported.
# maxCudaVersion: null | String
# - The maximum (exclusive) CUDA version that supports this GPU. null means there is no
# maximum.
# }
#
# Many thanks to Arnon Shimoni for maintaining a list of these architectures and capabilities.
# Without your work, this would have been much more difficult.
# https://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/
#
# https://en.wikipedia.org/wiki/CUDA#GPUs_supported
[
{
# Tesla K40
archName = "Kepler";
computeCapability = "3.5";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = "11.0";
maxCudaVersion = "11.8";
}
{
# Tesla K80
archName = "Kepler";
computeCapability = "3.7";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = "11.0";
maxCudaVersion = "11.8";
}
{
# Tesla/Quadro M series
archName = "Maxwell";
computeCapability = "5.0";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = "11.0";
maxCudaVersion = null;
}
{
# Quadro M6000, GeForce 900, GTX-970, GTX-980, GTX Titan X
archName = "Maxwell";
computeCapability = "5.2";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = "11.0";
maxCudaVersion = null;
}
{
# Tegra (Jetson) TX1 / Tegra X1, Drive CX, Drive PX, Jetson Nano
archName = "Maxwell";
computeCapability = "5.3";
isJetson = true;
minCudaVersion = "10.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# Quadro GP100, Tesla P100, DGX-1 (Generic Pascal)
archName = "Pascal";
computeCapability = "6.0";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# GTX 1080, GTX 1070, GTX 1060, GTX 1050, GTX 1030 (GP108), GT 1010 (GP108) Titan Xp, Tesla
# P40, Tesla P4, Discrete GPU on the NVIDIA Drive PX2
archName = "Pascal";
computeCapability = "6.1";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# Integrated GPU on the NVIDIA Drive PX2, Tegra (Jetson) TX2
archName = "Pascal";
computeCapability = "6.2";
isJetson = true;
minCudaVersion = "10.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# DGX-1 with Volta, Tesla V100, GTX 1180 (GV104), Titan V, Quadro GV100
archName = "Volta";
computeCapability = "7.0";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# Jetson AGX Xavier, Drive AGX Pegasus, Xavier NX
archName = "Volta";
computeCapability = "7.2";
isJetson = true;
minCudaVersion = "10.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# GTX/RTX Turing GTX 1660 Ti, RTX 2060, RTX 2070, RTX 2080, Titan RTX, Quadro RTX 4000,
# Quadro RTX 5000, Quadro RTX 6000, Quadro RTX 8000, Quadro T1000/T2000, Tesla T4
archName = "Turing";
computeCapability = "7.5";
isJetson = false;
minCudaVersion = "10.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# NVIDIA A100 (the name “Tesla” has been dropped GA100), NVIDIA DGX-A100
archName = "Ampere";
computeCapability = "8.0";
isJetson = false;
minCudaVersion = "11.2";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# Tesla GA10x cards, RTX Ampere RTX 3080, GA102 RTX 3090, RTX A2000, A3000, RTX A4000,
# A5000, A6000, NVIDIA A40, GA106 RTX 3060, GA104 RTX 3070, GA107 RTX 3050, RTX A10, RTX
# A16, RTX A40, A2 Tensor Core GPU
archName = "Ampere";
computeCapability = "8.6";
isJetson = false;
minCudaVersion = "11.2";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# Jetson AGX Orin and Drive AGX Orin only
archName = "Ampere";
computeCapability = "8.7";
isJetson = true;
minCudaVersion = "11.5";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# NVIDIA GeForce RTX 4090, RTX 4080, RTX 6000, Tesla L40
archName = "Ada";
computeCapability = "8.9";
isJetson = false;
minCudaVersion = "11.8";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# NVIDIA H100 (GH100)
archName = "Hopper";
computeCapability = "9.0";
isJetson = false;
minCudaVersion = "11.8";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# NVIDIA H100 (GH100) (Thor)
archName = "Hopper";
computeCapability = "9.0a";
isJetson = false;
minCudaVersion = "12.0";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# NVIDIA B100
archName = "Blackwell";
computeCapability = "10.0";
isJetson = false;
minCudaVersion = "12.8";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# NVIDIA B100 Accelerated
archName = "Blackwell";
computeCapability = "10.0a";
isJetson = false;
minCudaVersion = "12.8";
dontDefaultAfter = "12.0"; # disable to reduce size of OnnxRuntime and Torch CUDA binaries
maxCudaVersion = null;
}
{
# NVIDIA Blackwell
archName = "Blackwell";
computeCapability = "10.1";
isJetson = false;
minCudaVersion = "12.8";
dontDefaultAfter = "12.0"; # disable to reduce size of OnnxRuntime and Torch CUDA binaries
maxCudaVersion = null;
}
{
# NVIDIA Blackwell Accelerated
archName = "Blackwell";
computeCapability = "10.1a";
isJetson = false;
minCudaVersion = "12.8";
dontDefaultAfter = "12.0"; # disable to reduce size of OnnxRuntime and Torch CUDA binaries
maxCudaVersion = null;
}
{
# NVIDIA GeForce RTX 5090 (GB202), RTX 5080 (GB203), RTX 5070 (GB205)
archName = "Blackwell";
computeCapability = "12.0";
isJetson = false;
minCudaVersion = "12.8";
dontDefaultAfter = null;
maxCudaVersion = null;
}
{
# NVIDIA Blackwell Accelerated
archName = "Blackwell";
computeCapability = "12.0a";
isJetson = false;
minCudaVersion = "12.8";
dontDefaultAfter = "12.0"; # disable to reduce size of OnnxRuntime and Torch CUDA binaries
maxCudaVersion = null;
}
]

View file

@ -1,125 +0,0 @@
# Taken from
# https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#host-compiler-support-policy
#
# NVCC performs a version check on the host compilers major version and so newer minor versions
# of the compilers listed below will be supported, but major versions falling outside the range
# will not be supported.
#
# NOTE: These constraints don't apply to Jetson, which uses something else.
# NOTE: NVIDIA can and will add support for newer compilers even during patch releases.
# E.g.: CUDA 12.2.1 maxxed out with support for Clang 15.0; 12.2.2 added support for Clang 16.0.
# NOTE: Because all platforms NVIDIA supports use GCC and Clang, we omit the architectures here.
# Type Aliases
# CudaVersion = String (two-part version number, e.g. "11.2")
# Platform = String (e.g. "x86_64-linux")
# CompilerCompatibilities = {
# clangMaxMajorVersion = String (e.g. "15")
# clangMinMajorVersion = String (e.g. "7")
# gccMaxMajorVersion = String (e.g. "11")
# gccMinMajorVersion = String (e.g. "6")
# }
let
# attrs :: AttrSet CudaVersion CompilerCompatibilities
attrs = {
# Our baseline
# https://docs.nvidia.com/cuda/archive/11.0/cuda-toolkit-release-notes/index.html#cuda-compiler-new-features
"11.0" = {
clangMaxMajorVersion = "9";
clangMinMajorVersion = "7";
gccMaxMajorVersion = "9";
gccMinMajorVersion = "6";
};
# Added support for Clang 10 and GCC 10
# https://docs.nvidia.com/cuda/archive/11.1.1/cuda-toolkit-release-notes/index.html#cuda-compiler-new-features
"11.1" = attrs."11.0" // {
clangMaxMajorVersion = "10";
gccMaxMajorVersion = "10";
};
# Added support for Clang 11
# https://docs.nvidia.com/cuda/archive/11.2.2/cuda-installation-guide-linux/index.html#system-requirements
"11.2" = attrs."11.1" // {
clangMaxMajorVersion = "11";
};
# No changes from 11.2 to 11.3
"11.3" = attrs."11.2";
# Added support for Clang 12 and GCC 11
# https://docs.nvidia.com/cuda/archive/11.4.4/cuda-toolkit-release-notes/index.html#cuda-general-new-features
"11.4" = attrs."11.3" // {
clangMaxMajorVersion = "12";
# NOTE: There is a bug in the version of GLIBC that GCC 11 uses which causes it to fail to compile some CUDA
# code. As such, we skip it for this release, and do the bump in 11.6 (skipping 11.5).
# https://forums.developer.nvidia.com/t/cuda-11-5-samples-throw-multiple-error-attribute-malloc-does-not-take-arguments/192750/15
# gccMaxMajorVersion = "11";
};
# No changes from 11.4 to 11.5
"11.5" = attrs."11.4";
# No changes from 11.5 to 11.6
# However, as mentioned above, we add GCC 11 this release.
"11.6" = attrs."11.5" // {
gccMaxMajorVersion = "11";
};
# Added support for Clang 13
# https://docs.nvidia.com/cuda/archive/11.7.1/cuda-toolkit-release-notes/index.html#cuda-compiler-new-features
"11.7" = attrs."11.6" // {
clangMaxMajorVersion = "13";
};
# Added support for Clang 14
# https://docs.nvidia.com/cuda/archive/11.8.0/cuda-installation-guide-linux/index.html#system-requirements
"11.8" = attrs."11.7" // {
clangMaxMajorVersion = "14";
};
# Added support for GCC 12
# https://docs.nvidia.com/cuda/archive/12.0.1/cuda-installation-guide-linux/index.html#system-requirements
"12.0" = attrs."11.8" // {
gccMaxMajorVersion = "12";
};
# Added support for Clang 15
# https://docs.nvidia.com/cuda/archive/12.1.1/cuda-toolkit-release-notes/index.html#cuda-compilers-new-features
"12.1" = attrs."12.0" // {
clangMaxMajorVersion = "15";
};
# Added support for Clang 16
# https://docs.nvidia.com/cuda/archive/12.2.2/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.2" = attrs."12.1" // {
clangMaxMajorVersion = "16";
};
# No changes from 12.2 to 12.3
"12.3" = attrs."12.2";
# Added support for Clang 17 and GCC 13
# https://docs.nvidia.com/cuda/archive/12.4.0/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.4" = attrs."12.3" // {
clangMaxMajorVersion = "17";
gccMaxMajorVersion = "13";
};
# No changes from 12.4 to 12.5
"12.5" = attrs."12.4";
# Added support for Clang 18
# https://docs.nvidia.com/cuda/archive/12.6.0/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.6" = attrs."12.4" // {
clangMaxMajorVersion = "18";
};
# Added support for Clang 19 and GCC 14
# https://docs.nvidia.com/cuda/archive/12.8.0/cuda-installation-guide-linux/index.html#host-compiler-support-policy
"12.8" = attrs."12.6" // {
clangMaxMajorVersion = "19";
gccMaxMajorVersion = "14";
};
};
in
attrs

View file

@ -1,4 +1,3 @@
# Exposed as cudaPackages.backendStdenv.
# This is what nvcc uses as a backend, # This is what nvcc uses as a backend,
# and it has to be an officially supported one (e.g. gcc11 for cuda11). # and it has to be an officially supported one (e.g. gcc11 for cuda11).
# #
@ -7,26 +6,149 @@
# E.g. for cudaPackages_11_8 we use gcc11 with gcc12's libstdc++ # E.g. for cudaPackages_11_8 we use gcc11 with gcc12's libstdc++
# Cf. https://github.com/NixOS/nixpkgs/pull/218265 for context # Cf. https://github.com/NixOS/nixpkgs/pull/218265 for context
{ {
config,
_cuda,
cudaMajorMinorVersion, cudaMajorMinorVersion,
lib, lib,
nvccCompatibilities,
pkgs, pkgs,
stdenv, stdenv,
stdenvAdapters, stdenvAdapters,
}: }:
let let
gccMajorVersion = nvccCompatibilities.${cudaMajorMinorVersion}.gccMaxMajorVersion; inherit (builtins) toJSON;
cudaStdenv = stdenvAdapters.useLibsFrom stdenv pkgs."gcc${gccMajorVersion}Stdenv"; inherit (_cuda.db) allSortedCudaCapabilities cudaCapabilityToInfo nvccCompatibilities;
inherit (_cuda.lib)
_cudaCapabilityIsDefault
_cudaCapabilityIsSupported
_evaluateAssertions
getRedistSystem
mkVersionedName
;
inherit (lib) addErrorContext;
inherit (lib.customisation) extendDerivation;
inherit (lib.lists) filter intersectLists subtractLists;
# NOTE: By virtue of processing a sorted list (allSortedCudaCapabilities), our groups will be sorted.
architectureSpecificCudaCapabilities = filter (
cudaCapability: cudaCapabilityToInfo.${cudaCapability}.isArchitectureSpecific
) allSortedCudaCapabilities;
familySpecificCudaCapabilities = filter (
cudaCapability: cudaCapabilityToInfo.${cudaCapability}.isFamilySpecific
) allSortedCudaCapabilities;
jetsonCudaCapabilities = filter (
cudaCapability: cudaCapabilityToInfo.${cudaCapability}.isJetson
) allSortedCudaCapabilities;
passthruExtra = { passthruExtra = {
# cudaPackages.backendStdenv.nixpkgsCompatibleLibstdcxx has been removed, nvccHostCCMatchesStdenvCC = backendStdenv.cc == stdenv.cc;
# if you need it you're likely doing something wrong. There has been a
# warning here for a month or so. Now we can no longer return any # The Nix system of the host platform.
# meaningful value in its place and drop the attribute entirely. hostNixSystem = stdenv.hostPlatform.system;
# The Nix system of the host platform for the CUDA redistributable.
hostRedistSystem = getRedistSystem passthruExtra.hasJetsonCudaCapability stdenv.hostPlatform.system;
# Sets whether packages should be built with forward compatibility.
# TODO(@connorbaker): If the requested CUDA capabilities are not supported by the current CUDA version,
# should we throw an evaluation warning and build with forward compatibility?
cudaForwardCompat = config.cudaForwardCompat or true;
# CUDA capabilities which are supported by the current CUDA version.
supportedCudaCapabilities = filter (
cudaCapability:
_cudaCapabilityIsSupported cudaMajorMinorVersion cudaCapabilityToInfo.${cudaCapability}
) allSortedCudaCapabilities;
# Find the default set of capabilities for this CUDA version using the list of supported capabilities.
# Includes only baseline capabilities.
defaultCudaCapabilities = filter (
cudaCapability:
_cudaCapabilityIsDefault cudaMajorMinorVersion cudaCapabilityToInfo.${cudaCapability}
) passthruExtra.supportedCudaCapabilities;
# The resolved requested or default CUDA capabilities.
cudaCapabilities =
if config.cudaCapabilities or [ ] != [ ] then
config.cudaCapabilities
else
passthruExtra.defaultCudaCapabilities;
# Requested architecture-specific CUDA capabilities.
requestedArchitectureSpecificCudaCapabilities = intersectLists architectureSpecificCudaCapabilities passthruExtra.cudaCapabilities;
# Whether the requested CUDA capabilities include architecture-specific CUDA capabilities.
hasArchitectureSpecificCudaCapability =
passthruExtra.requestedArchitectureSpecificCudaCapabilities != [ ];
# Requested family-specific CUDA capabilities.
requestedFamilySpecificCudaCapabilities = intersectLists familySpecificCudaCapabilities passthruExtra.cudaCapabilities;
# Whether the requested CUDA capabilities include family-specific CUDA capabilities.
hasFamilySpecificCudaCapability = passthruExtra.requestedFamilySpecificCudaCapabilities != [ ];
# Requested Jetson CUDA capabilities.
requestedJetsonCudaCapabilities = intersectLists jetsonCudaCapabilities passthruExtra.cudaCapabilities;
# Whether the requested CUDA capabilities include Jetson CUDA capabilities.
hasJetsonCudaCapability = passthruExtra.requestedJetsonCudaCapabilities != [ ];
}; };
assertCondition = true;
assertions =
let
# Jetson devices cannot be targeted by the same binaries which target non-Jetson devices. While
# NVIDIA provides both `linux-aarch64` and `linux-sbsa` packages, which both target `aarch64`,
# they are built with different settings and cannot be mixed.
jetsonMesssagePrefix = "Jetson CUDA capabilities (${toJSON passthruExtra.requestedJetsonCudaCapabilities})";
# Remove all known capabilities from the user's list to find unrecognized capabilities.
unrecognizedCudaCapabilities = subtractLists allSortedCudaCapabilities passthruExtra.cudaCapabilities;
# Remove all supported capabilities from the user's list to find unsupported capabilities.
unsupportedCudaCapabilities = subtractLists passthruExtra.supportedCudaCapabilities passthruExtra.cudaCapabilities;
in in
[
{
message = "Unrecognized CUDA capabilities: ${toJSON unrecognizedCudaCapabilities}";
assertion = unrecognizedCudaCapabilities == [ ];
}
{
message = "Unsupported CUDA capabilities: ${toJSON unsupportedCudaCapabilities}";
assertion = unsupportedCudaCapabilities == [ ];
}
{
message =
"${jetsonMesssagePrefix} require hostPlatform (currently ${passthruExtra.hostNixSystem}) "
+ "to be aarch64-linux";
assertion = passthruExtra.hasJetsonCudaCapability -> passthruExtra.hostNixSystem == "aarch64-linux";
}
{
message =
let
# Find the capabilities which are not Jetson capabilities.
requestedNonJetsonCudaCapabilities = subtractLists (
passthruExtra.requestedJetsonCudaCapabilities
++ passthruExtra.requestedArchitectureSpecificCudaCapabilities
++ passthruExtra.requestedFamilySpecificCudaCapabilities
) passthruExtra.cudaCapabilities;
in
"${jetsonMesssagePrefix} cannot be specified with non-Jetson capabilities "
+ "(${toJSON requestedNonJetsonCudaCapabilities})";
assertion =
passthruExtra.hasJetsonCudaCapability
-> passthruExtra.requestedJetsonCudaCapabilities == passthruExtra.cudaCapabilities;
}
];
assertCondition = addErrorContext "while evaluating ${mkVersionedName "cudaPackages" cudaMajorMinorVersion}.backendStdenv" (
_evaluateAssertions assertions
);
backendStdenv =
stdenvAdapters.useLibsFrom stdenv
pkgs."gcc${nvccCompatibilities.${cudaMajorMinorVersion}.gcc.maxMajorVersion}Stdenv";
in
# TODO: Consider testing whether we in fact use the newer libstdc++ # TODO: Consider testing whether we in fact use the newer libstdc++
extendDerivation assertCondition passthruExtra backendStdenv
lib.extendDerivation assertCondition passthruExtra cudaStdenv

View file

@ -1,14 +1,14 @@
# Shims to mimic the shape of ../modules/generic/manifests/{feature,redistrib}/release.nix # Shims to mimic the shape of ../modules/generic/manifests/{feature,redistrib}/release.nix
{ {
package, package,
# redistArch :: String # redistSystem :: String
# String is `"unsupported"` if the given architecture is unsupported. # String is `"unsupported"` if the given architecture is unsupported.
redistArch, redistSystem,
}: }:
{ {
featureRelease = { featureRelease = {
inherit (package) cudnnVersion minCudaVersion maxCudaVersion; inherit (package) cudnnVersion minCudaVersion maxCudaVersion;
${redistArch}.outputs = { ${redistSystem}.outputs = {
bin = true; bin = true;
lib = true; lib = true;
static = true; static = true;

View file

@ -0,0 +1,79 @@
{
_cuda,
cudaNamePrefix,
lib,
runCommand,
}:
let
inherit (builtins) deepSeq toJSON tryEval;
inherit (_cuda.bootstrapData) cudaCapabilityToInfo;
inherit (_cuda.lib) formatCapabilities;
inherit (lib.asserts) assertMsg;
in
# When changing names or formats: pause, validate, and update the assert
assert assertMsg (
cudaCapabilityToInfo ? "7.5" && cudaCapabilityToInfo ? "8.6"
) "The following test requires both 7.5 and 8.6 be known CUDA capabilities";
assert
let
expected = {
cudaCapabilities = [
"7.5"
"8.6"
];
cudaForwardCompat = true;
# Sorted alphabetically
archNames = [
"Ampere"
"Turing"
];
realArches = [
"sm_75"
"sm_86"
];
virtualArches = [
"compute_75"
"compute_86"
];
arches = [
"sm_75"
"sm_86"
"compute_86"
];
gencode = [
"-gencode=arch=compute_75,code=sm_75"
"-gencode=arch=compute_86,code=sm_86"
"-gencode=arch=compute_86,code=compute_86"
];
gencodeString = "-gencode=arch=compute_75,code=sm_75 -gencode=arch=compute_86,code=sm_86 -gencode=arch=compute_86,code=compute_86";
cmakeCudaArchitecturesString = "75;86";
};
actual = formatCapabilities {
inherit cudaCapabilityToInfo;
cudaCapabilities = [
"7.5"
"8.6"
];
cudaForwardCompat = true;
};
actualWrapped = (tryEval (deepSeq actual actual)).value;
in
assertMsg (expected == actualWrapped) ''
Expected: ${toJSON expected}
Actual: ${toJSON actualWrapped}
'';
runCommand "${cudaNamePrefix}-tests-flags"
{
__structuredAttrs = true;
strictDeps = true;
}
''
touch "$out"
''

View file

@ -94,7 +94,7 @@ let
minArch = minArch =
let let
# E.g. [ "80" "86" "90" ] # E.g. [ "80" "86" "90" ]
cudaArchitectures = (builtins.map flags.dropDot flags.cudaCapabilities); cudaArchitectures = (builtins.map flags.dropDots flags.cudaCapabilities);
minArch' = builtins.head (builtins.sort strings.versionOlder cudaArchitectures); minArch' = builtins.head (builtins.sort strings.versionOlder cudaArchitectures);
in in
# "75" -> "750" Cf. https://github.com/icl-utk-edu/magma/blob/v2.9.0/CMakeLists.txt#L200-L201 # "75" -> "750" Cf. https://github.com/icl-utk-edu/magma/blob/v2.9.0/CMakeLists.txt#L200-L201

View file

@ -2742,6 +2742,9 @@ with pkgs;
cron = isc-cron; cron = isc-cron;
# Top-level fix-point used in `cudaPackages`' internals
_cuda = import ../development/cuda-modules/_cuda;
cudaPackages_11_0 = callPackage ./cuda-packages.nix { cudaMajorMinorVersion = "11.0"; }; cudaPackages_11_0 = callPackage ./cuda-packages.nix { cudaMajorMinorVersion = "11.0"; };
cudaPackages_11_1 = callPackage ./cuda-packages.nix { cudaMajorMinorVersion = "11.1"; }; cudaPackages_11_1 = callPackage ./cuda-packages.nix { cudaMajorMinorVersion = "11.1"; };
cudaPackages_11_2 = callPackage ./cuda-packages.nix { cudaMajorMinorVersion = "11.2"; }; cudaPackages_11_2 = callPackage ./cuda-packages.nix { cudaMajorMinorVersion = "11.2"; };

View file

@ -22,10 +22,10 @@
# I've (@connorbaker) attempted to do that, though I'm unsure of how this will interact with overrides. # I've (@connorbaker) attempted to do that, though I'm unsure of how this will interact with overrides.
{ {
config, config,
_cuda,
cudaMajorMinorVersion, cudaMajorMinorVersion,
lib, lib,
newScope, newScope,
pkgs,
stdenv, stdenv,
}: }:
let let
@ -37,41 +37,38 @@ let
strings strings
versions versions
; ;
# 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
cudaMajorMinorVersion
gpus
lib
stdenv
;
};
mkVersionedPackageName = cudaLib = _cuda.lib;
name: version: name + "_" + strings.replaceStrings [ "." ] [ "_" ] (versions.majorMinor version);
# Since Jetson capabilities are never built by default, we can check if any of them were requested
# through final.config.cudaCapabilities and use that to determine if we should change some manifest versions.
# Copied from backendStdenv.
jetsonCudaCapabilities = lib.filter (
cudaCapability: _cuda.db.cudaCapabilityToInfo.${cudaCapability}.isJetson
) _cuda.db.allSortedCudaCapabilities;
hasJetsonCudaCapability =
lib.intersectLists jetsonCudaCapabilities (config.cudaCapabilities or [ ]) != [ ];
redistSystem = _cuda.lib.getRedistSystem hasJetsonCudaCapability stdenv.hostPlatform.system;
passthruFunction = final: { passthruFunction = final: {
inherit # NOTE:
cudaMajorMinorVersion # It is important that _cuda is not part of the package set fixed-point. As described by
fixups # @SomeoneSerge:
flags # > The layering should be: configuration -> (identifies/is part of) cudaPackages -> (is built using) cudaLib.
gpus # > No arrows should point in the reverse directions.
lib # That is to say that cudaLib should only know about package sets and configurations, because it implements
nvccCompatibilities # functionality for interpreting configurations, resolving them against data, and constructing package sets.
pkgs # This decision is driven both by a separation of concerns and by "NAMESET STRICTNESS" (see above).
; # Also see the comment in `pkgs/top-level/all-packages.nix` about the `_cuda` attribute.
inherit cudaMajorMinorVersion;
cudaNamePrefix = "cuda${cudaMajorMinorVersion}";
cudaMajorVersion = versions.major cudaMajorMinorVersion; cudaMajorVersion = versions.major cudaMajorMinorVersion;
cudaOlder = strings.versionOlder cudaMajorMinorVersion; cudaOlder = strings.versionOlder cudaMajorMinorVersion;
cudaAtLeast = strings.versionAtLeast cudaMajorMinorVersion; cudaAtLeast = strings.versionAtLeast cudaMajorMinorVersion;
# 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. # Maintain a reference to the final cudaPackages.
# Without this, if we use `final.callPackage` and a package accepts `cudaPackages` as an # 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 # argument, it's provided with `cudaPackages` from the top-level scope, which is not what we
@ -82,6 +79,21 @@ let
__attrsFailEvaluation = true; __attrsFailEvaluation = true;
}; };
flags =
cudaLib.formatCapabilities {
inherit (final.backendStdenv) cudaCapabilities cudaForwardCompat;
inherit (_cuda.db) cudaCapabilityToInfo;
}
# TODO(@connorbaker): Enable the corresponding warnings in `../development/cuda-modules/aliases.nix` after some
# time to allow users to migrate to cudaLib and backendStdenv.
// {
inherit (cudaLib) dropDots;
cudaComputeCapabilityToName =
cudaCapability: _cuda.db.cudaCapabilityToInfo.${cudaCapability}.archName;
dropDot = cudaLib.dropDots;
isJetsonBuild = final.backendStdenv.hasJetsonCudaCapability;
};
# Loose packages # Loose packages
# Barring packages which share a home (e.g., cudatoolkit and cudatoolkit-legacy-runfile), new packages # Barring packages which share a home (e.g., cudatoolkit and cudatoolkit-legacy-runfile), new packages
# should be added to ../development/cuda-modules/packages in "by-name" style, where they will be automatically # should be added to ../development/cuda-modules/packages in "by-name" style, where they will be automatically
@ -128,7 +140,10 @@ let
value = final.callPackage ../development/cuda-modules/tests/opencv-and-torch config; value = final.callPackage ../development/cuda-modules/tests/opencv-and-torch config;
}; };
in in
attrsets.listToAttrs (attrsets.mapCartesianProduct builder configs); attrsets.listToAttrs (attrsets.mapCartesianProduct builder configs)
// {
flags = final.callPackage ../development/cuda-modules/tests/flags.nix { };
};
}; };
composedExtension = fixedPoints.composeManyExtensions ( composedExtension = fixedPoints.composeManyExtensions (
@ -143,10 +158,10 @@ let
(import ../development/cuda-modules/cuda/extension.nix { inherit cudaMajorMinorVersion lib; }) (import ../development/cuda-modules/cuda/extension.nix { inherit cudaMajorMinorVersion lib; })
(import ../development/cuda-modules/generic-builders/multiplex.nix { (import ../development/cuda-modules/generic-builders/multiplex.nix {
inherit inherit
cudaLib
cudaMajorMinorVersion cudaMajorMinorVersion
flags
lib lib
mkVersionedPackageName redistSystem
stdenv stdenv
; ;
pname = "cudnn"; pname = "cudnn";
@ -156,28 +171,25 @@ let
}) })
(import ../development/cuda-modules/cutensor/extension.nix { (import ../development/cuda-modules/cutensor/extension.nix {
inherit inherit
cudaLib
cudaMajorMinorVersion cudaMajorMinorVersion
flags
lib lib
mkVersionedPackageName redistSystem
stdenv
; ;
}) })
(import ../development/cuda-modules/cusparselt/extension.nix { (import ../development/cuda-modules/cusparselt/extension.nix {
inherit inherit
cudaMajorMinorVersion cudaLib
flags
lib lib
mkVersionedPackageName redistSystem
stdenv
; ;
}) })
(import ../development/cuda-modules/generic-builders/multiplex.nix { (import ../development/cuda-modules/generic-builders/multiplex.nix {
inherit inherit
cudaLib
cudaMajorMinorVersion cudaMajorMinorVersion
flags
lib lib
mkVersionedPackageName redistSystem
stdenv stdenv
; ;
pname = "tensorrt"; pname = "tensorrt";
@ -190,7 +202,9 @@ let
}) })
(import ../development/cuda-modules/cuda-library-samples/extension.nix { inherit lib stdenv; }) (import ../development/cuda-modules/cuda-library-samples/extension.nix { inherit lib stdenv; })
] ]
++ lib.optionals config.allowAliases [ (import ../development/cuda-modules/aliases.nix) ] ++ lib.optionals config.allowAliases [
(import ../development/cuda-modules/aliases.nix { inherit lib; })
]
); );
cudaPackages = customisation.makeScope newScope ( cudaPackages = customisation.makeScope newScope (

View file

@ -14,20 +14,7 @@
let let
lib = import ../../lib; lib = import ../../lib;
ensureList = x: if builtins.isList x then x else [ x ]; cudaLib = (import ../development/cuda-modules/_cuda).lib;
allowUnfreePredicate =
p:
builtins.all (
license:
license.free
|| builtins.elem license.shortName [
"CUDA EULA"
"cuDNN EULA"
"cuSPARSELt EULA"
"cuTENSOR EULA"
"NVidia OptiX EULA"
]
) (ensureList p.meta.license);
in in
{ {
@ -40,7 +27,7 @@ in
# Attributes passed to nixpkgs. # Attributes passed to nixpkgs.
nixpkgsArgs ? { nixpkgsArgs ? {
config = { config = {
inherit allowUnfreePredicate; allowUnfreePredicate = cudaLib.allowUnfreeCudaPredicate;
"${variant}Support" = true; "${variant}Support" = true;
inHydra = true; inHydra = true;