diff --git a/.flake8 b/.flake8 index a1e2fcc1f8..12ae2efa80 100644 --- a/.flake8 +++ b/.flake8 @@ -8,6 +8,9 @@ # - E221: multiple spaces before operator # - E241: multiple spaces after ‘,’ # +# Let people use terse Python features: +# - E731 : lambda expressions +# # Spack allows wildcard imports: # - F403: disable wildcard import # @@ -16,5 +19,5 @@ # - F999: name name be undefined or undefined from star imports. # [flake8] -ignore = E221,E241,F403,F821,F999 +ignore = E221,E241,E731,F403,F821,F999 max-line-length = 79 diff --git a/var/spack/repos/builtin/packages/metis/package.py b/var/spack/repos/builtin/packages/metis/package.py index 061179b78e..c4f2afaff2 100644 --- a/var/spack/repos/builtin/packages/metis/package.py +++ b/var/spack/repos/builtin/packages/metis/package.py @@ -24,55 +24,61 @@ ############################################################################## from spack import * -import glob, sys, os +import glob +import sys +import os + class Metis(Package): - """ - METIS is a set of serial programs for partitioning graphs, partitioning finite element meshes, and producing fill - reducing orderings for sparse matrices. The algorithms implemented in METIS are based on the multilevel - recursive-bisection, multilevel k-way, and multi-constraint partitioning schemes. - """ + """METIS is a set of serial programs for partitioning graphs, partitioning + finite element meshes, and producing fill reducing orderings for sparse + matrices. The algorithms implemented in METIS are based on the + multilevel recursive-bisection, multilevel k-way, and multi-constraint + partitioning schemes.""" - homepage = 'http://glaros.dtc.umn.edu/gkhome/metis/metis/overview' - url = "http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.1.0.tar.gz" + homepage = "http://glaros.dtc.umn.edu/gkhome/metis/metis/overview" + base_url = "http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis" - version('5.1.0', '5465e67079419a69e0116de24fce58fe', - url='http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.1.0.tar.gz') - version('4.0.3', '5efa35de80703c1b2c4d0de080fafbcf4e0d363a21149a1ad2f96e0144841a55', - url='http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/OLD/metis-4.0.3.tar.gz') + version('5.1.0', '5465e67079419a69e0116de24fce58fe') + version('5.0.2', 'acb521a4e8c2e6dd559a7f9abd0468c5') + version('4.0.3', 'd3848b454532ef18dc83e4fb160d1e10') variant('shared', default=True, description='Enables the build of shared libraries') variant('debug', default=False, description='Builds the library in debug mode') variant('gdb', default=False, description='Enables gdb support') variant('idx64', default=False, description='Use int64_t as default index type') - variant('double', default=False, description='Use double precision floating point types') + variant('real64', default=False, description='Use double precision floating point types') - depends_on('cmake @2.8:', when='@5:') # build-time dependency - depends_on('gdb', when='+gdb') + depends_on('cmake@2.8:', when='@5:') # build-time dependency patch('install_gklib_defs_rename.patch', when='@5:') + def url_for_version(self, version): + verdir = 'OLD/' if version < Version('4.0.3') else '' + return '%s/%smetis-%s.tar.gz' % (Metis.base_url, verdir, version) - @when('@4:4.0.3') + @when('@:4') def install(self, spec, prefix): - - if '+gdb' in spec: - raise InstallError('gdb support not implemented in METIS 4!') - if '+idx64' in spec: - raise InstallError('idx64 option not implemented in METIS 4!') - if '+double' in spec: - raise InstallError('double option not implemented for METIS 4!') + # Process library spec and options + unsupp_vars = [v for v in ('+gdb', '+idx64', '+real64') if v in spec] + if unsupp_vars: + msg = 'Given variants %s are unsupported by METIS 4!' % unsupp_vars + raise InstallError(msg) options = ['COPTIONS=-fPIC'] if '+debug' in spec: options.append('OPTFLAGS=-g -O0') make(*options) + # Compile and install library files + ccompile = Executable(self.compiler.cc) + mkdir(prefix.bin) - for x in ('pmetis', 'kmetis', 'oemetis', 'onmetis', 'partnmesh', - 'partdmesh', 'mesh2nodal', 'mesh2dual', 'graphchk'): - install(x, prefix.bin) + binfiles = ('pmetis', 'kmetis', 'oemetis', 'onmetis', 'partnmesh', + 'partdmesh', 'mesh2nodal', 'mesh2dual', 'graphchk') + for binfile in binfiles: + install(binfile, prefix.bin) mkdir(prefix.lib) install('libmetis.a', prefix.lib) @@ -82,106 +88,120 @@ def install(self, spec, prefix): install(h, prefix.include) mkdir(prefix.share) - for f in (join_path(*p) - for p in (('Programs', 'io.c'), - ('Test','mtest.c'), - ('Graphs','4elt.graph'), - ('Graphs', 'metis.mesh'), - ('Graphs', 'test.mgraph'))): - install(f, prefix.share) + sharefiles = (('Graphs', '4elt.graph'), ('Graphs', 'metis.mesh'), + ('Graphs', 'test.mgraph')) + for sharefile in tuple(join_path(*sf) for sf in sharefiles): + install(sharefile, prefix.share) if '+shared' in spec: + shared_flags = ['-fPIC', '-shared'] if sys.platform == 'darwin': - lib_dsuffix = 'dylib' - load_flag = '-Wl,-all_load' - no_load_flag = '' + shared_suffix = 'dylib' + shared_flags.extend(['-Wl,-all_load', 'libmetis.a']) else: - lib_dsuffix = 'so' - load_flag = '-Wl,-whole-archive' - no_load_flag = '-Wl,-no-whole-archive' + shared_suffix = 'so' + shared_flags.extend(['-Wl,-whole-archive', 'libmetis.a', + '-Wl,-no-whole-archive']) - os.system(spack_cc + ' -fPIC -shared ' + load_flag + - ' libmetis.a ' + no_load_flag + ' -o libmetis.' + - lib_dsuffix) - install('libmetis.' + lib_dsuffix, prefix.lib) + shared_out = '%s/libmetis.%s' % (prefix.lib, shared_suffix) + shared_flags.extend(['-o', shared_out]) + + ccompile(*shared_flags) # Set up and run tests on installation - symlink(join_path(prefix.share, 'io.c'), 'io.c') - symlink(join_path(prefix.share, 'mtest.c'), 'mtest.c') - os.system(spack_cc + ' -I%s' % prefix.include + ' -c io.c') - os.system(spack_cc + ' -I%s' % prefix.include + - ' -L%s' % prefix.lib + ' -lmetis mtest.c io.o -o mtest') - _4eltgraph = join_path(prefix.share, '4elt.graph') - test_mgraph = join_path(prefix.share, 'test.mgraph') - metis_mesh = join_path(prefix.share, 'metis.mesh') - kmetis = join_path(prefix.bin, 'kmetis') - os.system('./mtest ' + _4eltgraph) - os.system(kmetis + ' ' + _4eltgraph + ' 40') - os.system(join_path(prefix.bin, 'onmetis') + ' ' + _4eltgraph) - os.system(join_path(prefix.bin, 'pmetis') + ' ' + test_mgraph + ' 2') - os.system(kmetis + ' ' + test_mgraph + ' 2') - os.system(kmetis + ' ' + test_mgraph + ' 5') - os.system(join_path(prefix.bin, 'partnmesh') + metis_mesh + ' 10') - os.system(join_path(prefix.bin, 'partdmesh') + metis_mesh + ' 10') - os.system(join_path(prefix.bin, 'mesh2dual') + metis_mesh) + ccompile('-I%s' % prefix.include, '-L%s' % prefix.lib, + '-Wl,-rpath=%s' % (prefix.lib if '+shared' in spec else ''), + join_path('Programs', 'io.o'), join_path('Test', 'mtest.c'), + '-o', '%s/mtest' % prefix.bin, '-lmetis', '-lm') + test_bin = lambda testname: join_path(prefix.bin, testname) + test_graph = lambda graphname: join_path(prefix.share, graphname) + + graph = test_graph('4elt.graph') + os.system('%s %s' % (test_bin('mtest'), graph)) + os.system('%s %s 40' % (test_bin('kmetis'), graph)) + os.system('%s %s' % (test_bin('onmetis'), graph)) + graph = test_graph('test.mgraph') + os.system('%s %s 2' % (test_bin('pmetis'), graph)) + os.system('%s %s 2' % (test_bin('kmetis'), graph)) + os.system('%s %s 5' % (test_bin('kmetis'), graph)) + graph = test_graph('metis.mesh') + os.system('%s %s 10' % (test_bin('partnmesh'), graph)) + os.system('%s %s 10' % (test_bin('partdmesh'), graph)) + os.system('%s %s' % (test_bin('mesh2dual'), graph)) + + # FIXME: The following code should replace the testing code in the + # block above since it causes installs to fail when one or more of the + # Metis tests fail, but it currently doesn't work because the 'mtest', + # 'onmetis', and 'partnmesh' tests return error codes that trigger + # false positives for failure. + """ + Executable(test_bin('mtest'))(test_graph('4elt.graph')) + Executable(test_bin('kmetis'))(test_graph('4elt.graph'), '40') + Executable(test_bin('onmetis'))(test_graph('4elt.graph')) + + Executable(test_bin('pmetis'))(test_graph('test.mgraph'), '2') + Executable(test_bin('kmetis'))(test_graph('test.mgraph'), '2') + Executable(test_bin('kmetis'))(test_graph('test.mgraph'), '5') + + Executable(test_bin('partnmesh'))(test_graph('metis.mesh'), '10') + Executable(test_bin('partdmesh'))(test_graph('metis.mesh'), '10') + Executable(test_bin('mesh2dual'))(test_graph('metis.mesh')) + """ @when('@5:') def install(self, spec, prefix): - options = [] options.extend(std_cmake_args) build_directory = join_path(self.stage.path, 'spack-build') source_directory = self.stage.source_path - options.append('-DGKLIB_PATH:PATH={metis_source}/GKlib'.format(metis_source=source_directory)) + options.append('-DGKLIB_PATH:PATH=%s/GKlib' % source_directory) options.append('-DCMAKE_INSTALL_NAME_DIR:PATH=%s/lib' % prefix) if '+shared' in spec: options.append('-DSHARED:BOOL=ON') - if '+debug' in spec: options.extend(['-DDEBUG:BOOL=ON', '-DCMAKE_BUILD_TYPE:STRING=Debug']) - if '+gdb' in spec: options.append('-DGDB:BOOL=ON') metis_header = join_path(source_directory, 'include', 'metis.h') - if '+idx64' in spec: filter_file('IDXTYPEWIDTH 32', 'IDXTYPEWIDTH 64', metis_header) - - if '+double' in spec: + if '+real64' in spec: filter_file('REALTYPEWIDTH 32', 'REALTYPEWIDTH 64', metis_header) # Make clang 7.3 happy. # Prevents "ld: section __DATA/__thread_bss extends beyond end of file" # See upstream LLVM issue https://llvm.org/bugs/show_bug.cgi?id=27059 - # Adopted from https://github.com/Homebrew/homebrew-science/blob/master/metis.rb + # and https://github.com/Homebrew/homebrew-science/blob/master/metis.rb if spec.satisfies('%clang@7.3.0'): - filter_file('#define MAX_JBUFS 128', '#define MAX_JBUFS 24', join_path(source_directory, 'GKlib', 'error.c')) + filter_file('#define MAX_JBUFS 128', '#define MAX_JBUFS 24', + join_path(source_directory, 'GKlib', 'error.c')) with working_dir(build_directory, create=True): cmake(source_directory, *options) make() - make("install") - # now run some tests: - for f in ["4elt", "copter2", "mdual"]: - graph = join_path(source_directory,'graphs','%s.graph' % f) - Executable(join_path(prefix.bin,'graphchk'))(graph) - Executable(join_path(prefix.bin,'gpmetis'))(graph,'2') - Executable(join_path(prefix.bin,'ndmetis'))(graph) + make('install') - graph = join_path(source_directory,'graphs','test.mgraph') - Executable(join_path(prefix.bin,'gpmetis'))(graph,'2') - graph = join_path(source_directory,'graphs','metis.mesh') - Executable(join_path(prefix.bin,'mpmetis'))(graph,'2') + # now run some tests: + for f in ['4elt', 'copter2', 'mdual']: + graph = join_path(source_directory, 'graphs', '%s.graph' % f) + Executable(join_path(prefix.bin, 'graphchk'))(graph) + Executable(join_path(prefix.bin, 'gpmetis'))(graph, '2') + Executable(join_path(prefix.bin, 'ndmetis'))(graph) + + graph = join_path(source_directory, 'graphs', 'test.mgraph') + Executable(join_path(prefix.bin, 'gpmetis'))(graph, '2') + graph = join_path(source_directory, 'graphs', 'metis.mesh') + Executable(join_path(prefix.bin, 'mpmetis'))(graph, '2') # install GKlib headers, which will be needed for ParMETIS - GKlib_dist = join_path(prefix.include,'GKlib') + GKlib_dist = join_path(prefix.include, 'GKlib') mkdirp(GKlib_dist) - fs = glob.glob(join_path(source_directory,'GKlib',"*.h")) - for f in fs: - install(f, GKlib_dist) + hfiles = glob.glob(join_path(source_directory, 'GKlib', '*.h')) + for hfile in hfiles: + install(hfile, GKlib_dist) diff --git a/var/spack/repos/builtin/packages/parmetis/package.py b/var/spack/repos/builtin/packages/parmetis/package.py index 2dead4a76a..9b36f273e4 100644 --- a/var/spack/repos/builtin/packages/parmetis/package.py +++ b/var/spack/repos/builtin/packages/parmetis/package.py @@ -26,33 +26,36 @@ from spack import * import sys + class Parmetis(Package): - """ - ParMETIS is an MPI-based parallel library that implements a variety of algorithms for partitioning unstructured - graphs, meshes, and for computing fill-reducing orderings of sparse matrices. - """ + """ParMETIS is an MPI-based parallel library that implements a variety of + algorithms for partitioning unstructured graphs, meshes, and for + computing fill-reducing orderings of sparse matrices.""" + homepage = 'http://glaros.dtc.umn.edu/gkhome/metis/parmetis/overview' - url = 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/parmetis-4.0.3.tar.gz' + base_url = 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis' version('4.0.3', 'f69c479586bf6bb7aff6a9bc0c739628') + version('4.0.2', '0912a953da5bb9b5e5e10542298ffdce') variant('shared', default=True, description='Enables the build of shared libraries') variant('debug', default=False, description='Builds the library in debug mode') variant('gdb', default=False, description='Enables gdb support') - depends_on('cmake @2.8:') # build dependency + depends_on('cmake@2.8:') # build dependency depends_on('mpi') - - patch('enable_external_metis.patch') depends_on('metis@5:') + patch('enable_external_metis.patch') # bug fixes from PETSc developers - # https://bitbucket.org/petsc/pkg-parmetis/commits/1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b/raw/ + # https://bitbucket.org/petsc/pkg-parmetis/commits/1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b/raw/ # NOQA: ignore=E501 patch('pkg-parmetis-1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b.patch') - # https://bitbucket.org/petsc/pkg-parmetis/commits/82409d68aa1d6cbc70740d0f35024aae17f7d5cb/raw/ + # https://bitbucket.org/petsc/pkg-parmetis/commits/82409d68aa1d6cbc70740d0f35024aae17f7d5cb/raw/ # NOQA: ignore=E501 patch('pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch') - depends_on('gdb', when='+gdb') + def url_for_version(self, version): + verdir = 'OLD/' if version < Version('3.2.0') else '' + return '%s/%sparmetis-%s.tar.gz' % (Parmetis.base_url, verdir, version) def install(self, spec, prefix): options = [] @@ -60,30 +63,27 @@ def install(self, spec, prefix): build_directory = join_path(self.stage.path, 'spack-build') source_directory = self.stage.source_path - metis_source = join_path(source_directory, 'metis') - # FIXME : Once a contract is defined, MPI compilers should be retrieved indirectly via spec['mpi'] in case - # FIXME : they use a non-standard name - options.extend(['-DGKLIB_PATH:PATH={metis_source}/GKlib'.format(metis_source=spec['metis'].prefix.include), - '-DMETIS_PATH:PATH={metis_source}'.format(metis_source=spec['metis'].prefix), - '-DCMAKE_C_COMPILER:STRING=mpicc', - '-DCMAKE_CXX_COMPILER:STRING=mpicxx']) + options.extend([ + '-DGKLIB_PATH:PATH=%s/GKlib' % spec['metis'].prefix.include, + '-DMETIS_PATH:PATH=%s' % spec['metis'].prefix, + '-DCMAKE_C_COMPILER:STRING=%s' % spec['mpi'].mpicc, + '-DCMAKE_CXX_COMPILER:STRING=%s' % spec['mpi'].mpicxx + ]) if '+shared' in spec: options.append('-DSHARED:BOOL=ON') - if '+debug' in spec: options.extend(['-DDEBUG:BOOL=ON', '-DCMAKE_BUILD_TYPE:STRING=Debug']) - if '+gdb' in spec: options.append('-DGDB:BOOL=ON') with working_dir(build_directory, create=True): cmake(source_directory, *options) make() - make("install") + make('install') - # The shared library is not installed correctly on Darwin; correct this + # The shared library is not installed correctly on Darwin; fix this if (sys.platform == 'darwin') and ('+shared' in spec): fix_darwin_install_name(prefix.lib)