Abinit: a few modernizations for the package and its dependencies (#3699)
* libxc: added libs interface * hdf5: added libs interface, added conflicts * abinit: modernized package to use build interface * netcdf-fortran: added libs interface * abinit: added version 8.2.2
This commit is contained in:
parent
030127a071
commit
10c395b2f5
5 changed files with 180 additions and 87 deletions
|
@ -901,16 +901,12 @@ def __init__(self, spec, name, query_parameters):
|
||||||
)
|
)
|
||||||
|
|
||||||
is_virtual = Spec.is_virtual(name)
|
is_virtual = Spec.is_virtual(name)
|
||||||
self._query_to_package = QueryState(
|
self.last_query = QueryState(
|
||||||
name=name,
|
name=name,
|
||||||
extra_parameters=query_parameters,
|
extra_parameters=query_parameters,
|
||||||
isvirtual=is_virtual
|
isvirtual=is_virtual
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def last_query(self):
|
|
||||||
return self._query_to_package
|
|
||||||
|
|
||||||
|
|
||||||
@key_ordering
|
@key_ordering
|
||||||
class Spec(object):
|
class Spec(object):
|
||||||
|
|
|
@ -28,13 +28,15 @@
|
||||||
from spack import *
|
from spack import *
|
||||||
|
|
||||||
|
|
||||||
class Abinit(Package):
|
class Abinit(AutotoolsPackage):
|
||||||
"""ABINIT is a package whose main program allows one to find the total
|
"""ABINIT is a package whose main program allows one to find the total
|
||||||
energy, charge density and electronic structure of systems made of
|
energy, charge density and electronic structure of systems made of
|
||||||
electrons and nuclei (molecules and periodic solids) within
|
electrons and nuclei (molecules and periodic solids) within
|
||||||
Density Functional Theory (DFT), using pseudopotentials and a planewave
|
Density Functional Theory (DFT), using pseudopotentials and a planewave
|
||||||
or wavelet basis. ABINIT also includes options to optimize the geometry
|
or wavelet basis.
|
||||||
according to the DFT forces and stresses, or to perform molecular dynamics
|
|
||||||
|
ABINIT also includes options to optimize the geometry according to the
|
||||||
|
DFT forces and stresses, or to perform molecular dynamics
|
||||||
simulations using these forces, or to generate dynamical matrices,
|
simulations using these forces, or to generate dynamical matrices,
|
||||||
Born effective charges, and dielectric tensors, based on Density-Functional
|
Born effective charges, and dielectric tensors, based on Density-Functional
|
||||||
Perturbation Theory, and many more properties. Excited states can be
|
Perturbation Theory, and many more properties. Excited states can be
|
||||||
|
@ -44,11 +46,12 @@ class Abinit(Package):
|
||||||
programs are provided.
|
programs are provided.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
homepage = "http://www.abinit.org"
|
homepage = 'http://www.abinit.org'
|
||||||
url = "http://ftp.abinit.org/abinit-8.0.8b.tar.gz"
|
url = 'http://ftp.abinit.org/abinit-8.0.8b.tar.gz'
|
||||||
|
|
||||||
|
version('8.2.2', '5f25250e06fdc0815c224ffd29858860')
|
||||||
# Versions before 8.0.8b are not supported.
|
# Versions before 8.0.8b are not supported.
|
||||||
version("8.0.8b", "abc9e303bfa7f9f43f95598f87d84d5d")
|
version('8.0.8b', 'abc9e303bfa7f9f43f95598f87d84d5d')
|
||||||
|
|
||||||
variant('mpi', default=True,
|
variant('mpi', default=True,
|
||||||
description='Builds with MPI support. Requires MPI2+')
|
description='Builds with MPI support. Requires MPI2+')
|
||||||
|
@ -71,111 +74,108 @@ class Abinit(Package):
|
||||||
|
|
||||||
# Add dependencies
|
# Add dependencies
|
||||||
# currently one cannot forward options to virtual packages, see #1712.
|
# currently one cannot forward options to virtual packages, see #1712.
|
||||||
# depends_on("blas", when="~openmp")
|
# depends_on('blas', when='~openmp')
|
||||||
# depends_on("blas+openmp", when="+openmp")
|
# depends_on('blas+openmp', when='+openmp')
|
||||||
depends_on('blas')
|
depends_on('blas')
|
||||||
depends_on("lapack")
|
depends_on('lapack')
|
||||||
|
|
||||||
# Require MPI2+
|
# Require MPI2+
|
||||||
depends_on("mpi@2:", when="+mpi")
|
depends_on('mpi@2:', when='+mpi')
|
||||||
|
|
||||||
depends_on("scalapack", when="+scalapack+mpi")
|
depends_on('scalapack', when='+scalapack+mpi')
|
||||||
# depends_on("elpa", when="+elpa+mpi~openmp")
|
|
||||||
# depends_on("elpa+openmp", when="+elpa+mpi+openmp")
|
|
||||||
|
|
||||||
depends_on("fftw+float", when="~openmp")
|
# depends_on('elpa~openmp', when='+elpa+mpi~openmp')
|
||||||
depends_on("fftw+float+openmp", when="+openmp")
|
# depends_on('elpa+openmp', when='+elpa+mpi+openmp')
|
||||||
|
|
||||||
depends_on("netcdf-fortran", when="+hdf5")
|
depends_on('fftw+float', when='~openmp')
|
||||||
depends_on("hdf5+mpi", when='+mpi+hdf5') # required for NetCDF-4 support
|
depends_on('fftw+float+openmp', when='+openmp')
|
||||||
|
|
||||||
|
depends_on('netcdf-fortran', when='+hdf5')
|
||||||
|
depends_on('hdf5+mpi', when='+mpi+hdf5') # required for NetCDF-4 support
|
||||||
|
|
||||||
# pin libxc version
|
# pin libxc version
|
||||||
depends_on("libxc@2.2.1")
|
depends_on("libxc@2.2.2")
|
||||||
|
|
||||||
def validate(self, spec):
|
# Cannot ask for +scalapack if it does not depend on MPI
|
||||||
"""
|
conflicts('+scalapack', when='~mpi')
|
||||||
Checks if incompatible variants have been activated at the same time
|
|
||||||
|
|
||||||
:param spec: spec of the package
|
# Elpa is a substitute for scalapack and needs mpi
|
||||||
:raises RuntimeError: in case of inconsistencies
|
# conflicts('+elpa', when='~mpi')
|
||||||
"""
|
# conflicts('+elpa', when='+scalapack')
|
||||||
error = 'you cannot ask for \'+{variant}\' when \'+mpi\' is not active'
|
|
||||||
|
|
||||||
if '+scalapack' in spec and '~mpi' in spec:
|
def configure_args(self):
|
||||||
raise RuntimeError(error.format(variant='scalapack'))
|
|
||||||
|
|
||||||
if '+elpa' in spec and ('~mpi' in spec or '~scalapack' in spec):
|
spec = self.spec
|
||||||
raise RuntimeError(error.format(variant='elpa'))
|
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
options = []
|
||||||
self.validate(spec)
|
|
||||||
|
|
||||||
options = ['--prefix=%s' % prefix]
|
|
||||||
oapp = options.append
|
oapp = options.append
|
||||||
|
|
||||||
if '+mpi' in spec:
|
if '+mpi' in spec:
|
||||||
# MPI version:
|
# MPI version:
|
||||||
# let the configure script auto-detect MPI support from mpi_prefix
|
# let the configure script auto-detect MPI support from mpi_prefix
|
||||||
oapp("--with-mpi-prefix=%s" % spec["mpi"].prefix)
|
oapp('--with-mpi-prefix={0}'.format(spec['mpi'].prefix))
|
||||||
oapp("--enable-mpi=yes")
|
oapp('--enable-mpi=yes')
|
||||||
oapp("--enable-mpi-io=yes")
|
oapp('--enable-mpi-io=yes')
|
||||||
|
|
||||||
# Activate OpenMP in Abinit Fortran code.
|
# Activate OpenMP in Abinit Fortran code.
|
||||||
if '+openmp' in spec:
|
if '+openmp' in spec:
|
||||||
oapp('--enable-openmp=yes')
|
oapp('--enable-openmp=yes')
|
||||||
|
|
||||||
# BLAS/LAPACK
|
# BLAS/LAPACK/SCALAPACK-ELPA
|
||||||
|
linalg = spec['lapack'].libs + spec['blas'].libs
|
||||||
if '+scalapack' in spec:
|
if '+scalapack' in spec:
|
||||||
oapp("--with-linalg-flavor=custom+scalapack")
|
oapp('--with-linalg-flavor=custom+scalapack')
|
||||||
linalg = (spec['scalapack'].libs +
|
linalg = spec['scalapack'].libs + linalg
|
||||||
spec['lapack'].libs + spec['blas'].libs)
|
|
||||||
|
|
||||||
# elif '+elpa' in spec:
|
# elif '+elpa' in spec:
|
||||||
else:
|
else:
|
||||||
oapp("--with-linalg-flavor=custom")
|
oapp('--with-linalg-flavor=custom')
|
||||||
linalg = spec['lapack'].libs + spec['blas'].libs
|
|
||||||
|
|
||||||
oapp("--with-linalg-libs=%s" % linalg.ld_flags)
|
oapp('--with-linalg-libs={0}'.format(linalg.ld_flags))
|
||||||
|
|
||||||
# FFTW3: use sequential or threaded version if +openmp
|
# FFTW3: use sequential or threaded version if +openmp
|
||||||
fftflavor, fftlibs = "fftw3", "-lfftw3 -lfftw3f"
|
fftflavor, fftlibs = 'fftw3', '-lfftw3 -lfftw3f'
|
||||||
if '+openmp' in spec:
|
if '+openmp' in spec:
|
||||||
fftflavor = "fftw3-threads"
|
fftflavor = 'fftw3-threads'
|
||||||
fftlibs = "-lfftw3_omp -lfftw3 -lfftw3f"
|
fftlibs = '-lfftw3_omp -lfftw3 -lfftw3f'
|
||||||
|
|
||||||
options.extend([
|
options.extend([
|
||||||
"--with-fft-flavor=%s" % fftflavor,
|
'--with-fft-flavor=%s' % fftflavor,
|
||||||
"--with-fft-incs=-I%s" % spec["fftw"].prefix.include,
|
'--with-fft-incs=-I%s' % spec['fftw'].prefix.include,
|
||||||
"--with-fft-libs=-L%s %s" % (spec["fftw"].prefix.lib, fftlibs),
|
'--with-fft-libs=-L%s %s' % (spec['fftw'].prefix.lib, fftlibs),
|
||||||
])
|
])
|
||||||
oapp("--with-dft-flavor=atompaw+libxc")
|
oapp('--with-dft-flavor=atompaw+libxc')
|
||||||
|
|
||||||
# LibXC library
|
# LibXC library
|
||||||
|
libxc = spec['libxc:fortran']
|
||||||
options.extend([
|
options.extend([
|
||||||
"with_libxc_incs=-I%s" % spec["libxc"].prefix.include,
|
'with_libxc_incs={0}'.format(libxc.cppflags),
|
||||||
"with_libxc_libs=-L%s -lxcf90 -lxc" % spec["libxc"].prefix.lib,
|
'with_libxc_libs={0}'.format(libxc.libs.ld_flags + ' -lm')
|
||||||
])
|
])
|
||||||
|
|
||||||
# Netcdf4/HDF5
|
# Netcdf4/HDF5
|
||||||
if "+hdf5" in spec:
|
if '+hdf5' in spec:
|
||||||
oapp("--with-trio-flavor=netcdf")
|
oapp('--with-trio-flavor=netcdf')
|
||||||
# Since version 8, Abinit started to use netcdf4 + hdf5 and we have
|
# Since version 8, Abinit started to use netcdf4 + hdf5 and we have
|
||||||
# to link with -lhdf5_hl -lhdf5
|
# to link with the high level HDF5 library
|
||||||
hdf_libs = "-L%s -lhdf5_hl -lhdf5" % spec["hdf5"].prefix.lib
|
hdf5 = spec['hdf5:hl']
|
||||||
|
netcdff = spec['netcdf-fortran:shared']
|
||||||
options.extend([
|
options.extend([
|
||||||
"--with-netcdf-incs=-I%s" % (
|
'--with-netcdf-incs={0}'.format(netcdff.cppflags),
|
||||||
spec["netcdf-fortran"].prefix.include),
|
'--with-netcdf-libs={0}'.format(
|
||||||
"--with-netcdf-libs=-L%s -lnetcdff -lnetcdf %s" % (
|
netcdff.libs.ld_flags + ' ' + hdf5.libs.ld_flags
|
||||||
spec["netcdf-fortran"].prefix.lib, hdf_libs),
|
),
|
||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
# In Spack we do our best to avoid building any internally provided
|
# In Spack we do our best to avoid building any internally provided
|
||||||
# dependencies, such as netcdf3 in this case.
|
# dependencies, such as netcdf3 in this case.
|
||||||
oapp("--with-trio-flavor=none")
|
oapp('--with-trio-flavor=none')
|
||||||
|
|
||||||
configure(*options)
|
return options
|
||||||
make()
|
|
||||||
|
|
||||||
# make("check")
|
def check(self):
|
||||||
# make("tests_in")
|
"""This method is called after the build phase if tests have been
|
||||||
make("install")
|
explicitly activated by user.
|
||||||
|
"""
|
||||||
|
make('check')
|
||||||
|
make('tests_in')
|
||||||
|
|
|
@ -70,23 +70,82 @@ class Hdf5(AutotoolsPackage):
|
||||||
depends_on('szip', when='+szip')
|
depends_on('szip', when='+szip')
|
||||||
depends_on('zlib@1.1.2:')
|
depends_on('zlib@1.1.2:')
|
||||||
|
|
||||||
@run_before('configure')
|
# According to ./configure --help thread-safe capabilities are:
|
||||||
def validate(self):
|
# "Not compatible with the high-level library, Fortran, or C++ wrappers."
|
||||||
"""
|
# (taken from hdf5@1.10.0patch1)
|
||||||
Checks if incompatible variants have been activated at the same time
|
conflicts('+threadsafe', when='+cxx')
|
||||||
|
conflicts('+threadsafe', when='+fortran')
|
||||||
|
|
||||||
:param spec: spec of the package
|
@property
|
||||||
:raises RuntimeError: in case of inconsistencies
|
def libs(self):
|
||||||
|
"""Hdf5 can be queried for the following parameters:
|
||||||
|
|
||||||
|
- "hl": high-level interface
|
||||||
|
- "cxx": C++ APIs
|
||||||
|
- "fortran": fortran APIs
|
||||||
|
|
||||||
|
:return: list of matching libraries
|
||||||
"""
|
"""
|
||||||
|
query_parameters = self.spec.last_query.extra_parameters
|
||||||
|
|
||||||
|
shared = '+shared' in self.spec
|
||||||
|
|
||||||
|
# This map contains a translation from query_parameters
|
||||||
|
# to the libraries needed
|
||||||
|
query2libraries = {
|
||||||
|
tuple(): ['libhdf5'],
|
||||||
|
('cxx', 'fortran', 'hl'): [
|
||||||
|
'libhdf5hl_fortran',
|
||||||
|
'libhdf5_hl_cpp',
|
||||||
|
'libhdf5_hl',
|
||||||
|
'libhdf5_fortran',
|
||||||
|
'libhdf5',
|
||||||
|
],
|
||||||
|
('cxx', 'hl'): [
|
||||||
|
'libhdf5_hl_cpp',
|
||||||
|
'libhdf5_hl',
|
||||||
|
'libhdf5',
|
||||||
|
],
|
||||||
|
('fortran', 'hl'): [
|
||||||
|
'libhdf5hl_fortran',
|
||||||
|
'libhdf5_hl',
|
||||||
|
'libhdf5_fortran',
|
||||||
|
'libhdf5',
|
||||||
|
],
|
||||||
|
('hl',): [
|
||||||
|
'libhdf5_hl',
|
||||||
|
'libhdf5',
|
||||||
|
],
|
||||||
|
('cxx', 'fortran'): [
|
||||||
|
'libhdf5_fortran',
|
||||||
|
'libhdf5_cpp',
|
||||||
|
'libhdf5',
|
||||||
|
],
|
||||||
|
('cxx',): [
|
||||||
|
'libhdf5_cpp',
|
||||||
|
'libhdf5',
|
||||||
|
],
|
||||||
|
('fortran',): [
|
||||||
|
'libhdf5_fortran',
|
||||||
|
'libhdf5',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Turn the query into the appropriate key
|
||||||
|
key = tuple(sorted(query_parameters))
|
||||||
|
libraries = query2libraries[key]
|
||||||
|
|
||||||
|
return find_libraries(
|
||||||
|
libraries, root=self.prefix, shared=shared, recurse=True
|
||||||
|
)
|
||||||
|
|
||||||
|
@run_before('configure')
|
||||||
|
def fortran_check(self):
|
||||||
spec = self.spec
|
spec = self.spec
|
||||||
if '+fortran' in spec and not self.compiler.fc:
|
if '+fortran' in spec and not self.compiler.fc:
|
||||||
msg = 'cannot build a fortran variant without a fortran compiler'
|
msg = 'cannot build a fortran variant without a fortran compiler'
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
if '+threadsafe' in spec and ('+cxx' in spec or '+fortran' in spec):
|
|
||||||
msg = 'cannot use variant +threadsafe with either +cxx or +fortran'
|
|
||||||
raise RuntimeError(msg)
|
|
||||||
|
|
||||||
def configure_args(self):
|
def configure_args(self):
|
||||||
spec = self.spec
|
spec = self.spec
|
||||||
# Handle compilation after spec validation
|
# Handle compilation after spec validation
|
||||||
|
@ -156,11 +215,9 @@ def configure_args(self):
|
||||||
|
|
||||||
return ["--with-zlib=%s" % spec['zlib'].prefix] + extra_args
|
return ["--with-zlib=%s" % spec['zlib'].prefix] + extra_args
|
||||||
|
|
||||||
def configure(self, spec, prefix):
|
@run_after('configure')
|
||||||
# Run the default autotools package configure
|
def patch_postdeps(self):
|
||||||
super(Hdf5, self).configure(spec, prefix)
|
if '@:1.8.14' in self.spec:
|
||||||
|
|
||||||
if '@:1.8.14' in spec:
|
|
||||||
# On Ubuntu14, HDF5 1.8.12 (and maybe other versions)
|
# On Ubuntu14, HDF5 1.8.12 (and maybe other versions)
|
||||||
# mysteriously end up with "-l -l" in the postdeps in the
|
# mysteriously end up with "-l -l" in the postdeps in the
|
||||||
# libtool script. Patch this by removing the spurious -l's.
|
# libtool script. Patch this by removing the spurious -l's.
|
||||||
|
|
|
@ -36,6 +36,33 @@ class Libxc(Package):
|
||||||
version('2.2.2', 'd9f90a0d6e36df6c1312b6422280f2ec')
|
version('2.2.2', 'd9f90a0d6e36df6c1312b6422280f2ec')
|
||||||
version('2.2.1', '38dc3a067524baf4f8521d5bb1cd0b8f')
|
version('2.2.1', '38dc3a067524baf4f8521d5bb1cd0b8f')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def libs(self):
|
||||||
|
"""Libxc can be queried for the following parameters:
|
||||||
|
|
||||||
|
- "static": returns the static library version of libxc
|
||||||
|
(by default the shared version is returned)
|
||||||
|
|
||||||
|
:return: list of matching libraries
|
||||||
|
"""
|
||||||
|
query_parameters = self.spec.last_query.extra_parameters
|
||||||
|
|
||||||
|
libraries = ['libxc']
|
||||||
|
|
||||||
|
# Libxc installs both shared and static libraries.
|
||||||
|
# If a client ask for static explicitly then return
|
||||||
|
# the static libraries
|
||||||
|
shared = False if 'static' in query_parameters else True
|
||||||
|
|
||||||
|
# Libxc has a fortran90 interface: give clients the
|
||||||
|
# possibility to query for it
|
||||||
|
if 'fortran' in query_parameters:
|
||||||
|
libraries = ['libxcf90'] + libraries
|
||||||
|
|
||||||
|
return find_libraries(
|
||||||
|
libraries, root=self.prefix, shared=shared, recurse=True
|
||||||
|
)
|
||||||
|
|
||||||
def install(self, spec, prefix):
|
def install(self, spec, prefix):
|
||||||
# Optimizations for the Intel compiler, suggested by CP2K
|
# Optimizations for the Intel compiler, suggested by CP2K
|
||||||
optflags = '-O2'
|
optflags = '-O2'
|
||||||
|
|
|
@ -35,3 +35,16 @@ class NetcdfFortran(AutotoolsPackage):
|
||||||
version('4.4.3', 'bfd4ae23a34635b273d3eb0d91cbde9e')
|
version('4.4.3', 'bfd4ae23a34635b273d3eb0d91cbde9e')
|
||||||
|
|
||||||
depends_on('netcdf')
|
depends_on('netcdf')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def libs(self):
|
||||||
|
libraries = ['libnetcdff']
|
||||||
|
|
||||||
|
# This package installs both shared and static libraries. Permit
|
||||||
|
# clients to query which one they want.
|
||||||
|
query_parameters = self.spec.last_query.extra_parameters
|
||||||
|
shared = 'shared' in query_parameters
|
||||||
|
|
||||||
|
return find_libraries(
|
||||||
|
libraries, root=self.prefix, shared=shared, recurse=True
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue