diff --git a/pkgs/build-support/alternatives/blas/default.nix b/pkgs/build-support/alternatives/blas/default.nix new file mode 100644 index 000000000000..1b8783438662 --- /dev/null +++ b/pkgs/build-support/alternatives/blas/default.nix @@ -0,0 +1,137 @@ +{ lib, stdenv +, lapack-reference, openblasCompat, openblas +, is64bit ? false +, blasProvider ? if is64bit then openblas else openblasCompat }: + +let + blasFortranSymbols = [ + "caxpy" "ccopy" "cdotc" "cdotu" "cgbmv" "cgemm" "cgemv" "cgerc" "cgeru" + "chbmv" "chemm" "chemv" "cher" "cher2" "cher2k" "cherk" "chpmv" "chpr" + "chpr2" "crotg" "cscal" "csrot" "csscal" "cswap" "csymm" "csyr2k" "csyrk" + "ctbmv" "ctbsv" "ctpmv" "ctpsv" "ctrmm" "ctrmv" "ctrsm" "ctrsv" "dasum" + "daxpy" "dcabs1" "dcopy" "ddot" "dgbmv" "dgemm" "dgemv" "dger" "dnrm2" + "drot" "drotg" "drotm" "drotmg" "dsbmv" "dscal" "dsdot" "dspmv" "dspr" + "dspr2" "dswap" "dsymm" "dsymv" "dsyr" "dsyr2" "dsyr2k" "dsyrk" "dtbmv" + "dtbsv" "dtpmv" "dtpsv" "dtrmm" "dtrmv" "dtrsm" "dtrsv" "dzasum" "dznrm2" + "icamax" "idamax" "isamax" "izamax" "lsame" "sasum" "saxpy" "scabs1" + "scasum" "scnrm2" "scopy" "sdot" "sdsdot" "sgbmv" "sgemm" "sgemv" + "sger" "snrm2" "srot" "srotg" "srotm" "srotmg" "ssbmv" "sscal" "sspmv" + "sspr" "sspr2" "sswap" "ssymm" "ssymv" "ssyr" "ssyr2" "ssyr2k" "ssyrk" + "stbmv" "stbsv" "stpmv" "stpsv" "strmm" "strmv" "strsm" "strsv" "xerbla" + "xerbla_array" "zaxpy" "zcopy" "zdotc" "zdotu" "zdrot" "zdscal" "zgbmv" + "zgemm" "zgemv" "zgerc" "zgeru" "zhbmv" "zhemm" "zhemv" "zher" "zher2" + "zher2k" "zherk" "zhpmv" "zhpr" "zhpr2" "zrotg" "zscal" "zswap" "zsymm" + "zsyr2k" "zsyrk" "ztbmv" "ztbsv" "ztpmv" "ztpsv" "ztrmm" "ztrmv" "ztrsm" + "ztrsv" + ]; + + version = "3"; + canonicalExtension = if stdenv.hostPlatform.isLinux + then "${stdenv.hostPlatform.extensions.sharedLibrary}.${version}" + else stdenv.hostPlatform.extensions.sharedLibrary; + + + is64bit = blasProvider.blas64 or false; + blasImplementation = lib.getName blasProvider; + +in + +assert is64bit -> (blasImplementation == "openblas" && blasProvider.blas64) || blasImplementation == "mkl"; + +stdenv.mkDerivation { + pname = "blas"; + inherit version; + + outputs = [ "out" "dev" ]; + + meta = (blasProvider.meta or {}) // { + description = "${lib.getName blasProvider} with just the BLAS C and FORTRAN ABI"; + }; + + passthru = { + inherit is64bit; + provider = blasProvider; + implementation = blasImplementation; + }; + + dontBuild = true; + dontConfigure = true; + unpackPhase = "src=$PWD"; + + installPhase = ('' + mkdir -p $out/lib $dev/include $dev/include/pkgconfig + + libblas="${lib.getLib blasProvider}/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary}" + + if ! [ -e "$libblas" ]; then + echo "$libblas does not exist, ${blasProvider.name} does not provide libblas." + exit 1 + fi + + nm -an "$libblas" | cut -f3 -d' ' > symbols + for symbol in ${toString blasFortranSymbols}; do + grep "^$symbol_$" symbols || { echo "$symbol" was not found in "$libblas"; exit 1; } + done + + cp -L "$libblas" $out/lib/libblas${canonicalExtension} + chmod +w $out/lib/libblas${canonicalExtension} + +'' + (if stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf" then '' + patchelf --set-soname libblas${canonicalExtension} $out/lib/libblas${canonicalExtension} + patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libblas${canonicalExtension}):${lib.getLib blasProvider}/lib" $out/lib/libblas${canonicalExtension} +'' else if stdenv.hostPlatform.isDarwin then '' + install_name_tool \ + -id libblas${canonicalExtension} + -add_rpath ${lib.getLib blasProvider}/lib \ + $out/lib/libblas${canonicalExtension} +'' else "") + '' + + if [ "$out/lib/libblas${canonicalExtension}" != "$out/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then + ln -s $out/lib/libblas${canonicalExtension} "$out/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary}" + fi + + cat < $dev/lib/pkgconfig/blas.pc +Name: blas +Version: ${version} +Description: BLAS FORTRAN implementation +Libs: -L$out/lib -lblas +Cflags: -I$dev/include +EOF + + libcblas="${lib.getLib blasProvider}/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary}" + + if ! [ -e "$libcblas" ]; then + echo "$libcblas does not exist, ${blasProvider.name} does not provide libcblas." + exit 1 + fi + + cp -L "$libcblas" $out/lib/libcblas${canonicalExtension} + chmod +w $out/lib/libcblas${canonicalExtension} + +'' + (if stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf" then '' + patchelf --set-soname libcblas${canonicalExtension} $out/lib/libcblas${canonicalExtension} + patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libcblas${canonicalExtension}):${lib.getLib blasProvider}/lib" $out/lib/libcblas${canonicalExtension} +'' else if stdenv.hostPlatform.isDarwin then '' + install_name_tool \ + -id libcblas${canonicalExtension} \ + -add_rpath ${lib.getLib blasProvider}/lib \ + $out/lib/libcblas${canonicalExtension} +'' else "") + '' + if [ "$out/lib/libcblas${canonicalExtension}" != "$out/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then + ln -s $out/lib/libcblas${canonicalExtension} "$out/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary}" + fi + + cp ${lib.getDev lapack-reference}/include/cblas{,_mangling}.h $dev/include + + cat < $dev/lib/pkgconfig/cblas.pc +Name: cblas +Version: ${version} +Description: BLAS C implementation +Cflags: -I$dev/include +Libs: -L$out/lib -lcblas +EOF +'' + stdenv.lib.optionalString (blasImplementation == "mkl") '' + mkdir -p $out/nix-support + echo 'export MKL_INTERFACE_LAYER=${lib.optionalString is64bit "I"}LP64,GNU' > $out/nix-support/setup-hook +''); +} diff --git a/pkgs/build-support/alternatives/lapack/default.nix b/pkgs/build-support/alternatives/lapack/default.nix new file mode 100644 index 000000000000..24c339042a2f --- /dev/null +++ b/pkgs/build-support/alternatives/lapack/default.nix @@ -0,0 +1,111 @@ +{ lib, stdenv +, lapack-reference, openblasCompat, openblas +, is64bit ? false +, lapackProvider ? if is64bit then openblas else openblasCompat }: + +let + + version = "3"; + canonicalExtension = if stdenv.hostPlatform.isLinux + then "${stdenv.hostPlatform.extensions.sharedLibrary}.${version}" + else stdenv.hostPlatform.extensions.sharedLibrary; + + lapackImplementation = lib.getName lapackProvider; + +in + +assert is64bit -> (lapackImplementation == "openblas" && lapackProvider.blas64) || lapackImplementation == "mkl"; + +stdenv.mkDerivation { + pname = "lapack"; + inherit version; + + outputs = [ "out" "dev" ]; + + meta = (lapackProvider.meta or {}) // { + description = "${lib.getName lapackProvider} with just the LAPACK C and FORTRAN ABI"; + }; + + passthru = { + inherit is64bit; + provider = lapackProvider; + implementation = lapackImplementation; + }; + + dontBuild = true; + dontConfigure = true; + unpackPhase = "src=$PWD"; + + installPhase = ('' + mkdir -p $out/lib $dev/include $dev/lib/pkgconfig + + liblapack="${lib.getLib lapackProvider}/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary}" + + if ! [ -e "$liblapack" ]; then + echo "$liblapack does not exist, ${lapackProvider.name} does not provide liblapack." + exit 1 + fi + + cp -L "$liblapack" $out/lib/liblapack${canonicalExtension} + chmod +w $out/lib/liblapack${canonicalExtension} + +'' + (if stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf" then '' + patchelf --set-soname liblapack${canonicalExtension} $out/lib/liblapack${canonicalExtension} + patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapack${canonicalExtension}):${lapackProvider}/lib" $out/lib/liblapack${canonicalExtension} +'' else if stdenv.hostPlatform.isDarwin then '' + install_name_tool -id liblapack${canonicalExtension} \ + -add_rpath ${lib.getLib lapackProvider}/lib \ + $out/lib/liblapack${canonicalExtension} +'' else "") + '' + + if [ "$out/lib/liblapack${canonicalExtension}" != "$out/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then + ln -s $out/lib/liblapack${canonicalExtension} "$out/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary}" + fi + + install -D ${lib.getDev lapack-reference}/include/lapack.h $dev/include/lapack.h + + cat < $dev/lib/pkgconfig/lapack.pc +Name: lapack +Version: ${version} +Description: LAPACK FORTRAN implementation +Cflags: -I$dev/include +Libs: -L$out/lib -llapack +EOF + + liblapacke="${lib.getLib lapackProvider}/lib/liblapacke${stdenv.hostPlatform.extensions.sharedLibrary}" + + if ! [ -e "$liblapacke" ]; then + echo "$liblapacke does not exist, ${lapackProvider.name} does not provide liblapacke." + exit 1 + fi + + cp -L "$liblapacke" $out/lib/liblapacke${canonicalExtension} + chmod +w $out/lib/liblapacke${canonicalExtension} + +'' + (if stdenv.hostPlatform.parsed.kernel.execFormat.name == "elf" then '' + patchelf --set-soname liblapacke${canonicalExtension} $out/lib/liblapacke${canonicalExtension} + patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapacke${canonicalExtension}):${lib.getLib lapackProvider}/lib" $out/lib/liblapacke${canonicalExtension} +'' else if stdenv.hostPlatform.isDarwin then '' + install_name_tool -id liblapacke${canonicalExtension} \ + -add_rpath ${lib.getLib lapackProvider}/lib \ + $out/lib/liblapacke${canonicalExtension} +'' else "") + '' + + if [ -f "$out/lib/liblapacke.so.3" ]; then + ln -s $out/lib/liblapacke.so.3 $out/lib/liblapacke.so + fi + + cp ${lib.getDev lapack-reference}/include/lapacke{,_mangling,_config}.h $dev/include + + cat < $dev/lib/pkgconfig/lapacke.pc +Name: lapacke +Version: ${version} +Description: LAPACK C implementation +Cflags: -I$dev/include +Libs: -L$out/lib -llapacke +EOF +'' + stdenv.lib.optionalString (lapackImplementation == "mkl") '' + mkdir -p $out/nix-support + echo 'export MKL_INTERFACE_LAYER=${lib.optionalString is64bit "I"}LP64,GNU' > $out/nix-support/setup-hook +''); +} diff --git a/pkgs/development/libraries/fflas-ffpack/default.nix b/pkgs/development/libraries/fflas-ffpack/default.nix index 44267dfeceb5..16a9e3e79d45 100644 --- a/pkgs/development/libraries/fflas-ffpack/default.nix +++ b/pkgs/development/libraries/fflas-ffpack/default.nix @@ -1,6 +1,9 @@ -{ stdenv, fetchFromGitHub, autoreconfHook, givaro, pkgconfig, blas +{ stdenv, fetchFromGitHub, autoreconfHook, givaro, pkgconfig, blas, lapack , gmpxx }: + +assert (!blas.is64bit) && (!lapack.is64bit); + stdenv.mkDerivation rec { pname = "fflas-ffpack"; version = "2.4.3"; @@ -23,11 +26,11 @@ stdenv.mkDerivation rec { pkgconfig ] ++ stdenv.lib.optionals doCheck checkInputs; - buildInputs = [ givaro blas ]; + buildInputs = [ givaro blas lapack ]; configureFlags = [ - "--with-blas-libs=-l${blas.linkName}" - "--with-lapack-libs=-l${blas.linkName}" + "--with-blas-libs=-lcblas" + "--with-lapack-libs=-llapacke" ] ++ stdenv.lib.optionals stdenv.isx86_64 { # disable SIMD instructions (which are enabled *when available* by default) # for now we need to be careful to disable *all* relevant versions of an instruction set explicitly (https://github.com/linbox-team/fflas-ffpack/issues/284) diff --git a/pkgs/development/libraries/linbox/default.nix b/pkgs/development/libraries/linbox/default.nix index 006c774e9a1d..6d25cb459870 100644 --- a/pkgs/development/libraries/linbox/default.nix +++ b/pkgs/development/libraries/linbox/default.nix @@ -4,10 +4,14 @@ , givaro , pkgconfig , blas +, lapack , fflas-ffpack , gmpxx , withSage ? false # sage support }: + +assert (!blas.is64bit) && (!lapack.is64bit); + stdenv.mkDerivation rec { pname = "linbox"; version = "1.6.3"; @@ -33,7 +37,7 @@ stdenv.mkDerivation rec { ]; configureFlags = [ - "--with-blas-libs=-l${blas.linkName}" + "--with-blas-libs=-lblas" "--disable-optimization" ] ++ stdenv.lib.optionals stdenv.isx86_64 { # disable SIMD instructions (which are enabled *when available* by default) diff --git a/pkgs/development/libraries/science/math/blas/default.nix b/pkgs/development/libraries/science/math/blas/default.nix index c58ac6be23d9..c240a19cca67 100644 --- a/pkgs/development/libraries/science/math/blas/default.nix +++ b/pkgs/development/libraries/science/math/blas/default.nix @@ -68,10 +68,4 @@ EOF homepage = "http://www.netlib.org/blas/"; platforms = stdenv.lib.platforms.unix; }; - - # We use linkName to pass a different name to --with-blas-libs for - # fflas-ffpack and linbox, because we use blas on darwin but openblas - # elsewhere. - # See see https://github.com/NixOS/nixpkgs/pull/45013. - passthru.linkName = "blas"; } diff --git a/pkgs/development/libraries/science/math/liblapack/default.nix b/pkgs/development/libraries/science/math/liblapack/default.nix index d26bfbb3e6ea..045cccbd2ebf 100644 --- a/pkgs/development/libraries/science/math/liblapack/default.nix +++ b/pkgs/development/libraries/science/math/liblapack/default.nix @@ -42,7 +42,4 @@ stdenv.mkDerivation { license = licenses.bsd3; platforms = platforms.all; }; - - passthru.libblasName = "libblas"; - passthru.libcblasName = "libcblas"; } diff --git a/pkgs/development/libraries/science/math/mkl/default.nix b/pkgs/development/libraries/science/math/mkl/default.nix index 3def5e5b403c..f9026ec7b997 100644 --- a/pkgs/development/libraries/science/math/mkl/default.nix +++ b/pkgs/development/libraries/science/math/mkl/default.nix @@ -111,7 +111,14 @@ in stdenvNoCC.mkDerivation { cp -r opt/intel/compilers_and_libraries_${version}/linux/compiler/lib/intel64_lin/*.so* $out/lib/ cp -r opt/intel/compilers_and_libraries_${version}/linux/mkl/lib/intel64_lin/*.so* $out/lib/ cp -r opt/intel/compilers_and_libraries_${version}/linux/mkl/bin/pkgconfig/*dynamic*.pc $out/lib/pkgconfig - ''); + '') + '' + + # Setup symlinks for blas / lapack + ln -s $out/lib/libmkl_rt${stdenvNoCC.hostPlatform.extensions.sharedLibrary} $out/lib/libblas${stdenvNoCC.hostPlatform.extensions.sharedLibrary} + ln -s $out/lib/libmkl_rt${stdenvNoCC.hostPlatform.extensions.sharedLibrary} $out/lib/libcblas${stdenvNoCC.hostPlatform.extensions.sharedLibrary} + ln -s $out/lib/libmkl_rt${stdenvNoCC.hostPlatform.extensions.sharedLibrary} $out/lib/liblapack${stdenvNoCC.hostPlatform.extensions.sharedLibrary} + ln -s $out/lib/libmkl_rt${stdenvNoCC.hostPlatform.extensions.sharedLibrary} $out/lib/liblapacke${stdenvNoCC.hostPlatform.extensions.sharedLibrary} + ''; # fixDarwinDylibName fails for libmkl_cdft_core.dylib because the # larger updated load commands do not fit. Use install_name_tool diff --git a/pkgs/development/libraries/science/math/openblas/default.nix b/pkgs/development/libraries/science/math/openblas/default.nix index 23168d741ba9..c55a5cb7878f 100644 --- a/pkgs/development/libraries/science/math/openblas/default.nix +++ b/pkgs/development/libraries/science/math/openblas/default.nix @@ -176,6 +176,12 @@ Cflags: -I$out/include Libs: -L$out/lib -lopenblas EOF done + + # Setup symlinks for blas / lapack + ln -s $out/lib/libopenblas${stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary} + ln -s $out/lib/libopenblas${stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary} + ln -s $out/lib/libopenblas${stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary} + ln -s $out/lib/libopenblas${stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/liblapacke${stdenv.hostPlatform.extensions.sharedLibrary} ''; meta = with stdenv.lib; { @@ -185,10 +191,4 @@ EOF platforms = platforms.unix; maintainers = with maintainers; [ ttuegel ]; }; - - # We use linkName to pass a different name to --with-blas-libs for - # fflas-ffpack and linbox, because we use blas on darwin but openblas - # elsewhere. - # See see https://github.com/NixOS/nixpkgs/pull/45013. - passthru.linkName = "openblas"; } diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 5ba9b723edd6..6ebf2bcf8df7 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -237,7 +237,7 @@ mapAliases ({ libGL_driver = mesa.drivers; libintlOrEmpty = stdenv.lib.optional (!stdenv.isLinux || stdenv.hostPlatform.libc != "glibc") gettext; # added 2018-03-14 libjson_rpc_cpp = libjson-rpc-cpp; # added 2017-02-28 - liblapackWithoutAtlas = liblapack; # added 2018-11-05 + liblapackWithoutAtlas = lapack-reference; # added 2018-11-05 liblrdf = lrdf; # added 2018-04-25 libqrencode = qrencode; # added 2019-01-01 librdf = lrdf; # added 2020-03-22 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a7b711d5277c..1f11beb8ee3d 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -11479,20 +11479,11 @@ in ffcast = callPackage ../tools/X11/ffcast { }; - fflas-ffpack = callPackage ../development/libraries/fflas-ffpack { - # We need to use blas instead of openblas on darwin, - # see https://github.com/NixOS/nixpkgs/pull/45013. - blas = if stdenv.isDarwin then blas else openblas; - }; + fflas-ffpack = callPackage ../development/libraries/fflas-ffpack { }; forge = callPackage ../development/libraries/forge { }; - linbox = callPackage ../development/libraries/linbox { - # We need to use blas instead of openblas on darwin, see - # https://github.com/NixOS/nixpkgs/pull/45013 and - # https://github.com/NixOS/nixpkgs/pull/45015. - blas = if stdenv.isDarwin then blas else openblas; - }; + linbox = callPackage ../development/libraries/linbox { }; ffmpeg_2_8 = callPackage ../development/libraries/ffmpeg/2.8.nix { inherit (darwin.apple_sdk.frameworks) Cocoa; @@ -24428,7 +24419,9 @@ in arpack = callPackage ../development/libraries/science/math/arpack { }; - blas = callPackage ../development/libraries/science/math/blas { }; + blas = callPackage ../build-support/alternatives/blas { }; + + blas-reference = callPackage ../development/libraries/science/math/blas { }; brial = callPackage ../development/libraries/science/math/brial { }; @@ -24448,12 +24441,15 @@ in jags = callPackage ../applications/science/math/jags { }; + lapack = callPackage ../build-support/alternatives/lapack { }; + + lapack-reference = callPackage ../development/libraries/science/math/liblapack { }; + liblapack = lapack-reference; + libbraiding = callPackage ../development/libraries/science/math/libbraiding { }; libhomfly = callPackage ../development/libraries/science/math/libhomfly { }; - liblapack = callPackage ../development/libraries/science/math/liblapack {}; - liblbfgs = callPackage ../development/libraries/science/math/liblbfgs { }; lrs = callPackage ../development/libraries/science/math/lrs { }; diff --git a/pkgs/top-level/release-small.nix b/pkgs/top-level/release-small.nix index ab7e4ce00d7d..1c7f758ccff3 100644 --- a/pkgs/top-level/release-small.nix +++ b/pkgs/top-level/release-small.nix @@ -78,9 +78,9 @@ with import ./release-lib.nix { inherit supportedSystems; }; kvm = linux; qemu = linux; qemu_kvm = linux; + lapack-reference = linux; less = all; lftp = all; - liblapack = linux; libtool = all; libtool_2 = all; libxml2 = all;