2021-01-02 15:10:28 +08:00
|
|
|
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
|
2018-10-08 04:52:23 +08:00
|
|
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
2016-07-30 17:00:47 +08:00
|
|
|
#
|
2018-10-08 04:52:23 +08:00
|
|
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
|
|
|
|
2016-07-30 17:00:47 +08:00
|
|
|
import os
|
2019-02-14 14:11:20 +08:00
|
|
|
import os.path
|
2016-07-30 17:00:47 +08:00
|
|
|
import copy
|
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
import spack.util.environment
|
2016-07-30 17:00:47 +08:00
|
|
|
|
|
|
|
|
2019-08-14 01:59:08 +08:00
|
|
|
class Cp2k(MakefilePackage, CudaPackage):
|
2016-07-30 17:00:47 +08:00
|
|
|
"""CP2K is a quantum chemistry and solid state physics software package
|
|
|
|
that can perform atomistic simulations of solid state, liquid, molecular,
|
|
|
|
periodic, material, crystal, and biological systems
|
|
|
|
"""
|
|
|
|
homepage = 'https://www.cp2k.org'
|
2018-11-21 01:23:01 +08:00
|
|
|
url = 'https://github.com/cp2k/cp2k/releases/download/v3.0.0/cp2k-3.0.tar.bz2'
|
2019-05-01 03:52:13 +08:00
|
|
|
git = 'https://github.com/cp2k/cp2k.git'
|
2018-11-21 01:23:01 +08:00
|
|
|
list_url = 'https://github.com/cp2k/cp2k/releases'
|
2016-07-30 17:00:47 +08:00
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
maintainers = ['dev-zero']
|
|
|
|
|
2020-04-15 02:33:49 +08:00
|
|
|
version('7.1', sha256='ccd711a09a426145440e666310dd01cc5772ab103493c4ae6a3470898cd0addb')
|
2019-02-14 14:11:20 +08:00
|
|
|
version('6.1', sha256='af803558e0a6b9e9d9ce8a3ab955ba32bacd179922455424e061c82c9fefa34b')
|
|
|
|
version('5.1', sha256='e23613b593354fa82e0b8410e17d94c607a0b8c6d9b5d843528403ab09904412')
|
|
|
|
version('4.1', sha256='4a3e4a101d8a35ebd80a9e9ecb02697fb8256364f1eccdbe4e5a85d31fe21343')
|
|
|
|
version('3.0', sha256='1acfacef643141045b7cbade7006f9b7538476d861eeecd9658c9e468dc61151')
|
2020-04-28 08:42:33 +08:00
|
|
|
version('master', branch='master', submodules="True")
|
2016-07-30 17:00:47 +08:00
|
|
|
|
|
|
|
variant('mpi', default=True, description='Enable MPI support')
|
2020-09-10 23:00:31 +08:00
|
|
|
variant('openmp', default=True, description='Enable OpenMP support')
|
2018-11-21 01:23:01 +08:00
|
|
|
variant('smm', default='libxsmm', values=('libxsmm', 'libsmm', 'blas'),
|
2017-11-16 07:49:08 +08:00
|
|
|
description='Library for small matrix multiplications')
|
2016-08-04 15:42:02 +08:00
|
|
|
variant('plumed', default=False, description='Enable PLUMED support')
|
2020-07-22 00:13:59 +08:00
|
|
|
variant('libint', default=True,
|
|
|
|
description='Use libint, required for HFX (and possibly others)')
|
2018-11-21 01:23:01 +08:00
|
|
|
variant('libxc', default=True,
|
|
|
|
description='Support additional functionals via libxc')
|
|
|
|
variant('pexsi', default=False,
|
|
|
|
description=('Enable the alternative PEXSI method'
|
|
|
|
'for density matrix evaluation'))
|
|
|
|
variant('elpa', default=False,
|
|
|
|
description='Enable optimised diagonalisation routines from ELPA')
|
2019-04-24 22:27:52 +08:00
|
|
|
variant('sirius', default=False,
|
|
|
|
description=('Enable planewave electronic structure'
|
|
|
|
' calculations via SIRIUS'))
|
2020-04-15 02:33:49 +08:00
|
|
|
variant('cosma', default=False, description='Use COSMA for p?gemm')
|
2020-12-25 07:12:34 +08:00
|
|
|
variant('libvori', default=False,
|
|
|
|
description=('Enable support for Voronoi integration'
|
|
|
|
' and BQB compression'))
|
|
|
|
variant('spglib', default=False, description='Enable support for spglib')
|
2016-07-30 17:00:47 +08:00
|
|
|
|
2019-08-14 01:59:08 +08:00
|
|
|
variant('cuda_arch_35_k20x', default=False,
|
|
|
|
description=('CP2K (resp. DBCSR) has specific parameter sets for'
|
|
|
|
' different GPU models. Enable this when building'
|
|
|
|
' with cuda_arch=35 for a K20x instead of a K40'))
|
|
|
|
variant('cuda_fft', default=False,
|
|
|
|
description=('Use CUDA also for FFTs in the PW part of CP2K'))
|
|
|
|
variant('cuda_blas', default=False,
|
|
|
|
description=('Use CUBLAS for general matrix operations in DBCSR'))
|
|
|
|
|
2019-10-03 03:31:19 +08:00
|
|
|
HFX_LMAX_RANGE = range(4, 8)
|
|
|
|
|
|
|
|
variant('lmax',
|
|
|
|
description='Maximum supported angular momentum (HFX and others)',
|
|
|
|
default='5',
|
2020-11-07 10:58:38 +08:00
|
|
|
values=tuple(map(str, HFX_LMAX_RANGE)),
|
2019-10-03 03:31:19 +08:00
|
|
|
multi=False)
|
|
|
|
|
2016-08-15 22:45:19 +08:00
|
|
|
depends_on('python', type='build')
|
2016-07-30 17:00:47 +08:00
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
depends_on('blas')
|
|
|
|
depends_on('lapack')
|
|
|
|
depends_on('fftw-api@3')
|
2018-11-21 01:23:01 +08:00
|
|
|
|
2019-05-03 22:30:07 +08:00
|
|
|
# require libxsmm-1.11+ since 1.10 can leak file descriptors in Fortran
|
|
|
|
depends_on('libxsmm@1.11:~header-only', when='smm=libxsmm')
|
2018-11-21 01:23:01 +08:00
|
|
|
# use pkg-config (support added in libxsmm-1.10) to link to libxsmm
|
|
|
|
depends_on('pkgconfig', type='build', when='smm=libxsmm')
|
2019-10-03 03:31:19 +08:00
|
|
|
# ... and in CP2K 7.0+ for linking to libint2
|
2020-07-22 00:13:59 +08:00
|
|
|
depends_on('pkgconfig', type='build', when='+libint@7.0:')
|
|
|
|
depends_on('pkgconfig', type='build', when='+libxc@7.0:')
|
2018-11-21 01:23:01 +08:00
|
|
|
|
|
|
|
# libint & libxc are always statically linked
|
2020-07-22 00:13:59 +08:00
|
|
|
depends_on('libint@1.1.4:1.2', when='+libint@3.0:6.9', type='build')
|
2019-10-03 03:31:19 +08:00
|
|
|
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),
|
2020-07-22 00:13:59 +08:00
|
|
|
when='+libint@7.0: lmax={0}'.format(lmax))
|
2019-10-03 03:31:19 +08:00
|
|
|
|
2020-08-31 23:27:23 +08:00
|
|
|
depends_on('libxc@2.2.2:3.99.0', when='+libxc@:5.5999', type='build')
|
|
|
|
depends_on('libxc@4.0.3:4.99.0', when='+libxc@6.0:6.9', type='build')
|
|
|
|
depends_on('libxc@4.0.3:4.99.0', when='+libxc@7.0:')
|
2016-07-30 17:00:47 +08:00
|
|
|
|
2017-05-06 00:24:04 +08:00
|
|
|
depends_on('mpi@2:', when='+mpi')
|
2016-07-30 17:00:47 +08:00
|
|
|
depends_on('scalapack', when='+mpi')
|
2020-04-15 02:33:49 +08:00
|
|
|
depends_on('cosma+scalapack', when='+cosma')
|
|
|
|
depends_on('cosma+cuda+scalapack', when='+cosma+cuda')
|
2018-11-21 01:23:01 +08:00
|
|
|
depends_on('elpa@2011.12:2016.13+openmp', when='+openmp+elpa@:5.999')
|
2020-09-10 23:00:31 +08:00
|
|
|
depends_on('elpa@2011.12:2017.11+openmp', when='+openmp+elpa@6.0:6.999')
|
2020-04-28 08:42:33 +08:00
|
|
|
depends_on('elpa@2018.05:+openmp', when='+openmp+elpa@7.0:')
|
2018-11-21 01:23:01 +08:00
|
|
|
depends_on('elpa@2011.12:2016.13~openmp', when='~openmp+elpa@:5.999')
|
2020-09-10 23:00:31 +08:00
|
|
|
depends_on('elpa@2011.12:2017.11~openmp', when='~openmp+elpa@6.0:6.999')
|
2020-04-15 02:33:49 +08:00
|
|
|
depends_on('elpa@2018.05:~openmp', when='~openmp+elpa@7.0:')
|
2016-08-04 15:42:02 +08:00
|
|
|
depends_on('plumed+shared+mpi', when='+plumed+mpi')
|
|
|
|
depends_on('plumed+shared~mpi', when='+plumed~mpi')
|
2017-03-30 22:46:05 +08:00
|
|
|
|
2018-11-21 01:23:01 +08:00
|
|
|
# while we link statically against PEXSI, its own deps may be linked in
|
|
|
|
# dynamically, therefore can't set this as pure build-type dependency.
|
|
|
|
depends_on('pexsi+fortran@0.9.0:0.9.999', when='+pexsi@:4.999')
|
|
|
|
depends_on('pexsi+fortran@0.10.0:', when='+pexsi@5.0:')
|
|
|
|
|
2019-04-24 22:27:52 +08:00
|
|
|
# only OpenMP should be consistenly used, all other common things
|
|
|
|
# like ELPA, SCALAPACK are independent and Spack will ensure that
|
|
|
|
# a consistent/compat. combination is pulled in to the dependency graph.
|
2020-09-10 23:00:31 +08:00
|
|
|
depends_on('sirius@:6.999+fortran+vdwxc+shared+openmp', when='@:7.999+sirius+openmp')
|
|
|
|
depends_on('sirius@:6.999+fortran+vdwxc+shared~openmp', when='@:7.999+sirius~openmp')
|
|
|
|
|
|
|
|
depends_on('sirius@7:+fortran+vdwxc+shared+openmp', when='@8:+sirius+openmp')
|
2019-04-24 22:27:52 +08:00
|
|
|
|
2019-08-14 01:59:08 +08:00
|
|
|
# the bundled libcusmm uses numpy in the parameter prediction (v7+)
|
2020-04-15 02:33:49 +08:00
|
|
|
# which is written using Python 3
|
2019-08-14 01:59:08 +08:00
|
|
|
depends_on('py-numpy', when='@7:+cuda', type='build')
|
2020-04-15 02:33:49 +08:00
|
|
|
depends_on('python@3.6:', when='@7:+cuda', type='build')
|
2019-08-14 01:59:08 +08:00
|
|
|
|
2020-12-25 07:12:34 +08:00
|
|
|
depends_on('libvori@201217:', when='@8:+libvori', type='build')
|
|
|
|
depends_on('spglib', when='+spglib')
|
|
|
|
|
2020-04-15 02:33:49 +08:00
|
|
|
# PEXSI, ELPA, COSMA and SIRIUS depend on MPI
|
2018-11-21 01:23:01 +08:00
|
|
|
conflicts('~mpi', '+pexsi')
|
|
|
|
conflicts('~mpi', '+elpa')
|
2019-04-24 22:27:52 +08:00
|
|
|
conflicts('~mpi', '+sirius')
|
2020-04-15 02:33:49 +08:00
|
|
|
conflicts('~mpi', '+cosma')
|
2019-04-24 22:27:52 +08:00
|
|
|
conflicts('+sirius', '@:6.999') # sirius support was introduced in 7+
|
2020-04-15 02:33:49 +08:00
|
|
|
conflicts('+cosma', '@:7.999') # COSMA support was introduced in 8+
|
2018-11-21 01:23:01 +08:00
|
|
|
|
2020-12-25 07:12:34 +08:00
|
|
|
conflicts('+libvori', '@:7.999') # libvori support was introduced in 8+
|
|
|
|
|
2019-08-14 01:59:08 +08:00
|
|
|
conflicts('~cuda', '+cuda_fft')
|
|
|
|
conflicts('~cuda', '+cuda_blas')
|
|
|
|
|
2017-03-30 22:46:05 +08:00
|
|
|
# Apparently cp2k@4.1 needs an "experimental" version of libwannier.a
|
|
|
|
# which is only available contacting the developer directly. See INSTALL
|
|
|
|
# in the stage of cp2k@4.1
|
2018-11-21 01:23:01 +08:00
|
|
|
depends_on('wannier90', when='@3.0+mpi', type='build')
|
2016-07-30 17:00:47 +08:00
|
|
|
|
2018-11-21 01:23:01 +08:00
|
|
|
# CP2K needs compiler specific compilation flags, e.g. optflags
|
2020-06-26 00:18:48 +08:00
|
|
|
conflicts('%apple-clang')
|
2018-11-21 01:23:01 +08:00
|
|
|
conflicts('%clang')
|
|
|
|
conflicts('%nag')
|
2016-07-30 17:00:47 +08:00
|
|
|
|
2020-08-01 05:17:31 +08:00
|
|
|
# please set variants: smm=blas by configuring packages.yaml or install
|
|
|
|
# cp2k with option smm=blas on aarch64
|
|
|
|
conflicts('smm=libxsmm', when='target=aarch64:', msg='libxsmm is not available on arm')
|
|
|
|
|
libvdwxc: unbreak concretization, request fftw-api (#18688)
* libvdwxc: unbreak concretization, request fftw-api
mixing both fftw and fftw-api in a dependency tree can trigger the
following:
```
$ spack spec cp2k@master +sirius
==> [2020-09-16-12:36:06.552981] sirius applying constraint gsl
==> [2020-09-16-12:36:06.554270] sirius applying constraint openblas@0.3.10%gcc@7.5.0~consistent_fpcsr~ilp64+pic+shared threads=none arch=linux-opensuse_leap15-sandybridge
Traceback (most recent call last):
File "./bin/spack", line 64, in <module>
sys.exit(spack.main.main())
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/main.py", line 762, in main
return _invoke_command(command, parser, args, unknown)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/main.py", line 490, in _invoke_command
return_val = command(parser, args)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/cmd/spec.py", line 103, in spec
spec.concretize()
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/spec.py", line 2228, in concretize
user_spec_deps=user_spec_deps),
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/spec.py", line 2716, in normalize
visited, all_spec_deps, provider_index, tests)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/spec.py", line 2654, in _normalize_helper
dep, visited, spec_deps, provider_index, tests)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/spec.py", line 2613, in _merge_dependency
visited, spec_deps, provider_index, tests)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/spec.py", line 2654, in _normalize_helper
dep, visited, spec_deps, provider_index, tests)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/spec.py", line 2554, in _merge_dependency
provider = self._find_provider(dep, provider_index)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/spec.py", line 2489, in _find_provider
providers = provider_index.providers_for(vdep)
File "/data/tiziano/debug-spack/spack2/lib/spack/spack/provider_index.py", line 80, in providers_for
return sorted(s.copy() for s in result)
File "/data/tiziano/debug-spack/spack2/lib/spack/llnl/util/lang.py", line 249, in <lambda>
lambda s, o: o is not None and s._cmp_key() < o._cmp_key())
TypeError: '<' not supported between instances of 'str' and 'NoneType'
```
while at the same point disallowing MKL as a fftw provider.
Solving both issues by depending on `fftw-api@3` instead and adding a
conflict on `^fftw~mpi` when using `+mpi` (thanks to alalazo).
* cp2k: use conflicts instead of runtime checks for fftw/openblas variants
2020-09-16 23:41:46 +08:00
|
|
|
conflicts('^fftw~openmp', when='+openmp')
|
|
|
|
conflicts('^openblas threads=none', when='+openmp')
|
|
|
|
conflicts('^openblas threads=pthreads', when='+openmp')
|
|
|
|
|
2020-09-10 23:00:31 +08:00
|
|
|
conflicts('~openmp', when='@8:', msg='Building without OpenMP is not supported in CP2K 8+')
|
|
|
|
|
2021-01-13 01:01:32 +08:00
|
|
|
# We only support specific cuda_archs for which we have parameter files
|
|
|
|
# for optimal kernels. Note that we don't override the cuda_archs property
|
|
|
|
# from the parent class, since the parent class defines constraints for all
|
|
|
|
# versions. Instead just mark all unsupported cuda archs as conflicting.
|
|
|
|
dbcsr_cuda_archs = ('35', '37', '60', '70')
|
|
|
|
cuda_msg = 'cp2k only supports cuda_arch {0}'.format(dbcsr_cuda_archs)
|
|
|
|
|
|
|
|
for arch in CudaPackage.cuda_arch_values:
|
|
|
|
if arch not in dbcsr_cuda_archs:
|
|
|
|
conflicts('+cuda', when='cuda_arch={0}'.format(arch), msg=cuda_msg)
|
|
|
|
|
|
|
|
conflicts('+cuda', when='cuda_arch=none', msg=cuda_msg)
|
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
@property
|
|
|
|
def makefile_architecture(self):
|
|
|
|
return '{0.architecture}-{0.compiler.name}'.format(self.spec)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def makefile_version(self):
|
|
|
|
return '{prefix}{suffix}'.format(
|
|
|
|
prefix='p' if '+mpi' in self.spec else 's',
|
|
|
|
suffix='smp' if '+openmp' in self.spec else 'opt'
|
|
|
|
)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def makefile(self):
|
|
|
|
makefile_basename = '.'.join([
|
|
|
|
self.makefile_architecture, self.makefile_version
|
|
|
|
])
|
|
|
|
return os.path.join('arch', makefile_basename)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def archive_files(self):
|
|
|
|
return [os.path.join(self.stage.source_path, self.makefile)]
|
|
|
|
|
|
|
|
def edit(self, spec, prefix):
|
2020-04-28 08:42:33 +08:00
|
|
|
pkgconf = which('pkg-config')
|
|
|
|
|
|
|
|
if '^fftw' in spec:
|
|
|
|
fftw = spec['fftw:openmp' if '+openmp' in spec else 'fftw']
|
|
|
|
fftw_header_dir = fftw.headers.directories[0]
|
|
|
|
elif '^intel-mkl' in spec:
|
|
|
|
fftw = spec['intel-mkl']
|
|
|
|
fftw_header_dir = fftw.headers.directories[0] + '/fftw'
|
|
|
|
elif '^intel-parallel-studio+mkl' in spec:
|
|
|
|
fftw = spec['intel-parallel-studio']
|
2020-10-26 23:32:15 +08:00
|
|
|
fftw_header_dir = '<NOTFOUND>'
|
|
|
|
for incdir in [join_path(f, 'fftw')
|
|
|
|
for f in fftw.headers.directories]:
|
|
|
|
if os.path.exists(incdir):
|
|
|
|
fftw_header_dir = incdir
|
|
|
|
break
|
2019-02-14 14:11:20 +08:00
|
|
|
|
|
|
|
optimization_flags = {
|
|
|
|
'gcc': [
|
|
|
|
'-O2',
|
|
|
|
'-funroll-loops',
|
|
|
|
'-ftree-vectorize',
|
|
|
|
],
|
2020-04-28 08:42:33 +08:00
|
|
|
'intel': ['-O2', '-pc64', '-unroll', ],
|
2019-02-14 14:11:20 +08:00
|
|
|
'pgi': ['-fast'],
|
2020-10-23 05:42:48 +08:00
|
|
|
'nvhpc': ['-fast'],
|
2020-04-28 08:42:33 +08:00
|
|
|
'cray': ['-O2'],
|
|
|
|
'xl': ['-O3'],
|
2019-02-14 14:11:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
dflags = ['-DNDEBUG']
|
|
|
|
cppflags = [
|
2019-10-03 03:31:19 +08:00
|
|
|
'-D__FFTW3',
|
2020-04-28 08:42:33 +08:00
|
|
|
'-I{0}'.format(fftw_header_dir),
|
2019-02-14 14:11:20 +08:00
|
|
|
]
|
|
|
|
|
|
|
|
if '^mpi@3:' in spec:
|
|
|
|
cppflags.append('-D__MPI_VERSION=3')
|
|
|
|
elif '^mpi@2:' in spec:
|
|
|
|
cppflags.append('-D__MPI_VERSION=2')
|
|
|
|
|
|
|
|
cflags = optimization_flags[self.spec.compiler.name][:]
|
|
|
|
cxxflags = optimization_flags[self.spec.compiler.name][:]
|
|
|
|
fcflags = optimization_flags[self.spec.compiler.name][:]
|
2019-08-14 01:59:08 +08:00
|
|
|
nvflags = ['-O3']
|
2019-02-14 14:11:20 +08:00
|
|
|
ldflags = []
|
|
|
|
libs = []
|
2019-08-14 01:59:08 +08:00
|
|
|
gpuver = ''
|
2019-02-14 14:11:20 +08:00
|
|
|
|
|
|
|
if '%intel' in spec:
|
|
|
|
cflags.append('-fp-model precise')
|
|
|
|
cxxflags.append('-fp-model precise')
|
2019-08-14 01:59:08 +08:00
|
|
|
fcflags += [
|
2020-04-28 08:42:33 +08:00
|
|
|
'-fp-model precise',
|
2019-08-14 01:59:08 +08:00
|
|
|
'-heap-arrays 64',
|
|
|
|
'-g',
|
|
|
|
'-traceback',
|
|
|
|
]
|
2019-02-14 14:11:20 +08:00
|
|
|
elif '%gcc' in spec:
|
2020-04-28 08:42:33 +08:00
|
|
|
fcflags += [
|
2019-04-26 16:27:11 +08:00
|
|
|
'-ffree-form',
|
|
|
|
'-ffree-line-length-none',
|
|
|
|
'-ggdb', # make sure we get proper Fortran backtraces
|
2020-04-28 08:42:33 +08:00
|
|
|
]
|
2020-10-23 05:42:48 +08:00
|
|
|
elif '%pgi' in spec or '%nvhpc' in spec:
|
2020-04-28 08:42:33 +08:00
|
|
|
fcflags += ['-Mfreeform', '-Mextend']
|
|
|
|
elif '%cray' in spec:
|
|
|
|
fcflags += ['-emf', '-ffree', '-hflex_mp=strict']
|
|
|
|
elif '%xl' in spec:
|
|
|
|
fcflags += ['-qpreprocess', '-qstrict', '-q64']
|
|
|
|
ldflags += ['-Wl,--allow-multiple-definition']
|
2019-02-14 14:11:20 +08:00
|
|
|
|
|
|
|
if '+openmp' in spec:
|
2019-08-14 01:59:08 +08:00
|
|
|
cflags.append(self.compiler.openmp_flag)
|
|
|
|
cxxflags.append(self.compiler.openmp_flag)
|
2019-02-14 14:11:20 +08:00
|
|
|
fcflags.append(self.compiler.openmp_flag)
|
|
|
|
ldflags.append(self.compiler.openmp_flag)
|
2019-08-14 01:59:08 +08:00
|
|
|
nvflags.append('-Xcompiler="{0}"'.format(
|
|
|
|
self.compiler.openmp_flag))
|
2020-04-28 08:42:33 +08:00
|
|
|
elif '%cray' in spec: # Cray enables OpenMP by default
|
|
|
|
cflags += ['-hnoomp']
|
|
|
|
cxxflags += ['-hnoomp']
|
|
|
|
fcflags += ['-hnoomp']
|
|
|
|
ldflags += ['-hnoomp']
|
|
|
|
|
|
|
|
if '@7:' in spec: # recent versions of CP2K use C++14 CUDA code
|
|
|
|
cxxflags.append(self.compiler.cxx14_flag)
|
|
|
|
nvflags.append(self.compiler.cxx14_flag)
|
2019-02-14 14:11:20 +08:00
|
|
|
|
|
|
|
ldflags.append(fftw.libs.search_flags)
|
|
|
|
|
|
|
|
if 'superlu-dist@4.3' in spec:
|
|
|
|
ldflags.insert(0, '-Wl,--allow-multiple-definition')
|
|
|
|
|
|
|
|
if '+plumed' in self.spec:
|
|
|
|
dflags.extend(['-D__PLUMED2'])
|
|
|
|
cppflags.extend(['-D__PLUMED2'])
|
|
|
|
libs.extend([
|
|
|
|
os.path.join(self.spec['plumed'].prefix.lib,
|
|
|
|
'libplumed.{0}'.format(dso_suffix))
|
|
|
|
])
|
2017-05-06 00:24:04 +08:00
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
cc = spack_cc if '~mpi' in spec else spec['mpi'].mpicc
|
|
|
|
cxx = spack_cxx if '~mpi' in spec else spec['mpi'].mpicxx
|
|
|
|
fc = spack_fc if '~mpi' in spec else spec['mpi'].mpifc
|
2017-05-06 00:24:04 +08:00
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
# Intel
|
2020-04-28 08:42:33 +08:00
|
|
|
if '%intel' in spec:
|
2019-02-14 14:11:20 +08:00
|
|
|
cppflags.extend([
|
|
|
|
'-D__INTEL',
|
|
|
|
'-D__HAS_ISO_C_BINDING',
|
|
|
|
'-D__USE_CP2K_TRACE',
|
|
|
|
])
|
|
|
|
fcflags.extend([
|
|
|
|
'-diag-disable 8290,8291,10010,10212,11060',
|
|
|
|
'-free',
|
|
|
|
'-fpp'
|
|
|
|
])
|
2017-05-06 00:24:04 +08:00
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
# FFTW, LAPACK, BLAS
|
|
|
|
lapack = spec['lapack'].libs
|
|
|
|
blas = spec['blas'].libs
|
|
|
|
ldflags.append((lapack + blas).search_flags)
|
|
|
|
libs.extend([str(x) for x in (fftw.libs, lapack, blas)])
|
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if '^intel-mkl' in spec or '^intel-parallel-studio+mkl' in spec:
|
2019-08-14 01:59:08 +08:00
|
|
|
cppflags += ['-D__MKL']
|
2020-04-28 08:42:33 +08:00
|
|
|
elif '^accelerate' in spec:
|
2019-08-14 01:59:08 +08:00
|
|
|
cppflags += ['-D__ACCELERATE']
|
|
|
|
|
2020-04-15 02:33:49 +08:00
|
|
|
if '+cosma' in spec:
|
|
|
|
# add before ScaLAPACK to override the p?gemm symbols
|
|
|
|
cosma = spec['cosma'].libs
|
|
|
|
ldflags.append(cosma.search_flags)
|
|
|
|
libs.extend(cosma)
|
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
# MPI
|
2020-04-28 08:42:33 +08:00
|
|
|
if '+mpi' in spec:
|
2019-02-14 14:11:20 +08:00
|
|
|
cppflags.extend([
|
|
|
|
'-D__parallel',
|
|
|
|
'-D__SCALAPACK'
|
|
|
|
])
|
2017-05-06 00:24:04 +08:00
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
scalapack = spec['scalapack'].libs
|
|
|
|
ldflags.append(scalapack.search_flags)
|
|
|
|
|
|
|
|
libs.extend(scalapack)
|
2020-04-28 08:42:33 +08:00
|
|
|
libs.extend(spec['mpi:cxx'].libs)
|
2019-02-14 14:11:20 +08:00
|
|
|
libs.extend(self.compiler.stdcxx_libs)
|
|
|
|
|
|
|
|
if 'wannier90' in spec:
|
|
|
|
cppflags.append('-D__WANNIER90')
|
|
|
|
wannier = os.path.join(
|
|
|
|
spec['wannier90'].libs.directories[0], 'libwannier.a'
|
|
|
|
)
|
|
|
|
libs.append(wannier)
|
|
|
|
|
2020-07-22 00:13:59 +08:00
|
|
|
if '+libint' in spec:
|
|
|
|
cppflags += ['-D__LIBINT']
|
|
|
|
|
|
|
|
if '@:6.9' in spec:
|
|
|
|
cppflags += [
|
|
|
|
'-D__LIBINT_MAX_AM=6',
|
|
|
|
'-D__LIBDERIV_MAX_AM1=5',
|
|
|
|
]
|
|
|
|
|
|
|
|
# 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 due to wrong offsets into the shared library
|
|
|
|
# symbols.
|
|
|
|
libs.extend([
|
|
|
|
os.path.join(
|
|
|
|
spec['libint'].libs.directories[0], 'libderiv.a'),
|
|
|
|
os.path.join(
|
|
|
|
spec['libint'].libs.directories[0], 'libint.a'),
|
|
|
|
])
|
|
|
|
else:
|
|
|
|
fcflags += pkgconf('--cflags', 'libint2', output=str).split()
|
|
|
|
libs += pkgconf('--libs', 'libint2', output=str).split()
|
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
if '+libxc' in spec:
|
2019-10-03 03:31:19 +08:00
|
|
|
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:
|
2020-04-28 08:42:33 +08:00
|
|
|
fcflags += pkgconf('--cflags', 'libxcf03', output=str).split()
|
|
|
|
libs += pkgconf('--libs', 'libxcf03', output=str).split()
|
2019-02-14 14:11:20 +08:00
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if '+pexsi' in spec:
|
2019-02-14 14:11:20 +08:00
|
|
|
cppflags.append('-D__LIBPEXSI')
|
|
|
|
fcflags.append('-I' + os.path.join(
|
|
|
|
spec['pexsi'].prefix, 'fortran'))
|
2018-11-21 01:23:01 +08:00
|
|
|
libs.extend([
|
2019-02-14 14:11:20 +08:00
|
|
|
os.path.join(spec['pexsi'].libs.directories[0],
|
|
|
|
'libpexsi.a'),
|
|
|
|
os.path.join(spec['superlu-dist'].libs.directories[0],
|
|
|
|
'libsuperlu_dist.a'),
|
|
|
|
os.path.join(
|
|
|
|
spec['parmetis'].libs.directories[0],
|
|
|
|
'libparmetis.{0}'.format(dso_suffix)
|
|
|
|
),
|
|
|
|
os.path.join(
|
|
|
|
spec['metis'].libs.directories[0],
|
|
|
|
'libmetis.{0}'.format(dso_suffix)
|
|
|
|
),
|
|
|
|
])
|
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if '+elpa' in spec:
|
2019-02-14 14:11:20 +08:00
|
|
|
elpa = spec['elpa']
|
|
|
|
elpa_suffix = '_openmp' if '+openmp' in elpa else ''
|
2019-05-09 21:08:51 +08:00
|
|
|
elpa_incdir = elpa.headers.directories[0]
|
2019-02-14 14:11:20 +08:00
|
|
|
|
2019-05-09 21:08:51 +08:00
|
|
|
fcflags += ['-I{0}'.format(os.path.join(elpa_incdir, 'modules'))]
|
2019-02-14 14:11:20 +08:00
|
|
|
libs.append(os.path.join(elpa.libs.directories[0],
|
|
|
|
('libelpa{elpa_suffix}.{dso_suffix}'
|
|
|
|
.format(elpa_suffix=elpa_suffix,
|
|
|
|
dso_suffix=dso_suffix))))
|
|
|
|
|
|
|
|
if spec.satisfies('@:4.999'):
|
|
|
|
if elpa.satisfies('@:2014.5.999'):
|
|
|
|
cppflags.append('-D__ELPA')
|
|
|
|
elif elpa.satisfies('@2014.6:2015.10.999'):
|
|
|
|
cppflags.append('-D__ELPA2')
|
|
|
|
else:
|
|
|
|
cppflags.append('-D__ELPA3')
|
|
|
|
else:
|
|
|
|
cppflags.append('-D__ELPA={0}{1:02d}'
|
|
|
|
.format(elpa.version[0],
|
|
|
|
int(elpa.version[1])))
|
2019-05-09 21:08:51 +08:00
|
|
|
fcflags += ['-I{0}'.format(os.path.join(elpa_incdir, 'elpa'))]
|
2019-02-14 14:11:20 +08:00
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if spec.satisfies('+sirius'):
|
2019-04-24 22:27:52 +08:00
|
|
|
sirius = spec['sirius']
|
|
|
|
cppflags.append('-D__SIRIUS')
|
2020-09-10 23:00:31 +08:00
|
|
|
fcflags += ['-I{0}'.format(sirius.prefix.include.sirius)]
|
2019-08-14 01:59:08 +08:00
|
|
|
libs += list(sirius.libs)
|
2019-04-24 22:27:52 +08:00
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if spec.satisfies('+cuda'):
|
2019-08-14 01:59:08 +08:00
|
|
|
cppflags += ['-D__ACC']
|
|
|
|
libs += ['-lcudart', '-lnvrtc', '-lcuda']
|
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if spec.satisfies('+cuda_blas'):
|
2019-08-14 01:59:08 +08:00
|
|
|
cppflags += ['-D__DBCSR_ACC=2']
|
|
|
|
libs += ['-lcublas']
|
|
|
|
else:
|
|
|
|
cppflags += ['-D__DBCSR_ACC']
|
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if spec.satisfies('+cuda_fft'):
|
2019-08-14 01:59:08 +08:00
|
|
|
cppflags += ['-D__PW_CUDA']
|
|
|
|
libs += ['-lcufft', '-lcublas']
|
|
|
|
|
2021-01-13 01:01:32 +08:00
|
|
|
cuda_arch = spec.variants['cuda_arch'].value[0]
|
2019-08-14 01:59:08 +08:00
|
|
|
if cuda_arch:
|
|
|
|
gpuver = {
|
|
|
|
'35': 'K40',
|
|
|
|
'37': 'K80',
|
|
|
|
'60': 'P100',
|
2019-10-29 21:08:58 +08:00
|
|
|
'70': 'V100',
|
2019-08-14 01:59:08 +08:00
|
|
|
}[cuda_arch]
|
|
|
|
|
|
|
|
if (cuda_arch == '35'
|
2020-04-28 08:42:33 +08:00
|
|
|
and spec.satisfies('+cuda_arch_35_k20x')):
|
2019-08-14 01:59:08 +08:00
|
|
|
gpuver = 'K20X'
|
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
if 'smm=libsmm' in spec:
|
|
|
|
lib_dir = os.path.join(
|
|
|
|
'lib', self.makefile_architecture, self.makefile_version
|
|
|
|
)
|
|
|
|
mkdirp(lib_dir)
|
|
|
|
try:
|
|
|
|
copy(env['LIBSMM_PATH'], os.path.join(lib_dir, 'libsmm.a'))
|
|
|
|
except KeyError:
|
|
|
|
raise KeyError('Point environment variable LIBSMM_PATH to '
|
|
|
|
'the absolute path of the libsmm.a file')
|
|
|
|
except IOError:
|
|
|
|
raise IOError('The file LIBSMM_PATH pointed to does not '
|
|
|
|
'exist. Note that it must be absolute path.')
|
|
|
|
cppflags.extend([
|
|
|
|
'-D__HAS_smm_dnn',
|
|
|
|
'-D__HAS_smm_vec',
|
|
|
|
])
|
|
|
|
libs.append('-lsmm')
|
|
|
|
|
|
|
|
elif 'smm=libxsmm' in spec:
|
2020-04-28 08:42:33 +08:00
|
|
|
cppflags += ['-D__LIBXSMM']
|
|
|
|
cppflags += pkgconf('--cflags-only-other', 'libxsmmf',
|
|
|
|
output=str).split()
|
|
|
|
fcflags += pkgconf('--cflags-only-I', 'libxsmmf',
|
|
|
|
output=str).split()
|
|
|
|
libs += pkgconf('--libs', 'libxsmmf', output=str).split()
|
2019-02-14 14:11:20 +08:00
|
|
|
|
2020-12-25 07:12:34 +08:00
|
|
|
if '+libvori' in spec:
|
|
|
|
cppflags += ['-D__LIBVORI']
|
|
|
|
libvori = spec['libvori'].libs
|
|
|
|
ldflags += [libvori.search_flags]
|
|
|
|
libs += libvori
|
|
|
|
libs += ['-lstdc++']
|
|
|
|
|
|
|
|
if '+spglib' in spec:
|
|
|
|
cppflags += ['-D__SPGLIB']
|
|
|
|
spglib = spec['spglib'].libs
|
|
|
|
ldflags += [spglib.search_flags]
|
|
|
|
libs += spglib
|
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
dflags.extend(cppflags)
|
|
|
|
cflags.extend(cppflags)
|
|
|
|
cxxflags.extend(cppflags)
|
|
|
|
fcflags.extend(cppflags)
|
2019-08-14 01:59:08 +08:00
|
|
|
nvflags.extend(cppflags)
|
2017-05-06 00:24:04 +08:00
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
with open(self.makefile, 'w') as mkf:
|
2020-04-28 08:42:33 +08:00
|
|
|
if '+plumed' in spec:
|
|
|
|
mkf.write('# include Plumed.inc as recommended by'
|
|
|
|
'PLUMED to include libraries and flags')
|
2016-08-04 15:42:02 +08:00
|
|
|
mkf.write('include {0}\n'.format(
|
2020-04-28 08:42:33 +08:00
|
|
|
spec['plumed'].package.plumed_inc
|
2016-08-04 15:42:02 +08:00
|
|
|
))
|
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
mkf.write('\n# COMPILER, LINKER, TOOLS\n\n')
|
|
|
|
mkf.write('FC = {0}\n'
|
|
|
|
'CC = {1}\n'
|
|
|
|
'CXX = {2}\n'
|
|
|
|
'LD = {3}\n'
|
|
|
|
.format(fc, cc, cxx, fc))
|
|
|
|
|
|
|
|
if '%intel' in spec:
|
2019-12-23 06:19:12 +08:00
|
|
|
intel_bin_dir = ancestor(self.compiler.cc)
|
2016-08-04 15:42:02 +08:00
|
|
|
# CPP is a commented command in Intel arch of CP2K
|
|
|
|
# This is the hack through which cp2k developers avoid doing :
|
|
|
|
#
|
|
|
|
# ${CPP} <file>.F > <file>.f90
|
|
|
|
#
|
|
|
|
# and use `-fpp` instead
|
2020-04-28 08:42:33 +08:00
|
|
|
mkf.write('CPP = # {0} -P\n'.format(spack_cc))
|
|
|
|
mkf.write('AR = {0}/xiar -r\n'.format(intel_bin_dir))
|
2016-08-04 15:42:02 +08:00
|
|
|
else:
|
2020-04-28 08:42:33 +08:00
|
|
|
mkf.write('CPP = # {0} -E\n'.format(spack_cc))
|
|
|
|
mkf.write('AR = ar -r\n')
|
2018-11-21 01:23:01 +08:00
|
|
|
|
2020-04-28 08:42:33 +08:00
|
|
|
if spec.satisfies('+cuda'):
|
2019-08-14 01:59:08 +08:00
|
|
|
mkf.write('NVCC = {0}\n'.format(
|
2020-04-28 08:42:33 +08:00
|
|
|
os.path.join(spec['cuda'].prefix, 'bin', 'nvcc')))
|
2019-08-14 01:59:08 +08:00
|
|
|
|
2016-07-30 17:00:47 +08:00
|
|
|
# Write compiler flags to file
|
2020-04-28 08:42:33 +08:00
|
|
|
def fflags(var, lst):
|
|
|
|
return '{0} = {1}\n\n'.format(
|
|
|
|
var,
|
|
|
|
' \\\n\t'.join(lst))
|
|
|
|
|
|
|
|
mkf.write('\n# FLAGS & LIBRARIES\n')
|
|
|
|
mkf.write(fflags('DFLAGS', dflags))
|
|
|
|
mkf.write(fflags('CPPFLAGS', cppflags))
|
|
|
|
mkf.write(fflags('CFLAGS', cflags))
|
|
|
|
mkf.write(fflags('CXXFLAGS', cxxflags))
|
|
|
|
mkf.write(fflags('NVFLAGS', nvflags))
|
|
|
|
mkf.write(fflags('FCFLAGS', fcflags))
|
|
|
|
mkf.write(fflags('LDFLAGS', ldflags))
|
|
|
|
mkf.write(fflags('LIBS', libs))
|
|
|
|
|
2017-05-06 00:24:04 +08:00
|
|
|
if '%intel' in spec:
|
2020-04-28 08:42:33 +08:00
|
|
|
mkf.write(fflags('LDFLAGS_C', ldflags + ['-nofor_main']))
|
|
|
|
|
|
|
|
mkf.write('# CP2K-specific flags\n\n')
|
|
|
|
mkf.write('GPUVER = {0}\n'.format(gpuver))
|
|
|
|
mkf.write('DATA_DIR = {0}\n'.format(self.prefix.share.data))
|
2016-07-30 17:00:47 +08:00
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
@property
|
|
|
|
def build_directory(self):
|
2019-05-01 03:52:13 +08:00
|
|
|
build_dir = self.stage.source_path
|
|
|
|
|
|
|
|
if self.spec.satisfies('@:6.9999'):
|
|
|
|
# prior to version 7.1 was the Makefile located in makefiles/
|
|
|
|
build_dir = os.path.join(build_dir, 'makefiles')
|
|
|
|
|
|
|
|
return build_dir
|
2019-02-14 14:11:20 +08:00
|
|
|
|
|
|
|
@property
|
|
|
|
def build_targets(self):
|
|
|
|
return [
|
|
|
|
'ARCH={0}'.format(self.makefile_architecture),
|
|
|
|
'VERSION={0}'.format(self.makefile_version)
|
|
|
|
]
|
|
|
|
|
|
|
|
def build(self, spec, prefix):
|
2021-01-13 01:01:32 +08:00
|
|
|
if len(spec.variants['cuda_arch'].value) > 1:
|
|
|
|
raise InstallError("cp2k supports only one cuda_arch at a time")
|
|
|
|
|
2019-02-14 14:11:20 +08:00
|
|
|
# Apparently the Makefile bases its paths on PWD
|
|
|
|
# so we need to set PWD = self.build_directory
|
|
|
|
with spack.util.environment.set_env(PWD=self.build_directory):
|
|
|
|
super(Cp2k, self).build(spec, prefix)
|
|
|
|
|
|
|
|
def install(self, spec, prefix):
|
|
|
|
exe_dir = os.path.join('exe', self.makefile_architecture)
|
2018-08-16 00:30:09 +08:00
|
|
|
install_tree(exe_dir, self.prefix.bin)
|
2018-11-21 01:23:01 +08:00
|
|
|
install_tree('data', self.prefix.share.data)
|
2019-05-01 03:52:13 +08:00
|
|
|
|
|
|
|
def check(self):
|
|
|
|
data_dir = os.path.join(self.stage.source_path, 'data')
|
|
|
|
|
|
|
|
# CP2K < 7 still uses $PWD to detect the current working dir
|
|
|
|
# and Makefile is in a subdir, account for both facts here:
|
|
|
|
with spack.util.environment.set_env(CP2K_DATA_DIR=data_dir,
|
|
|
|
PWD=self.build_directory):
|
|
|
|
with working_dir(self.build_directory):
|
|
|
|
make('test', *self.build_targets)
|