Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1# Notes: 2# 3# Silvan (Tweag) covered some things on recursive attribute sets in the Nix Hour: 4# https://www.youtube.com/watch?v=BgnUFtd1Ivs 5# 6# I (@connorbaker) highly recommend watching it. 7# 8# Most helpful comment regarding recursive attribute sets: 9# 10# https://github.com/NixOS/nixpkgs/pull/256324#issuecomment-1749935979 11# 12# To summarize: 13# 14# - `prev` should only be used to access attributes which are going to be overridden. 15# - `final` should only be used to access `callPackage` to build new packages. 16# - Attribute names are evaluated eagerly ("NAMESET STRICTNESS"). 17# - Extensions must not depend on `final` when computing names and count of new attributes. 18# 19# Silvan's recommendation then is to explicitly use `callPackage` to provide everything our 20# extensions need to compute the attribute names, without relying on `final`. 21# 22# I've (@connorbaker) attempted to do that, though I'm unsure of how this will interact with overrides. 23{ 24 config, 25 _cuda, 26 cudaMajorMinorVersion, 27 lib, 28 pkgs, 29 stdenv, 30 runCommand, 31}: 32let 33 inherit (lib) 34 attrsets 35 customisation 36 fixedPoints 37 lists 38 strings 39 versions 40 ; 41 42 cudaLib = _cuda.lib; 43 44 # Since Jetson capabilities are never built by default, we can check if any of them were requested 45 # through final.config.cudaCapabilities and use that to determine if we should change some manifest versions. 46 # Copied from backendStdenv. 47 jetsonCudaCapabilities = lib.filter ( 48 cudaCapability: _cuda.db.cudaCapabilityToInfo.${cudaCapability}.isJetson 49 ) _cuda.db.allSortedCudaCapabilities; 50 hasJetsonCudaCapability = 51 lib.intersectLists jetsonCudaCapabilities (config.cudaCapabilities or [ ]) != [ ]; 52 redistSystem = _cuda.lib.getRedistSystem hasJetsonCudaCapability stdenv.hostPlatform.system; 53 54 # We must use an instance of Nixpkgs where the CUDA package set we're building is the default; if we do not, members 55 # of the versioned, non-default package sets may rely on (transitively) members of the default, unversioned CUDA 56 # package set. 57 # See `Using cudaPackages.pkgs` in doc/languages-frameworks/cuda.section.md for more information. 58 pkgs' = 59 let 60 cudaPackagesUnversionedName = "cudaPackages"; 61 cudaPackagesMajorVersionName = cudaLib.mkVersionedName cudaPackagesUnversionedName ( 62 versions.major cudaMajorMinorVersion 63 ); 64 cudaPackagesMajorMinorVersionName = cudaLib.mkVersionedName cudaPackagesUnversionedName cudaMajorMinorVersion; 65 in 66 # If the CUDA version of pkgs matches our CUDA version, we are constructing the default package set and can use 67 # pkgs without modification. 68 if pkgs.cudaPackages.cudaMajorMinorVersion == cudaMajorMinorVersion then 69 pkgs 70 else 71 pkgs.extend ( 72 final: _: { 73 recurseForDerivations = false; 74 # The CUDA package set will be available as cudaPackages_x_y, so we need only update the aliases for the 75 # minor-versioned and unversioned package sets. 76 # cudaPackages_x = cudaPackages_x_y 77 ${cudaPackagesMajorVersionName} = final.${cudaPackagesMajorMinorVersionName}; 78 # cudaPackages = cudaPackages_x 79 ${cudaPackagesUnversionedName} = final.${cudaPackagesMajorVersionName}; 80 } 81 ); 82 83 passthruFunction = final: { 84 # NOTE: 85 # It is important that _cuda is not part of the package set fixed-point. As described by 86 # @SomeoneSerge: 87 # > The layering should be: configuration -> (identifies/is part of) cudaPackages -> (is built using) cudaLib. 88 # > No arrows should point in the reverse directions. 89 # That is to say that cudaLib should only know about package sets and configurations, because it implements 90 # functionality for interpreting configurations, resolving them against data, and constructing package sets. 91 # This decision is driven both by a separation of concerns and by "NAMESET STRICTNESS" (see above). 92 # Also see the comment in `pkgs/top-level/all-packages.nix` about the `_cuda` attribute. 93 94 inherit cudaMajorMinorVersion; 95 96 pkgs = pkgs'; 97 98 cudaNamePrefix = "cuda${cudaMajorMinorVersion}"; 99 100 cudaMajorVersion = versions.major cudaMajorMinorVersion; 101 cudaOlder = strings.versionOlder cudaMajorMinorVersion; 102 cudaAtLeast = strings.versionAtLeast cudaMajorMinorVersion; 103 104 flags = 105 cudaLib.formatCapabilities { 106 inherit (final.backendStdenv) cudaCapabilities cudaForwardCompat; 107 inherit (_cuda.db) cudaCapabilityToInfo; 108 } 109 # TODO(@connorbaker): Enable the corresponding warnings in `../development/cuda-modules/aliases.nix` after some 110 # time to allow users to migrate to cudaLib and backendStdenv. 111 // { 112 inherit (cudaLib) dropDots; 113 cudaComputeCapabilityToName = 114 cudaCapability: _cuda.db.cudaCapabilityToInfo.${cudaCapability}.archName; 115 dropDot = cudaLib.dropDots; 116 isJetsonBuild = final.backendStdenv.hasJetsonCudaCapability; 117 }; 118 119 # Loose packages 120 # Barring packages which share a home (e.g., cudatoolkit and cudatoolkit-legacy-runfile), new packages 121 # should be added to ../development/cuda-modules/packages in "by-name" style, where they will be automatically 122 # discovered and added to the package set. 123 124 # TODO: Move to aliases.nix once all Nixpkgs has migrated to the splayed CUDA packages 125 cudatoolkit = final.callPackage ../development/cuda-modules/cudatoolkit/redist-wrapper.nix { }; 126 cudatoolkit-legacy-runfile = final.callPackage ../development/cuda-modules/cudatoolkit { }; 127 128 tests = 129 let 130 bools = [ 131 true 132 false 133 ]; 134 configs = { 135 openCVFirst = bools; 136 useOpenCVDefaultCuda = bools; 137 useTorchDefaultCuda = bools; 138 }; 139 builder = 140 { 141 openCVFirst, 142 useOpenCVDefaultCuda, 143 useTorchDefaultCuda, 144 }@config: 145 { 146 name = strings.concatStringsSep "-" ( 147 [ 148 "test" 149 (if openCVFirst then "opencv" else "torch") 150 ] 151 ++ lists.optionals (if openCVFirst then useOpenCVDefaultCuda else useTorchDefaultCuda) [ 152 "with-default-cuda" 153 ] 154 ++ [ 155 "then" 156 (if openCVFirst then "torch" else "opencv") 157 ] 158 ++ lists.optionals (if openCVFirst then useTorchDefaultCuda else useOpenCVDefaultCuda) [ 159 "with-default-cuda" 160 ] 161 ); 162 value = final.callPackage ../development/cuda-modules/tests/opencv-and-torch config; 163 }; 164 in 165 attrsets.listToAttrs (attrsets.mapCartesianProduct builder configs) 166 // { 167 flags = final.callPackage ../development/cuda-modules/tests/flags.nix { }; 168 }; 169 }; 170 171 composedExtension = fixedPoints.composeManyExtensions ( 172 [ 173 ( 174 final: _: 175 { 176 cuda_compat = runCommand "cuda_compat" { meta.platforms = [ ]; } "false"; # Prevent missing attribute errors 177 } 178 // lib.packagesFromDirectoryRecursive { 179 inherit (final) callPackage; 180 directory = ../development/cuda-modules/packages; 181 } 182 ) 183 (import ../development/cuda-modules/cuda/extension.nix { inherit cudaMajorMinorVersion lib; }) 184 (import ../development/cuda-modules/generic-builders/multiplex.nix { 185 inherit 186 cudaLib 187 cudaMajorMinorVersion 188 lib 189 redistSystem 190 stdenv 191 ; 192 pname = "cudnn"; 193 redistName = "cudnn"; 194 releasesModule = ../development/cuda-modules/cudnn/releases.nix; 195 shimsFn = ../development/cuda-modules/cudnn/shims.nix; 196 }) 197 (import ../development/cuda-modules/cutensor/extension.nix { 198 inherit 199 cudaLib 200 cudaMajorMinorVersion 201 lib 202 redistSystem 203 ; 204 }) 205 (import ../development/cuda-modules/cusparselt/extension.nix { 206 inherit 207 cudaLib 208 lib 209 redistSystem 210 ; 211 }) 212 (import ../development/cuda-modules/generic-builders/multiplex.nix { 213 inherit 214 cudaLib 215 cudaMajorMinorVersion 216 lib 217 redistSystem 218 stdenv 219 ; 220 pname = "tensorrt"; 221 redistName = "tensorrt"; 222 releasesModule = ../development/cuda-modules/tensorrt/releases.nix; 223 shimsFn = ../development/cuda-modules/tensorrt/shims.nix; 224 }) 225 (import ../development/cuda-modules/cuda-samples/extension.nix { 226 inherit cudaMajorMinorVersion lib stdenv; 227 }) 228 (import ../development/cuda-modules/cuda-library-samples/extension.nix { inherit lib stdenv; }) 229 ] 230 ++ lib.optionals config.allowAliases [ 231 (import ../development/cuda-modules/aliases.nix { inherit lib; }) 232 ] 233 ++ _cuda.extensions 234 ); 235 236 cudaPackages = customisation.makeScope pkgs'.newScope ( 237 fixedPoints.extends composedExtension passthruFunction 238 ); 239in 240# We want to warn users about the upcoming deprecation of old CUDA 241# versions, without breaking Nixpkgs CI with evaluation warnings. This 242# gross hack ensures that the warning only triggers if aliases are 243# enabled, which is true by default, but not for ofborg. 244lib.warnIf (cudaPackages.cudaOlder "12.0" && config.allowAliases) 245 "CUDA versions older than 12.0 will be removed in Nixpkgs 25.05; see the 24.11 release notes for more information" 246 cudaPackages