cp2k: add a separate MakefileBuilder (#42130)

This commit is contained in:
Massimiliano Culpo 2024-01-23 21:39:40 +01:00 committed by GitHub
parent 84868b57c7
commit a68fcb2fb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 122 additions and 178 deletions

View File

@ -11,10 +11,24 @@
import spack.util.environment import spack.util.environment
import spack.util.executable import spack.util.executable
from spack.build_environment import dso_suffix from spack.build_environment import dso_suffix
from spack.build_systems import cmake, makefile
from spack.package import * from spack.package import *
GPU_MAP = {
"35": "K40",
"37": "K80",
"60": "P100",
"70": "V100",
"80": "A100",
"gfx906": "Mi50",
"gfx908": "Mi100",
"gfx90a": "Mi250",
"gfx90a:xnack-": "Mi250",
"gfx90a:xnack+": "Mi250",
}
class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
class Cp2k(MakefilePackage, CMakePackage, CudaPackage, ROCmPackage):
"""CP2K is a quantum chemistry and solid state physics software package """CP2K is a quantum chemistry and solid state physics software package
that can perform atomistic simulations of solid state, liquid, molecular, that can perform atomistic simulations of solid state, liquid, molecular,
periodic, material, crystal, and biological systems periodic, material, crystal, and biological systems
@ -40,26 +54,6 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
version("8.2", sha256="2e24768720efed1a5a4a58e83e2aca502cd8b95544c21695eb0de71ed652f20a") version("8.2", sha256="2e24768720efed1a5a4a58e83e2aca502cd8b95544c21695eb0de71ed652f20a")
version("8.1", sha256="7f37aead120730234a60b2989d0547ae5e5498d93b1e9b5eb548c041ee8e7772") version("8.1", sha256="7f37aead120730234a60b2989d0547ae5e5498d93b1e9b5eb548c041ee8e7772")
version("7.1", sha256="ccd711a09a426145440e666310dd01cc5772ab103493c4ae6a3470898cd0addb") version("7.1", sha256="ccd711a09a426145440e666310dd01cc5772ab103493c4ae6a3470898cd0addb")
version(
"6.1",
sha256="af803558e0a6b9e9d9ce8a3ab955ba32bacd179922455424e061c82c9fefa34b",
deprecated=True,
)
version(
"5.1",
sha256="e23613b593354fa82e0b8410e17d94c607a0b8c6d9b5d843528403ab09904412",
deprecated=True,
)
version(
"4.1",
sha256="4a3e4a101d8a35ebd80a9e9ecb02697fb8256364f1eccdbe4e5a85d31fe21343",
deprecated=True,
)
version(
"3.0",
sha256="1acfacef643141045b7cbade7006f9b7538476d861eeecd9658c9e468dc61151",
deprecated=True,
)
version("master", branch="master", submodules="True") version("master", branch="master", submodules="True")
variant("mpi", default=True, description="Enable MPI support") variant("mpi", default=True, description="Enable MPI support")
@ -79,29 +73,33 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
"pexsi", "pexsi",
default=False, default=False,
description="Enable the alternative PEXSI method for density matrix evaluation", description="Enable the alternative PEXSI method for density matrix evaluation",
when="+mpi",
) )
variant( variant(
"elpa", "elpa",
default=False, default=False,
description="Enable optimised diagonalisation routines from ELPA", description="Enable optimised diagonalisation routines from ELPA",
when="@6.1:", when="+mpi",
) )
variant( variant(
"dlaf", "dlaf",
default=False, default=False,
description="Enable DLA-Future eigensolver and Cholesky decomposition", description="Enable DLA-Future eigensolver and Cholesky decomposition",
when="@2024.1: build_system=cmake", when="@2024.1: build_system=cmake +mpi",
) )
# sirius support was introduced in 7, but effectively usable starting from CP2K 9
variant( variant(
"sirius", "sirius",
default=False, default=False,
description="Enable planewave electronic structure calculations via SIRIUS", description="Enable planewave electronic structure calculations via SIRIUS",
when="@9: +mpi",
) )
variant("cosma", default=False, description="Use COSMA for p?gemm") variant("cosma", default=False, description="Use COSMA for p?gemm", when="@8: +mpi")
variant( variant(
"libvori", "libvori",
default=False, default=False,
description="Enable support for Voronoi integration and BQB compression", description="Enable support for Voronoi integration and BQB compression",
when="@8:",
) )
variant("spglib", default=False, description="Enable support for spglib") variant("spglib", default=False, description="Enable support for spglib")
variant( variant(
@ -133,15 +131,13 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
), ),
) )
variant( variant(
"cuda_fft", "cuda_fft", default=False, description="Use CUDA also for FFTs in the PW part of CP2K"
default=False,
description=("Use CUDA also for FFTs in the PW part of CP2K"),
) )
variant( variant(
"cuda_blas", "cuda_blas",
default=False, default=False,
when="@:7", # req in CP2K v8+ when="@:7", # req in CP2K v8+
description=("Use CUBLAS for general matrix operations in DBCSR"), description="Use CUBLAS for general matrix operations in DBCSR",
) )
HFX_LMAX_RANGE = range(4, 8) HFX_LMAX_RANGE = range(4, 8)
@ -154,8 +150,7 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
multi=False, multi=False,
) )
depends_on("python", type="build") depends_on("python@3", type="build")
depends_on("python@3:", when="@8:", type="build")
depends_on("blas") depends_on("blas")
depends_on("lapack") depends_on("lapack")
@ -184,21 +179,15 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
conflicts("target=aarch64:", msg="libxsmm is not available on arm") conflicts("target=aarch64:", msg="libxsmm is not available on arm")
with when("+libint"): with when("+libint"):
# ... and in CP2K 7.0+ for linking to libint2
depends_on("pkgconfig", type="build", when="@7.0:") depends_on("pkgconfig", type="build", when="@7.0:")
# libint & libxc are always statically linked
depends_on("libint@1.1.4:1.2", when="@3.0:6.9")
for lmax in HFX_LMAX_RANGE: for lmax in HFX_LMAX_RANGE:
# libint2 can be linked dynamically again
depends_on( depends_on(
"libint@2.6.0:+fortran tune=cp2k-lmax-{0}".format(lmax), "libint@2.6.0:+fortran tune=cp2k-lmax-{0}".format(lmax),
when="@7.0: lmax={0}".format(lmax), when="@7.0: lmax={0}".format(lmax),
) )
with when("+libxc"): with when("+libxc"):
depends_on("pkgconfig", when="@7.0:") depends_on("pkgconfig", type="build", when="@7.0:")
depends_on("libxc@2.2.2:3", when="@:5")
depends_on("libxc@4.0.3:4", when="@6.0:6.9")
depends_on("libxc@4.0.3:4", when="@7.0:8.1") depends_on("libxc@4.0.3:4", when="@7.0:8.1")
depends_on("libxc@5.1.3:5.1", when="@8.2:8") depends_on("libxc@5.1.3:5.1", when="@8.2:8")
depends_on("libxc@5.1.7:5.1", when="@9:2022.2") depends_on("libxc@5.1.7:5.1", when="@9:2022.2")
@ -223,12 +212,8 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
depends_on("cosma@2.6.3:", when="@2023.2:") depends_on("cosma@2.6.3:", when="@2023.2:")
depends_on("cosma+cuda", when="+cuda") depends_on("cosma+cuda", when="+cuda")
depends_on("cosma+rocm", when="+rocm") depends_on("cosma+rocm", when="+rocm")
conflicts("~mpi")
# COSMA support was introduced in 8+
conflicts("@:7")
with when("+elpa"): with when("+elpa"):
conflicts("~mpi", msg="elpa requires MPI")
depends_on("elpa+openmp", when="+openmp") depends_on("elpa+openmp", when="+openmp")
depends_on("elpa~openmp", when="~openmp") depends_on("elpa~openmp", when="~openmp")
depends_on("elpa+cuda", when="+cuda") depends_on("elpa+cuda", when="+cuda")
@ -240,9 +225,6 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
depends_on("elpa@2023.05.001:", when="@2023.2:") depends_on("elpa@2023.05.001:", when="@2023.2:")
with when("+dlaf"): with when("+dlaf"):
conflicts(
"~mpi", msg="DLA-Future requires MPI. Only the distributed eigensolver is available."
)
depends_on("dla-future@0.2.1: +scalapack") depends_on("dla-future@0.2.1: +scalapack")
depends_on("dla-future ~cuda", when="~cuda") depends_on("dla-future ~cuda", when="~cuda")
depends_on("dla-future ~rocm", when="~rocm") depends_on("dla-future ~rocm", when="~rocm")
@ -256,10 +238,7 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
# while we link statically against PEXSI, its own deps may be linked in # while we link statically against PEXSI, its own deps may be linked in
# dynamically, therefore can't set this as pure build-type dependency. # dynamically, therefore can't set this as pure build-type dependency.
with when("+pexsi"): depends_on("pexsi+fortran@0.10.0:", when="+pexsi")
conflicts("~mpi", msg="pexsi requires MPI")
depends_on("pexsi+fortran@0.9.0:0.9", when="@:4")
depends_on("pexsi+fortran@0.10.0:", when="@5.0:")
# only OpenMP should be consistently used, all other common things # only OpenMP should be consistently used, all other common things
# like ELPA, SCALAPACK are independent and Spack will ensure that # like ELPA, SCALAPACK are independent and Spack will ensure that
@ -275,16 +254,11 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
depends_on("sirius@7.3:", when="@9.1") depends_on("sirius@7.3:", when="@9.1")
depends_on("sirius@7.4:7.5", when="@2023.2") depends_on("sirius@7.4:7.5", when="@2023.2")
depends_on("sirius@7.5:", when="@2024.1:") depends_on("sirius@7.5:", when="@2024.1:")
conflicts("~mpi", msg="SIRIUS requires MPI")
# sirius support was introduced in 7, but effectively usable starting from CP2K 9
conflicts("@:8")
with when("+libvori"): with when("+libvori"):
depends_on("libvori@201219:", when="@8.1") depends_on("libvori@201219:", when="@8.1")
depends_on("libvori@210412:", when="@8.2:") depends_on("libvori@210412:", when="@8.2:")
depends_on("libvori@220621:", when="@2023.1:") depends_on("libvori@220621:", when="@2023.1:")
# libvori support was introduced in 8+
conflicts("@:7")
# the bundled libcusmm uses numpy in the parameter prediction (v7+) # the bundled libcusmm uses numpy in the parameter prediction (v7+)
# which is written using Python 3 # which is written using Python 3
@ -294,11 +268,6 @@ class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
depends_on("spglib", when="+spglib") depends_on("spglib", when="+spglib")
# Apparently cp2k@4.1 needs an "experimental" version of libwannier.a
# which is only available contacting the developer directly. See INSTALL
# in the stage of cp2k@4.1
depends_on("wannier90", when="@3.0+mpi")
with when("build_system=cmake"): with when("build_system=cmake"):
depends_on("cmake@3.22:", type="build") depends_on("cmake@3.22:", type="build")
@ -385,27 +354,9 @@ def url_for_version(self, version):
url = "https://github.com/cp2k/cp2k/releases/download/v{0}/cp2k-{0}.tar.bz2" url = "https://github.com/cp2k/cp2k/releases/download/v{0}/cp2k-{0}.tar.bz2"
return url.format(version) return url.format(version)
@property
def makefile_architecture(self):
return "{0.architecture}-{0.compiler.name}".format(self.spec)
@property class MakefileBuilder(makefile.MakefileBuilder):
def makefile_version(self): def edit(self, pkg, spec, prefix):
return "{prefix}{suffix}".format(
prefix="p" if "+mpi" in self.spec else "s",
suffix="smp" if "+openmp" in self.spec else "opt",
)
@property
def makefile(self):
makefile_basename = ".".join([self.makefile_architecture, self.makefile_version])
return join_path("arch", makefile_basename)
@property
def archive_files(self):
return [join_path(self.stage.source_path, self.makefile)]
def edit(self, spec, prefix):
pkgconf = which("pkg-config") pkgconf = which("pkg-config")
fftw = spec["fftw-api:openmp" if "+openmp" in spec else "fftw-api"] fftw = spec["fftw-api:openmp" if "+openmp" in spec else "fftw-api"]
@ -428,6 +379,9 @@ def edit(self, spec, prefix):
} }
dflags = ["-DNDEBUG"] if spec.satisfies("@:2023.2") else [] dflags = ["-DNDEBUG"] if spec.satisfies("@:2023.2") else []
if spec["fftw-api"].name in ("intel-mkl", "intel-parallel-studio", "intel-oneapi-mkl"):
cppflags = ["-D__FFTW3_MKL", "-I{0}".format(fftw_header_dir)]
else:
cppflags = ["-D__FFTW3", "-I{0}".format(fftw_header_dir)] cppflags = ["-D__FFTW3", "-I{0}".format(fftw_header_dir)]
# CP2K requires MPI 3 starting at version 2023.1 # CP2K requires MPI 3 starting at version 2023.1
@ -438,9 +392,9 @@ def edit(self, spec, prefix):
elif "^mpi@2:" in spec: elif "^mpi@2:" in spec:
cppflags.append("-D__MPI_VERSION=2") cppflags.append("-D__MPI_VERSION=2")
cflags = optimization_flags[self.spec.compiler.name][:] cflags = optimization_flags[spec.compiler.name][:]
cxxflags = optimization_flags[self.spec.compiler.name][:] cxxflags = optimization_flags[spec.compiler.name][:]
fcflags = optimization_flags[self.spec.compiler.name][:] fcflags = optimization_flags[spec.compiler.name][:]
nvflags = ["-O3"] nvflags = ["-O3"]
ldflags = [] ldflags = []
libs = [] libs = []
@ -448,10 +402,10 @@ def edit(self, spec, prefix):
# CP2K Makefile doesn't set C standard # CP2K Makefile doesn't set C standard
if spec.satisfies("@2023.2:"): if spec.satisfies("@2023.2:"):
# Use of DBL_DECIMAL_DIG # Use of DBL_DECIMAL_DIG
cflags.append(self.compiler.c11_flag) cflags.append(pkg.compiler.c11_flag)
else: else:
# C99-style for-loops with inline definition of iterating variable. # C99-style for-loops with inline definition of iterating variable.
cflags.append(self.compiler.c99_flag) cflags.append(pkg.compiler.c99_flag)
if "%intel" in spec: if "%intel" in spec:
cflags.append("-fp-model precise") cflags.append("-fp-model precise")
@ -481,11 +435,11 @@ def edit(self, spec, prefix):
fcflags.append("-fallow-argument-mismatch") fcflags.append("-fallow-argument-mismatch")
if "+openmp" in spec: if "+openmp" in spec:
cflags.append(self.compiler.openmp_flag) cflags.append(pkg.compiler.openmp_flag)
cxxflags.append(self.compiler.openmp_flag) cxxflags.append(pkg.compiler.openmp_flag)
fcflags.append(self.compiler.openmp_flag) fcflags.append(pkg.compiler.openmp_flag)
ldflags.append(self.compiler.openmp_flag) ldflags.append(pkg.compiler.openmp_flag)
nvflags.append('-Xcompiler="{0}"'.format(self.compiler.openmp_flag)) nvflags.append('-Xcompiler="{0}"'.format(pkg.compiler.openmp_flag))
elif "%cce" in spec: # Cray enables OpenMP by default elif "%cce" in spec: # Cray enables OpenMP by default
cflags += ["-hnoomp"] cflags += ["-hnoomp"]
cxxflags += ["-hnoomp"] cxxflags += ["-hnoomp"]
@ -493,20 +447,18 @@ def edit(self, spec, prefix):
ldflags += ["-hnoomp"] ldflags += ["-hnoomp"]
if "@7:" in spec: # recent versions of CP2K use C++14 CUDA code if "@7:" in spec: # recent versions of CP2K use C++14 CUDA code
cxxflags.append(self.compiler.cxx14_flag) cxxflags.append(pkg.compiler.cxx14_flag)
nvflags.append(self.compiler.cxx14_flag) nvflags.append(pkg.compiler.cxx14_flag)
ldflags.append(fftw.libs.search_flags) ldflags.append(fftw.libs.search_flags)
if "superlu-dist@4.3" in spec: if "superlu-dist@4.3" in spec:
ldflags.insert(0, "-Wl,--allow-multiple-definition") ldflags.insert(0, "-Wl,--allow-multiple-definition")
if "+plumed" in self.spec: if "+plumed" in spec:
dflags.extend(["-D__PLUMED2"]) dflags.extend(["-D__PLUMED2"])
cppflags.extend(["-D__PLUMED2"]) cppflags.extend(["-D__PLUMED2"])
libs.extend( libs.extend([join_path(spec["plumed"].prefix.lib, "libplumed.{0}".format(dso_suffix))])
[join_path(self.spec["plumed"].prefix.lib, "libplumed.{0}".format(dso_suffix))]
)
cc = spack_cc if "~mpi" in spec else spec["mpi"].mpicc cc = spack_cc if "~mpi" in spec else spec["mpi"].mpicc
cxx = spack_cxx if "~mpi" in spec else spec["mpi"].mpicxx cxx = spack_cxx if "~mpi" in spec else spec["mpi"].mpicxx
@ -523,7 +475,7 @@ def edit(self, spec, prefix):
ldflags.append((lapack + blas).search_flags) ldflags.append((lapack + blas).search_flags)
libs.extend([str(x) for x in (fftw.libs, lapack, blas)]) libs.extend([str(x) for x in (fftw.libs, lapack, blas)])
if self.spec.satisfies("platform=darwin"): if spec.satisfies("platform=darwin"):
cppflags.extend(["-D__NO_STATM_ACCESS"]) cppflags.extend(["-D__NO_STATM_ACCESS"])
if spec["blas"].name in ("intel-mkl", "intel-parallel-studio", "intel-oneapi-mkl"): if spec["blas"].name in ("intel-mkl", "intel-parallel-studio", "intel-oneapi-mkl"):
@ -549,7 +501,7 @@ def edit(self, spec, prefix):
# while intel-mkl has a mpi variant and adds the scalapack # while intel-mkl has a mpi variant and adds the scalapack
# libs to its libs, intel-oneapi-mkl does not. # libs to its libs, intel-oneapi-mkl does not.
if spec["scalapack"].name == "intel-oneapi-mkl": if spec["scalapack"].name == "intel-oneapi-mkl":
mpi_impl = "openmpi" if spec["mpi"] == "openmpi" else "intelmpi" mpi_impl = "openmpi" if spec["mpi"].name in ["openmpi", "hpcx-mpi"] else "intelmpi"
scalapack = [ scalapack = [
join_path( join_path(
spec["intel-oneapi-mkl"].libs.directories[0], "libmkl_scalapack_lp64.so" spec["intel-oneapi-mkl"].libs.directories[0], "libmkl_scalapack_lp64.so"
@ -565,7 +517,7 @@ def edit(self, spec, prefix):
libs.extend(scalapack) libs.extend(scalapack)
libs.extend(mpi) libs.extend(mpi)
libs.extend(self.compiler.stdcxx_libs) libs.extend(pkg.compiler.stdcxx_libs)
if "+mpi_f08" in spec: if "+mpi_f08" in spec:
cppflags.append("-D__MPI_F08") cppflags.append("-D__MPI_F08")
@ -675,18 +627,6 @@ def edit(self, spec, prefix):
fcflags += ["-I{0}".format(sirius.prefix.include.sirius)] fcflags += ["-I{0}".format(sirius.prefix.include.sirius)]
libs += list(sirius.libs) libs += list(sirius.libs)
gpu_map = {
"35": "K40",
"37": "K80",
"60": "P100",
"70": "V100",
"80": "A100",
"gfx906": "Mi50",
"gfx908": "Mi100",
"gfx90a": "Mi250",
"gfx90a:xnack-": "Mi250",
"gfx90a:xnack+": "Mi250",
}
gpuver = "" gpuver = ""
if spec.satisfies("+cuda"): if spec.satisfies("+cuda"):
libs += [ libs += [
@ -730,7 +670,7 @@ def edit(self, spec, prefix):
libs += ["-lcufft", "-lcublas"] libs += ["-lcufft", "-lcublas"]
cuda_arch = spec.variants["cuda_arch"].value[0] cuda_arch = spec.variants["cuda_arch"].value[0]
gpuver = gpu_map[cuda_arch] gpuver = GPU_MAP[cuda_arch]
if cuda_arch == "35" and spec.satisfies("+cuda_arch_35_k20x"): if cuda_arch == "35" and spec.satisfies("+cuda_arch_35_k20x"):
gpuver = "K20X" gpuver = "K20X"
@ -748,7 +688,7 @@ def edit(self, spec, prefix):
acc_flags_var = "NVFLAGS" acc_flags_var = "NVFLAGS"
cppflags += ["-D__ACC"] cppflags += ["-D__ACC"]
cppflags += ["-D__DBCSR_ACC"] cppflags += ["-D__DBCSR_ACC"]
gpuver = gpu_map[spec.variants["amdgpu_target"].value[0]] gpuver = GPU_MAP[spec.variants["amdgpu_target"].value[0]]
if "smm=libsmm" in spec: if "smm=libsmm" in spec:
lib_dir = join_path("lib", self.makefile_architecture, self.makefile_version) lib_dir = join_path("lib", self.makefile_architecture, self.makefile_version)
@ -807,7 +747,7 @@ def edit(self, spec, prefix):
) )
if "%intel" in spec: if "%intel" in spec:
intel_bin_dir = ancestor(self.compiler.cc) intel_bin_dir = ancestor(pkg.compiler.cc)
# CPP is a commented command in Intel arch of CP2K # CPP is a commented command in Intel arch of CP2K
# This is the hack through which cp2k developers avoid doing : # This is the hack through which cp2k developers avoid doing :
# #
@ -847,11 +787,34 @@ def fflags(var, lst):
mkf.write("# CP2K-specific flags\n\n") mkf.write("# CP2K-specific flags\n\n")
mkf.write("GPUVER = {0}\n".format(gpuver)) mkf.write("GPUVER = {0}\n".format(gpuver))
mkf.write("DATA_DIR = {0}\n".format(self.prefix.share.data)) mkf.write("DATA_DIR = {0}\n".format(prefix.share.data))
def build(self, pkg, spec, prefix):
if "+cuda" in spec and len(spec.variants["cuda_arch"].value) > 1:
raise InstallError("cp2k supports only one cuda_arch at a time")
# Apparently the Makefile bases its paths on PWD
# so we need to set PWD = self.build_directory
with spack.util.environment.set_env(PWD=self.build_directory):
super().build(pkg, spec, prefix)
with working_dir(self.build_directory):
make("libcp2k", *self.build_targets)
def install(self, pkg, spec, prefix):
exe_dir = join_path("exe", self.makefile_architecture)
lib_dir = join_path("lib", self.makefile_architecture, self.makefile_version)
install_tree(exe_dir, self.prefix.bin)
install_tree("data", self.prefix.share.data)
install_tree(lib_dir, self.prefix.lib)
mkdirp(self.prefix.include)
install("src/start/libcp2k.h", join_path(self.prefix.include, "libcp2k.h"))
@property @property
def build_directory(self): def build_directory(self):
build_dir = self.stage.source_path build_dir = self.pkg.stage.source_path
if self.spec.satisfies("@:6"): if self.spec.satisfies("@:6"):
# prior to version 7.1 was the Makefile located in makefiles/ # prior to version 7.1 was the Makefile located in makefiles/
@ -866,30 +829,36 @@ def build_targets(self):
"VERSION={0}".format(self.makefile_version), "VERSION={0}".format(self.makefile_version),
] ]
def build(self, spec, prefix): @property
if "+cuda" in spec and len(spec.variants["cuda_arch"].value) > 1: def makefile(self):
raise InstallError("cp2k supports only one cuda_arch at a time") makefile_basename = ".".join([self.makefile_architecture, self.makefile_version])
return join_path("arch", makefile_basename)
# Apparently the Makefile bases its paths on PWD @property
# so we need to set PWD = self.build_directory def makefile_architecture(self):
with spack.util.environment.set_env(PWD=self.build_directory): return "{0.architecture}-{0.compiler.name}".format(self.spec)
super().build(spec, prefix)
@property
def makefile_version(self):
return "{prefix}{suffix}".format(
prefix="p" if "+mpi" in self.spec else "s",
suffix="smp" if "+openmp" in self.spec else "opt",
)
@property
def archive_files(self):
return [join_path(self.pkg.stage.source_path, self.makefile)]
def check(self):
data_dir = join_path(self.pkg.stage.source_path, "data")
# CP2K < 7 still uses $PWD to detect the current working dir
# and Makefile is in a subdir, account for both facts here:
with spack.util.environment.set_env(CP2K_DATA_DIR=data_dir, PWD=self.build_directory):
with working_dir(self.build_directory): with working_dir(self.build_directory):
make("libcp2k", *self.build_targets) make("test", *self.build_targets)
def install(self, spec, prefix): @run_after("install", when="@9.1:")
exe_dir = join_path("exe", self.makefile_architecture)
lib_dir = join_path("lib", self.makefile_architecture, self.makefile_version)
install_tree(exe_dir, self.prefix.bin)
install_tree("data", self.prefix.share.data)
install_tree(lib_dir, self.prefix.lib)
mkdirp(self.prefix.include)
install("src/start/libcp2k.h", join_path(self.prefix.include, "libcp2k.h"))
@run_after("install")
def fix_package_config(self): def fix_package_config(self):
""" """
Default build procedure generates libcp2k.pc with invalid paths, Default build procedure generates libcp2k.pc with invalid paths,
@ -903,7 +872,6 @@ def fix_package_config(self):
In case such approach causes issues in the future, it might be necessary In case such approach causes issues in the future, it might be necessary
to generate and override entire libcp2k.pc. to generate and override entire libcp2k.pc.
""" """
if self.spec.satisfies("@9.1:"):
pkgconfig_file = join_path(self.prefix.lib.pkgconfig, "libcp2k.pc") pkgconfig_file = join_path(self.prefix.lib.pkgconfig, "libcp2k.pc")
filter_file(r"(^includedir=).*", r"\1{0}".format(self.prefix.include), pkgconfig_file) filter_file(r"(^includedir=).*", r"\1{0}".format(self.prefix.include), pkgconfig_file)
filter_file(r"(^libdir=).*", r"\1{0}".format(self.prefix.lib), pkgconfig_file) filter_file(r"(^libdir=).*", r"\1{0}".format(self.prefix.lib), pkgconfig_file)
@ -923,41 +891,17 @@ def fix_package_config(self):
handle.seek(0) handle.seek(0)
handle.write(content) handle.write(content)
def check(self):
data_dir = join_path(self.stage.source_path, "data")
# CP2K < 7 still uses $PWD to detect the current working dir
# and Makefile is in a subdir, account for both facts here:
with spack.util.environment.set_env(CP2K_DATA_DIR=data_dir, PWD=self.build_directory):
with working_dir(self.build_directory):
make("test", *self.build_targets)
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
"""Use the new CMake build system to build CP2K."""
class CMakeBuilder(cmake.CMakeBuilder):
def cmake_args(self): def cmake_args(self):
spec = self.spec spec = self.spec
args = [] args = []
gpu_map = {
"35": "K40",
"37": "K80",
"60": "P100",
"70": "V100",
"80": "A100",
"gfx906": "Mi50",
"gfx908": "Mi100",
"gfx90a": "Mi250",
"gfx90a:xnack-": "Mi250",
"gfx90a:xnack+": "Mi250",
}
if "+cuda" in spec: if "+cuda" in spec:
if (len(spec.variants["cuda_arch"].value) > 1) or spec.satisfies("cuda_arch=none"): if (len(spec.variants["cuda_arch"].value) > 1) or spec.satisfies("cuda_arch=none"):
raise InstallError("CP2K supports only one cuda_arch at a time.") raise InstallError("CP2K supports only one cuda_arch at a time.")
else: else:
gpu_ver = gpu_map[spec.variants["cuda_arch"].value[0]] gpu_ver = GPU_MAP[spec.variants["cuda_arch"].value[0]]
args += [ args += [
self.define("CP2K_USE_ACCEL", "CUDA"), self.define("CP2K_USE_ACCEL", "CUDA"),
self.define("CP2K_WITH_GPU", gpu_ver), self.define("CP2K_WITH_GPU", gpu_ver),
@ -967,7 +911,7 @@ def cmake_args(self):
if len(spec.variants["amdgpu_target"].value) > 1: if len(spec.variants["amdgpu_target"].value) > 1:
raise InstallError("CP2K supports only one amdgpu_target at a time.") raise InstallError("CP2K supports only one amdgpu_target at a time.")
else: else:
gpu_ver = gpu_map[spec.variants["amdgpu_target"].value[0]] gpu_ver = GPU_MAP[spec.variants["amdgpu_target"].value[0]]
args += [ args += [
self.define("CP2K_USE_ACCEL", "HIP"), self.define("CP2K_USE_ACCEL", "HIP"),
self.define("CP2K_WITH_GPU", gpu_ver), self.define("CP2K_WITH_GPU", gpu_ver),
@ -1044,5 +988,3 @@ def cmake_args(self):
) )
return args return args
pass

View File

@ -272,6 +272,8 @@ class Gromacs(CMakePackage, CudaPackage):
depends_on("cmake@3.16.3:3", type="build", when="@2022:") depends_on("cmake@3.16.3:3", type="build", when="@2022:")
depends_on("cmake@3.18.4:3", type="build", when="@main") depends_on("cmake@3.18.4:3", type="build", when="@main")
depends_on("cmake@3.16.0:3", type="build", when="%fj") depends_on("cmake@3.16.0:3", type="build", when="%fj")
depends_on("pkgconfig", type="build")
depends_on("cuda", when="+cuda") depends_on("cuda", when="+cuda")
depends_on("sycl", when="+sycl") depends_on("sycl", when="+sycl")
depends_on("lapack") depends_on("lapack")