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:
Massimiliano Culpo
2017-04-07 11:18:34 +02:00
committed by GitHub
parent 030127a071
commit 10c395b2f5
5 changed files with 180 additions and 87 deletions

View File

@@ -28,13 +28,15 @@
from spack import *
class Abinit(Package):
class Abinit(AutotoolsPackage):
"""ABINIT is a package whose main program allows one to find the total
energy, charge density and electronic structure of systems made of
electrons and nuclei (molecules and periodic solids) within
Density Functional Theory (DFT), using pseudopotentials and a planewave
or wavelet basis. ABINIT also includes options to optimize the geometry
according to the DFT forces and stresses, or to perform molecular dynamics
or wavelet basis.
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,
Born effective charges, and dielectric tensors, based on Density-Functional
Perturbation Theory, and many more properties. Excited states can be
@@ -44,11 +46,12 @@ class Abinit(Package):
programs are provided.
"""
homepage = "http://www.abinit.org"
url = "http://ftp.abinit.org/abinit-8.0.8b.tar.gz"
homepage = 'http://www.abinit.org'
url = 'http://ftp.abinit.org/abinit-8.0.8b.tar.gz'
version('8.2.2', '5f25250e06fdc0815c224ffd29858860')
# Versions before 8.0.8b are not supported.
version("8.0.8b", "abc9e303bfa7f9f43f95598f87d84d5d")
version('8.0.8b', 'abc9e303bfa7f9f43f95598f87d84d5d')
variant('mpi', default=True,
description='Builds with MPI support. Requires MPI2+')
@@ -57,7 +60,7 @@ class Abinit(Package):
variant('scalapack', default=False,
description='Enables scalapack support. Requires MPI')
# variant('elpa', default=False,
# description='Uses elpa instead of scalapack. Requires MPI')
# description='Uses elpa instead of scalapack. Requires MPI')
# TODO: To be tested.
# It was working before the last `git pull` but now all tests crash.
@@ -71,111 +74,108 @@ class Abinit(Package):
# Add dependencies
# currently one cannot forward options to virtual packages, see #1712.
# depends_on("blas", when="~openmp")
# depends_on("blas+openmp", when="+openmp")
# depends_on('blas', when='~openmp')
# depends_on('blas+openmp', when='+openmp')
depends_on('blas')
depends_on("lapack")
depends_on('lapack')
# Require MPI2+
depends_on("mpi@2:", when="+mpi")
depends_on('mpi@2:', when='+mpi')
depends_on("scalapack", when="+scalapack+mpi")
# depends_on("elpa", when="+elpa+mpi~openmp")
# depends_on("elpa+openmp", when="+elpa+mpi+openmp")
depends_on('scalapack', when='+scalapack+mpi')
depends_on("fftw+float", when="~openmp")
depends_on("fftw+float+openmp", when="+openmp")
# depends_on('elpa~openmp', when='+elpa+mpi~openmp')
# depends_on('elpa+openmp', when='+elpa+mpi+openmp')
depends_on("netcdf-fortran", when="+hdf5")
depends_on("hdf5+mpi", when='+mpi+hdf5') # required for NetCDF-4 support
depends_on('fftw+float', when='~openmp')
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
depends_on("libxc@2.2.1")
depends_on("libxc@2.2.2")
def validate(self, spec):
"""
Checks if incompatible variants have been activated at the same time
# Cannot ask for +scalapack if it does not depend on MPI
conflicts('+scalapack', when='~mpi')
:param spec: spec of the package
:raises RuntimeError: in case of inconsistencies
"""
error = 'you cannot ask for \'+{variant}\' when \'+mpi\' is not active'
# Elpa is a substitute for scalapack and needs mpi
# conflicts('+elpa', when='~mpi')
# conflicts('+elpa', when='+scalapack')
if '+scalapack' in spec and '~mpi' in spec:
raise RuntimeError(error.format(variant='scalapack'))
def configure_args(self):
if '+elpa' in spec and ('~mpi' in spec or '~scalapack' in spec):
raise RuntimeError(error.format(variant='elpa'))
spec = self.spec
def install(self, spec, prefix):
self.validate(spec)
options = ['--prefix=%s' % prefix]
options = []
oapp = options.append
if '+mpi' in spec:
# MPI version:
# let the configure script auto-detect MPI support from mpi_prefix
oapp("--with-mpi-prefix=%s" % spec["mpi"].prefix)
oapp("--enable-mpi=yes")
oapp("--enable-mpi-io=yes")
oapp('--with-mpi-prefix={0}'.format(spec['mpi'].prefix))
oapp('--enable-mpi=yes')
oapp('--enable-mpi-io=yes')
# Activate OpenMP in Abinit Fortran code.
if '+openmp' in spec:
oapp('--enable-openmp=yes')
# BLAS/LAPACK
# BLAS/LAPACK/SCALAPACK-ELPA
linalg = spec['lapack'].libs + spec['blas'].libs
if '+scalapack' in spec:
oapp("--with-linalg-flavor=custom+scalapack")
linalg = (spec['scalapack'].libs +
spec['lapack'].libs + spec['blas'].libs)
oapp('--with-linalg-flavor=custom+scalapack')
linalg = spec['scalapack'].libs + linalg
# elif '+elpa' in spec:
else:
oapp("--with-linalg-flavor=custom")
linalg = spec['lapack'].libs + spec['blas'].libs
oapp('--with-linalg-flavor=custom')
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
fftflavor, fftlibs = "fftw3", "-lfftw3 -lfftw3f"
fftflavor, fftlibs = 'fftw3', '-lfftw3 -lfftw3f'
if '+openmp' in spec:
fftflavor = "fftw3-threads"
fftlibs = "-lfftw3_omp -lfftw3 -lfftw3f"
fftflavor = 'fftw3-threads'
fftlibs = '-lfftw3_omp -lfftw3 -lfftw3f'
options.extend([
"--with-fft-flavor=%s" % fftflavor,
"--with-fft-incs=-I%s" % spec["fftw"].prefix.include,
"--with-fft-libs=-L%s %s" % (spec["fftw"].prefix.lib, fftlibs),
'--with-fft-flavor=%s' % fftflavor,
'--with-fft-incs=-I%s' % spec['fftw'].prefix.include,
'--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 = spec['libxc:fortran']
options.extend([
"with_libxc_incs=-I%s" % spec["libxc"].prefix.include,
"with_libxc_libs=-L%s -lxcf90 -lxc" % spec["libxc"].prefix.lib,
'with_libxc_incs={0}'.format(libxc.cppflags),
'with_libxc_libs={0}'.format(libxc.libs.ld_flags + ' -lm')
])
# Netcdf4/HDF5
if "+hdf5" in spec:
oapp("--with-trio-flavor=netcdf")
if '+hdf5' in spec:
oapp('--with-trio-flavor=netcdf')
# Since version 8, Abinit started to use netcdf4 + hdf5 and we have
# to link with -lhdf5_hl -lhdf5
hdf_libs = "-L%s -lhdf5_hl -lhdf5" % spec["hdf5"].prefix.lib
# to link with the high level HDF5 library
hdf5 = spec['hdf5:hl']
netcdff = spec['netcdf-fortran:shared']
options.extend([
"--with-netcdf-incs=-I%s" % (
spec["netcdf-fortran"].prefix.include),
"--with-netcdf-libs=-L%s -lnetcdff -lnetcdf %s" % (
spec["netcdf-fortran"].prefix.lib, hdf_libs),
'--with-netcdf-incs={0}'.format(netcdff.cppflags),
'--with-netcdf-libs={0}'.format(
netcdff.libs.ld_flags + ' ' + hdf5.libs.ld_flags
),
])
else:
# In Spack we do our best to avoid building any internally provided
# dependencies, such as netcdf3 in this case.
oapp("--with-trio-flavor=none")
oapp('--with-trio-flavor=none')
configure(*options)
make()
return options
# make("check")
# make("tests_in")
make("install")
def check(self):
"""This method is called after the build phase if tests have been
explicitly activated by user.
"""
make('check')
make('tests_in')