Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at python-updates 250 lines 9.8 kB view raw
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 # Prevent missing attribute errors 177 # NOTE(@connorbaker): CUDA 12.3 does not have a cuda_compat package; indeed, none of the release supports 178 # Jetson devices. To avoid errors in the case that cuda_compat is not defined, we have a dummy package which 179 # is always defined, but does nothing, will not build successfully, and has no platforms. 180 cuda_compat = runCommand "cuda_compat" { meta.platforms = [ ]; } "false"; 181 } 182 // lib.packagesFromDirectoryRecursive { 183 inherit (final) callPackage; 184 directory = ../development/cuda-modules/packages; 185 } 186 ) 187 (import ../development/cuda-modules/cuda/extension.nix { inherit cudaMajorMinorVersion lib; }) 188 (import ../development/cuda-modules/generic-builders/multiplex.nix { 189 inherit 190 cudaLib 191 cudaMajorMinorVersion 192 lib 193 redistSystem 194 stdenv 195 ; 196 pname = "cudnn"; 197 redistName = "cudnn"; 198 releasesModule = ../development/cuda-modules/cudnn/releases.nix; 199 shimsFn = ../development/cuda-modules/cudnn/shims.nix; 200 }) 201 (import ../development/cuda-modules/cutensor/extension.nix { 202 inherit 203 cudaLib 204 cudaMajorMinorVersion 205 lib 206 redistSystem 207 ; 208 }) 209 (import ../development/cuda-modules/cusparselt/extension.nix { 210 inherit 211 cudaLib 212 lib 213 redistSystem 214 ; 215 }) 216 (import ../development/cuda-modules/generic-builders/multiplex.nix { 217 inherit 218 cudaLib 219 cudaMajorMinorVersion 220 lib 221 redistSystem 222 stdenv 223 ; 224 pname = "tensorrt"; 225 redistName = "tensorrt"; 226 releasesModule = ../development/cuda-modules/tensorrt/releases.nix; 227 shimsFn = ../development/cuda-modules/tensorrt/shims.nix; 228 }) 229 (import ../development/cuda-modules/cuda-samples/extension.nix { 230 inherit cudaMajorMinorVersion lib stdenv; 231 }) 232 (import ../development/cuda-modules/cuda-library-samples/extension.nix { inherit lib stdenv; }) 233 ] 234 ++ lib.optionals config.allowAliases [ 235 (import ../development/cuda-modules/aliases.nix { inherit lib; }) 236 ] 237 ++ _cuda.extensions 238 ); 239 240 cudaPackages = customisation.makeScope pkgs'.newScope ( 241 fixedPoints.extends composedExtension passthruFunction 242 ); 243in 244# We want to warn users about the upcoming deprecation of old CUDA 245# versions, without breaking Nixpkgs CI with evaluation warnings. This 246# gross hack ensures that the warning only triggers if aliases are 247# enabled, which is true by default, but not for ofborg. 248lib.warnIf (cudaPackages.cudaOlder "12.0" && config.allowAliases) 249 "CUDA versions older than 12.0 will be removed in Nixpkgs 25.05; see the 24.11 release notes for more information" 250 cudaPackages