libint + cp2k: 2-stage build with 'tune' and 'fortran' variants (#12475)

* libint: switch to 2-stage build for 2.6.0+

* libint: add tune and fortran variants

* cp2k: add support for libint >= 2.0

* cp2k: use pkg-config for linking libxc
This commit is contained in:
Tiziano Müller 2019-10-02 21:31:19 +02:00 committed by Massimiliano Culpo
parent da18ac3a0f
commit d99b92febd
2 changed files with 128 additions and 20 deletions

View File

@ -61,6 +61,14 @@ class Cp2k(MakefilePackage, CudaPackage):
variant('cuda_blas', default=False,
description=('Use CUBLAS for general matrix operations in DBCSR'))
HFX_LMAX_RANGE = range(4, 8)
variant('lmax',
description='Maximum supported angular momentum (HFX and others)',
default='5',
values=list(HFX_LMAX_RANGE),
multi=False)
depends_on('python', type='build')
depends_on('fftw@3:', when='~openmp')
@ -80,11 +88,19 @@ class Cp2k(MakefilePackage, CudaPackage):
depends_on('libxsmm@1.11:~header-only', when='smm=libxsmm')
# use pkg-config (support added in libxsmm-1.10) to link to libxsmm
depends_on('pkgconfig', type='build', when='smm=libxsmm')
# ... and in CP2K 7.0+ for linking to libint2
depends_on('pkgconfig', type='build', when='@7.0:')
# libint & libxc are always statically linked
depends_on('libint@1.1.4:1.2', when='@3.0:', type='build')
depends_on('libint@1.1.4:1.2', when='@3.0:6.9', type='build')
for lmax in HFX_LMAX_RANGE:
# libint2 can be linked dynamically again
depends_on('libint@2.6.0:+fortran tune=cp2k-lmax-{0}'.format(lmax),
when='@7.0: lmax={0}'.format(lmax))
depends_on('libxc@2.2.2:', when='+libxc@:5.5999', type='build')
depends_on('libxc@4.0.3:', when='+libxc@6.0:', type='build')
depends_on('libxc@4.0.3:', when='+libxc@6.0:6.9', type='build')
depends_on('libxc@4.0.3:', when='+libxc@7.0:')
depends_on('mpi@2:', when='+mpi')
depends_on('scalapack', when='+mpi')
@ -169,11 +185,15 @@ def edit(self, spec, prefix):
dflags = ['-DNDEBUG']
cppflags = [
'-D__FFTW3',
'-D__LIBINT',
'-D__FFTW3',
fftw.headers.cpp_flags,
]
if '@:6.9' in spec:
cppflags += [
'-D__LIBINT_MAX_AM=6',
'-D__LIBDERIV_MAX_AM1=5',
fftw.headers.cpp_flags,
]
if '^mpi@3:' in spec:
@ -220,6 +240,7 @@ def edit(self, spec, prefix):
if 'superlu-dist@4.3' in spec:
ldflags.insert(0, '-Wl,--allow-multiple-definition')
if '@:6.9' in spec:
# libint-1.x.y has to be linked statically to work around
# inconsistencies in its Fortran interface definition
# (short-int vs int) which otherwise causes segfaults at runtime
@ -228,6 +249,9 @@ def edit(self, spec, prefix):
os.path.join(spec['libint'].libs.directories[0], 'libderiv.a'),
os.path.join(spec['libint'].libs.directories[0], 'libint.a'),
])
else:
fcflags += ['$(shell pkg-config --cflags libint2)']
libs += ['$(shell pkg-config --libs libint2)']
if '+plumed' in self.spec:
dflags.extend(['-D__PLUMED2'])
@ -286,14 +310,16 @@ def edit(self, spec, prefix):
libs.append(wannier)
if '+libxc' in spec:
libxc = spec['libxc:fortran,static']
cppflags += [
'-D__LIBXC',
libxc.headers.cpp_flags
]
cppflags += ['-D__LIBXC']
if '@:6.9' in spec:
libxc = spec['libxc:fortran,static']
cppflags += [libxc.headers.cpp_flags]
ldflags.append(libxc.libs.search_flags)
libs.append(str(libxc.libs))
else:
fcflags += ['$(shell pkg-config --cflags libxcf03)']
libs += ['$(shell pkg-config --libs libxcf03)']
if '+pexsi' in self.spec:
cppflags.append('-D__LIBPEXSI')

View File

@ -3,9 +3,19 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
from spack import *
TUNE_VARIANTS = (
'none',
'cp2k-lmax-4',
'cp2k-lmax-5',
'cp2k-lmax-6',
'cp2k-lmax-7',
)
class Libint(AutotoolsPackage):
"""Libint is a high-performance library for computing
Gaussian integrals in quantum mechanics.
@ -14,6 +24,7 @@ class Libint(AutotoolsPackage):
homepage = "https://github.com/evaleev/libint"
url = "https://github.com/evaleev/libint/archive/v2.1.0.tar.gz"
version('2.6.0', sha256='4ae47e8f0b5632c3d2a956469a7920896708e9f0e396ec10071b8181e4c8d9fa')
version('2.4.2', sha256='86dff38065e69a3a51d15cfdc638f766044cb87e5c6682d960c14f9847e2eac3')
version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4')
version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019')
@ -22,6 +33,12 @@ class Libint(AutotoolsPackage):
version('1.1.6', sha256='f201b0c621df678cfe8bdf3990796b8976ff194aba357ae398f2f29b0e2985a6')
version('1.1.5', sha256='ec8cd4a4ba1e1a98230165210c293632372f0e573acd878ed62e5ec6f8b6174b')
variant('fortran', default=False,
description='Build & install Fortran bindings')
variant('tune', default='none', multi=False,
values=TUNE_VARIANTS,
description='Tune libint for use with the given package')
# Build dependencies
depends_on('autoconf@2.52:', type='build')
depends_on('automake', type='build')
@ -31,6 +48,11 @@ class Libint(AutotoolsPackage):
depends_on('boost', when='@2:')
depends_on('gmp', when='@2:')
for tvariant in TUNE_VARIANTS[1:]:
conflicts('tune={0}'.format(tvariant), when='@:2.5.99',
msg=('for versions prior to 2.6, tuning for specific'
'codes/configurations is not supported'))
def url_for_version(self, version):
base_url = "https://github.com/evaleev/libint/archive"
if version == Version('1.0.0'):
@ -45,6 +67,10 @@ def autoreconf(self, spec, prefix):
aclocal('-I', 'lib/autoconf')
autoconf()
if '@2.6.0:' in spec:
# skip tarball creation and removal of dir with generated code
filter_file(r'^(export::.*)\s+tgz$', r'\1', 'export/Makefile')
@property
def optflags(self):
flags = '-O2'
@ -89,4 +115,60 @@ def configure_args(self):
'--with-libint-max-am=5',
'--with-libderiv-max-am1=4'
])
if '@2.6.0:' in self.spec:
config_args += ['--with-libint-exportdir=generated']
tune_value = self.spec.variants['tune'].value
if tune_value.startswith('cp2k'):
lmax = int(tune_value.split('-lmax-')[1])
config_args += [
'--enable-eri=1',
'--enable-eri2=1',
'--enable-eri3=1',
'--with-max-am={0}'.format(lmax),
'--with-eri-max-am={0},{1}'.format(lmax, lmax - 1),
'--with-eri2-max-am={0},{1}'.format(lmax + 2, lmax + 1),
'--with-eri3-max-am={0},{1}'.format(lmax + 2, lmax + 1),
'--with-opt-am=3',
# keep code-size at an acceptable limit,
# cf. https://github.com/evaleev/libint/wiki#program-specific-notes:
'--enable-generic-code',
'--disable-unrolling',
]
return config_args
@property
def build_targets(self):
if '@2.6.0:' in self.spec:
return ['export']
return []
@when('@2.6.0:')
def install(self, spec, prefix):
"""
Starting from libint 2.6.0 we're using the 2-stage build
to get support for the Fortran bindings, required by some
packages (CP2K notably).
"""
# upstream says that using configure/make for the generated code
# is deprecated and one should use CMake, but with the currently
# recent 2.7.0.b1 it still doesn't work
with working_dir(os.path.join(self.build_directory, 'generated')):
# straight from the AutotoolsPackage class:
options = [
'--prefix={0}'.format(prefix),
'--enable-shared',
'--with-cxx-optflags={0}'.format(self.optflags),
]
if '+fortran' in spec:
options += ['--enable-fortran']
configure = Executable('./configure')
configure(*options)
make()
make('install')