Skip to content

Commit

Permalink
Update cp2k recipe to use cmake or the current build system (spack#35718
Browse files Browse the repository at this point in the history
)

* Update cp2k recipe to use cmake or the current build system

Offers the possibility to build cp2k with the new cmake build system. commands like this are now supported

spack install cp2k@master build_system=cmake +.....

the recipe supports the following optional functionalities

- superlu, cosma, sirius, spglib, metis, spglib, libxc, libint, cuda/rocm, mkl/openblas/sci (and others), mpi, openmp, dbcsr
- dbcsr is built separately using the currently available recipe.

Two PRs need to be merged to be fully functional (cosma update in spack + one PR in cp2k github).

* Fix indentation

* Fix indentation

* Update libvori

* More typos

* Simplify BLAS/LAPACK

* Simplify BLAS/LAPACK

* Add A100 gpu value

* Fix typo

* Add the enable_regtests option

if -DCP2K_ENABLE_REGTESTS=ON (+enable_regtests with spack) then the location of the binary executables will be in the cp2k root directory under exe/build-cmake-*. This option is needed to run the regtests afterwards.

* Minor update

* more fixes

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Mikael Simberg <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Mikael Simberg <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Mikael Simberg <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Mikael Simberg <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Mikael Simberg <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Mikael Simberg <[email protected]>

* small changes

* Remove any reference to nvidia architecture in the rocm list

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Alberto Invernizzi <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Alberto Invernizzi <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Alberto Invernizzi <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Alberto Invernizzi <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Alberto Invernizzi <[email protected]>

* Update var/spack/repos/builtin/packages/cp2k/package.py

Co-authored-by: Alberto Invernizzi <[email protected]>

* Final reformating

* Update py-fypp

---------

Co-authored-by: Mikael Simberg <[email protected]>
Co-authored-by: Alberto Invernizzi <[email protected]>
  • Loading branch information
3 people authored Jul 10, 2023
1 parent 0ed6ff3 commit 64c6d63
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 28 deletions.
237 changes: 210 additions & 27 deletions var/spack/repos/builtin/packages/cp2k/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,33 @@
import copy
import os
import os.path
import sys

import spack.platforms
import spack.util.environment
import spack.util.executable
from spack.build_environment import dso_suffix
from spack.package import *


class Cp2k(MakefilePackage, CudaPackage):
class Cp2k(MakefilePackage, CudaPackage, CMakePackage, ROCmPackage):
"""CP2K is a quantum chemistry and solid state physics software package
that can perform atomistic simulations of solid state, liquid, molecular,
periodic, material, crystal, and biological systems
"""

build_system(
conditional("cmake", when="@master:"),
conditional("makefile", when="@:2023.1"),
default="makefile",
)

homepage = "https://www.cp2k.org"
url = "https://github.com/cp2k/cp2k/releases/download/v3.0.0/cp2k-3.0.tar.bz2"
git = "https://github.com/cp2k/cp2k.git"
list_url = "https://github.com/cp2k/cp2k/releases"

maintainers("dev-zero")
maintainers("dev-zero", "mtaillefumier")

version("2023.1", sha256="dff343b4a80c3a79363b805429bdb3320d3e1db48e0ff7d20a3dfd1c946a51ce")
version("2022.2", sha256="1a473dea512fe264bb45419f83de432d441f90404f829d89cbc3a03f723b8354")
Expand Down Expand Up @@ -52,7 +62,7 @@ class Cp2k(MakefilePackage, CudaPackage):
variant(
"pexsi",
default=False,
description=("Enable the alternative PEXSI method" "for density matrix evaluation"),
description="Enable the alternative PEXSI method for density matrix evaluation",
)
variant(
"elpa",
Expand All @@ -63,15 +73,31 @@ class Cp2k(MakefilePackage, CudaPackage):
variant(
"sirius",
default=False,
description=("Enable planewave electronic structure" " calculations via SIRIUS"),
description="Enable planewave electronic structure calculations via SIRIUS",
)
variant("cosma", default=False, description="Use COSMA for p?gemm")
variant(
"libvori",
default=False,
description=("Enable support for Voronoi integration" " and BQB compression"),
description="Enable support for Voronoi integration and BQB compression",
)
variant("spglib", default=False, description="Enable support for spglib")
variant(
"spla",
default=False,
description="Use SPLA off-loading functionality. Only relevant when CUDA or ROCM"
" are enabled",
)
variant("pytorch", default=False, description="Enable libtorch support")
variant("quip", default=False, description="Enable quip support")

variant(
"enable_regtests",
default=False,
description="Configure cp2k to run the regtests afterwards."
" It build cp2k normally but put the executables in exe/cmake-build-* instead of the"
" conventional location. This option is only relevant when regtests need to be run.",
)

with when("+cuda"):
variant(
Expand Down Expand Up @@ -147,13 +173,13 @@ class Cp2k(MakefilePackage, CudaPackage):
)

with when("+libxc"):
depends_on("pkgconfig", type="build", when="@7.0:")
depends_on("[email protected]:3", when="@:5", type="build")
depends_on("[email protected]:4", when="@6.0:6.9", type="build")
depends_on("pkgconfig", when="@7.0:")
depends_on("[email protected]:3", when="@:5")
depends_on("[email protected]:4", when="@6.0:6.9")
depends_on("[email protected]:4", when="@7.0:8.1")
depends_on("[email protected]:5.1", when="@8.2:8")
depends_on("[email protected]:5.1", when="@9:2022")
depends_on("libxc@6:6.1", when="@2023:")
depends_on("[email protected]:5.1", when="@9:2022.2")
depends_on("libxc@6.1:", when="@2023.1:")

with when("+mpi"):
depends_on("mpi@2:")
Expand All @@ -163,6 +189,7 @@ class Cp2k(MakefilePackage, CudaPackage):
with when("+cosma"):
depends_on("cosma+scalapack")
depends_on("[email protected]:", when="@9:")
depends_on("[email protected]:", when="@master:")
depends_on("cosma+cuda", when="+cuda")
conflicts("~mpi")
# COSMA support was introduced in 8+
Expand Down Expand Up @@ -198,27 +225,36 @@ class Cp2k(MakefilePackage, CudaPackage):
depends_on("[email protected]:7.0", when="@8:8.2")
depends_on("[email protected]", when="@8.3:8.9")
depends_on("[email protected]:", when="@9.1")
conflicts("~mpi")
depends_on("[email protected]:", when="@master")
conflicts("~mpi", msg="SIRIUS requires MPI")
# sirius support was introduced in 7+
conflicts("@:6")

with when("+libvori"):
depends_on("libvori@201219:", when="@8.1", type="build")
depends_on("libvori@210412:", when="@8.2:", type="build")
depends_on("libvori@201219:", when="@8.1")
depends_on("libvori@210412:", when="@8.2:")
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+)
# which is written using Python 3
depends_on("py-numpy", when="@7:+cuda", type="build")
depends_on("[email protected]:", when="@7:+cuda", type="build")
depends_on("py-numpy", when="@7:+cuda")
depends_on("[email protected]:", when="@7:+cuda")
depends_on("py-fypp")

depends_on("spglib", when="+spglib")

# Apparently [email protected] needs an "experimental" version of libwannier.a
# which is only available contacting the developer directly. See INSTALL
# in the stage of [email protected]
depends_on("wannier90", when="@3.0+mpi", type="build")
depends_on("wannier90", when="@3.0+mpi")

with when("build_system=cmake"):
depends_on("dbcsr")
depends_on("dbcsr+openmp", when="+openmp")
depends_on("dbcsr+cuda", when="+cuda")
depends_on("dbcsr+rocm", when="+rocm")

# CP2K needs compiler specific compilation flags, e.g. optflags
conflicts("%apple-clang")
Expand All @@ -231,14 +267,37 @@ class Cp2k(MakefilePackage, CudaPackage):
# for optimal kernels. Note that we don't override the cuda_archs property
# from the parent class, since the parent class defines constraints for all
# versions. Instead just mark all unsupported cuda archs as conflicting.
dbcsr_cuda_archs = ("35", "37", "60", "70")
cuda_msg = "cp2k only supports cuda_arch {0}".format(dbcsr_cuda_archs)

for arch in CudaPackage.cuda_arch_values:
if arch not in dbcsr_cuda_archs:
conflicts("+cuda", when="cuda_arch={0}".format(arch), msg=cuda_msg)
supported_cuda_arch_list = ("35", "37", "60", "70", "80")
supported_rocm_arch_list = ("gfx906", "gfx908", "gfx90a", "gfx90a:xnack-", "gfx90a:xnack+")
gpu_map = {
"35": "K40",
"37": "K80",
"60": "P100",
"70": "V100",
"80": "A100",
"gfx906": "Mi50",
"gfx908": "Mi100",
"gfx90a": "Mi250",
"gfx90a:xnack-": "Mi250",
"gfx90a:xnack+": "Mi250",
}
cuda_msg = "cp2k only supports cuda_arch {0}".format(supported_cuda_arch_list)
rocm_msg = "cp2k only supports amdgpu_target {0}".format(supported_rocm_arch_list)

conflicts("+cuda", when="cuda_arch=none")

# ROCm already emits an error if +rocm amdgpu_target=none is given

conflicts("+cuda", when="cuda_arch=none", msg=cuda_msg)
with when("+cuda"):
for arch in CudaPackage.cuda_arch_values:
if arch not in supported_cuda_arch_list:
conflicts("+cuda", when="cuda_arch={0}".format(arch), msg=cuda_msg)

with when("+rocm"):
for arch in ROCmPackage.amdgpu_targets:
if arch not in supported_rocm_arch_list:
conflicts("+rocm", when="amdgpu_target={0}".format(arch), msg=rocm_msg)

# Fix 2- and 3-center integral calls to libint
patch(
Expand Down Expand Up @@ -311,7 +370,6 @@ def edit(self, spec, prefix):
nvflags = ["-O3"]
ldflags = []
libs = []
gpuver = ""

# CP2K Makefile doesn't set C standard, but the source code uses
# C99-style for-loops with inline definition of iterating variable.
Expand Down Expand Up @@ -534,6 +592,7 @@ def edit(self, spec, prefix):
fcflags += ["-I{0}".format(sirius.prefix.include.sirius)]
libs += list(sirius.libs)

gpuver = ""
if spec.satisfies("+cuda"):
libs += [
"-L{}".format(spec["cuda"].libs.directories[0]),
Expand Down Expand Up @@ -576,11 +635,25 @@ def edit(self, spec, prefix):
libs += ["-lcufft", "-lcublas"]

cuda_arch = spec.variants["cuda_arch"].value[0]
if cuda_arch:
gpuver = {"35": "K40", "37": "K80", "60": "P100", "70": "V100"}[cuda_arch]
gpuver = gpu_map[cuda_arch]
if cuda_arch == "35" and spec.satisfies("+cuda_arch_35_k20x"):
gpuver = "K20X"

if cuda_arch == "35" and spec.satisfies("+cuda_arch_35_k20x"):
gpuver = "K20X"
if "@2022: +rocm" in spec:
libs += [
"-L{}".format(spec["rocm"].libs.directories[0]),
"-L{}/stubs".format(spec["rocm"].libs.directories[0]),
"-lhipblas",
"-lhipfft",
"-lstdc++",
]

cppflags += ["-D__OFFLOAD_HIP"]
acc_compiler_var = "hipcc"
acc_flags_var = "NVFLAGS"
cppflags += ["-D__ACC"]
cppflags += ["-D__DBCSR_ACC"]
gpuver = gpu_map[spec.variants["amdgpu_target"].value[0]]

if "smm=libsmm" in spec:
lib_dir = join_path("lib", self.makefile_architecture, self.makefile_version)
Expand Down Expand Up @@ -763,3 +836,113 @@ def check(self):
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. It is the default when
building the master branch of cp2k."""

def cmake_args(self):
spec = self.spec
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 (len(spec.variants["cuda_arch"].value) > 1) or spec.satisfies("cuda_arch=none"):
raise InstallError("CP2K supports only one cuda_arch at a time.")
else:
gpu_ver = gpu_map[spec.variants["cuda_arch"].value[0]]
args += ["-DCP2K_USE_ACCEL=CUDA"]
args += [self.define("CP2K_WITH_GPU", gpu_ver)]

if "+rocm" in spec:
if len(spec.variants["amdgpu_target"].value) > 1:
raise InstallError("CP2K supports only one amdgpu_target at a time.")
else:
gpu_ver = gpu_map[spec.variants["amdgpu_target"].value[0]]
args += ["-DCP2K_USE_ACCEL=HIP"]
args += [self.define("CP2K_WITH_GPU", gpu_ver)]

args += [
self.define_from_variant("CP2K_ENABLE_REGTESTS", "enable_regtests"),
self.define_from_variant("CP2K_USE_ELPA", "elpa"),
self.define_from_variant("CP2K_USE_LIBINT2", "libint"),
self.define_from_variant("CP2K_USE_SIRIUS", "sirius"),
self.define_from_variant("CP2K_USE_SPLA", "spla"),
self.define_from_variant("CP2K_USE_COSMA", "cosma"),
self.define_from_variant("CP2K_USE_LIBXC", "libxc"),
self.define_from_variant("CP2K_USE_LIBTORCH", "pytorch"),
self.define_from_variant("CP2K_USE_METIS", "pexsi"),
self.define_from_variant("CP2K_USE_SUPERLU", "pexsi"),
self.define_from_variant("CP2K_USE_PLUMED", "plumed"),
self.define_from_variant("CP2K_USE_SPGLIB", "spglib"),
self.define_from_variant("CP2K_USE_VORI", "libvori"),
self.define_from_variant("CP2K_USE_SPLA", "spla"),
self.define_from_variant("CP2K_USE_QUIP", "quip"),
]

# we force the use elpa openmp threading support. might need to be revisited though
args += [
self.define(
"CP2K_ENABLE_ELPA_OPENMP_SUPPORT",
("+elpa +openmp" in spec) or ("^elpa +openmp" in spec),
)
]

if "spla" in spec and (spec.satisfies("+cuda") or spec.satisfies("+rocm")):
args += ["-DCP2K_USE_SPLA_GEMM_OFFLOADING=ON"]

args += ["-DCP2K_USE_FFTW3=ON"]

if spec.satisfies("smm=libxsmm"):
args += ["-DCP2K_USE_LIBXSMM=ON"]
else:
args += ["-DCP2K_USE_LIBXSMM=OFF"]

lapack = spec["lapack"]
blas = spec["blas"]

if blas.name in ["intel-mkl", "intel-parallel-studio", "intel-oneapi-mkl"]:
args += ["-DCP2K_BLAS_VENDOR=MKL"]
if sys.platform == "darwin":
args += [
self.define("CP2K_BLAS_VENDOR", "CUSTOM"),
self.define("CP2K_SCALAPACK_VENDOR", "GENERIC"),
self.define(
"CP2K_SCALAPACK_LINK_LIBRARIES", spec["scalapack"].libs.joined(";")
),
]
else:
args += ["-DCP2K_SCALAPACK_VENDOR=MKL"]
else:
args.extend(
[
self.define("CP2K_LAPACK_FOUND", True),
self.define("CP2K_LAPACK_LINK_LIBRARIES", lapack.libs.joined(";")),
self.define("CP2K_BLAS_FOUND", True),
self.define("CP2K_BLAS_LINK_LIBRARIES", blas.libs.joined(";")),
self.define("CP2K_SCALAPACK_FOUND", True),
self.define("CP2K_SCALAPACK_INCLUDE_DIRS", spec["scalapack"].prefix.include),
self.define("CP2K_BLAS_VENDOR", "CUSTOM"),
self.define("CP2K_SCALAPACK_VENDOR", "GENERIC"),
self.define(
"CP2K_SCALAPACK_LINK_LIBRARIES", spec["scalapack"].libs.joined(";")
),
]
)

return args

pass
2 changes: 1 addition & 1 deletion var/spack/repos/builtin/packages/libvori/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Libvori(CMakePackage):
homepage = "https://brehm-research.de/voronoi.php"
url = "https://www.cp2k.org/static/downloads/libvori-201217.tar.gz"

maintainers("dev-zero")
maintainers("dev-zero", "mtaillefumier")

version("220621", sha256="1cfa98c564814bddacf1c0e7f11582137d758668f6307e6eb392c72317984c14")
version("210412", sha256="331886aea9d093d8c44b95a07fab13d47f101b1f94a0640d7d670eb722bf90ac")
Expand Down
1 change: 1 addition & 0 deletions var/spack/repos/builtin/packages/py-fypp/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class PyFypp(PythonPackage):
homepage = "https://github.com/aradi/fypp"
url = "https://github.com/aradi/fypp/archive/2.1.1.zip"

version("3.1", sha256="bac9d02be308b6bff7fd17da835f01fb9ce9b2dddaaad1ccd22ac7628b2dc53c")
version("2.1.1", sha256="3744ad17045e91466bbb75a33ce0cab0f65bc2c377127067a932cdf15655e049")

depends_on("py-setuptools", type="build")

0 comments on commit 64c6d63

Please sign in to comment.