spack/var/spack/repos/builtin/packages/cp2k/package.py

687 lines
27 KiB
Python
Raw Normal View History

# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
2016-07-30 17:00:47 +08:00
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import copy
2016-07-30 17:00:47 +08:00
import os
import os.path
2016-07-30 17:00:47 +08:00
import spack.util.environment
2016-07-30 17:00:47 +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'
url = 'https://github.com/cp2k/cp2k/releases/download/v3.0.0/cp2k-3.0.tar.bz2'
git = 'https://github.com/cp2k/cp2k.git'
list_url = 'https://github.com/cp2k/cp2k/releases'
2016-07-30 17:00:47 +08:00
maintainers = ['dev-zero']
version('8.2', sha256='2e24768720efed1a5a4a58e83e2aca502cd8b95544c21695eb0de71ed652f20a')
2021-01-13 16:39:35 +08:00
version('8.1', sha256='7f37aead120730234a60b2989d0547ae5e5498d93b1e9b5eb548c041ee8e7772')
version('7.1', sha256='ccd711a09a426145440e666310dd01cc5772ab103493c4ae6a3470898cd0addb')
version('6.1', sha256='af803558e0a6b9e9d9ce8a3ab955ba32bacd179922455424e061c82c9fefa34b')
version('5.1', sha256='e23613b593354fa82e0b8410e17d94c607a0b8c6d9b5d843528403ab09904412')
version('4.1', sha256='4a3e4a101d8a35ebd80a9e9ecb02697fb8256364f1eccdbe4e5a85d31fe21343')
version('3.0', sha256='1acfacef643141045b7cbade7006f9b7538476d861eeecd9658c9e468dc61151')
version('master', branch='master', submodules="True")
2016-07-30 17:00:47 +08:00
variant('mpi', default=True, description='Enable MPI support')
variant('openmp', default=True, description='Enable OpenMP support')
variant('smm', default='libxsmm', values=('libxsmm', 'libsmm', 'blas'),
description='Library for small matrix multiplications')
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)')
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'))
variant('cosma', default=False, description='Use COSMA for p?gemm')
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
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'))
HFX_LMAX_RANGE = range(4, 8)
variant('lmax',
description='Maximum supported angular momentum (HFX and others)',
default='5',
values=[str(x) for x in HFX_LMAX_RANGE],
multi=False)
depends_on('python', type='build')
2021-01-13 16:39:35 +08:00
depends_on('python@3:', when='@8:', type='build')
2016-07-30 17:00:47 +08:00
depends_on('blas')
depends_on('lapack')
depends_on('fftw-api@3')
# Force openmp propagation on some providers of blas / fftw-api
with when('+openmp'):
depends_on('fftw+openmp', when='^fftw')
depends_on('amdfftw+openmp', when='^amdfftw')
depends_on('openblas threads=openmp', when='^openblas')
with when('smm=libxsmm'):
# require libxsmm-1.11+ since 1.10 can leak file descriptors in Fortran
depends_on('libxsmm@1.11:~header-only')
# use pkg-config (support added in libxsmm-1.10) to link to libxsmm
depends_on('pkgconfig', type='build')
# please set variants: smm=blas by configuring packages.yaml or install
# cp2k with option smm=blas on aarch64
conflicts('target=aarch64:', msg='libxsmm is not available on arm')
with when('+libint'):
# ... 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:6.9')
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))
with when('+libxc'):
depends_on('pkgconfig', type='build', when='@7.0:')
depends_on('libxc@2.2.2:3', when='@:5', type='build')
depends_on('libxc@4.0.3:4', when='@6.0:6.9', type='build')
depends_on('libxc@4.0.3:4', when='@7.0:8.1')
depends_on('libxc@5.1.3:5.1', when='@8.2:')
with when('+mpi'):
depends_on('mpi@2:')
depends_on('scalapack')
with when('+cosma'):
depends_on('cosma+scalapack')
depends_on('cosma+cuda', when='+cuda')
conflicts('~mpi')
# COSMA support was introduced in 8+
conflicts('@:7')
with when('+elpa'):
conflicts('~mpi', msg='elpa requires MPI')
depends_on('elpa+openmp', when='+openmp')
depends_on('elpa~openmp', when='~openmp')
depends_on('elpa@2011.12:2016.13', when='@:5')
depends_on('elpa@2011.12:2017.11', when='@6.0:6')
depends_on('elpa@2018.05:2020.11.001', when='@7.0:8.2')
depends_on('elpa@2021.05:', when='@8.3:')
with when('+plumed'):
depends_on('plumed+shared')
depends_on('plumed+mpi', when='+mpi')
depends_on('plumed~mpi', when='~mpi')
# while we link statically against PEXSI, its own deps may be linked in
# dynamically, therefore can't set this as pure build-type dependency.
with when('+pexsi'):
conflicts('~mpi', msg='pexsi requires MPI')
depends_on('pexsi+fortran@0.9.0:0.9', when='@:4')
depends_on('pexsi+fortran@0.10.0:', when='@5.0:')
# only OpenMP should be consistently used, all other common things
2019-04-24 22:27:52 +08:00
# like ELPA, SCALAPACK are independent and Spack will ensure that
# a consistent/compatible combination is pulled into the dependency graph.
with when('+sirius'):
depends_on('sirius+fortran+shared')
depends_on('sirius+openmp', when='+openmp')
depends_on('sirius~openmp', when='~openmp')
depends_on('sirius@:6', when='@:7')
depends_on('sirius@7.0.0:7.0', when='@8:8.2')
depends_on('sirius@7.2:', when='@8.3:')
conflicts('~mpi')
# sirius support was introduced in 7+
conflicts('@:6')
with when('+libvori'):
depends_on('libvori@201219:', when='@8.1', type='build')
depends_on('libvori@210412:', when='@8.2:', type='build')
# libvori support was introduced in 8+
conflicts('@:7')
2019-04-24 22:27:52 +08:00
# the bundled libcusmm uses numpy in the parameter prediction (v7+)
# which is written using Python 3
depends_on('py-numpy', when='@7:+cuda', type='build')
depends_on('python@3.6:', when='@7:+cuda', type='build')
depends_on('spglib', when='+spglib')
conflicts('~cuda', '+cuda_fft')
conflicts('~cuda', '+cuda_blas')
# 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
depends_on('wannier90', when='@3.0+mpi', type='build')
2016-07-30 17:00:47 +08:00
# CP2K needs compiler specific compilation flags, e.g. optflags
conflicts('%apple-clang')
conflicts('%clang')
conflicts('%nag')
2016-07-30 17:00:47 +08:00
conflicts('~openmp', when='@8:', msg='Building without OpenMP is not supported in CP2K 8+')
# 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)
2021-10-04 20:41:49 +08:00
# Fix 2- and 3-center integral calls to libint
patch("https://github.com/cp2k/cp2k/commit/5eaf864ed2bd21fb1b05a9173bb77a815ad4deda.patch",
sha256="18e58ba8fdde5c507bece48ec064f7f2b80e59d1b7cfe6b7a639e5f64f84d43f",
when="@8.2")
@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 join_path('arch', makefile_basename)
@property
def archive_files(self):
return [join_path(self.stage.source_path, self.makefile)]
def edit(self, spec, prefix):
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 '^amdfftw' in spec:
fftw = spec['amdfftw:openmp' if '+openmp' in spec else 'amdfftw']
fftw_header_dir = fftw.headers.directories[0]
elif '^intel-mkl' in spec:
fftw = spec['intel-mkl']
fftw_header_dir = fftw.headers.directories[0] + '/fftw'
2021-10-04 20:41:49 +08:00
elif '^intel-oneapi-mkl' in spec:
fftw = spec['intel-oneapi-mkl']
fftw_header_dir = fftw.headers.directories[0] + '/fftw'
elif '^intel-parallel-studio+mkl' in spec:
fftw = spec['intel-parallel-studio']
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
elif '^cray-fftw' in spec:
fftw = spec['cray-fftw']
fftw_header_dir = fftw.headers.directories[0]
optimization_flags = {
'gcc': [
'-O2',
'-funroll-loops',
'-ftree-vectorize',
],
'intel': ['-O2', '-pc64', '-unroll', ],
'pgi': ['-fast'],
'nvhpc': ['-fast'],
'cce': ['-O2'],
'xl': ['-O3'],
'aocc': ['-O1'],
}
dflags = ['-DNDEBUG']
cppflags = [
'-D__FFTW3',
'-I{0}'.format(fftw_header_dir),
]
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][:]
nvflags = ['-O3']
ldflags = []
libs = []
gpuver = ''
if '%intel' in spec:
cflags.append('-fp-model precise')
cxxflags.append('-fp-model precise')
fcflags += [
'-fp-model precise',
'-heap-arrays 64',
'-g',
'-traceback',
]
elif '%gcc' in spec:
fcflags += [
'-ffree-form',
'-ffree-line-length-none',
'-ggdb', # make sure we get proper Fortran backtraces
]
elif '%aocc' in spec:
fcflags += [
'-ffree-form',
'-Mbackslash',
]
elif '%pgi' in spec or '%nvhpc' in spec:
fcflags += ['-Mfreeform', '-Mextend']
elif '%cce' in spec:
fcflags += ['-emf', '-ffree', '-hflex_mp=strict']
elif '%xl' in spec:
fcflags += ['-qpreprocess', '-qstrict', '-q64']
ldflags += ['-Wl,--allow-multiple-definition']
if '%gcc@10: +mpi' in spec and spec['mpi'].name in ['mpich', 'cray-mpich']:
fcflags += ['-fallow-argument-mismatch'] # https://github.com/pmodels/mpich/issues/4300
if '+openmp' in spec:
cflags.append(self.compiler.openmp_flag)
cxxflags.append(self.compiler.openmp_flag)
fcflags.append(self.compiler.openmp_flag)
ldflags.append(self.compiler.openmp_flag)
nvflags.append('-Xcompiler="{0}"'.format(
self.compiler.openmp_flag))
elif '%cce' 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)
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([
join_path(self.spec['plumed'].prefix.lib,
'libplumed.{0}'.format(dso_suffix))
])
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
# Intel
if '%intel' in spec:
cppflags.extend([
'-D__INTEL',
'-D__HAS_ISO_C_BINDING',
'-D__USE_CP2K_TRACE',
])
fcflags.extend([
'-diag-disable 8290,8291,10010,10212,11060',
'-free',
'-fpp'
])
# 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)])
2021-10-04 20:41:49 +08:00
if any(p in spec for p in ('^intel-mkl',
'^intel-parallel-studio+mkl',
'^intel-oneapi-mkl')):
cppflags += ['-D__MKL']
elif '^accelerate' in spec:
cppflags += ['-D__ACCELERATE']
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)
# MPI
if '+mpi' in spec:
cppflags.extend([
'-D__parallel',
'-D__SCALAPACK'
])
2021-10-04 20:41:49 +08:00
if '^intel-oneapi-mpi' in spec:
mpi = [join_path(
spec['intel-oneapi-mpi'].libs.directories[0],
'libmpi.so')]
else:
mpi = spec['mpi:cxx'].libs
# while intel-mkl has a mpi variant and adds the scalapack
# libs to its libs, intel-oneapi-mkl does not.
if '^intel-oneapi-mkl' in spec:
mpi_impl = 'openmpi' if '^openmpi' in spec else 'intelmpi'
scalapack = [
join_path(
spec['intel-oneapi-mkl'].libs.directories[0],
'libmkl_scalapack_lp64.so'),
join_path(
spec['intel-oneapi-mkl'].libs.directories[0],
'libmkl_blacs_{0}_lp64.so'.format(mpi_impl)
)
]
else:
scalapack = spec['scalapack'].libs
ldflags.append(scalapack.search_flags)
libs.extend(scalapack)
2021-10-04 20:41:49 +08:00
libs.extend(mpi)
libs.extend(self.compiler.stdcxx_libs)
if 'wannier90' in spec:
cppflags.append('-D__WANNIER90')
wannier = join_path(
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([
join_path(
2020-07-22 00:13:59 +08:00
spec['libint'].libs.directories[0], 'libderiv.a'),
join_path(
2020-07-22 00:13:59 +08:00
spec['libint'].libs.directories[0], 'libint.a'),
])
else:
fcflags += pkgconf('--cflags', 'libint2', output=str).split()
libs += pkgconf('--libs', 'libint2', output=str).split()
if '+libxc' in spec:
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 += pkgconf('--cflags', 'libxcf03', output=str).split()
# some Fortran functions seem to be direct wrappers of the
# C functions such that we get a direct dependency on them,
# requiring `-lxc` to be present in addition to `-lxcf03`
libs += pkgconf('--libs', 'libxcf03', 'libxc', output=str).split()
if '+pexsi' in spec:
cppflags.append('-D__LIBPEXSI')
fcflags.append('-I' + join_path(
spec['pexsi'].prefix, 'fortran'))
libs.extend([
join_path(spec['pexsi'].libs.directories[0], 'libpexsi.a'),
join_path(spec['superlu-dist'].libs.directories[0],
'libsuperlu_dist.a'),
join_path(
spec['parmetis'].libs.directories[0],
'libparmetis.{0}'.format(dso_suffix)
),
join_path(
spec['metis'].libs.directories[0],
'libmetis.{0}'.format(dso_suffix)
),
])
if '+elpa' in spec:
elpa = spec['elpa']
elpa_suffix = '_openmp' if '+openmp' in elpa else ''
elpa_incdir = elpa.headers.directories[0]
fcflags += ['-I{0}'.format(join_path(elpa_incdir, 'modules'))]
# Currently AOCC support only static libraries of ELPA
if '%aocc' in spec:
libs.append(join_path(elpa.prefix.lib,
('libelpa{elpa_suffix}.a'
.format(elpa_suffix=elpa_suffix))))
else:
libs.append(join_path(elpa.prefix.lib,
('libelpa{elpa_suffix}.{dso_suffix}'
.format(elpa_suffix=elpa_suffix,
dso_suffix=dso_suffix))))
if spec.satisfies('@:4'):
if elpa.satisfies('@:2014.5'):
cppflags.append('-D__ELPA')
elif elpa.satisfies('@2014.6:2015.10'):
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])))
fcflags += ['-I{0}'.format(join_path(elpa_incdir, 'elpa'))]
if spec.satisfies('+sirius'):
2019-04-24 22:27:52 +08:00
sirius = spec['sirius']
cppflags.append('-D__SIRIUS')
fcflags += ['-I{0}'.format(sirius.prefix.include.sirius)]
libs += list(sirius.libs)
2019-04-24 22:27:52 +08:00
if spec.satisfies('+cuda'):
cppflags += ['-D__ACC']
libs += ['-lcudart', '-lnvrtc', '-lcuda']
if spec.satisfies('+cuda_blas'):
cppflags += ['-D__DBCSR_ACC=2']
libs += ['-lcublas']
else:
cppflags += ['-D__DBCSR_ACC']
if spec.satisfies('+cuda_fft'):
cppflags += ['-D__PW_CUDA']
libs += ['-lcufft', '-lcublas']
cuda_arch = spec.variants['cuda_arch'].value[0]
if cuda_arch:
gpuver = {
'35': 'K40',
'37': 'K80',
'60': 'P100',
'70': 'V100',
}[cuda_arch]
if (cuda_arch == '35'
and spec.satisfies('+cuda_arch_35_k20x')):
gpuver = 'K20X'
if 'smm=libsmm' in spec:
lib_dir = join_path(
'lib', self.makefile_architecture, self.makefile_version
)
mkdirp(lib_dir)
try:
copy(env['LIBSMM_PATH'], join_path(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:
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()
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
dflags.extend(cppflags)
cflags.extend(cppflags)
cxxflags.extend(cppflags)
fcflags.extend(cppflags)
nvflags.extend(cppflags)
with open(self.makefile, 'w') as mkf:
if '+plumed' in spec:
mkf.write('# include Plumed.inc as recommended by'
'PLUMED to include libraries and flags')
mkf.write('include {0}\n'.format(
spec['plumed'].package.plumed_inc
))
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:
intel_bin_dir = ancestor(self.compiler.cc)
# 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
mkf.write('CPP = # {0} -P\n'.format(spack_cc))
mkf.write('AR = {0}/xiar -r\n'.format(intel_bin_dir))
else:
mkf.write('CPP = # {0} -E\n'.format(spack_cc))
mkf.write('AR = ar -r\n')
if spec.satisfies('+cuda'):
mkf.write('NVCC = {0}\n'.format(
join_path(spec['cuda'].prefix, 'bin', 'nvcc')))
2016-07-30 17:00:47 +08:00
# Write compiler flags to file
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))
if '%intel' in spec:
2021-10-04 20:41:49 +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
@property
def build_directory(self):
build_dir = self.stage.source_path
if self.spec.satisfies('@:6'):
# prior to version 7.1 was the Makefile located in makefiles/
build_dir = join_path(build_dir, 'makefiles')
return build_dir
@property
def build_targets(self):
return [
'ARCH={0}'.format(self.makefile_architecture),
'VERSION={0}'.format(self.makefile_version)
]
def build(self, spec, prefix):
if len(spec.variants['cuda_arch'].value) > 1:
raise InstallError("cp2k supports only one cuda_arch at a time")
# 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 = join_path('exe', self.makefile_architecture)
install_tree(exe_dir, self.prefix.bin)
install_tree('data', self.prefix.share.data)
def check(self):
data_dir = join_path(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)