From b3dd95bd6241444184f763f4543b7ba864cdc1cb Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Thu, 14 Feb 2019 07:11:20 +0100 Subject: 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 --- var/spack/repos/builtin/packages/cp2k/package.py | 489 +++++++++++---------- var/spack/repos/builtin/packages/libint/package.py | 11 +- var/spack/repos/builtin/packages/libxc/package.py | 9 +- var/spack/repos/builtin/packages/plumed/package.py | 11 +- 4 files changed, 269 insertions(+), 251 deletions(-) diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py index c7ad9ecf30..6a5d9a46fb 100644 --- a/var/spack/repos/builtin/packages/cp2k/package.py +++ b/var/spack/repos/builtin/packages/cp2k/package.py @@ -4,12 +4,13 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os +import os.path 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 that can perform atomistic simulations of solid state, liquid, molecular, 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' list_url = 'https://github.com/cp2k/cp2k/releases' - version('6.1', '573a4de5a0ee2aaabb213e04543cb10f') - version('5.1', 'f25cf301aec471d7059179de4dac3ee7') - version('4.1', 'b0534b530592de15ac89828b1541185e') - version('3.0', 'c05bc47335f68597a310b1ed75601d35') + version('6.1', sha256='af803558e0a6b9e9d9ce8a3ab955ba32bacd179922455424e061c82c9fefa34b') + version('5.1', sha256='e23613b593354fa82e0b8410e17d94c607a0b8c6d9b5d843528403ab09904412') + version('4.1', sha256='4a3e4a101d8a35ebd80a9e9ecb02697fb8256364f1eccdbe4e5a85d31fe21343') + version('3.0', sha256='1acfacef643141045b7cbade7006f9b7538476d861eeecd9658c9e468dc61151') variant('mpi', default=True, description='Enable MPI support') variant('blas', default='openblas', values=('openblas', 'mkl', 'accelerate'), @@ -93,114 +94,240 @@ class Cp2k(Package): conflicts('%nag') conflicts('%xl') - def install(self, spec, prefix): - # Construct a proper filename for the architecture file - cp2k_architecture = '{0.architecture}-{0.compiler.name}'.format(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]) - makefile = join_path('arch', makefile_basename) - - # Write the custom makefile - with open(makefile, 'w') as mkf: - # Optimization flags - optflags = { - 'gcc': [ - '-O2', - '-mtune=native', - '-funroll-loops', - '-ffast-math', - '-ftree-vectorize', - ], - 'intel': [ - '-O2', - '-pc64', - '-unroll', - ], - 'pgi': [ - '-fast', - ], - } - - dflags = ['-DNDEBUG'] - - if '+openmp' in spec: - fftw = spec['fftw:openmp'] - else: - fftw = spec['fftw'] - - cppflags = [ - '-D__FFTW3', - '-D__LIBINT', - '-D__LIBINT_MAX_AM=6', - '-D__LIBDERIV_MAX_AM1=5', - fftw.headers.cpp_flags, - ] + @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): + + fftw = spec['fftw:openmp' if '+openmp' in spec else 'fftw'] + + optimization_flags = { + 'gcc': [ + '-O2', + '-mtune=native', + '-funroll-loops', + '-ffast-math', + '-ftree-vectorize', + ], + 'intel': ['-O2', '-pc64', '-unroll'], + 'pgi': ['-fast'], + } + + dflags = ['-DNDEBUG'] + cppflags = [ + '-D__FFTW3', + '-D__LIBINT', + '-D__LIBINT_MAX_AM=6', + '-D__LIBDERIV_MAX_AM1=5', + fftw.headers.cpp_flags, + ] + + if '^mpi@3:' in spec: + cppflags.append('-D__MPI_VERSION=3') + elif '^mpi@2:' in spec: + cppflags.append('-D__MPI_VERSION=2') + + if '^intel-mkl' in spec: + cppflags.append('-D__FFTSG') + + cflags = optimization_flags[self.spec.compiler.name][:] + cxxflags = optimization_flags[self.spec.compiler.name][:] + fcflags = optimization_flags[self.spec.compiler.name][:] + ldflags = [] + libs = [] + + if '%intel' in spec: + cflags.append('-fp-model precise') + cxxflags.append('-fp-model precise') + fcflags.extend(['-fp-model source', '-heap-arrays 64']) + elif '%gcc' in spec: + fcflags.extend(['-ffree-form', '-ffree-line-length-none']) + elif '%pgi' in spec: + fcflags.extend(['-Mfreeform', '-Mextend']) + + if '+openmp' in spec: + fcflags.append(self.compiler.openmp_flag) + ldflags.append(self.compiler.openmp_flag) + + ldflags.append(fftw.libs.search_flags) + + if 'superlu-dist@4.3' in spec: + ldflags.insert(0, '-Wl,--allow-multiple-definition') + + # 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'), + ]) + + 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)) + ]) - if '^mpi@3:' in spec: - cppflags.append('-D__MPI_VERSION=3') - elif '^mpi@2:' in spec: - cppflags.append('-D__MPI_VERSION=2') + fc = self.compiler.fc if '~mpi' in spec else self.spec['mpi'].mpifc - if '^intel-mkl' in spec: - cppflags.append('-D__FFTSG') + # Intel + if '%intel' in self.spec: + cppflags.extend([ + '-D__INTEL', + '-D__HAS_ISO_C_BINDING', + '-D__USE_CP2K_TRACE', + '-D__MKL' + ]) + fcflags.extend([ + '-diag-disable 8290,8291,10010,10212,11060', + '-free', + '-fpp' + ]) - cflags = copy.deepcopy(optflags[self.spec.compiler.name]) - cxxflags = copy.deepcopy(optflags[self.spec.compiler.name]) - fcflags = copy.deepcopy(optflags[self.spec.compiler.name]) - ldflags = [] - libs = [] + # 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)]) + + # MPI + if '+mpi' in self.spec: + cppflags.extend([ + '-D__parallel', + '-D__SCALAPACK' + ]) - if '%intel' in spec: - cflags.append('-fp-model precise') - cxxflags.append('-fp-model precise') - fcflags.extend(['-fp-model source', '-heap-arrays 64']) - if '+openmp' in spec: - fcflags.append('-openmp') - ldflags.append('-openmp') - elif '%gcc' in spec: - fcflags.extend(['-ffree-form', '-ffree-line-length-none']) - if '+openmp' in spec: - fcflags.append('-fopenmp') - ldflags.append('-fopenmp') - elif '%pgi' in spec: - fcflags.extend(['-Mfreeform', '-Mextend']) - if '+openmp' in spec: - fcflags.append('-mp') - ldflags.append('-mp') - - ldflags.append(fftw.libs.search_flags) - - if 'superlu-dist@4.3' in spec: - ldflags.insert(0, '-Wl,--allow-multiple-definition') - - # 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. + scalapack = spec['scalapack'].libs + ldflags.append(scalapack.search_flags) + + libs.extend(scalapack) + libs.extend(self.spec['mpi:cxx'].libs) + 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) + + if '+libxc' in spec: + libxc = spec['libxc:fortran,static'] + cppflags += [ + '-D__LIBXC', + libxc.headers.cpp_flags + ] + + ldflags.append(libxc.libs.search_flags) + libs.append(str(libxc.libs)) + + if '+pexsi' in self.spec: + cppflags.append('-D__LIBPEXSI') + fcflags.append('-I' + os.path.join( + spec['pexsi'].prefix, 'fortran')) libs.extend([ - join_path(spec['libint'].libs.directories[0], 'libderiv.a'), - join_path(spec['libint'].libs.directories[0], 'libint.a'), + 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) + ), + ]) + + if '+elpa' in self.spec: + elpa = spec['elpa'] + elpa_suffix = '_openmp' if '+openmp' in elpa else '' + elpa_base_path = os.path.join( + elpa.prefix, + 'include', + 'elpa{suffix}-{version!s}'.format( + suffix=elpa_suffix, version=elpa.version)) + + fcflags.append('-I' + os.path.join(elpa_base_path, 'modules')) + 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]))) + fcflags.append('-I' + os.path.join(elpa_base_path, 'elpa')) + + 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: + cppflags.extend([ + '-D__LIBXSMM', + '$(shell pkg-config --cflags-only-other libxsmmf)', ]) + fcflags.append('$(shell pkg-config --cflags-only-I libxsmmf)') + libs.append('$(shell pkg-config --libs libxsmmf)') + + dflags.extend(cppflags) + cflags.extend(cppflags) + cxxflags.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( - join_path(self.spec['plumed'].prefix.lib, - 'plumed', - 'src', - 'lib', - 'Plumed.inc') + self.spec['plumed'].package.plumed_inc )) - # Add required macro - dflags.extend(['-D__PLUMED2']) - cppflags.extend(['-D__PLUMED2']) - libs.extend([ - join_path(self.spec['plumed'].prefix.lib, - 'libplumed.{0}'.format(dso_suffix)) - ]) mkf.write('CC = {0.compiler.cc}\n'.format(self)) if '%intel' in self.spec: @@ -215,137 +342,9 @@ class Cp2k(Package): 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 mkf.write('FC = {0}\n'.format(fc)) mkf.write('LD = {0}\n'.format(fc)) - # Intel - if '%intel' in self.spec: - cppflags.extend([ - '-D__INTEL', - '-D__HAS_ISO_C_BINDING', - '-D__USE_CP2K_TRACE', - '-D__MKL' - ]) - 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)]) - - # MPI - if '+mpi' in self.spec: - cppflags.extend([ - '-D__parallel', - '-D__SCALAPACK' - ]) - - scalapack = spec['scalapack'].libs - ldflags.append(scalapack.search_flags) - - libs.extend(scalapack) - libs.extend(self.spec['mpi:cxx'].libs) - 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) - - if '+libxc' in spec: - libxc = spec['libxc:fortran,static'] - cppflags += [ - '-D__LIBXC', - libxc.headers.cpp_flags - ] - - ldflags.append(libxc.libs.search_flags) - libs.append(str(libxc.libs)) - - if '+pexsi' in self.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 self.spec: - elpa = spec['elpa'] - elpa_suffix = '_openmp' if '+openmp' in elpa else '' - elpa_base_path = join_path( - elpa.prefix, - 'include', - 'elpa{suffix}-{version!s}'.format( - suffix=elpa_suffix, version=elpa.version)) - - fcflags.append('-I' + join_path(elpa_base_path, 'modules')) - libs.append(join_path(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]))) - fcflags.append('-I' + join_path(elpa_base_path, 'elpa')) - - if 'smm=libsmm' in spec: - lib_dir = join_path('lib', cp2k_architecture, cp2k_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.extend([ - '-D__LIBXSMM', - '$(shell pkg-config --cflags-only-other libxsmmf)', - ]) - fcflags.append('$(shell pkg-config --cflags-only-I libxsmmf)') - libs.append('$(shell pkg-config --libs libxsmmf)') - - dflags.extend(cppflags) - cflags.extend(cppflags) - cxxflags.extend(cppflags) - fcflags.extend(cppflags) - # Write compiler flags to file mkf.write('DFLAGS = {0}\n\n'.format(' '.join(dflags))) mkf.write('CPPFLAGS = {0}\n\n'.format(' '.join(cppflags))) @@ -360,14 +359,24 @@ class Cp2k(Package): mkf.write('LIBS = {0}\n\n'.format(' '.join(libs))) mkf.write('DATA_DIR = {0}\n\n'.format(self.prefix.share.data)) - with working_dir('makefiles'): - # Apparently the Makefile bases its paths on PWD - # so we need to set PWD = os.getcwd() - pwd_backup = env['PWD'] - env['PWD'] = os.getcwd() - make('ARCH={0}'.format(cp2k_architecture), - 'VERSION={0}'.format(cp2k_version)) - env['PWD'] = pwd_backup - exe_dir = join_path('exe', cp2k_architecture) + @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 + # 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) install_tree(exe_dir, self.prefix.bin) install_tree('data', self.prefix.share.data) diff --git a/var/spack/repos/builtin/packages/libint/package.py b/var/spack/repos/builtin/packages/libint/package.py index cca6395548..08094d5c68 100644 --- a/var/spack/repos/builtin/packages/libint/package.py +++ b/var/spack/repos/builtin/packages/libint/package.py @@ -14,10 +14,13 @@ class Libint(AutotoolsPackage): homepage = "https://github.com/evaleev/libint" url = "https://github.com/evaleev/libint/archive/v2.1.0.tar.gz" - version('2.2.0', 'da37dab862fb0b97a7ed7d007695ef47') - version('2.1.0', 'd0dcb985fe32ddebc78fe571ce37e2d6') - version('1.1.6', '990f67b55f49ecc18f32c58da9240684') - version('1.1.5', '379b7d0718ff398715d6898807adf628') + version('2.4.2', sha256='86dff38065e69a3a51d15cfdc638f766044cb87e5c6682d960c14f9847e2eac3') + version('2.4.1', sha256='0513be124563fdbbc7cd3c7043e221df1bda236a037027ba9343429a27db8ce4') + version('2.4.0', sha256='52eb16f065406099dcfaceb12f9a7f7e329c9cfcf6ed9bfacb0cff7431dd6019') + 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 depends_on('autoconf@2.52:', type='build') diff --git a/var/spack/repos/builtin/packages/libxc/package.py b/var/spack/repos/builtin/packages/libxc/package.py index 595670990a..62bfd5eb57 100644 --- a/var/spack/repos/builtin/packages/libxc/package.py +++ b/var/spack/repos/builtin/packages/libxc/package.py @@ -13,10 +13,11 @@ class Libxc(AutotoolsPackage): 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" - version('4.2.3', '6176ac7edf234425d973903f82199350') - version('3.0.0', '8227fa3053f8fc215bd9d7b0d36de03c') - version('2.2.2', 'd9f90a0d6e36df6c1312b6422280f2ec') - version('2.2.1', '38dc3a067524baf4f8521d5bb1cd0b8f') + version('4.3.2', sha256='bc159aea2537521998c7fb1199789e1be71e04c4b7758d58282622e347603a6f') + version('4.2.3', sha256='02e49e9ba7d21d18df17e9e57eae861e6ce05e65e966e1e832475aa09e344256') + version('3.0.0', sha256='5542b99042c09b2925f2e3700d769cda4fb411b476d446c833ea28c6bfa8792a') + version('2.2.2', sha256='6ca1d0bb5fdc341d59960707bc67f23ad54de8a6018e19e02eee2b16ea7cc642') + version('2.2.1', sha256='ade61c1fa4ed238edd56408fd8ee6c2e305a3d5753e160017e2a71817c98fd00') def url_for_version(self, version): if version < Version('3.0.0'): diff --git a/var/spack/repos/builtin/packages/plumed/package.py b/var/spack/repos/builtin/packages/plumed/package.py index 9542e287a4..babcadc7ea 100644 --- a/var/spack/repos/builtin/packages/plumed/package.py +++ b/var/spack/repos/builtin/packages/plumed/package.py @@ -4,8 +4,7 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import collections - -from spack import * +import os.path class Plumed(AutotoolsPackage): @@ -80,7 +79,7 @@ class Plumed(AutotoolsPackage): # Get available patches 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) @@ -103,6 +102,12 @@ class Plumed(AutotoolsPackage): # Make plumed visible from dependent packages 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') def filter_gslcblas(self): # This part is needed to avoid linking with gsl cblas -- cgit v1.2.3-60-g2f50