siesta: add v4.1.5, v5.0.0 and v5.0.1, add variants and build v5 using cmake (#45518)

Co-authored-by: Bernhard Kaindl <bernhardkaindl7@gmail.com>
This commit is contained in:
BOUDAOUD34 2024-08-13 12:10:22 +02:00 committed by GitHub
parent 7001a2a65a
commit 7999686856
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -5,16 +5,40 @@
import os import os
import shutil
from spack.build_systems import cmake
from spack.package import * from spack.package import *
class Siesta(MakefilePackage): class Siesta(MakefilePackage, CMakePackage):
"""SIESTA performs electronic structure calculations and ab initio molecular """SIESTA performs electronic structure calculations and ab initio molecular
dynamics simulations of molecules and solids. dynamics simulations of molecules and solids.
""" """
build_system(
conditional("cmake", when="@5:"), conditional("makefile", when="@:4"), default="cmake"
)
homepage = "https://departments.icmab.es/leem/siesta/" homepage = "https://departments.icmab.es/leem/siesta/"
git = "https://gitlab.com/siesta-project/siesta"
version(
"5.0.1",
url="https://gitlab.com/siesta-project/siesta/-/archive/5.0.1/siesta-5.0.1.tar.gz",
sha256="800a22a831c1d36c6f5fe4aa9c49ee510cbd49a0b2f87b3c8bf3edb6ebd0193a",
)
version(
"5.0.0",
url="https://gitlab.com/siesta-project/siesta/-/archive/rel-5.0/siesta-rel-5.0.tar.gz",
sha256="0b40c341dfd47e99e7e191189600bbcaadb0f9af03977fefed6a69836bd523e4",
)
version(
"4.1.5",
url="https://gitlab.com/siesta-project/siesta/-/archive/v4.1.5/siesta-v4.1.5.tar.gz",
sha256="adc88619bf7e17fca2c67ecdcdae1f07ec4b3caf3541c0edf12964c8c330edc9",
)
license("GPL-3.0-or-later") license("GPL-3.0-or-later")
@ -30,17 +54,43 @@ class Siesta(MakefilePackage):
url="http://departments.icmab.es/leem/siesta/CodeAccess/Code/siesta-3.2-pl-5.tgz", url="http://departments.icmab.es/leem/siesta/CodeAccess/Code/siesta-3.2-pl-5.tgz",
) )
depends_on("c", type="build") # generated
depends_on("fortran", type="build") # generated
patch("configure.patch", when="@:4.0") patch("configure.patch", when="@:4.0")
depends_on("mpi") variant("mpi", default=True, description="Builds with mpi support")
variant("openmp", default=True, description="Enables OpenMP support")
variant("netcdf", default=False, description="Compile with Netcdf")
variant("metis", default=False, description="Activate Metis as a possible ordering library")
variant("elpa", default=False, description="Use ELPA")
variant("mumps", default=False, description="Compile with support for MUMPS solvers")
variant("pexsi", default=False, description="Compile with PEXSI")
variant(
"cray",
default=False,
description="Enable specific cray settings for using cray-hdf5"
" and cray-netcdf modulefiles",
)
variant("debug", default=False, description="Build in debug mode")
variant(
"build_type",
default="Release",
description="The build type to build",
values=("Debug", "Release", "RelWithDebInfo", "MinSizeRel", "check"),
)
depends_on("mpi", when="+mpi")
depends_on("blas") depends_on("blas")
depends_on("lapack") depends_on("lapack")
depends_on("scalapack") depends_on("scalapack", when="+mpi")
depends_on("netcdf-c") depends_on("netcdf-c")
depends_on("netcdf-fortran") depends_on("netcdf-fortran")
depends_on("cray-libsci+openmp", when="^[virtuals=cray-libsci] cray-libsci")
depends_on("metis@5:", when="+metis")
depends_on("elpa", when="+elpa")
depends_on("mumps", when="+mumps")
depends_on("pexsi", when="+pexsi")
with when("build_system=cmake"):
depends_on("cmake@3.20:", type="build")
def flag_handler(self, name, flags): def flag_handler(self, name, flags):
if "%gcc@10:" in self.spec and name == "fflags": if "%gcc@10:" in self.spec and name == "fflags":
@ -49,6 +99,10 @@ def flag_handler(self, name, flags):
def edit(self, spec, prefix): def edit(self, spec, prefix):
sh = which("sh") sh = which("sh")
if "+cray" in spec:
netcdff_prefix = os.environ.get("NETCDF_DIR", "")
hdf5_prefix = os.environ.get("HDF5_DIR", "")
if spec.satisfies("@:4.0.2 +mpi"):
configure_args = [ configure_args = [
"--enable-mpi", "--enable-mpi",
"--with-blas=%s" % spec["blas"].libs, "--with-blas=%s" % spec["blas"].libs,
@ -58,12 +112,23 @@ def edit(self, spec, prefix):
# test fails # test fails
"--with-blacs=%s" % (spec["scalapack"].libs + spec["blas"].libs), "--with-blacs=%s" % (spec["scalapack"].libs + spec["blas"].libs),
"--with-scalapack=%s" % spec["scalapack"].libs, "--with-scalapack=%s" % spec["scalapack"].libs,
"--with-netcdf=%s" % (spec["netcdf-fortran"].libs + spec["netcdf-c"].libs),
# need to specify MPIFC explicitly below, otherwise # need to specify MPIFC explicitly below, otherwise
# Intel's mpiifort is not found # Intel's mpiifort is not found
"MPIFC=%s" % spec["mpi"].mpifc, "MPIFC=%s" % spec["mpi"].mpifc,
] ]
if "+cray" in spec:
configure_args += ["--with-netcdf={0}/lib/libnetcdff.so".format(netcdff_prefix)]
else:
configure_args += [
"--with-netcdf=%s" % (spec["netcdf-fortran"].libs + spec["netcdf-c"].libs)
]
if self.spec.satisfies("%gcc"): if self.spec.satisfies("%gcc"):
if "+cray" in spec:
configure_args.append(
"FCFLAGS=-ffree-line-length-0 -I{0}/include".format(netcdff_prefix)
)
else:
configure_args.append("FCFLAGS=-ffree-line-length-0") configure_args.append("FCFLAGS=-ffree-line-length-0")
for d in ["Obj", "Obj_trans"]: for d in ["Obj", "Obj_trans"]:
with working_dir(d, create=True): with working_dir(d, create=True):
@ -75,9 +140,97 @@ def edit(self, spec, prefix):
f.write("$(INCFLAGS) $(FPPFLAGS) $<") f.write("$(INCFLAGS) $(FPPFLAGS) $<")
sh("../Src/obj_setup.sh") sh("../Src/obj_setup.sh")
elif self.spec.satisfies("@:4.1.5"):
with working_dir("Obj", create=True):
sh("../Src/obj_setup.sh")
if spec.satisfies("@:4.1.5%gcc"):
shutil.copy("./gfortran.make", "./arch.make")
libs_arg = []
fppflags_arg = []
arch_make = FileFilter("./arch.make")
arch_make.filter(
"FFLAGS = .*",
"FFLAGS = {0}".format(
"-O2 -fPIC -ftree-vectorize -fallow-argument-mismatch"
),
)
if "+debug" in spec:
arch_make.filter("FFLAGS_DEBUG=.*", "FFLAGS_DEBUG= -g -O1")
if "^cray-libsci" in spec:
libs_arg.append("-L{0}/lib -lsci_gnu".format(spec["cray-libsci"].prefix))
with open("arch.make", "a") as f:
if "+mpi" in spec:
arch_make.filter("CC = .*", "CC = {0}".format(spec["mpi"].mpicc))
arch_make.filter("FC = .*", "FC = {0}".format(spec["mpi"].mpifc))
if "^cray-libsci" in spec:
libs_arg.append("-lsci_gnu_mpi")
f.write("MPI_INTERFACE = libmpi_f90.a\n")
f.write("MPI_INCLUDE = .\n")
f.write("LIBS += " + spec["scalapack"].libs.ld_flags + "\n")
fppflags_arg.append("-DMPI ")
if "+openmp" in spec:
f.write("FFLAGS += -fopenmp\n")
f.write("LIBS += -fopenmp\n")
if "+netcdf" in spec:
if "+cray" in spec:
libs_arg.append(
"-L{0}/lib -lnetcdff -lnetcdf".format(netcdff_prefix)
)
libs_arg.append(
"-L{0}/lib -lhdf5_fortran -lhdf5".format(hdf5_prefix)
)
else:
libs_arg.append(
"-L{0}/lib -lnetcdff -lnetcdf".format(
spec["netcdf-fortran"].prefix
)
)
libs_arg.append(
"-L{0}/lib -lhdf5_fortran -lhdf5".format(spec["hdf5"].prefix)
)
if "+metis" in spec:
libs_arg.append("-L{0} -lmetis".format(self.spec["metis"].prefix.lib))
fppflags_arg.append("-DSIESTA__METIS ")
if "elpa" in spec:
elpa = spec["elpa"]
elpa_suffix = "_openmp" if "+openmp" in elpa else ""
elpa_incdir = elpa.headers.directories[0]
libs_arg.append(
"-L{0} -lelpa{1}".format(self.spec["elpa"].prefix.lib, elpa_suffix)
)
fppflags_arg.append(
"-DSIESTA__ELPA -I{0}".format(join_path(elpa_incdir, "modules"))
)
if "mumps" in spec:
libs_arg.append(
"-L{0} -lmumps_common -lzmumps".format(
self.spec["mumps"].prefix.lib
)
)
fppflags_arg.append("-DSIESTA__MUMPS ")
if "+pexsi" in spec:
libs_arg.append(
"-L{0} -lpexsi_linux".format(self.spec["pexsi"].prefix.lib)
)
fppflags_arg.append("-DSIESTA__PEXSI ")
f.write("INCFLAGS += -I{0}/include".format(self.spec["pexsi"].prefix))
arch_make.filter("^LIBS =.*", "LIBS = {0}".format(" ".join(libs_arg)))
f.write("FPPFLAGS = {0}".format(" ".join(fppflags_arg)))
def build(self, spec, prefix): def build(self, spec, prefix):
with working_dir("Obj"): with working_dir("Obj"):
make(parallel=False) make(parallel=False)
if spec.satisfies("@:4.0.2"):
with working_dir("Obj_trans"): with working_dir("Obj_trans"):
make("transiesta", parallel=False) make("transiesta", parallel=False)
with working_dir("Util"): with working_dir("Util"):
@ -88,6 +241,7 @@ def install(self, spec, prefix):
mkdir(prefix.bin) mkdir(prefix.bin)
with working_dir("Obj"): with working_dir("Obj"):
install("siesta", prefix.bin) install("siesta", prefix.bin)
if spec.satisfies("@:4.0.2"):
with working_dir("Obj_trans"): with working_dir("Obj_trans"):
install("transiesta", prefix.bin) install("transiesta", prefix.bin)
for root, _, files in os.walk("Util"): for root, _, files in os.walk("Util"):
@ -95,3 +249,60 @@ def install(self, spec, prefix):
fname = join_path(root, fname) fname = join_path(root, fname)
if os.access(fname, os.X_OK): if os.access(fname, os.X_OK):
install(fname, prefix.bin) install(fname, prefix.bin)
class CMakeBuilder(cmake.CMakeBuilder):
"""Use the new CMake build system to build siesta@5.0.0:."""
def cmake_args(self):
spec = self.spec
args = []
args += ["-DBLAS_LIBRARIES={0}".format(self.spec["blas"].libs.link_flags)]
args += ["-DLAPACK_LIBRARIES={0}".format(self.spec["lapack"].libs.link_flags)]
if "+mpi" in spec:
args += [
"-DCMAKE_C_COMPILER=%s" % spec["mpi"].mpicc,
"-DCMAKE_CXX_COMPILER=%s" % spec["mpi"].mpicxx,
"-DCMAKE_Fortran_COMPILER=%s" % spec["mpi"].mpifc,
]
args += ["-DSIESTA_WITH_MPI=ON"]
args += ["-DSCALAPACK_LIBRARY={0}".format(spec["scalapack"].libs.joined(";"))]
if "+openmp" in spec:
args += ["-DSIESTA_WITH_OPENMP=ON"]
if "+cray" in spec:
args += ["-DFortran_FLAGS=-fopenmp"]
if "build_type=Debug" in spec:
args += [
"-DFortran_FLAGS=-Og -g -Wall -fcheck=all -fbacktrace"
" -Warray-bounds -Wunused -Wuninitialized"
]
else:
args += ["-DFortran_FLAGS=-O2 -fPIC -ftree-vectorize -fallow-argument-mismatch"]
if "+netcdf" in spec:
args += ["-DSIESTA_WITH_NETCDF=ON"]
if "+cray" in spec:
args += ["-DNetCDF_PATH={0}".format(os.environ.get("NETCDF_DIR", ""))]
else:
args += ["-DNetCDF_PATH={0}".format(spec["netcdf-fortran"].prefix)]
if "+elpa" in spec:
args += ["-DSIESTA_WITH_ELPA=ON"]
if "+mumps" in spec:
args += ["-DSIESTA__MUMPS=ON"]
args += [
"-DSIESTA_LINKER_FLAGS=-L{0} -lmumps_common -lzmumps".format(
self.spec["mumps"].prefix.lib
)
]
if "+metis" in spec:
args += ["-DSIESTA__METIS=ON"]
args += ["-DSIESTA_LINKER_FLAGS=-L{0} -lmetis".format(self.spec["metis"].prefix.lib)]
return args