spack/var/spack/repos/builtin/packages/gromacs/package.py
Mark Abraham cf163eecc5
gromacs: fix newly added variant (#41178)
In practice, one can only compiler for the Intel Data Center Max GPU
via a SYCL build and the oneAPI compiler. This is unlikely to change,
so we can be explicit about that.
2023-11-20 19:49:34 -07:00

687 lines
31 KiB
Python

# Copyright 2013-2023 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import llnl.util.filesystem as fs
from spack.package import *
class Gromacs(CMakePackage, CudaPackage):
"""GROMACS is a molecular dynamics package primarily designed for simulations
of proteins, lipids and nucleic acids. It was originally developed in
the Biophysical Chemistry department of University of Groningen, and is now
maintained by contributors in universities and research centers across the world.
GROMACS is one of the fastest and most popular software packages
available and can run on CPUs as well as GPUs. It is free, open source
released under the GNU Lesser General Public License. Before the version 4.6,
GROMACS was released under the GNU General Public License.
"""
homepage = "https://www.gromacs.org"
url = "https://ftp.gromacs.org/gromacs/gromacs-2022.2.tar.gz"
list_url = "https://ftp.gromacs.org/gromacs"
git = "https://gitlab.com/gromacs/gromacs.git"
maintainers("danielahlin", "eirrgang", "junghans")
version("main", branch="main")
version("master", branch="main", deprecated=True)
version("2023.3", sha256="4ec8f8d0c7af76b13f8fd16db8e2c120e749de439ae9554d9f653f812d78d1cb")
version("2023.2", sha256="bce1480727e4b2bb900413b75d99a3266f3507877da4f5b2d491df798f9fcdae")
version("2023.1", sha256="eef2bb4a6cb6314cf9da47f26df2a0d27af4bf7b3099723d43601073ab0a42f4")
version("2023", sha256="ac92c6da72fbbcca414fd8a8d979e56ecf17c4c1cdabed2da5cfb4e7277b7ba8")
version("2022.6", sha256="75d277138475679dd3e334e384a71516570cde767310476687f2a5b72333ea41")
version("2022.5", sha256="083cc3c424bb93ffe86c12f952e3e5b4e6c9f6520de5338761f24b75e018c223")
version("2022.4", sha256="c511be602ff29402065b50906841def98752639b92a95f1b0a1060d9b5e27297")
version("2022.3", sha256="14cfb130ddaf8f759a3af643c04f5a0d0d32b09bc3448b16afa5b617f5e35dae")
version("2022.2", sha256="656404f884d2fa2244c97d2a5b92af148d0dbea94ad13004724b3fcbf45e01bf")
version("2022.1", sha256="85ddab5197d79524a702c4959c2c43be875e0fc471df3a35224939dce8512450")
version("2022", sha256="fad60d606c02e6164018692c6c9f2c159a9130c2bf32e8c5f4f1b6ba2dda2b68")
version("2021.7", sha256="4db7bbbfe5424de48373686ec0e8c5bfa7175d5cd74290ef1c1e840e6df67f06")
version("2021.6", sha256="52df2c1d7586fd028d9397985c68bd6dd26e6e905ead382b7e6c473d087902c3")
version("2021.5", sha256="eba63fe6106812f72711ef7f76447b12dd1ee6c81b3d8d4d0e3098cd9ea009b6")
version("2021.4", sha256="cb708a3e3e83abef5ba475fdb62ef8d42ce8868d68f52dafdb6702dc9742ba1d")
version("2021.3", sha256="e109856ec444768dfbde41f3059e3123abdb8fe56ca33b1a83f31ed4575a1cc6")
version("2021.2", sha256="d940d865ea91e78318043e71f229ce80d32b0dc578d64ee5aa2b1a4be801aadb")
version("2021.1", sha256="bc1d0a75c134e1fb003202262fe10d3d32c59bbb40d714bc3e5015c71effe1e5")
version("2021", sha256="efa78ab8409b0f5bf0fbca174fb8fbcf012815326b5c71a9d7c385cde9a8f87b")
version("2020.7", sha256="744158d8f61b0d36ffe89ec934519b7e0981a7af438897740160da648d36c2f0")
version("2020.6", sha256="d8bbe57ed3c9925a8cb99ecfe39e217f930bed47d5268a9e42b33da544bdb2ee")
version("2020.5", sha256="7b6aff647f7c8ee1bf12204d02cef7c55f44402a73195bd5f42cf11850616478")
version("2020.4", sha256="5519690321b5500c7951aaf53ff624042c3edd1a5f5d6dd1f2d802a3ecdbf4e6")
version("2020.3", sha256="903183691132db14e55b011305db4b6f4901cc4912d2c56c131edfef18cc92a9")
version("2020.2", sha256="7465e4cd616359d84489d919ec9e4b1aaf51f0a4296e693c249e83411b7bd2f3")
version("2020.1", sha256="e1666558831a3951c02b81000842223698016922806a8ce152e8f616e29899cf")
version("2020", sha256="477e56142b3dcd9cb61b8f67b24a55760b04d1655e8684f979a75a5eec40ba01")
version("2019.6", sha256="bebe396dc0db11a9d4cc205abc13b50d88225617642508168a2195324f06a358")
version("2019.5", sha256="438061a4a2d45bbb5cf5c3aadd6c6df32d2d77ce8c715f1c8ffe56156994083a")
version("2019.4", sha256="ba4366eedfc8a1dbf6bddcef190be8cd75de53691133f305a7f9c296e5ca1867")
version("2019.3", sha256="4211a598bf3b7aca2b14ad991448947da9032566f13239b1a05a2d4824357573")
version("2019.2", sha256="bcbf5cc071926bc67baa5be6fb04f0986a2b107e1573e15fadcb7d7fc4fb9f7e")
version("2019.1", sha256="b2c37ed2fcd0e64c4efcabdc8ee581143986527192e6e647a197c76d9c4583ec")
version("2019", sha256="c5b281a5f0b5b4eeb1f4c7d4dc72f96985b566561ca28acc9c7c16f6ee110d0b")
version("2018.8", sha256="776923415df4bc78869d7f387c834141fdcda930b2e75be979dc59ecfa6ebecf")
version("2018.5", sha256="32261df6f7ec4149fc0508f9af416953d056e281590359838c1ed6644ba097b8")
version("2018.4", sha256="6f2ee458c730994a8549d6b4f601ecfc9432731462f8bd4ffa35d330d9aaa891")
version("2018.3", sha256="4423a49224972969c52af7b1f151579cea6ab52148d8d7cbae28c183520aa291")
version("2018.2", sha256="4bdde8120c510b6543afb4b18f82551fddb11851f7edbd814aa24022c5d37857")
version("2018.1", sha256="4d3533340499323fece83b4a2d4251fa856376f2426c541e00b8e6b4c0d705cd")
version("2018", sha256="deb5d0b749a52a0c6083367b5f50a99e08003208d81954fb49e7009e1b1fd0e9")
version("2016.6", sha256="bac0117d2cad21f9b94fe5b854fb9ae7435b098a6da4e732ee745f18e52473d7")
version("2016.5", sha256="57db26c6d9af84710a1e0c47a1f5bf63a22641456448dcd2eeb556ebd14e0b7c")
version("2016.4", sha256="4be9d3bfda0bdf3b5c53041e0b8344f7d22b75128759d9bfa9442fe65c289264")
version("2016.3", sha256="7bf00e74a9d38b7cef9356141d20e4ba9387289cbbfd4d11be479ef932d77d27")
version("5.1.5", sha256="c25266abf07690ecad16ed3996899b1d489cbb1ef733a1befb3b5c75c91a703e")
version("5.1.4", sha256="0f3793d8f1f0be747cf9ebb0b588fb2b2b5dc5acc32c3046a7bee2d2c03437bc")
version("5.1.2", sha256="39d6f1d7ae8ba38cea6089da40676bfa4049a49903d21551abc030992a58f304")
version("4.6.7", sha256="6afb1837e363192043de34b188ca3cf83db6bd189601f2001a1fc5b0b2a214d9")
version("4.5.5", sha256="e0605e4810b0d552a8761fef5540c545beeaf85893f4a6e21df9905a33f871ba")
variant(
"mpi", default=True, description="Activate MPI support (disable for Thread-MPI support)"
)
variant("shared", default=True, description="Enables the build of shared libraries")
variant(
"double",
default=False,
description="Produces a double precision version of the executables",
)
variant(
"cufftmp",
default=False,
when="@2022: +cuda+mpi",
description="Enable multi-GPU FFT support with cuFFTMp",
)
variant(
"heffte",
default=False,
when="@2021: +sycl+mpi",
description="Enable multi-GPU FFT support with HeFFTe",
)
variant("opencl", default=False, description="Enable OpenCL support")
variant("sycl", default=False, when="@2021:", description="Enable SYCL support")
variant(
"intel-data-center-gpu-max",
default=False,
when="@2022: +sycl",
description="Enable support for Intel Data Center GPU Max",
)
variant("nosuffix", default=False, description="Disable default suffixes")
variant(
"build_type",
default="Release",
description="The build type to build",
values=(
"Debug",
"Release",
"RelWithDebInfo",
"MinSizeRel",
"Reference",
"RelWithAssert",
"Profile",
),
)
variant(
"nblib",
default=True,
when="@2021:",
description="Build and install the NB-LIB C++ API for GROMACS",
)
variant(
"gmxapi",
default=True,
when="@2019:",
description="Build and install the gmxlib python API for GROMACS",
)
variant(
"mdrun_only",
default=False,
description="Enables the build of a cut-down version"
" of libgromacs and/or the mdrun program",
)
conflicts(
"+mdrun_only", when="@2021:", msg="mdrun-only build option was removed for GROMACS 2021."
)
variant("openmp", default=True, description="Enables OpenMP at configure time")
variant("openmp_max_threads", default="none", description="Max number of OpenMP threads")
conflicts(
"+openmp_max_threads", when="~openmp", msg="OpenMP is off but OpenMP Max threads is set"
)
variant(
"sve",
default=True,
description="Enable SVE on aarch64 if available",
when="target=neoverse_v1",
)
variant(
"sve", default=True, description="Enable SVE on aarch64 if available", when="target=a64fx"
)
variant(
"relaxed_double_precision",
default=False,
description="GMX_RELAXED_DOUBLE_PRECISION, use only for Fujitsu PRIMEHPC",
)
conflicts(
"+relaxed_double_precision",
when="@2021:",
msg="GMX_RELAXED_DOUBLE_PRECISION option removed for GROMACS 2021.",
)
variant("hwloc", default=True, description="Use the hwloc portable hardware locality library")
variant("cycle_subcounters", default=False, description="Enables cycle subcounters")
variant("cp2k", default=False, description="CP2K QM/MM interface integration")
conflicts(
"+cp2k", when="@:2021", msg="CP2K QM/MM support have been introduced in GROMACS 2022"
)
conflicts("+shared", when="+cp2k", msg="Enabling CP2K requires static build")
conflicts("%intel", when="@2022:", msg="GROMACS %intel support was removed in version 2022")
conflicts("%gcc@:8", when="@2023:", msg="GROMACS requires GCC 9 or later since version 2023")
conflicts(
"^intel-oneapi-mkl@:2021.2",
when="@2023:",
msg="GROMACS requires oneMKL 2021.3 or later since version 2023",
)
depends_on("mpi", when="+mpi")
# Plumed 2.9.0 needs Gromacs 2023, 2022.5, 2021.7, 2020.7
# Plumed 2.8.3 needs Gromacs 2022.5, 2021.7, 2020.7, 2019.6
# Plumed 2.8.2 needs Gromacs 2022.5, 2021.7, 2020.7, 2019.6
# Plumed 2.8.1 needs Gromacs 2022.3, 2021.6, 2020.7, 2019.6
# Plumed 2.8.0 needs Gromacs 2021.4, 2020.6, 2019.6
# Plumed 2.7.6 needs Gromacs 2021.5, 2020.6, 2019.6
# Plumed 2.7.5 needs Gromacs 2021.5, 2020.6, 2019.6
# Plumed 2.7.4 needs Gromacs 2021.4, 2020.6, 2019.6
# Plumed 2.7.3 needs Gromacs 2021.4, 2020.6, 2019.6
# Plumed 2.7.2 needs Gromacs 2021, 2020.6, 2019.6
# Plumed 2.7.1 needs Gromacs 2021, 2020.5, 2019.6
# Plumed 2.7.0 needs Gromacs 2020.4, 2019.6
# Plumed 2.6.6 needs Gromacs 2020.4, 2019.6, 2018.8
# Plumed 2.6.5 needs Gromacs 2020.4, 2019.6, 2018.8
# Plumed 2.6.4 needs Gromacs 2020.4, 2019.6, 2018.8
# Plumed 2.6.3 needs Gromacs 2020.4, 2019.6, 2018.8
# Plumed 2.6.2 needs Gromacs 2020.4, 2019.6, 2018.8
# Plumed 2.6.1 needs Gromacs 2020.2, 2019.6, 2018.8
# Plumed 2.6.0 needs Gromacs 2019.4, 2018.8
# Plumed 2.5.7 needs Gromacs 2019.4, 2018.8, 2016.6
# Plumed 2.5.6 needs Gromacs 2019.4, 2018.8, 2016.6
# Plumed 2.5.5 needs Gromacs 2019.4, 2018.8, 2016.6
# Plumed 2.5.4 needs Gromacs 2019.4, 2018.8, 2016.6
# Plumed 2.5.3 needs Gromacs 2019.4, 2018.8, 2016.6
# Plumed 2.5.2 needs Gromacs 2019.2, 2018.6, 2016.6
# Plumed 2.5.1 needs Gromacs 2018.6, 2016.6
# Plumed 2.5.0 needs Gromacs 2018.4, 2016.5
# Above dependencies can be verified, and new versions added, by going to
# https://github.com/plumed/plumed2/tree/v2.9.0/patches
# and switching tags.
plumed_patches = {
"2023": "2.9.0",
"2022.5": "2.8.2:2.9.0",
"2022.3": "2.8.1",
"2021.7": "2.8.2:2.9.0",
"2021.6": "2.8.1",
"2021.5": "2.7.5:2.7.6",
"2021.4": "2.7.3:2.8.0",
"2021": "2.7.1:2.7.2",
"2020.7": "2.8.1:2.9.0",
"2020.6": "2.7.2:2.8.0",
"2020.5": "2.7.1",
"2020.4": "2.6.2:2.7.0",
"2020.2": "2.6.1",
"2019.6": "2.6.1:2.8.3",
"2019.4": "2.5.3:2.6.0",
"2019.2": "2.5.2",
"2018.8": "2.5.3:2.6",
"2018.6": "2.5.1:2.5.2",
"2018.4": "2.5.0",
"2016.6": "2.5.1:2.5",
"2016.5": "2.5.0",
}
variant(
"plumed",
default=False,
description="Enable PLUMED support",
when="@{0}".format(",".join(plumed_patches.keys())),
)
with when("+plumed"):
depends_on("plumed+mpi", when="+mpi")
depends_on("plumed~mpi", when="~mpi")
for gmx_ver, plumed_vers in plumed_patches.items():
depends_on("plumed@{0}".format(plumed_vers), when="@{0}+plumed".format(gmx_ver))
variant(
"intel_provided_gcc",
default=False,
description="Use this if Intel compiler is installed through spack."
+ "The g++ location is written to icp{c,x}.cfg",
)
depends_on("fftw-api@3")
depends_on("cmake@2.8.8:3", type="build")
depends_on("cmake@3.4.3:3", type="build", when="@2018:")
depends_on("cmake@3.9.6:3", type="build", when="@2020")
depends_on("cmake@3.13.0:3", type="build", when="@2021")
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.16.0:3", type="build", when="%fj")
depends_on("cuda", when="+cuda")
depends_on("sycl", when="+sycl")
depends_on("lapack")
depends_on("blas")
depends_on("gcc", when="%oneapi ~intel_provided_gcc")
depends_on("gcc", when="%intel ~intel_provided_gcc")
depends_on("hwloc@1.0:1", when="+hwloc@2016:2018")
depends_on("hwloc", when="+hwloc@2019:")
depends_on("cp2k@8.1:", when="+cp2k")
depends_on("nvhpc", when="+cufftmp")
depends_on("heffte", when="+heffte")
requires(
"%intel",
"%oneapi",
policy="one_of",
when="+intel_provided_gcc",
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)
patch(
"https://gitlab.com/gromacs/gromacs/-/commit/10262892e11a87fda0f59e633c89ed5ab1100509.diff",
sha256="2c30d00404b76421c13866cc42afa5e63276f7926c862838751b158df8727b1b",
when="@2021.1:2021.2",
)
filter_compiler_wrappers(
"*.cmake", relative_root=os.path.join("share", "cmake", "gromacs_mpi")
)
filter_compiler_wrappers("*.cmake", relative_root=os.path.join("share", "cmake", "gromacs"))
def patch(self):
# Otherwise build fails with GCC 11 (11.2)
if self.spec.satisfies("@2018:2020.6"):
filter_file(
"#include <vector>",
"#include <vector>\n#include <limits>",
"src/gromacs/awh/biasparams.h",
)
if self.spec.satisfies("@2018:2018.8"):
filter_file(
"#include <vector>",
"#include <vector>\n#include <limits>",
"src/gromacs/mdlib/minimize.cpp",
)
if self.spec.satisfies("@2019:2019.6,2020:2020.6"):
filter_file(
"#include <vector>",
"#include <vector>\n#include <limits>",
"src/gromacs/mdrun/minimize.cpp",
)
if self.spec.satisfies("@2020:2020.6"):
filter_file(
"#include <queue>",
"#include <queue>\n#include <limits>",
"src/gromacs/modularsimulator/modularsimulator.h",
)
# Ref: https://gitlab.com/gromacs/gromacs/-/merge_requests/3504
if self.spec.satisfies("@2023"):
filter_file(
" if (std::filesystem::equivalent(searchPath, buildBinPath))",
" if (std::error_code c; std::filesystem::equivalent(searchPath,"
" buildBinPath, c))",
"src/gromacs/commandline/cmdlineprogramcontext.cpp",
string=True,
)
if "+plumed" in self.spec:
self.spec["plumed"].package.apply_patch(self)
if self.spec.satisfies("%nvhpc"):
# Disable obsolete workaround
filter_file("ifdef __PGI", "if 0", "src/gromacs/fileio/xdrf.h")
if "+cuda" in self.spec:
# Upstream supports building of last two major versions of Gromacs.
# Older versions of Gromacs need to be patched to build with more recent
# versions of CUDA library.
# Hardware version 3.0 is supported up to CUDA 10.2 (Gromacs 4.6-2020.3
# needs to be patched, 2020.4 is handling it correctly)
if self.spec.satisfies("@4.6:2020.3^cuda@11:"):
filter_file(
r"-gencode;arch=compute_30,code=sm_30;?", "", "cmake/gmxManageNvccConfig.cmake"
)
filter_file(
r"-gencode;arch=compute_30,code=compute_30;?",
"",
"cmake/gmxManageNvccConfig.cmake",
)
# Hardware version 2.0 is supported up to CUDA 8 (Gromacs 4.6-2016.3
# needs to be patched, 2016.4 is handling it correctly, removed in 2019)
if self.spec.satisfies("@4.6:2016.3^cuda@9:"):
filter_file(
r"-gencode;arch=compute_20,code=sm_20;?", "", "cmake/gmxManageNvccConfig.cmake"
)
filter_file(
r"-gencode;arch=compute_20,code=compute_20;?",
"",
"cmake/gmxManageNvccConfig.cmake",
)
if self.spec.satisfies("@4.6:5.0^cuda@9:"):
filter_file(
r"-gencode;arch=compute_20,code=sm_21;?", "", "cmake/gmxManageNvccConfig.cmake"
)
class CMakeBuilder(spack.build_systems.cmake.CMakeBuilder):
@run_after("build")
def build_test_binaries(self):
"""Build the test binaries.
GROMACS usually excludes tests from the default build target, but building
the tests during spack's ``check`` phase takes a long time while producing
no visible output, even with ``--verbose``.
Here, we make sure the test binaries are built during the build phase
(as would normally be expected when configured with BUILD_TESTING)
when the ``--test`` flag is used.
Note: the GMX_DEVELOPER_BUILD option disables the EXCLUDE_FROM_ALL on the
test binaries, but the option incurs additional side effects that may
not be intended with ``--test``.
"""
if self.pkg.run_tests:
with fs.working_dir(self.build_directory):
make("tests")
def check(self):
"""Run the ``check`` target (skipping the ``test`` target).
Override the standard CMakeBuilder behavior. GROMACS has both `test`
and `check` targets, but we are only interested in the latter.
"""
with fs.working_dir(self.build_directory):
if self.generator == "Unix Makefiles":
make("check")
elif self.generator == "Ninja":
ninja("check")
def cmake_args(self):
options = []
# Warning: Use `define_from_variant()` with caution.
# GROMACS may use unexpected conventions for CMake variable values.
# For example: variables that accept boolean values like "OFF"
# may actually be STRING type, and undefined variables may trigger
# different defaults for dependent options than explicitly defined variables.
# `-DGMX_VAR=OFF` may not have the same meaning as `-DGMX_VAR=`.
# In other words, the mapping between package variants and the
# GMX CMake variables is often non-trivial.
if "+mpi" in self.spec:
options.append("-DGMX_MPI:BOOL=ON")
if self.pkg.version < Version("2020"):
# Ensures gmxapi builds properly
options.extend(
[
"-DCMAKE_C_COMPILER=%s" % self.spec["mpi"].mpicc,
"-DCMAKE_CXX_COMPILER=%s" % self.spec["mpi"].mpicxx,
"-DCMAKE_Fortran_COMPILER=%s" % self.spec["mpi"].mpifc,
]
)
elif self.pkg.version == Version("2021"):
# Work around https://gitlab.com/gromacs/gromacs/-/issues/3896
# Ensures gmxapi builds properly
options.extend(
[
"-DCMAKE_C_COMPILER=%s" % self.spec["mpi"].mpicc,
"-DCMAKE_CXX_COMPILER=%s" % self.spec["mpi"].mpicxx,
]
)
else:
options.extend(
[
"-DCMAKE_C_COMPILER=%s" % spack_cc,
"-DCMAKE_CXX_COMPILER=%s" % spack_cxx,
"-DMPI_C_COMPILER=%s" % self.spec["mpi"].mpicc,
"-DMPI_CXX_COMPILER=%s" % self.spec["mpi"].mpicxx,
]
)
else:
options.extend(
[
"-DCMAKE_C_COMPILER=%s" % spack_cc,
"-DCMAKE_CXX_COMPILER=%s" % spack_cxx,
"-DGMX_MPI:BOOL=OFF",
"-DGMX_THREAD_MPI:BOOL=ON",
]
)
if self.spec.satisfies("%aocc"):
options.append("-DCMAKE_CXX_FLAGS=--stdlib=libc++")
if self.spec.satisfies("@2020:"):
options.append("-DGMX_INSTALL_LEGACY_API=ON")
if self.spec.satisfies("%oneapi") or self.spec.satisfies("%intel"):
# If intel-oneapi-compilers was installed through spack the gcc is added to the
# configuration file.
if self.spec.satisfies("+intel_provided_gcc") and os.path.exists(
".".join([os.environ["SPACK_CXX"], "cfg"])
):
with open(".".join([os.environ["SPACK_CXX"], "cfg"]), "r") as f:
options.append("-DCMAKE_CXX_FLAGS={}".format(f.read()))
else:
options.append("-DGMX_GPLUSPLUS_PATH=%s/g++" % self.spec["gcc"].prefix.bin)
if "+double" in self.spec:
options.append("-DGMX_DOUBLE:BOOL=ON")
if "+nosuffix" in self.spec:
options.append("-DGMX_DEFAULT_SUFFIX:BOOL=OFF")
if "~shared" in self.spec:
options.append("-DBUILD_SHARED_LIBS:BOOL=OFF")
options.append("-DGMXAPI:BOOL=OFF")
if "+hwloc" in self.spec:
options.append("-DGMX_HWLOC:BOOL=ON")
else:
options.append("-DGMX_HWLOC:BOOL=OFF")
if self.pkg.version >= Version("2021"):
if "+cuda" in self.spec:
options.append("-DGMX_GPU:STRING=CUDA")
elif "+opencl" in self.spec:
options.append("-DGMX_GPU:STRING=OpenCL")
elif "+sycl" in self.spec:
options.append("-DGMX_GPU:STRING=SYCL")
else:
options.append("-DGMX_GPU:STRING=OFF")
else:
if "+cuda" in self.spec or "+opencl" in self.spec:
options.append("-DGMX_GPU:BOOL=ON")
if "+opencl" in self.spec:
options.append("-DGMX_USE_OPENCL=ON")
else:
options.append("-DGMX_GPU:BOOL=OFF")
if "+cuda" in self.spec:
options.append("-DCUDA_TOOLKIT_ROOT_DIR:STRING=" + self.spec["cuda"].prefix)
options.append("-DGMX_EXTERNAL_LAPACK:BOOL=ON")
if self.spec["lapack"].libs:
options.append("-DGMX_LAPACK_USER={0}".format(self.spec["lapack"].libs.joined(";")))
options.append("-DGMX_EXTERNAL_BLAS:BOOL=ON")
if self.spec["blas"].libs:
options.append("-DGMX_BLAS_USER={0}".format(self.spec["blas"].libs.joined(";")))
if "+cp2k" in self.spec:
options.append("-DGMX_CP2K:BOOL=ON")
options.append("-DCP2K_DIR:STRING={0}".format(self.spec["cp2k"].prefix))
if "+cufftmp" in self.spec:
options.append("-DGMX_USE_CUFFTMP=ON")
options.append(
f'-DcuFFTMp_ROOT={self.spec["nvhpc"].prefix}/Linux_{self.spec.target.family}'
+ f'/{self.spec["nvhpc"].version}/math_libs'
)
if "+heffte" in self.spec:
options.append("-DGMX_USE_HEFFTE=on")
options.append(f'-DHeffte_ROOT={self.spec["heffte"].prefix}')
if "+intel-data-center-gpu-max" in self.spec:
options.append("-DGMX_GPU_NB_CLUSTER_SIZE=8")
options.append("-DGMX_GPU_NB_NUM_CLUSTER_PER_CELL_X=1")
if "~nblib" in self.spec:
options.append("-DGMX_INSTALL_NBLIB_API=OFF")
if "~gmxapi" in self.spec:
options.append("-DGMXAPI=OFF")
# Activate SIMD based on properties of the target
target = self.spec.target
if target >= "zen4":
# AMD Family 17h (EPYC Genoa)
options.append("-DGMX_SIMD=AVX_512")
elif target >= "zen2":
# AMD Family 17h (EPYC Rome)
options.append("-DGMX_SIMD=AVX2_256")
elif target >= "zen":
# AMD Family 17h (EPYC Naples)
options.append("-DGMX_SIMD=AVX2_128")
elif target >= "bulldozer":
# AMD Family 15h
options.append("-DGMX_SIMD=AVX_128_FMA")
elif "vsx" in target:
# IBM Power 7 and beyond
if self.spec.satisfies("%nvhpc"):
options.append("-DGMX_SIMD=None")
else:
options.append("-DGMX_SIMD=IBM_VSX")
elif target.family == "aarch64":
# ARMv8
if self.spec.satisfies("%nvhpc"):
options.append("-DGMX_SIMD=None")
elif "sve" in target.features and "+sve" in self.spec:
options.append("-DGMX_SIMD=ARM_SVE")
else:
options.append("-DGMX_SIMD=ARM_NEON_ASIMD")
elif target == "mic_knl":
# Intel KNL
options.append("-DGMX_SIMD=AVX_512_KNL")
else:
# Other architectures
simd_features = [
("sse2", "SSE2"),
("sse4_1", "SSE4.1"),
("avx", "AVX_256"),
("axv128", "AVX2_128"),
("avx2", "AVX2_256"),
("avx512", "AVX_512"),
]
# Workaround NVIDIA compiler bug when avx512 is enabled
if self.spec.satisfies("%nvhpc") and ("avx512", "AVX_512") in simd_features:
simd_features.remove(("avx512", "AVX_512"))
feature_set = False
for feature, flag in reversed(simd_features):
if feature in target:
options.append("-DGMX_SIMD:STRING={0}".format(flag))
feature_set = True
break
# Fall back
if not feature_set:
options.append("-DGMX_SIMD:STRING=None")
# Use the 'rtdscp' assembly instruction only on
# appropriate architectures
options.append(self.define("GMX_USE_RDTSCP", str(target.family) in ("x86_64", "x86")))
if self.spec.satisfies("@:2020"):
options.append(self.define_from_variant("GMX_BUILD_MDRUN_ONLY", "mdrun_only"))
options.append(self.define_from_variant("GMX_OPENMP", "openmp"))
if self.spec.satisfies("@:2020"):
options.append(
self.define_from_variant(
"GMX_RELAXED_DOUBLE_PRECISION", "relaxed_double_precision"
)
)
if "+cycle_subcounters" in self.spec:
options.append("-DGMX_CYCLE_SUBCOUNTERS:BOOL=ON")
else:
options.append("-DGMX_CYCLE_SUBCOUNTERS:BOOL=OFF")
if "+openmp" in self.spec and self.spec.variants["openmp_max_threads"].value != "none":
options.append(
"-DGMX_OPENMP_MAX_THREADS=%s" % self.spec.variants["openmp_max_threads"].value
)
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")
if self.spec.satisfies("@:2022"):
options.append(
"-DMKL_INCLUDE_DIR={0}".format(self.spec["mkl"].headers.directories[0])
)
# The 'blas' property provides a minimal set of libraries
# that is sufficient for fft. Using full mkl fails the cmake test
options.append("-DMKL_LIBRARIES={0}".format(self.spec["blas"].libs.joined(";")))
else:
# we rely on the fftw-api@3
options.append("-DGMX_FFT_LIBRARY=fftw3")
if "^amdfftw" in self.spec:
options.append("-DGMX_FFT_LIBRARY=fftw3")
options.append(
"-DFFTWF_INCLUDE_DIRS={0}".format(self.spec["amdfftw"].headers.directories[0])
)
options.append(
"-DFFTWF_LIBRARIES={0}".format(self.spec["amdfftw"].libs.joined(";"))
)
elif "^armpl-gcc" in self.spec:
options.append(
"-DFFTWF_INCLUDE_DIR={0}".format(self.spec["armpl-gcc"].headers.directories[0])
)
options.append(
"-DFFTWF_LIBRARY={0}".format(self.spec["armpl-gcc"].libs.joined(";"))
)
elif "^acfl" in self.spec:
options.append(
"-DFFTWF_INCLUDE_DIR={0}".format(self.spec["acfl"].headers.directories[0])
)
options.append("-DFFTWF_LIBRARY={0}".format(self.spec["acfl"].libs.joined(";")))
# Ensure that the GROMACS log files report how the code was patched
# during the build, so that any problems are easier to diagnose.
if "+plumed" in self.spec:
options.append("-DGMX_VERSION_STRING_OF_FORK=PLUMED-spack")
else:
options.append("-DGMX_VERSION_STRING_OF_FORK=spack")
return options