nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 352 lines 11 kB view raw
1{ 2 lib, 3 stdenv, 4 fetchFromGitHub, 5 fetchpatch, 6 perl, 7 which, 8 # Most packages depending on openblas expect integer width to match 9 # pointer width, but some expect to use 32-bit integers always 10 # (for compatibility with reference BLAS). 11 blas64 ? null, 12 # Multi-threaded applications must not call a threaded OpenBLAS 13 # (the only exception is when an application uses OpenMP as its 14 # *only* form of multi-threading). See 15 # https://github.com/OpenMathLib/OpenBLAS/wiki/Faq/4bded95e8dc8aadc70ce65267d1093ca7bdefc4c#multi-threaded 16 # https://github.com/OpenMathLib/OpenBLAS/issues/2543 17 # This flag builds a single-threaded OpenBLAS using the flags 18 # stated in thre. 19 singleThreaded ? false, 20 buildPackages, 21 # Select a specific optimization target (other than the default) 22 # See https://github.com/OpenMathLib/OpenBLAS/blob/develop/TargetList.txt 23 target ? null, 24 # Select whether DYNAMIC_ARCH is enabled or not. 25 dynamicArch ? null, 26 # enable AVX512 optimized kernels. 27 # These kernels have been a source of trouble in the past. 28 # Use with caution. 29 enableAVX512 ? false, 30 enableStatic ? stdenv.hostPlatform.isStatic, 31 enableShared ? !stdenv.hostPlatform.isStatic, 32 33 # for passthru.tests 34 ceres-solver, 35 giac, 36 octave, 37 opencv, 38 python3, 39 openmp ? null, 40}: 41 42let 43 blas64_ = blas64; 44in 45 46let 47 setTarget = x: if target == null then x else target; 48 setDynamicArch = x: if dynamicArch == null then x else dynamicArch; 49 50 # To add support for a new platform, add an element to this set. 51 configs = { 52 armv6l-linux = { 53 BINARY = 32; 54 TARGET = setTarget "ARMV6"; 55 DYNAMIC_ARCH = setDynamicArch false; 56 USE_OPENMP = true; 57 }; 58 59 armv7l-linux = { 60 BINARY = 32; 61 TARGET = setTarget "ARMV7"; 62 DYNAMIC_ARCH = setDynamicArch false; 63 USE_OPENMP = true; 64 }; 65 66 aarch64-darwin = { 67 BINARY = 64; 68 TARGET = setTarget "VORTEX"; 69 DYNAMIC_ARCH = setDynamicArch true; 70 USE_OPENMP = false; 71 MACOSX_DEPLOYMENT_TARGET = "11.0"; 72 }; 73 74 aarch64-linux = { 75 BINARY = 64; 76 TARGET = setTarget "ARMV8"; 77 DYNAMIC_ARCH = setDynamicArch true; 78 USE_OPENMP = true; 79 }; 80 81 i686-linux = { 82 BINARY = 32; 83 TARGET = setTarget "P2"; 84 DYNAMIC_ARCH = setDynamicArch true; 85 USE_OPENMP = true; 86 }; 87 88 x86_64-darwin = { 89 BINARY = 64; 90 TARGET = setTarget "ATHLON"; 91 DYNAMIC_ARCH = setDynamicArch true; 92 NO_AVX512 = !enableAVX512; 93 USE_OPENMP = false; 94 MACOSX_DEPLOYMENT_TARGET = "10.7"; 95 }; 96 97 x86_64-linux = { 98 BINARY = 64; 99 TARGET = setTarget "ATHLON"; 100 DYNAMIC_ARCH = setDynamicArch true; 101 NO_AVX512 = !enableAVX512; 102 USE_OPENMP = !stdenv.hostPlatform.isMusl; 103 }; 104 105 x86_64-windows = { 106 BINARY = 64; 107 TARGET = setTarget "ATHLON"; 108 DYNAMIC_ARCH = setDynamicArch true; 109 NO_AVX512 = !enableAVX512; 110 USE_OPENMP = false; 111 }; 112 113 powerpc64-linux = { 114 BINARY = 64; 115 TARGET = setTarget "POWER4"; 116 DYNAMIC_ARCH = setDynamicArch false; 117 USE_OPENMP = !stdenv.hostPlatform.isMusl; 118 }; 119 120 powerpc64le-linux = { 121 BINARY = 64; 122 TARGET = setTarget "POWER5"; 123 DYNAMIC_ARCH = setDynamicArch true; 124 USE_OPENMP = !stdenv.hostPlatform.isMusl; 125 }; 126 127 riscv64-linux = { 128 BINARY = 64; 129 TARGET = setTarget "RISCV64_GENERIC"; 130 DYNAMIC_ARCH = setDynamicArch false; 131 USE_OPENMP = true; 132 }; 133 134 loongarch64-linux = { 135 TARGET = setTarget "LA64_GENERIC"; 136 DYNAMIC_ARCH = setDynamicArch false; 137 USE_OPENMP = true; 138 }; 139 140 s390x-linux = { 141 BINARY = 64; 142 TARGET = setTarget "ZARCH_GENERIC"; 143 DYNAMIC_ARCH = setDynamicArch true; 144 USE_OPENMP = true; 145 }; 146 147 x86_64-freebsd = { 148 BINARY = 64; 149 TARGET = setTarget "ATHLON"; 150 DYNAMIC_ARCH = setDynamicArch true; 151 NO_AVX512 = !enableAVX512; 152 USE_OPENMP = true; 153 }; 154 }; 155in 156 157let 158 config = 159 configs.${stdenv.hostPlatform.system} 160 or (throw "unsupported system: ${stdenv.hostPlatform.system}"); 161in 162 163let 164 blas64 = if blas64_ != null then blas64_ else lib.hasPrefix "x86_64" stdenv.hostPlatform.system; 165 # Convert flag values to format OpenBLAS's build expects. 166 # `toString` is almost what we need other than bools, 167 # which we need to map {true -> 1, false -> 0} 168 # (`toString` produces empty string `""` for false instead of `0`) 169 mkMakeFlagValue = 170 val: 171 if !builtins.isBool val then 172 toString val 173 else if val then 174 "1" 175 else 176 "0"; 177 mkMakeFlagsFromConfig = lib.mapAttrsToList (var: val: "${var}=${mkMakeFlagValue val}"); 178 179 shlibExt = stdenv.hostPlatform.extensions.sharedLibrary; 180 181in 182stdenv.mkDerivation rec { 183 pname = "openblas"; 184 version = "0.3.30"; 185 186 outputs = [ 187 "out" 188 "dev" 189 ]; 190 191 src = fetchFromGitHub { 192 owner = "OpenMathLib"; 193 repo = "OpenBLAS"; 194 rev = "v${version}"; 195 hash = "sha256-foP2OXUL6ttgYvCxLsxUiVdkPoTvGiHomdNudbSUmSE="; 196 }; 197 198 patches = [ 199 # Remove this once https://github.com/OpenMathLib/OpenBLAS/issues/5414 is 200 # resolved. 201 ./disable-sme-sgemm-kernel.patch 202 203 # https://github.com/OpenMathLib/OpenBLAS/issues/5460 204 (fetchpatch { 205 name = "0001-openblas-Use-generic-kernels-for-SCAL-on-POWER4-5.patch"; 206 url = "https://github.com/OpenMathLib/OpenBLAS/commit/14c9dcaac70d9382de00ba4418643d9587f4950e.patch"; 207 hash = "sha256-mIOqRc7tE1rV/krrAu630JwApZHdeHCdVmO5j6eDC8U="; 208 }) 209 ]; 210 211 postPatch = '' 212 # cc1: error: invalid feature modifier 'sve2' in '-march=armv8.5-a+sve+sve2+bf16' 213 substituteInPlace Makefile.arm64 --replace "+sve2+bf16" "" 214 ''; 215 216 inherit blas64; 217 218 # Some hardening features are disabled due to sporadic failures in 219 # OpenBLAS-based programs. The problem may not be with OpenBLAS itself, but 220 # with how these flags interact with hardening measures used downstream. 221 # In either case, OpenBLAS must only be used by trusted code--it is 222 # inherently unsuitable for security-conscious applications--so there should 223 # be no objection to disabling these hardening measures. 224 hardeningDisable = [ 225 # don't modify or move the stack 226 "stackprotector" 227 "pic" 228 # don't alter index arithmetic 229 "strictoverflow" 230 # don't interfere with dynamic target detection 231 "relro" 232 "bindnow" 233 ] 234 ++ lib.optionals stdenv.hostPlatform.isAarch64 [ 235 # "__builtin_clear_padding not supported for variable length aggregates" 236 # in aarch64-specific code 237 "trivialautovarinit" 238 ]; 239 240 nativeBuildInputs = [ 241 perl 242 which 243 ]; 244 245 buildInputs = lib.optional (stdenv.cc.isClang && config.USE_OPENMP) openmp; 246 247 depsBuildBuild = [ 248 buildPackages.gfortran 249 buildPackages.stdenv.cc 250 ]; 251 252 enableParallelBuilding = true; 253 254 makeFlags = mkMakeFlagsFromConfig ( 255 config 256 // { 257 FC = "${stdenv.cc.targetPrefix}gfortran"; 258 CC = "${stdenv.cc.targetPrefix}${if stdenv.cc.isClang then "clang" else "cc"}"; 259 PREFIX = placeholder "out"; 260 OPENBLAS_INCLUDE_DIR = "${placeholder "dev"}/include"; 261 NUM_THREADS = 64; 262 INTERFACE64 = blas64; 263 NO_STATIC = !enableStatic; 264 NO_SHARED = !enableShared; 265 CROSS = stdenv.hostPlatform != stdenv.buildPlatform; 266 HOSTCC = "cc"; 267 # Makefile.system only checks defined status 268 # This seems to be a bug in the openblas Makefile: 269 # on x86_64 it expects NO_BINARY_MODE= 270 # but on aarch64 it expects NO_BINARY_MODE=0 271 NO_BINARY_MODE = 272 if stdenv.hostPlatform.isx86_64 then 273 toString (stdenv.hostPlatform != stdenv.buildPlatform) 274 else 275 stdenv.hostPlatform != stdenv.buildPlatform; 276 # This disables automatic build job count detection (which honours neither enableParallelBuilding nor NIX_BUILD_CORES) 277 # and uses the main make invocation's job count, falling back to 1 if no parallelism is used. 278 # https://github.com/OpenMathLib/OpenBLAS/blob/v0.3.20/getarch.c#L1781-L1792 279 MAKE_NB_JOBS = 0; 280 } 281 // (lib.optionalAttrs stdenv.cc.isClang { 282 LDFLAGS = "-L${lib.getLib buildPackages.gfortran.cc}/lib"; # contains `libgfortran.so`; building with clang needs this, gcc has it implicit 283 }) 284 // (lib.optionalAttrs singleThreaded { 285 # As described on https://github.com/OpenMathLib/OpenBLAS/wiki/Faq/4bded95e8dc8aadc70ce65267d1093ca7bdefc4c#multi-threaded 286 USE_THREAD = false; 287 USE_LOCKING = true; # available with openblas >= 0.3.7 288 USE_OPENMP = false; # openblas will refuse building with both USE_OPENMP=1 and USE_THREAD=0 289 }) 290 ); 291 292 # The default "all" target unconditionally builds the "tests" target. 293 buildFlags = lib.optionals (!doCheck) [ "shared" ]; 294 295 doCheck = true; 296 checkTarget = "tests"; 297 298 postInstall = '' 299 # Write pkgconfig aliases. Upstream report: 300 # https://github.com/OpenMathLib/OpenBLAS/issues/1740 301 for alias in blas cblas lapack; do 302 cat <<EOF > $out/lib/pkgconfig/$alias.pc 303 Name: $alias 304 Version: ${version} 305 Description: $alias provided by the OpenBLAS package. 306 Cflags: -I$dev/include 307 Libs: -L$out/lib -lopenblas 308 EOF 309 done 310 311 # Setup symlinks for blas / lapack 312 '' 313 + lib.optionalString stdenv.hostPlatform.isMinGW '' 314 ln -s $out/bin/*.dll $out/lib 315 '' 316 + lib.optionalString enableShared '' 317 ln -s $out/lib/libopenblas${shlibExt} $out/lib/libblas${shlibExt} 318 ln -s $out/lib/libopenblas${shlibExt} $out/lib/libcblas${shlibExt} 319 ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapack${shlibExt} 320 ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapacke${shlibExt} 321 '' 322 + lib.optionalString (stdenv.hostPlatform.isLinux && enableShared) '' 323 ln -s $out/lib/libopenblas${shlibExt} $out/lib/libblas${shlibExt}.3 324 ln -s $out/lib/libopenblas${shlibExt} $out/lib/libcblas${shlibExt}.3 325 ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapack${shlibExt}.3 326 ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapacke${shlibExt}.3 327 '' 328 + lib.optionalString enableStatic '' 329 ln -s $out/lib/libopenblas.a $out/lib/libblas.a 330 ln -s $out/lib/libopenblas.a $out/lib/libcblas.a 331 ln -s $out/lib/libopenblas.a $out/lib/liblapack.a 332 ln -s $out/lib/libopenblas.a $out/lib/liblapacke.a 333 ''; 334 335 passthru.tests = { 336 inherit (python3.pkgs) numpy scipy scikit-learn; 337 inherit 338 ceres-solver 339 giac 340 octave 341 opencv 342 ; 343 }; 344 345 meta = { 346 description = "Basic Linear Algebra Subprograms"; 347 license = lib.licenses.bsd3; 348 homepage = "https://github.com/OpenMathLib/OpenBLAS"; 349 platforms = lib.attrNames configs; 350 maintainers = with lib.maintainers; [ ttuegel ]; 351 }; 352}