diff --git a/lib/spack/spack/build_systems/oneapi.py b/lib/spack/spack/build_systems/oneapi.py index 1961eb312c..4c432c0cac 100644 --- a/lib/spack/spack/build_systems/oneapi.py +++ b/lib/spack/spack/build_systems/oneapi.py @@ -9,11 +9,10 @@ import shutil from os.path import basename, dirname, isdir -from llnl.util.filesystem import find_headers, find_libraries, join_path +from llnl.util.filesystem import find_headers, find_libraries, join_path, mkdirp from llnl.util.link_tree import LinkTree from spack.directives import conflicts, variant -from spack.package import mkdirp from spack.util.environment import EnvironmentModifications from spack.util.executable import Executable @@ -212,3 +211,7 @@ def link_flags(self): @property def ld_flags(self): return "{0} {1}".format(self.search_flags, self.link_flags) + + +#: Tuple of Intel math libraries, exported to packages +INTEL_MATH_LIBRARIES = ("intel-mkl", "intel-oneapi-mkl", "intel-parallel-studio") diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index c537a7103a..16b1216acb 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -49,6 +49,7 @@ from spack.build_systems.nmake import NMakePackage from spack.build_systems.octave import OctavePackage from spack.build_systems.oneapi import ( + INTEL_MATH_LIBRARIES, IntelOneApiLibraryPackage, IntelOneApiPackage, IntelOneApiStaticLibraryList, diff --git a/var/spack/repos/builtin/packages/abinit/package.py b/var/spack/repos/builtin/packages/abinit/package.py index a343bf69d7..9f0938daf1 100644 --- a/var/spack/repos/builtin/packages/abinit/package.py +++ b/var/spack/repos/builtin/packages/abinit/package.py @@ -85,6 +85,11 @@ class Abinit(AutotoolsPackage): # libxml2 depends_on("libxml2", when="@9:+libxml2") + # If the Intel suite is used for Lapack, it must be used for fftw and vice-versa + for _intel_pkg in INTEL_MATH_LIBRARIES: + requires(f"^[virtuals=fftw-api] {_intel_pkg}", when=f"^[virtuals=lapack] {_intel_pkg}") + requires(f"^[virtuals=lapack] {_intel_pkg}", when=f"^[virtuals=fftw-api] {_intel_pkg}") + # Cannot ask for +scalapack if it does not depend on MPI conflicts("+scalapack", when="~mpi") @@ -186,7 +191,8 @@ def configure_args(self): # BLAS/LAPACK/SCALAPACK-ELPA linalg = spec["lapack"].libs + spec["blas"].libs - if "^mkl" in spec: + is_using_intel_libraries = spec["lapack"].name in INTEL_MATH_LIBRARIES + if is_using_intel_libraries: linalg_flavor = "mkl" elif "@9:" in spec and "^openblas" in spec: linalg_flavor = "openblas" @@ -207,7 +213,7 @@ def configure_args(self): oapp(f"--with-linalg-flavor={linalg_flavor}") - if "^mkl" in spec: + if is_using_intel_libraries: fftflavor = "dfti" else: if "+openmp" in spec: @@ -218,7 +224,7 @@ def configure_args(self): oapp(f"--with-fft-flavor={fftflavor}") if "@:8" in spec: - if "^mkl" in spec: + if is_using_intel_libraries: oapp(f"--with-fft-incs={spec['fftw-api'].headers.cpp_flags}") oapp(f"--with-fft-libs={spec['fftw-api'].libs.ld_flags}") else: @@ -229,7 +235,7 @@ def configure_args(self): ] ) else: - if "^mkl" in spec: + if is_using_intel_libraries: options.extend( [ f"FFT_CPPFLAGS={spec['fftw-api'].headers.cpp_flags}", diff --git a/var/spack/repos/builtin/packages/gromacs/package.py b/var/spack/repos/builtin/packages/gromacs/package.py index 7a4147a6ee..66c594c71e 100644 --- a/var/spack/repos/builtin/packages/gromacs/package.py +++ b/var/spack/repos/builtin/packages/gromacs/package.py @@ -263,6 +263,11 @@ class Gromacs(CMakePackage, CudaPackage): msg="Only attempt to find gcc libs for Intel compiler if Intel compiler is used.", ) + # If the Intel suite is used for Lapack, it must be used for fftw and vice-versa + for _intel_pkg in INTEL_MATH_LIBRARIES: + requires(f"^[virtuals=fftw-api] {_intel_pkg}", when=f"^[virtuals=lapack] {_intel_pkg}") + requires(f"^[virtuals=lapack] {_intel_pkg}", when=f"^[virtuals=fftw-api] {_intel_pkg}") + patch("gmxDetectCpu-cmake-3.14.patch", when="@2018:2019.3^cmake@3.14.0:") patch("gmxDetectSimd-cmake-3.14.patch", when="@5.0:2017^cmake@3.14.0:") # 2021.2 will always try to build tests (see https://gromacs.bioexcel.eu/t/compilation-failure-for-gromacs-2021-1-and-2021-2-with-cmake-3-20-2/2129) @@ -594,7 +599,7 @@ def cmake_args(self): "-DGMX_OPENMP_MAX_THREADS=%s" % self.spec.variants["openmp_max_threads"].value ) - if "^mkl" in self.spec: + if self.spec["lapack"].name in INTEL_MATH_LIBRARIES: # fftw-api@3 is provided by intel-mkl or intel-parllel-studio # we use the mkl interface of gromacs options.append("-DGMX_FFT_LIBRARY=mkl") diff --git a/var/spack/repos/builtin/packages/intel-mkl/package.py b/var/spack/repos/builtin/packages/intel-mkl/package.py index 7dd8ab4122..c66235f382 100644 --- a/var/spack/repos/builtin/packages/intel-mkl/package.py +++ b/var/spack/repos/builtin/packages/intel-mkl/package.py @@ -153,8 +153,7 @@ class IntelMkl(IntelPackage): multi=False, ) - provides("blas") - provides("lapack") + provides("blas", "lapack") provides("lapack@3.9.0", when="@2020.4") provides("lapack@3.7.0", when="@11.3") provides("scalapack") diff --git a/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py b/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py index 1d80c52f62..db3fdd6d7e 100644 --- a/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py +++ b/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py @@ -126,8 +126,7 @@ class IntelOneapiMkl(IntelOneApiLibraryPackage): provides("fftw-api@3") provides("scalapack", when="+cluster") provides("mkl") - provides("lapack") - provides("blas") + provides("lapack", "blas") @property def component_dir(self): diff --git a/var/spack/repos/builtin/packages/intel-parallel-studio/package.py b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py index 84810bacfa..50e7021de8 100644 --- a/var/spack/repos/builtin/packages/intel-parallel-studio/package.py +++ b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py @@ -536,8 +536,7 @@ class IntelParallelStudio(IntelPackage): provides("ipp", when="+ipp") provides("mkl", when="+mkl") - provides("blas", when="+mkl") - provides("lapack", when="+mkl") + provides("blas", "lapack", when="+mkl") provides("scalapack", when="+mkl") provides("fftw-api@3", when="+mkl@professional.2017:") diff --git a/var/spack/repos/builtin/packages/lammps/package.py b/var/spack/repos/builtin/packages/lammps/package.py index a44c7bd603..b2d3d11133 100644 --- a/var/spack/repos/builtin/packages/lammps/package.py +++ b/var/spack/repos/builtin/packages/lammps/package.py @@ -791,7 +791,7 @@ def cmake_args(self): # FFTW libraries are available and enable them by default. if "^fftw" in spec or "^cray-fftw" in spec or "^amdfftw" in spec: args.append(self.define("FFT", "FFTW3")) - elif "^mkl" in spec: + elif spec["fftw-api"].name in INTEL_MATH_LIBRARIES: args.append(self.define("FFT", "MKL")) elif "^armpl-gcc" in spec or "^acfl" in spec: args.append(self.define("FFT", "FFTW3")) diff --git a/var/spack/repos/builtin/packages/quantum-espresso/package.py b/var/spack/repos/builtin/packages/quantum-espresso/package.py index 4d41903cd6..40c036320d 100644 --- a/var/spack/repos/builtin/packages/quantum-espresso/package.py +++ b/var/spack/repos/builtin/packages/quantum-espresso/package.py @@ -242,6 +242,11 @@ class QuantumEspresso(CMakePackage, Package): depends_on("git@2.13:", type="build") depends_on("m4", type="build") + # If the Intel suite is used for Lapack, it must be used for fftw and vice-versa + for _intel_pkg in INTEL_MATH_LIBRARIES: + requires(f"^[virtuals=fftw-api] {_intel_pkg}", when=f"^[virtuals=lapack] {_intel_pkg}") + requires(f"^[virtuals=lapack] {_intel_pkg}", when=f"^[virtuals=fftw-api] {_intel_pkg}") + # CONFLICTS SECTION # Omitted for now due to concretizer bug # MKL with 64-bit integers not supported. @@ -489,7 +494,8 @@ def install(self, pkg, spec, prefix): # you need to pass it in the FFTW_INCLUDE and FFT_LIBS directory. # QE supports an internal FFTW2, but only an external FFTW3 interface. - if "^mkl" in spec: + is_using_intel_libraries = spec["lapack"].name in INTEL_MATH_LIBRARIES + if is_using_intel_libraries: # A seperate FFT library is not needed when linking against MKL options.append("FFTW_INCLUDE={0}".format(join_path(env["MKLROOT"], "include/fftw"))) if "^fftw@3:" in spec: @@ -531,11 +537,11 @@ def install(self, pkg, spec, prefix): if spec.satisfies("@:6.4"): # set even if MKL is selected options.append("BLAS_LIBS={0}".format(lapack_blas.ld_flags)) else: # behavior changed at 6.5 and later - if not spec.satisfies("^mkl"): + if not is_using_intel_libraries: options.append("BLAS_LIBS={0}".format(lapack_blas.ld_flags)) if "+scalapack" in spec: - if "^mkl" in spec: + if is_using_intel_libraries: if "^openmpi" in spec: scalapack_option = "yes" else: # mpich, intel-mpi diff --git a/var/spack/repos/builtin/packages/r/package.py b/var/spack/repos/builtin/packages/r/package.py index dfe397ca2c..7232a7e6c1 100644 --- a/var/spack/repos/builtin/packages/r/package.py +++ b/var/spack/repos/builtin/packages/r/package.py @@ -137,7 +137,7 @@ def configure_args(self): ] if "+external-lapack" in spec: - if "^mkl" in spec and "gfortran" in self.compiler.fc: + if spec["lapack"].name in INTEL_MATH_LIBRARIES and "gfortran" in self.compiler.fc: mkl_re = re.compile(r"(mkl_)intel(_i?lp64\b)") config_args.extend( [