Abinit+wannier90 fix (#17417)

* wannier90: add versions 3.0.0 and 3.1.0 and 'shared variant'

Added versions 3.0.0 and 3.1.0

Added shared variant

Added url_for_version function as versions less than 3 are from the
wannier.org site and versions 3 and up are from github.com

Added the MPI libraries to the list of libs substituted into the make.sys file
in place of @LIBS

Made it possible to build a shared object version of the library for versions
< 3 by filtering the src/Makefile.2 file (based off of the patch from a src rpm
from RHEL for version 2.0.1)

Create a modules directory in the install prefix root directory and copy the
Fortran .mod files there.

Set the MPIFC variable to the Spack Fortran MPI compiler wrapper.

* abinit: added 'wannier90' variant  which enables building abinit with wannier90

Added wannier90 variant

Made abinit depend on the shared object ('shared') variant of
wannier90 if the wannier90 variant is selected

Add configure args for wannier90 libs, includes, and binaries and to
set MPIFC

set the dft-flavor to wannier90 when wannier90 is enabled and only
set the dft flavor to 'atompaw+libxc' if wannier90 is not selected

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

Co-authored-by: Greg Becker <becker33@llnl.gov>

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

Co-authored-by: Greg Becker <becker33@llnl.gov>

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

Co-authored-by: Greg Becker <becker33@llnl.gov>

* incorporated bbecker's suggestion for making the strings less ugly!

* incorporated bbecker's suggestion to fix the logic for picking which
"DFT flavor" configure argument.
If the wannier variant is enabled, it passes --with-dft-flavor=wannier90
to configure, otherwise it passes --with-dft-flavor=atompaw+libxc to configure

* Changed to using plain strings

* Fixed version tests

* incorporated @adamjstewart's fix for testing if the major version is > 2

* incorporated @adamjstewart's fix to check if mpi is enabled and
only set the MPIFC variable if it is.

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

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Only set MPIFC if '+mpi' is set

* incorporated fixes from @adamjstewart including:
	- using the string=True argument to filter_file (and removed the unneeded
 	  escapes)
	- changing the url to the github location
	- fixing the version checks
	- building a libwannier.dylib on darwin

* incorporated fixes suggested by @adamjstewart including:
	- using the string=True argument to filter_file and cleaned up the escapes
	- only pass the MPIFC argument to configure when '+mpi' is set
	- chaned the url to the github site for Wannier090
	- fixed the version checks
	- build a 'libwannier.dylib' file when building the shared variant on darwin

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

Co-authored-by: Greg Becker <becker33@llnl.gov>

* moved a configure argument from it's own '+mpi' check to under the lower one

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

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* Cleaned up syntax as suggested by @adamjstewart
It looks *so much better* now!  Thanks!

* removed unneeded import of 'find' from 'llnl.util.filesystem' package
as suggested by @adamjstewart

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

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>

* incorporated changes from @adamjstewart
changed check to "if '@:2 +shared' in spec:" instead of a nested check of '@:2' and
'+shared'
removed unneeded joins used in filter_file and spliced the list of objs directly into
the filter_file call
used the dso_suffix instead of testing for darwin to determine the name of the
shared library

* removed whitespace from blank line

* fixed bug with '../../wannier90.x: .*' not being treated as a regexp.  Thanks Adam!

* fixed missing whitespace when modifying Makefile.2

Co-authored-by: Greg Becker <becker33@llnl.gov>
Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
This commit is contained in:
downloadico 2020-07-16 14:57:42 -06:00 committed by GitHub
parent 3449087284
commit 3f24188d19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 134 additions and 20 deletions

View File

@ -56,6 +56,9 @@ class Abinit(AutotoolsPackage):
variant('hdf5', default=False, variant('hdf5', default=False,
description='Enables HDF5+Netcdf4 with MPI. WARNING: experimental') description='Enables HDF5+Netcdf4 with MPI. WARNING: experimental')
variant('wannier90', default=False,
description='Enables the Wannier90 library')
# 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')
@ -84,6 +87,8 @@ class Abinit(AutotoolsPackage):
# Cannot ask for +scalapack if it does not depend on MPI # Cannot ask for +scalapack if it does not depend on MPI
conflicts('+scalapack', when='~mpi') conflicts('+scalapack', when='~mpi')
depends_on("wannier90+shared", when='+wannier90')
# Elpa is a substitute for scalapack and needs mpi # Elpa is a substitute for scalapack and needs mpi
# conflicts('+elpa', when='~mpi') # conflicts('+elpa', when='~mpi')
# conflicts('+elpa', when='+scalapack') # conflicts('+elpa', when='+scalapack')
@ -95,12 +100,25 @@ def configure_args(self):
options = [] options = []
oapp = options.append oapp = options.append
if '+wannier90' in spec:
oapp('--with-wannier90-libs=-L{0}'
.format(spec['wannier90'].prefix.lib + ' -lwannier -lm'))
oapp('--with-wannier90-incs=-I{0}'
.format(spec['wannier90'].prefix.modules))
oapp('--with-wannier90-bins={0}'
.format(spec['wannier90'].prefix.bin))
oapp('--enable-connectors')
oapp('--with-dft-flavor=wannier90')
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={0}'.format(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')
oapp('MPIFC={0}/mpifc'.format(spec['mpi'].prefix.bin))
if '~wannier90' in spec:
oapp('--with-dft-flavor=atompaw+libxc')
# Activate OpenMP in Abinit Fortran code. # Activate OpenMP in Abinit Fortran code.
if '+openmp' in spec: if '+openmp' in spec:
@ -129,7 +147,6 @@ def configure_args(self):
'--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')
# LibXC library # LibXC library
libxc = spec['libxc:fortran'] libxc = spec['libxc:fortran']

View File

@ -15,8 +15,10 @@ class Wannier90(MakefilePackage):
Wannier90 is released under the GNU General Public License. Wannier90 is released under the GNU General Public License.
""" """
homepage = 'http://wannier.org' homepage = 'http://wannier.org'
url = 'http://wannier.org/code/wannier90-2.0.1.tar.gz' url = 'https://github.com/wannier-developers/wannier90/archive/v3.1.0.tar.gz'
version('3.1.0', sha256='40651a9832eb93dec20a8360dd535262c261c34e13c41b6755fa6915c936b254')
version('3.0.0', sha256='f196e441dcd7b67159a1d09d2d7de2893b011a9f03aab6b30c4703ecbf20fe5b')
version('2.1.0', sha256='ee90108d4bc4aa6a1cf16d72abebcb3087cf6c1007d22dda269eb7e7076bddca') version('2.1.0', sha256='ee90108d4bc4aa6a1cf16d72abebcb3087cf6c1007d22dda269eb7e7076bddca')
version('2.0.1', sha256='05ea7cd421a219ce19d379ad6ae3d9b1a84be4ffb367506ffdfab1e729309e94') version('2.0.1', sha256='05ea7cd421a219ce19d379ad6ae3d9b1a84be4ffb367506ffdfab1e729309e94')
@ -26,17 +28,40 @@ class Wannier90(MakefilePackage):
parallel = False parallel = False
build_targets = [ variant(
'wannier', 'post', 'lib', 'w90chk2chk', 'w90vdw', 'w90pov' 'shared',
] default=True,
description='Builds a shared version of the library'
)
@property
def build_targets(self):
targets = []
if '@:2' in self.spec:
targets = [
'lib', 'wannier', 'post', 'w90chk2chk', 'w90vdw', 'w90pov'
]
if '@3:' in self.spec:
targets = ['wannier', 'post', 'lib', 'w90chk2chk', 'w90vdw']
if '+shared' in self.spec:
targets.append('dynlib')
return targets
def url_for_version(self, version):
if (version > Version('2')):
url = 'https://github.com/wannier-developers/wannier90/archive/v{0}.tar.gz'
else:
url = 'http://wannier.org/code/wannier90-{0}.tar.gz'
return url.format(version)
@property @property
def makefile_name(self): def makefile_name(self):
# Older versions use 'make.sys' # Version 2.0.1 uses make.sys,
filename = 'make.sys' # other verions use make.inc
if self.spec.satisfies('@2.0.1'):
# While newer search for 'make.inc' filename = 'make.sys'
if self.spec.satisfies('@2.1.0:'): else:
filename = 'make.inc' filename = 'make.inc'
abspath = join_path(self.stage.source_path, filename) abspath = join_path(self.stage.source_path, filename)
@ -46,10 +71,12 @@ def edit(self, spec, prefix):
lapack = self.spec['lapack'].libs lapack = self.spec['lapack'].libs
blas = self.spec['blas'].libs blas = self.spec['blas'].libs
mpi = self.spec['mpi'].libs
substitutions = { substitutions = {
'@F90': spack_fc, '@F90': spack_fc,
'@MPIF90': self.spec['mpi'].mpifc, '@MPIF90': self.spec['mpi'].mpifc,
'@LIBS': (lapack + blas).joined() '@LIBS': (lapack + blas + mpi).joined()
} }
template = join_path( template = join_path(
@ -61,10 +88,67 @@ def edit(self, spec, prefix):
for key, value in substitutions.items(): for key, value in substitutions.items():
filter_file(key, value, self.makefile_name) filter_file(key, value, self.makefile_name)
def install(self, spec, prefix): if '@:2 +shared' in self.spec:
# this is to build a .shared wannier90 library
filter_file('LIBRARY = ../../libwannier.a',
'LIBRARY = ../../libwannier.' + dso_suffix,
join_path(self.stage.source_path, 'src/Makefile.2'))
filter_file('parameters.o kmesh.o io.o comms.o '
'utility.o get_oper.o constants.o '
'postw90_common.o wan_ham.o spin.o '
'dos.o berry.o kpath.o kslice.o '
'boltzwann.o geninterp.o',
'comms.o get_oper.o postw90_common.o '
'wan_ham.o spin.o dos.o berry.o '
'kpath.o kslice.o boltzwann.o geninterp.o',
join_path(self.stage.source_path,
'src/Makefile.2'))
filter_file('../../wannier90.x: .*',
'../../wannier90.x: $(OBJS) '
'../wannier_prog.F90 $(LIBRARY)',
join_path(self.stage.source_path,
'src/Makefile.2'))
filter_file('../../postw90.x: $(OBJS_POST) '
'$(POSTDIR)postw90.F90',
'../../postw90.x: $(OBJS_POST) '
'$(POSTDIR)postw90.F90 $(LIBRARY)',
join_path(self.stage.source_path,
'src/Makefile.2'), string=True)
filter_file(
'$(COMPILER) ../wannier_prog.F90 '
'$(LDOPTS) $(OBJS) $(LIBS) '
'-o ../../wannier90.x',
'$(COMPILER) -I../obj ../wannier_prog.F90 '
'$(LDOPTS) -L../.. -lwannier '
'-o ../../wannier90.x',
join_path(self.stage.source_path,
'src/Makefile.2'), string=True)
filter_file(
'$(COMPILER) $(POSTDIR)postw90.F90 '
'$(POSTOPTS) $(LDOPTS) '
'$(OBJS_POST) '
'$(LIBS) -o ../../postw90.x',
'$(COMPILER) -I../obj $(POSTDIR)postw90.F90 '
'$(POSTOPTS) $(LDOPTS) $(OBJS_POST) '
'-L../.. -lwannier $(LIBS) -o ../../postw90.x',
join_path(self.stage.source_path,
'src/Makefile.2'), string=True)
filter_file(
'$(AR) $(ARFLAGS) '
'$(LIBRARY) $(OBJS2) $(OBJS)',
'$(MPIF90) $(FCOPTS) -shared -o '
'$(LIBRARY) $(OBJS2) $(OBJS) $(LIBS)',
join_path(self.stage.source_path,
'src/Makefile.2'), string=True)
def setup_build_environment(self, env):
env.set('MPIFC', self.prefix.bin.mpifc)
def install(self, spec, prefix):
mkdirp(self.prefix.bin) mkdirp(self.prefix.bin)
mkdirp(self.prefix.lib) mkdirp(self.prefix.lib)
if '+shared' in spec:
mkdirp(self.prefix.modules)
install( install(
join_path(self.stage.source_path, 'wannier90.x'), join_path(self.stage.source_path, 'wannier90.x'),
@ -76,10 +160,17 @@ def install(self, spec, prefix):
join_path(self.prefix.bin, 'postw90.x') join_path(self.prefix.bin, 'postw90.x')
) )
install( inst = []
join_path(self.stage.source_path, 'libwannier.a'), if '+shared' in spec:
join_path(self.prefix.lib, 'libwannier.a') inst.append('libwannier.' + dso_suffix)
) # version 3 or 2 without the shared variant
# also has a .a version of the library
if '@3:' in spec or '~shared' in spec:
inst.append('libwannier.a')
for file in inst:
install(join_path(self.stage.source_path, file),
join_path(self.prefix.lib, file))
install( install(
join_path(self.stage.source_path, 'w90chk2chk.x'), join_path(self.stage.source_path, 'w90chk2chk.x'),
@ -91,12 +182,18 @@ def install(self, spec, prefix):
join_path(self.prefix.bin, 'w90vdw.x') join_path(self.prefix.bin, 'w90vdw.x')
) )
install( if spec.satisfies('@:2'):
join_path(self.stage.source_path, 'utility', 'w90pov', 'w90pov'), install(
join_path(self.prefix.bin, 'w90pov') join_path(self.stage.source_path,
) 'utility', 'w90pov', 'w90pov'),
join_path(self.prefix.bin, 'w90pov')
)
install_tree( install_tree(
join_path(self.stage.source_path, 'pseudo'), join_path(self.stage.source_path, 'pseudo'),
join_path(self.prefix.bin, 'pseudo') join_path(self.prefix.bin, 'pseudo')
) )
for file in find(join_path(self.stage.source_path, 'src/obj'),
'*.mod'):
install(file, self.prefix.modules)