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:
parent
da18ac3a0f
commit
d99b92febd
@ -61,6 +61,14 @@ class Cp2k(MakefilePackage, CudaPackage):
|
|||||||
variant('cuda_blas', default=False,
|
variant('cuda_blas', default=False,
|
||||||
description=('Use CUBLAS for general matrix operations in DBCSR'))
|
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('python', type='build')
|
||||||
|
|
||||||
depends_on('fftw@3:', when='~openmp')
|
depends_on('fftw@3:', when='~openmp')
|
||||||
@ -80,11 +88,19 @@ class Cp2k(MakefilePackage, CudaPackage):
|
|||||||
depends_on('libxsmm@1.11:~header-only', when='smm=libxsmm')
|
depends_on('libxsmm@1.11:~header-only', when='smm=libxsmm')
|
||||||
# use pkg-config (support added in libxsmm-1.10) to link to libxsmm
|
# use pkg-config (support added in libxsmm-1.10) to link to libxsmm
|
||||||
depends_on('pkgconfig', type='build', when='smm=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
|
# 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@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('mpi@2:', when='+mpi')
|
||||||
depends_on('scalapack', when='+mpi')
|
depends_on('scalapack', when='+mpi')
|
||||||
@ -169,11 +185,15 @@ def edit(self, spec, prefix):
|
|||||||
|
|
||||||
dflags = ['-DNDEBUG']
|
dflags = ['-DNDEBUG']
|
||||||
cppflags = [
|
cppflags = [
|
||||||
'-D__FFTW3',
|
|
||||||
'-D__LIBINT',
|
'-D__LIBINT',
|
||||||
|
'-D__FFTW3',
|
||||||
|
fftw.headers.cpp_flags,
|
||||||
|
]
|
||||||
|
|
||||||
|
if '@:6.9' in spec:
|
||||||
|
cppflags += [
|
||||||
'-D__LIBINT_MAX_AM=6',
|
'-D__LIBINT_MAX_AM=6',
|
||||||
'-D__LIBDERIV_MAX_AM1=5',
|
'-D__LIBDERIV_MAX_AM1=5',
|
||||||
fftw.headers.cpp_flags,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if '^mpi@3:' in spec:
|
if '^mpi@3:' in spec:
|
||||||
@ -220,6 +240,7 @@ def edit(self, spec, prefix):
|
|||||||
if 'superlu-dist@4.3' in spec:
|
if 'superlu-dist@4.3' in spec:
|
||||||
ldflags.insert(0, '-Wl,--allow-multiple-definition')
|
ldflags.insert(0, '-Wl,--allow-multiple-definition')
|
||||||
|
|
||||||
|
if '@:6.9' in spec:
|
||||||
# libint-1.x.y has to be linked statically to work around
|
# libint-1.x.y has to be linked statically to work around
|
||||||
# inconsistencies in its Fortran interface definition
|
# inconsistencies in its Fortran interface definition
|
||||||
# (short-int vs int) which otherwise causes segfaults at runtime
|
# (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], 'libderiv.a'),
|
||||||
os.path.join(spec['libint'].libs.directories[0], 'libint.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:
|
if '+plumed' in self.spec:
|
||||||
dflags.extend(['-D__PLUMED2'])
|
dflags.extend(['-D__PLUMED2'])
|
||||||
@ -286,14 +310,16 @@ def edit(self, spec, prefix):
|
|||||||
libs.append(wannier)
|
libs.append(wannier)
|
||||||
|
|
||||||
if '+libxc' in spec:
|
if '+libxc' in spec:
|
||||||
libxc = spec['libxc:fortran,static']
|
cppflags += ['-D__LIBXC']
|
||||||
cppflags += [
|
|
||||||
'-D__LIBXC',
|
|
||||||
libxc.headers.cpp_flags
|
|
||||||
]
|
|
||||||
|
|
||||||
|
if '@:6.9' in spec:
|
||||||
|
libxc = spec['libxc:fortran,static']
|
||||||
|
cppflags += [libxc.headers.cpp_flags]
|
||||||
ldflags.append(libxc.libs.search_flags)
|
ldflags.append(libxc.libs.search_flags)
|
||||||
libs.append(str(libxc.libs))
|
libs.append(str(libxc.libs))
|
||||||
|
else:
|
||||||
|
fcflags += ['$(shell pkg-config --cflags libxcf03)']
|
||||||
|
libs += ['$(shell pkg-config --libs libxcf03)']
|
||||||
|
|
||||||
if '+pexsi' in self.spec:
|
if '+pexsi' in self.spec:
|
||||||
cppflags.append('-D__LIBPEXSI')
|
cppflags.append('-D__LIBPEXSI')
|
||||||
|
@ -3,9 +3,19 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
import os
|
||||||
from spack import *
|
from spack import *
|
||||||
|
|
||||||
|
|
||||||
|
TUNE_VARIANTS = (
|
||||||
|
'none',
|
||||||
|
'cp2k-lmax-4',
|
||||||
|
'cp2k-lmax-5',
|
||||||
|
'cp2k-lmax-6',
|
||||||
|
'cp2k-lmax-7',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Libint(AutotoolsPackage):
|
class Libint(AutotoolsPackage):
|
||||||
"""Libint is a high-performance library for computing
|
"""Libint is a high-performance library for computing
|
||||||
Gaussian integrals in quantum mechanics.
|
Gaussian integrals in quantum mechanics.
|
||||||
@ -14,6 +24,7 @@ class Libint(AutotoolsPackage):
|
|||||||
homepage = "https://github.com/evaleev/libint"
|
homepage = "https://github.com/evaleev/libint"
|
||||||
url = "https://github.com/evaleev/libint/archive/v2.1.0.tar.gz"
|
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.2', sha256='86dff38065e69a3a51d15cfdc638f766044cb87e5c6682d960c14f9847e2eac3')
|
||||||
version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4')
|
version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4')
|
||||||
version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019')
|
version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019')
|
||||||
@ -22,6 +33,12 @@ class Libint(AutotoolsPackage):
|
|||||||
version('1.1.6', sha256='f201b0c621df678cfe8bdf3990796b8976ff194aba357ae398f2f29b0e2985a6')
|
version('1.1.6', sha256='f201b0c621df678cfe8bdf3990796b8976ff194aba357ae398f2f29b0e2985a6')
|
||||||
version('1.1.5', sha256='ec8cd4a4ba1e1a98230165210c293632372f0e573acd878ed62e5ec6f8b6174b')
|
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
|
# Build dependencies
|
||||||
depends_on('autoconf@2.52:', type='build')
|
depends_on('autoconf@2.52:', type='build')
|
||||||
depends_on('automake', type='build')
|
depends_on('automake', type='build')
|
||||||
@ -31,6 +48,11 @@ class Libint(AutotoolsPackage):
|
|||||||
depends_on('boost', when='@2:')
|
depends_on('boost', when='@2:')
|
||||||
depends_on('gmp', 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):
|
def url_for_version(self, version):
|
||||||
base_url = "https://github.com/evaleev/libint/archive"
|
base_url = "https://github.com/evaleev/libint/archive"
|
||||||
if version == Version('1.0.0'):
|
if version == Version('1.0.0'):
|
||||||
@ -45,6 +67,10 @@ def autoreconf(self, spec, prefix):
|
|||||||
aclocal('-I', 'lib/autoconf')
|
aclocal('-I', 'lib/autoconf')
|
||||||
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
|
@property
|
||||||
def optflags(self):
|
def optflags(self):
|
||||||
flags = '-O2'
|
flags = '-O2'
|
||||||
@ -89,4 +115,60 @@ def configure_args(self):
|
|||||||
'--with-libint-max-am=5',
|
'--with-libint-max-am=5',
|
||||||
'--with-libderiv-max-am1=4'
|
'--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
|
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')
|
||||||
|
Loading…
Reference in New Issue
Block a user