gromacs et al: fix ^mkl pattern (#41002)

The ^mkl pattern was used to refer to three packages
even though none of software using it was depending
on "mkl".

This pattern, which follows Hyrum's law, is now being
removed in favor of a more explicit one.

In this PR gromacs, abinit, lammps, and quantum-espresso
are modified.

Intel packages are also modified to provide "lapack"
and "blas" together.
This commit is contained in:
Massimiliano Culpo 2023-11-10 14:56:04 +01:00 committed by Todd Gamblin
parent c266e69cde
commit 74172fb9d2
10 changed files with 36 additions and 18 deletions

View file

@ -9,11 +9,10 @@
import shutil import shutil
from os.path import basename, dirname, isdir 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 llnl.util.link_tree import LinkTree
from spack.directives import conflicts, variant from spack.directives import conflicts, variant
from spack.package import mkdirp
from spack.util.environment import EnvironmentModifications from spack.util.environment import EnvironmentModifications
from spack.util.executable import Executable from spack.util.executable import Executable
@ -212,3 +211,7 @@ def link_flags(self):
@property @property
def ld_flags(self): def ld_flags(self):
return "{0} {1}".format(self.search_flags, self.link_flags) 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")

View file

@ -49,6 +49,7 @@
from spack.build_systems.nmake import NMakePackage from spack.build_systems.nmake import NMakePackage
from spack.build_systems.octave import OctavePackage from spack.build_systems.octave import OctavePackage
from spack.build_systems.oneapi import ( from spack.build_systems.oneapi import (
INTEL_MATH_LIBRARIES,
IntelOneApiLibraryPackage, IntelOneApiLibraryPackage,
IntelOneApiPackage, IntelOneApiPackage,
IntelOneApiStaticLibraryList, IntelOneApiStaticLibraryList,

View file

@ -85,6 +85,11 @@ class Abinit(AutotoolsPackage):
# libxml2 # libxml2
depends_on("libxml2", when="@9:+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 # Cannot ask for +scalapack if it does not depend on MPI
conflicts("+scalapack", when="~mpi") conflicts("+scalapack", when="~mpi")
@ -186,7 +191,8 @@ def configure_args(self):
# BLAS/LAPACK/SCALAPACK-ELPA # BLAS/LAPACK/SCALAPACK-ELPA
linalg = spec["lapack"].libs + spec["blas"].libs 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" linalg_flavor = "mkl"
elif "@9:" in spec and "^openblas" in spec: elif "@9:" in spec and "^openblas" in spec:
linalg_flavor = "openblas" linalg_flavor = "openblas"
@ -207,7 +213,7 @@ def configure_args(self):
oapp(f"--with-linalg-flavor={linalg_flavor}") oapp(f"--with-linalg-flavor={linalg_flavor}")
if "^mkl" in spec: if is_using_intel_libraries:
fftflavor = "dfti" fftflavor = "dfti"
else: else:
if "+openmp" in spec: if "+openmp" in spec:
@ -218,7 +224,7 @@ def configure_args(self):
oapp(f"--with-fft-flavor={fftflavor}") oapp(f"--with-fft-flavor={fftflavor}")
if "@:8" in spec: 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-incs={spec['fftw-api'].headers.cpp_flags}")
oapp(f"--with-fft-libs={spec['fftw-api'].libs.ld_flags}") oapp(f"--with-fft-libs={spec['fftw-api'].libs.ld_flags}")
else: else:
@ -229,7 +235,7 @@ def configure_args(self):
] ]
) )
else: else:
if "^mkl" in spec: if is_using_intel_libraries:
options.extend( options.extend(
[ [
f"FFT_CPPFLAGS={spec['fftw-api'].headers.cpp_flags}", f"FFT_CPPFLAGS={spec['fftw-api'].headers.cpp_flags}",

View file

@ -263,6 +263,11 @@ class Gromacs(CMakePackage, CudaPackage):
msg="Only attempt to find gcc libs for Intel compiler if Intel compiler is used.", 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("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:") 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) # 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 "-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 # fftw-api@3 is provided by intel-mkl or intel-parllel-studio
# we use the mkl interface of gromacs # we use the mkl interface of gromacs
options.append("-DGMX_FFT_LIBRARY=mkl") options.append("-DGMX_FFT_LIBRARY=mkl")

View file

@ -153,8 +153,7 @@ class IntelMkl(IntelPackage):
multi=False, multi=False,
) )
provides("blas") provides("blas", "lapack")
provides("lapack")
provides("lapack@3.9.0", when="@2020.4") provides("lapack@3.9.0", when="@2020.4")
provides("lapack@3.7.0", when="@11.3") provides("lapack@3.7.0", when="@11.3")
provides("scalapack") provides("scalapack")

View file

@ -126,8 +126,7 @@ class IntelOneapiMkl(IntelOneApiLibraryPackage):
provides("fftw-api@3") provides("fftw-api@3")
provides("scalapack", when="+cluster") provides("scalapack", when="+cluster")
provides("mkl") provides("mkl")
provides("lapack") provides("lapack", "blas")
provides("blas")
@property @property
def component_dir(self): def component_dir(self):

View file

@ -536,8 +536,7 @@ class IntelParallelStudio(IntelPackage):
provides("ipp", when="+ipp") provides("ipp", when="+ipp")
provides("mkl", when="+mkl") provides("mkl", when="+mkl")
provides("blas", when="+mkl") provides("blas", "lapack", when="+mkl")
provides("lapack", when="+mkl")
provides("scalapack", when="+mkl") provides("scalapack", when="+mkl")
provides("fftw-api@3", when="+mkl@professional.2017:") provides("fftw-api@3", when="+mkl@professional.2017:")

View file

@ -791,7 +791,7 @@ def cmake_args(self):
# FFTW libraries are available and enable them by default. # FFTW libraries are available and enable them by default.
if "^fftw" in spec or "^cray-fftw" in spec or "^amdfftw" in spec: if "^fftw" in spec or "^cray-fftw" in spec or "^amdfftw" in spec:
args.append(self.define("FFT", "FFTW3")) 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")) args.append(self.define("FFT", "MKL"))
elif "^armpl-gcc" in spec or "^acfl" in spec: elif "^armpl-gcc" in spec or "^acfl" in spec:
args.append(self.define("FFT", "FFTW3")) args.append(self.define("FFT", "FFTW3"))

View file

@ -242,6 +242,11 @@ class QuantumEspresso(CMakePackage, Package):
depends_on("git@2.13:", type="build") depends_on("git@2.13:", type="build")
depends_on("m4", 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 # CONFLICTS SECTION
# Omitted for now due to concretizer bug # Omitted for now due to concretizer bug
# MKL with 64-bit integers not supported. # 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. # you need to pass it in the FFTW_INCLUDE and FFT_LIBS directory.
# QE supports an internal FFTW2, but only an external FFTW3 interface. # 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 # A seperate FFT library is not needed when linking against MKL
options.append("FFTW_INCLUDE={0}".format(join_path(env["MKLROOT"], "include/fftw"))) options.append("FFTW_INCLUDE={0}".format(join_path(env["MKLROOT"], "include/fftw")))
if "^fftw@3:" in spec: 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 if spec.satisfies("@:6.4"): # set even if MKL is selected
options.append("BLAS_LIBS={0}".format(lapack_blas.ld_flags)) options.append("BLAS_LIBS={0}".format(lapack_blas.ld_flags))
else: # behavior changed at 6.5 and later 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)) options.append("BLAS_LIBS={0}".format(lapack_blas.ld_flags))
if "+scalapack" in spec: if "+scalapack" in spec:
if "^mkl" in spec: if is_using_intel_libraries:
if "^openmpi" in spec: if "^openmpi" in spec:
scalapack_option = "yes" scalapack_option = "yes"
else: # mpich, intel-mpi else: # mpich, intel-mpi

View file

@ -137,7 +137,7 @@ def configure_args(self):
] ]
if "+external-lapack" in spec: 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)") mkl_re = re.compile(r"(mkl_)intel(_i?lp64\b)")
config_args.extend( config_args.extend(
[ [