cp2k is now a MakefilePackage (#10570)

* cp2k: archive the Makefile after a successful installation

* cp2k: all checksums are now sha256

* libint: all checksums are now sha256 + added versions 2.4.X

* libxc: all checksums are now sha256 + added version 4.3.2

* cp2k: os.path.join instead of join_path + simplified openmp flags

* cp2k: turned into a MakefilePackage

* cp2k: refactored edit method so that Makefile writing happens last
This commit is contained in:
Massimiliano Culpo 2019-02-14 07:11:20 +01:00 committed by GitHub
parent 051c66335f
commit b3dd95bd62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 261 additions and 243 deletions

View File

@ -4,12 +4,13 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os import os
import os.path
import copy import copy
from spack import * import spack.util.environment
class Cp2k(Package): class Cp2k(MakefilePackage):
"""CP2K is a quantum chemistry and solid state physics software package """CP2K is a quantum chemistry and solid state physics software package
that can perform atomistic simulations of solid state, liquid, molecular, that can perform atomistic simulations of solid state, liquid, molecular,
periodic, material, crystal, and biological systems periodic, material, crystal, and biological systems
@ -18,10 +19,10 @@ class Cp2k(Package):
url = 'https://github.com/cp2k/cp2k/releases/download/v3.0.0/cp2k-3.0.tar.bz2' url = 'https://github.com/cp2k/cp2k/releases/download/v3.0.0/cp2k-3.0.tar.bz2'
list_url = 'https://github.com/cp2k/cp2k/releases' list_url = 'https://github.com/cp2k/cp2k/releases'
version('6.1', '573a4de5a0ee2aaabb213e04543cb10f') version('6.1', sha256='af803558e0a6b9e9d9ce8a3ab955ba32bacd179922455424e061c82c9fefa34b')
version('5.1', 'f25cf301aec471d7059179de4dac3ee7') version('5.1', sha256='e23613b593354fa82e0b8410e17d94c607a0b8c6d9b5d843528403ab09904412')
version('4.1', 'b0534b530592de15ac89828b1541185e') version('4.1', sha256='4a3e4a101d8a35ebd80a9e9ecb02697fb8256364f1eccdbe4e5a85d31fe21343')
version('3.0', 'c05bc47335f68597a310b1ed75601d35') version('3.0', sha256='1acfacef643141045b7cbade7006f9b7538476d861eeecd9658c9e468dc61151')
variant('mpi', default=True, description='Enable MPI support') variant('mpi', default=True, description='Enable MPI support')
variant('blas', default='openblas', values=('openblas', 'mkl', 'accelerate'), variant('blas', default='openblas', values=('openblas', 'mkl', 'accelerate'),
@ -93,20 +94,33 @@ class Cp2k(Package):
conflicts('%nag') conflicts('%nag')
conflicts('%xl') conflicts('%xl')
def install(self, spec, prefix): @property
# Construct a proper filename for the architecture file def makefile_architecture(self):
cp2k_architecture = '{0.architecture}-{0.compiler.name}'.format(spec) return '{0.architecture}-{0.compiler.name}'.format(self.spec)
cp2k_version = ('{prefix}{suffix}'
.format(prefix='p' if '+mpi' in spec else 's',
suffix='smp' if '+openmp' in spec else 'opt'))
makefile_basename = '.'.join([cp2k_architecture, cp2k_version]) @property
makefile = join_path('arch', makefile_basename) 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'
)
# Write the custom makefile @property
with open(makefile, 'w') as mkf: def makefile(self):
# Optimization flags makefile_basename = '.'.join([
optflags = { 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):
fftw = spec['fftw:openmp' if '+openmp' in spec else 'fftw']
optimization_flags = {
'gcc': [ 'gcc': [
'-O2', '-O2',
'-mtune=native', '-mtune=native',
@ -114,23 +128,11 @@ def install(self, spec, prefix):
'-ffast-math', '-ffast-math',
'-ftree-vectorize', '-ftree-vectorize',
], ],
'intel': [ 'intel': ['-O2', '-pc64', '-unroll'],
'-O2', 'pgi': ['-fast'],
'-pc64',
'-unroll',
],
'pgi': [
'-fast',
],
} }
dflags = ['-DNDEBUG'] dflags = ['-DNDEBUG']
if '+openmp' in spec:
fftw = spec['fftw:openmp']
else:
fftw = spec['fftw']
cppflags = [ cppflags = [
'-D__FFTW3', '-D__FFTW3',
'-D__LIBINT', '-D__LIBINT',
@ -147,9 +149,9 @@ def install(self, spec, prefix):
if '^intel-mkl' in spec: if '^intel-mkl' in spec:
cppflags.append('-D__FFTSG') cppflags.append('-D__FFTSG')
cflags = copy.deepcopy(optflags[self.spec.compiler.name]) cflags = optimization_flags[self.spec.compiler.name][:]
cxxflags = copy.deepcopy(optflags[self.spec.compiler.name]) cxxflags = optimization_flags[self.spec.compiler.name][:]
fcflags = copy.deepcopy(optflags[self.spec.compiler.name]) fcflags = optimization_flags[self.spec.compiler.name][:]
ldflags = [] ldflags = []
libs = [] libs = []
@ -157,19 +159,14 @@ def install(self, spec, prefix):
cflags.append('-fp-model precise') cflags.append('-fp-model precise')
cxxflags.append('-fp-model precise') cxxflags.append('-fp-model precise')
fcflags.extend(['-fp-model source', '-heap-arrays 64']) fcflags.extend(['-fp-model source', '-heap-arrays 64'])
if '+openmp' in spec:
fcflags.append('-openmp')
ldflags.append('-openmp')
elif '%gcc' in spec: elif '%gcc' in spec:
fcflags.extend(['-ffree-form', '-ffree-line-length-none']) fcflags.extend(['-ffree-form', '-ffree-line-length-none'])
if '+openmp' in spec:
fcflags.append('-fopenmp')
ldflags.append('-fopenmp')
elif '%pgi' in spec: elif '%pgi' in spec:
fcflags.extend(['-Mfreeform', '-Mextend']) fcflags.extend(['-Mfreeform', '-Mextend'])
if '+openmp' in spec: if '+openmp' in spec:
fcflags.append('-mp') fcflags.append(self.compiler.openmp_flag)
ldflags.append('-mp') ldflags.append(self.compiler.openmp_flag)
ldflags.append(fftw.libs.search_flags) ldflags.append(fftw.libs.search_flags)
@ -181,43 +178,19 @@ def install(self, spec, prefix):
# (short-int vs int) which otherwise causes segfaults at runtime # (short-int vs int) which otherwise causes segfaults at runtime
# due to wrong offsets into the shared library symbols. # due to wrong offsets into the shared library symbols.
libs.extend([ libs.extend([
join_path(spec['libint'].libs.directories[0], 'libderiv.a'), os.path.join(spec['libint'].libs.directories[0], 'libderiv.a'),
join_path(spec['libint'].libs.directories[0], 'libint.a'), os.path.join(spec['libint'].libs.directories[0], 'libint.a'),
]) ])
if '+plumed' in self.spec: if '+plumed' in self.spec:
# Include Plumed.inc in the Makefile
mkf.write('include {0}\n'.format(
join_path(self.spec['plumed'].prefix.lib,
'plumed',
'src',
'lib',
'Plumed.inc')
))
# Add required macro
dflags.extend(['-D__PLUMED2']) dflags.extend(['-D__PLUMED2'])
cppflags.extend(['-D__PLUMED2']) cppflags.extend(['-D__PLUMED2'])
libs.extend([ libs.extend([
join_path(self.spec['plumed'].prefix.lib, os.path.join(self.spec['plumed'].prefix.lib,
'libplumed.{0}'.format(dso_suffix)) 'libplumed.{0}'.format(dso_suffix))
]) ])
mkf.write('CC = {0.compiler.cc}\n'.format(self))
if '%intel' in self.spec:
# 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.compiler.cc} -P\n\n'.format(self))
mkf.write('AR = xiar -r\n\n')
else:
mkf.write('CPP = # {0.compiler.cc} -E\n\n'.format(self))
mkf.write('AR = ar -r\n\n')
fc = self.compiler.fc if '~mpi' in spec else self.spec['mpi'].mpifc fc = self.compiler.fc if '~mpi' in spec else self.spec['mpi'].mpifc
mkf.write('FC = {0}\n'.format(fc))
mkf.write('LD = {0}\n'.format(fc))
# Intel # Intel
if '%intel' in self.spec: if '%intel' in self.spec:
@ -255,7 +228,7 @@ def install(self, spec, prefix):
if 'wannier90' in spec: if 'wannier90' in spec:
cppflags.append('-D__WANNIER90') cppflags.append('-D__WANNIER90')
wannier = join_path( wannier = os.path.join(
spec['wannier90'].libs.directories[0], 'libwannier.a' spec['wannier90'].libs.directories[0], 'libwannier.a'
) )
libs.append(wannier) libs.append(wannier)
@ -272,18 +245,18 @@ def install(self, spec, prefix):
if '+pexsi' in self.spec: if '+pexsi' in self.spec:
cppflags.append('-D__LIBPEXSI') cppflags.append('-D__LIBPEXSI')
fcflags.append('-I' + join_path( fcflags.append('-I' + os.path.join(
spec['pexsi'].prefix, 'fortran')) spec['pexsi'].prefix, 'fortran'))
libs.extend([ libs.extend([
join_path(spec['pexsi'].libs.directories[0], os.path.join(spec['pexsi'].libs.directories[0],
'libpexsi.a'), 'libpexsi.a'),
join_path(spec['superlu-dist'].libs.directories[0], os.path.join(spec['superlu-dist'].libs.directories[0],
'libsuperlu_dist.a'), 'libsuperlu_dist.a'),
join_path( os.path.join(
spec['parmetis'].libs.directories[0], spec['parmetis'].libs.directories[0],
'libparmetis.{0}'.format(dso_suffix) 'libparmetis.{0}'.format(dso_suffix)
), ),
join_path( os.path.join(
spec['metis'].libs.directories[0], spec['metis'].libs.directories[0],
'libmetis.{0}'.format(dso_suffix) 'libmetis.{0}'.format(dso_suffix)
), ),
@ -292,14 +265,14 @@ def install(self, spec, prefix):
if '+elpa' in self.spec: if '+elpa' in self.spec:
elpa = spec['elpa'] elpa = spec['elpa']
elpa_suffix = '_openmp' if '+openmp' in elpa else '' elpa_suffix = '_openmp' if '+openmp' in elpa else ''
elpa_base_path = join_path( elpa_base_path = os.path.join(
elpa.prefix, elpa.prefix,
'include', 'include',
'elpa{suffix}-{version!s}'.format( 'elpa{suffix}-{version!s}'.format(
suffix=elpa_suffix, version=elpa.version)) suffix=elpa_suffix, version=elpa.version))
fcflags.append('-I' + join_path(elpa_base_path, 'modules')) fcflags.append('-I' + os.path.join(elpa_base_path, 'modules'))
libs.append(join_path(elpa.libs.directories[0], libs.append(os.path.join(elpa.libs.directories[0],
('libelpa{elpa_suffix}.{dso_suffix}' ('libelpa{elpa_suffix}.{dso_suffix}'
.format(elpa_suffix=elpa_suffix, .format(elpa_suffix=elpa_suffix,
dso_suffix=dso_suffix)))) dso_suffix=dso_suffix))))
@ -315,13 +288,15 @@ def install(self, spec, prefix):
cppflags.append('-D__ELPA={0}{1:02d}' cppflags.append('-D__ELPA={0}{1:02d}'
.format(elpa.version[0], .format(elpa.version[0],
int(elpa.version[1]))) int(elpa.version[1])))
fcflags.append('-I' + join_path(elpa_base_path, 'elpa')) fcflags.append('-I' + os.path.join(elpa_base_path, 'elpa'))
if 'smm=libsmm' in spec: if 'smm=libsmm' in spec:
lib_dir = join_path('lib', cp2k_architecture, cp2k_version) lib_dir = os.path.join(
'lib', self.makefile_architecture, self.makefile_version
)
mkdirp(lib_dir) mkdirp(lib_dir)
try: try:
copy(env['LIBSMM_PATH'], join_path(lib_dir, 'libsmm.a')) copy(env['LIBSMM_PATH'], os.path.join(lib_dir, 'libsmm.a'))
except KeyError: except KeyError:
raise KeyError('Point environment variable LIBSMM_PATH to ' raise KeyError('Point environment variable LIBSMM_PATH to '
'the absolute path of the libsmm.a file') 'the absolute path of the libsmm.a file')
@ -333,6 +308,7 @@ def install(self, spec, prefix):
'-D__HAS_smm_vec', '-D__HAS_smm_vec',
]) ])
libs.append('-lsmm') libs.append('-lsmm')
elif 'smm=libxsmm' in spec: elif 'smm=libxsmm' in spec:
cppflags.extend([ cppflags.extend([
'-D__LIBXSMM', '-D__LIBXSMM',
@ -346,6 +322,29 @@ def install(self, spec, prefix):
cxxflags.extend(cppflags) cxxflags.extend(cppflags)
fcflags.extend(cppflags) fcflags.extend(cppflags)
with open(self.makefile, 'w') as mkf:
if '+plumed' in self.spec:
# Include Plumed.inc in the Makefile
mkf.write('include {0}\n'.format(
self.spec['plumed'].package.plumed_inc
))
mkf.write('CC = {0.compiler.cc}\n'.format(self))
if '%intel' in self.spec:
# 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.compiler.cc} -P\n\n'.format(self))
mkf.write('AR = xiar -r\n\n')
else:
mkf.write('CPP = # {0.compiler.cc} -E\n\n'.format(self))
mkf.write('AR = ar -r\n\n')
mkf.write('FC = {0}\n'.format(fc))
mkf.write('LD = {0}\n'.format(fc))
# Write compiler flags to file # Write compiler flags to file
mkf.write('DFLAGS = {0}\n\n'.format(' '.join(dflags))) mkf.write('DFLAGS = {0}\n\n'.format(' '.join(dflags)))
mkf.write('CPPFLAGS = {0}\n\n'.format(' '.join(cppflags))) mkf.write('CPPFLAGS = {0}\n\n'.format(' '.join(cppflags)))
@ -360,14 +359,24 @@ def install(self, spec, prefix):
mkf.write('LIBS = {0}\n\n'.format(' '.join(libs))) mkf.write('LIBS = {0}\n\n'.format(' '.join(libs)))
mkf.write('DATA_DIR = {0}\n\n'.format(self.prefix.share.data)) mkf.write('DATA_DIR = {0}\n\n'.format(self.prefix.share.data))
with working_dir('makefiles'): @property
def build_directory(self):
return os.path.join(self.stage.source_path, 'makefiles')
@property
def build_targets(self):
return [
'ARCH={0}'.format(self.makefile_architecture),
'VERSION={0}'.format(self.makefile_version)
]
def build(self, spec, prefix):
# Apparently the Makefile bases its paths on PWD # Apparently the Makefile bases its paths on PWD
# so we need to set PWD = os.getcwd() # so we need to set PWD = self.build_directory
pwd_backup = env['PWD'] with spack.util.environment.set_env(PWD=self.build_directory):
env['PWD'] = os.getcwd() super(Cp2k, self).build(spec, prefix)
make('ARCH={0}'.format(cp2k_architecture),
'VERSION={0}'.format(cp2k_version)) def install(self, spec, prefix):
env['PWD'] = pwd_backup exe_dir = os.path.join('exe', self.makefile_architecture)
exe_dir = join_path('exe', cp2k_architecture)
install_tree(exe_dir, self.prefix.bin) install_tree(exe_dir, self.prefix.bin)
install_tree('data', self.prefix.share.data) install_tree('data', self.prefix.share.data)

View File

@ -14,10 +14,13 @@ 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.2.0', 'da37dab862fb0b97a7ed7d007695ef47') version('2.4.2', sha256='86dff38065e69a3a51d15cfdc638f766044cb87e5c6682d960c14f9847e2eac3')
version('2.1.0', 'd0dcb985fe32ddebc78fe571ce37e2d6') version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4')
version('1.1.6', '990f67b55f49ecc18f32c58da9240684') version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019')
version('1.1.5', '379b7d0718ff398715d6898807adf628') version('2.2.0', sha256='f737d485f33ac819d7f28c6ce303b1f3a2296bfd2c14f7c1323f8c5d370bb0e3')
version('2.1.0', sha256='43c453a1663aa1c55294df89ff9ece3aefc8d1bbba5ea31dbfe71b2d812e24c8')
version('1.1.6', sha256='f201b0c621df678cfe8bdf3990796b8976ff194aba357ae398f2f29b0e2985a6')
version('1.1.5', sha256='ec8cd4a4ba1e1a98230165210c293632372f0e573acd878ed62e5ec6f8b6174b')
# Build dependencies # Build dependencies
depends_on('autoconf@2.52:', type='build') depends_on('autoconf@2.52:', type='build')

View File

@ -13,10 +13,11 @@ class Libxc(AutotoolsPackage):
homepage = "http://www.tddft.org/programs/octopus/wiki/index.php/Libxc" homepage = "http://www.tddft.org/programs/octopus/wiki/index.php/Libxc"
url = "http://www.tddft.org/programs/octopus/down.php?file=libxc/libxc-2.2.2.tar.gz" url = "http://www.tddft.org/programs/octopus/down.php?file=libxc/libxc-2.2.2.tar.gz"
version('4.2.3', '6176ac7edf234425d973903f82199350') version('4.3.2', sha256='bc159aea2537521998c7fb1199789e1be71e04c4b7758d58282622e347603a6f')
version('3.0.0', '8227fa3053f8fc215bd9d7b0d36de03c') version('4.2.3', sha256='02e49e9ba7d21d18df17e9e57eae861e6ce05e65e966e1e832475aa09e344256')
version('2.2.2', 'd9f90a0d6e36df6c1312b6422280f2ec') version('3.0.0', sha256='5542b99042c09b2925f2e3700d769cda4fb411b476d446c833ea28c6bfa8792a')
version('2.2.1', '38dc3a067524baf4f8521d5bb1cd0b8f') version('2.2.2', sha256='6ca1d0bb5fdc341d59960707bc67f23ad54de8a6018e19e02eee2b16ea7cc642')
version('2.2.1', sha256='ade61c1fa4ed238edd56408fd8ee6c2e305a3d5753e160017e2a71817c98fd00')
def url_for_version(self, version): def url_for_version(self, version):
if version < Version('3.0.0'): if version < Version('3.0.0'):

View File

@ -4,8 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import collections import collections
import os.path
from spack import *
class Plumed(AutotoolsPackage): class Plumed(AutotoolsPackage):
@ -80,7 +79,7 @@ def apply_patch(self, other):
# Get available patches # Get available patches
plumed_patch = Executable( plumed_patch = Executable(
join_path(self.spec.prefix.bin, 'plumed-patch') os.path.join(self.spec.prefix.bin, 'plumed-patch')
) )
out = plumed_patch('-q', '-l', output=str) out = plumed_patch('-q', '-l', output=str)
@ -103,6 +102,12 @@ def setup_dependent_package(self, module, dependent_spec):
# Make plumed visible from dependent packages # Make plumed visible from dependent packages
module.plumed = dependent_spec['plumed'].command module.plumed = dependent_spec['plumed'].command
@property
def plumed_inc(self):
return os.path.join(
self.prefix.lib, 'plumed', 'src', 'lib', 'Plumed.inc'
)
@run_before('autoreconf') @run_before('autoreconf')
def filter_gslcblas(self): def filter_gslcblas(self):
# This part is needed to avoid linking with gsl cblas # This part is needed to avoid linking with gsl cblas