nixpkgs/pkgs/development/libraries/science/math/openblas/default.nix

207 lines
6.3 KiB
Nix
Raw Normal View History

{ stdenv, fetchFromGitHub, perl, which
# Most packages depending on openblas expect integer width to match
# pointer width, but some expect to use 32-bit integers always
# (for compatibility with reference BLAS).
, blas64 ? null
# Multi-threaded applications must not call a threaded OpenBLAS
# (the only exception is when an application uses OpenMP as its
# *only* form of multi-threading). See
# https://github.com/xianyi/OpenBLAS/wiki/Faq/4bded95e8dc8aadc70ce65267d1093ca7bdefc4c#multi-threaded
# https://github.com/xianyi/OpenBLAS/issues/2543
# This flag builds a single-threaded OpenBLAS using the flags
# stated in thre.
, singleThreaded ? false
2019-01-05 12:46:40 +00:00
, buildPackages
# Select a specific optimization target (other than the default)
# See https://github.com/xianyi/OpenBLAS/blob/develop/TargetList.txt
, target ? null
, enableStatic ? stdenv.hostPlatform.isStatic
, enableShared ? !stdenv.hostPlatform.isStatic
}:
2014-08-28 21:39:01 +00:00
with stdenv.lib;
2015-02-26 12:44:03 +00:00
2015-10-11 14:16:27 +00:00
let blas64_ = blas64; in
let
setTarget = x: if target == null then x else target;
# To add support for a new platform, add an element to this set.
configs = {
2017-12-29 22:19:15 +00:00
armv6l-linux = {
BINARY = 32;
TARGET = setTarget "ARMV6";
DYNAMIC_ARCH = false;
USE_OPENMP = true;
2017-12-29 22:19:15 +00:00
};
armv7l-linux = {
BINARY = 32;
TARGET = setTarget "ARMV7";
DYNAMIC_ARCH = false;
USE_OPENMP = true;
};
2014-08-28 21:39:01 +00:00
2017-12-07 23:59:50 +00:00
aarch64-linux = {
BINARY = 64;
TARGET = setTarget "ARMV8";
DYNAMIC_ARCH = true;
USE_OPENMP = true;
2017-12-07 23:59:50 +00:00
};
i686-linux = {
BINARY = 32;
TARGET = setTarget "P2";
DYNAMIC_ARCH = true;
USE_OPENMP = true;
};
x86_64-darwin = {
BINARY = 64;
TARGET = setTarget "ATHLON";
DYNAMIC_ARCH = true;
USE_OPENMP = false;
MACOSX_DEPLOYMENT_TARGET = "10.7";
};
x86_64-linux = {
BINARY = 64;
TARGET = setTarget "ATHLON";
DYNAMIC_ARCH = true;
NO_AVX512 = true;
2020-01-02 17:53:00 +00:00
USE_OPENMP = !stdenv.hostPlatform.isMusl;
};
2020-10-03 01:10:44 +00:00
powerpc64le-linux = {
BINARY = 64;
TARGET = setTarget "POWER5";
DYNAMIC_ARCH = true;
USE_OPENMP = !stdenv.hostPlatform.isMusl;
};
};
in
let
config =
configs.${stdenv.hostPlatform.system}
or (throw "unsupported system: ${stdenv.hostPlatform.system}");
in
let
blas64 =
if blas64_ != null
then blas64_
else hasPrefix "x86_64" stdenv.hostPlatform.system;
# Convert flag values to format OpenBLAS's build expects.
# `toString` is almost what we need other than bools,
# which we need to map {true -> 1, false -> 0}
# (`toString` produces empty string `""` for false instead of `0`)
mkMakeFlagValue = val:
if !builtins.isBool val then toString val
else if val then "1" else "0";
mkMakeFlagsFromConfig = mapAttrsToList (var: val: "${var}=${mkMakeFlagValue val}");
shlibExt = stdenv.hostPlatform.extensions.sharedLibrary;
2015-10-11 14:16:27 +00:00
in
2018-03-12 17:40:49 +00:00
stdenv.mkDerivation rec {
pname = "openblas";
version = "0.3.12";
2020-09-20 18:18:35 +00:00
outputs = [ "out" "dev" ];
src = fetchFromGitHub {
owner = "xianyi";
repo = "OpenBLAS";
rev = "v${version}";
sha256 = "0mk1kjkr96bvvcq2zigzjrs0cnhwsf6gfi0855mp9yifn8lvp20y";
2014-08-28 21:39:01 +00:00
};
2015-10-11 14:16:27 +00:00
inherit blas64;
2016-10-20 21:37:50 +00:00
# Some hardening features are disabled due to sporadic failures in
# OpenBLAS-based programs. The problem may not be with OpenBLAS itself, but
# with how these flags interact with hardening measures used downstream.
# In either case, OpenBLAS must only be used by trusted code--it is
# inherently unsuitable for security-conscious applications--so there should
# be no objection to disabling these hardening measures.
hardeningDisable = [
# don't modify or move the stack
"stackprotector" "pic"
# don't alter index arithmetic
"strictoverflow"
# don't interfere with dynamic target detection
2016-10-20 21:37:50 +00:00
"relro" "bindnow"
];
nativeBuildInputs = [
perl
which
2019-12-19 12:14:07 +00:00
];
depsBuildBuild = [
buildPackages.gfortran
buildPackages.stdenv.cc
];
makeFlags = mkMakeFlagsFromConfig (config // {
FC = "${stdenv.cc.targetPrefix}gfortran";
CC = "${stdenv.cc.targetPrefix}${if stdenv.cc.isClang then "clang" else "cc"}";
PREFIX = placeholder "out";
NUM_THREADS = 64;
INTERFACE64 = blas64;
2019-05-17 02:45:42 +00:00
NO_STATIC = !enableStatic;
2020-01-02 17:53:00 +00:00
NO_SHARED = !enableShared;
CROSS = stdenv.hostPlatform != stdenv.buildPlatform;
HOSTCC = "cc";
2019-02-22 18:46:58 +00:00
# Makefile.system only checks defined status
2019-03-30 16:55:24 +00:00
# This seems to be a bug in the openblas Makefile:
# on x86_64 it expects NO_BINARY_MODE=
# but on aarch64 it expects NO_BINARY_MODE=0
NO_BINARY_MODE = if stdenv.isx86_64
then toString (stdenv.hostPlatform != stdenv.buildPlatform)
else stdenv.hostPlatform != stdenv.buildPlatform;
} // (stdenv.lib.optionalAttrs singleThreaded {
# As described on https://github.com/xianyi/OpenBLAS/wiki/Faq/4bded95e8dc8aadc70ce65267d1093ca7bdefc4c#multi-threaded
USE_THREAD = false;
USE_LOCKING = true; # available with openblas >= 0.3.7
USE_OPENMP = false; # openblas will refuse building with both USE_OPENMP=1 and USE_THREAD=0
}));
doCheck = true;
2015-10-11 14:16:27 +00:00
checkTarget = "tests";
2018-08-17 12:49:52 +00:00
postInstall = ''
# Write pkgconfig aliases. Upstream report:
# https://github.com/xianyi/OpenBLAS/issues/1740
for alias in blas cblas lapack; do
cat <<EOF > $out/lib/pkgconfig/$alias.pc
2018-08-17 12:49:52 +00:00
Name: $alias
Version: ${version}
Description: $alias provided by the OpenBLAS package.
Cflags: -I$out/include
Libs: -L$out/lib -lopenblas
EOF
done
blas/lapack: add wrapper for “alternative”s of BLAS/LAPACK provider This is based on previous work for switching between BLAS and LAPACK implementation in Debian[1] and Gentoo[2]. The goal is to have one way to depend on the BLAS/LAPACK libraries that all packages must use. The attrs “blas” and “lapack” are used to represent a wrapped BLAS/LAPACK provider. Derivations that don’t care how BLAS and LAPACK are implemented can just use blas and lapack directly. If you do care what you get (perhaps for some CPP), you should verify that blas and lapack match what you expect with an assertion. The “blas” package collides with the old “blas” reference implementation. This has been renamed to “blas-reference”. In addition, “lapack-reference” is also included, corresponding to “liblapack” from Netlib.org. Currently, there are 3 providers of the BLAS and LAPACK interfaces: - lapack-reference: the BLAS/LAPACK implementation maintained by netlib.org - OpenBLAS: an optimized version of BLAS and LAPACK - MKL: Intel’s unfree but highly optimized BLAS/LAPACK implementation By default, the above implementations all use the “LP64” BLAS and LAPACK ABI. This corresponds to “openblasCompat” and is the safest way to use BLAS/LAPACK. You may received some benefits from “ILP64” or 8-byte integer BLAS at the expense of breaking compatibility with some packages. This can be switched at build time with an override like: import <nixpkgs> { config.allowUnfree = true; overlays = [(self: super: { lapack = super.lapack.override { lapackProvider = super.lapack-reference; }; blas = super.blas.override { blasProvider = super.lapack-reference; }; })]; } or, switched at runtime via LD_LIBRARY_PATH like: $ LD_LIBRARY_PATH=$(nix-build -E '(with import <nixpkgs> {}).lapack.override { lapackProvider = pkgs.mkl; is64bit = true; })')/lib:$(nix-build -E '(with import <nixpkgs> {}).blas.override { blasProvider = pkgs.mkl; is64bit = true; })')/lib ./your-blas-linked-binary By default, we use OpenBLAS LP64 also known in Nixpkgs as openblasCompat. [1]: https://wiki.debian.org/DebianScience/LinearAlgebraLibraries [2]: https://wiki.gentoo.org/wiki/Blas-lapack-switch
2020-03-27 18:50:45 +00:00
# Setup symlinks for blas / lapack
ln -s $out/lib/libopenblas${shlibExt} $out/lib/libblas${shlibExt}
ln -s $out/lib/libopenblas${shlibExt} $out/lib/libcblas${shlibExt}
ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapack${shlibExt}
ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapacke${shlibExt}
'' + stdenv.lib.optionalString stdenv.hostPlatform.isLinux ''
ln -s $out/lib/libopenblas${shlibExt} $out/lib/libblas${shlibExt}.3
ln -s $out/lib/libopenblas${shlibExt} $out/lib/libcblas${shlibExt}.3
ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapack${shlibExt}.3
ln -s $out/lib/libopenblas${shlibExt} $out/lib/liblapacke${shlibExt}.3
'';
2018-08-17 12:49:52 +00:00
2014-08-29 15:02:39 +00:00
meta = with stdenv.lib; {
2014-08-28 21:39:01 +00:00
description = "Basic Linear Algebra Subprograms";
2014-08-29 15:02:39 +00:00
license = licenses.bsd3;
homepage = "https://github.com/xianyi/OpenBLAS";
platforms = platforms.unix;
2014-08-29 15:02:39 +00:00
maintainers = with maintainers; [ ttuegel ];
2014-08-28 21:39:01 +00:00
};
}