diff options
28 files changed, 581 insertions, 106 deletions
diff --git a/lib/spack/env/cc b/lib/spack/env/cc index 0966277a91..aacba996b3 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -94,11 +94,11 @@ case "$command" in command="$SPACK_CXX" language="C++" ;; - f90|fc|f95|gfortran|ifort|pgf90|xlf90) + f90|fc|f95|gfortran|ifort|pgf90|xlf90|nagfor) command="$SPACK_FC" language="Fortran 90" ;; - f77|gfortran|ifort|pgf77|xlf) + f77|gfortran|ifort|pgf77|xlf|nagfor) command="$SPACK_F77" language="Fortran 77" ;; diff --git a/lib/spack/env/nag/nagfor b/lib/spack/env/nag/nagfor new file mode 120000 index 0000000000..82c2b8e90a --- /dev/null +++ b/lib/spack/env/nag/nagfor @@ -0,0 +1 @@ +../cc
\ No newline at end of file diff --git a/lib/spack/spack/cmd/bootstrap.py b/lib/spack/spack/cmd/bootstrap.py index e4ec7da35d..bdbd623b39 100644 --- a/lib/spack/spack/cmd/bootstrap.py +++ b/lib/spack/spack/cmd/bootstrap.py @@ -42,7 +42,7 @@ def get_origin_url(): git = which('git', required=True) origin_url = git( '--git-dir=%s' % git_dir, 'config', '--get', 'remote.origin.url', - return_output=True) + output=str) return origin_url.strip() diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py index 7cea39cb55..edcea0718c 100644 --- a/lib/spack/spack/cmd/create.py +++ b/lib/spack/spack/cmd/create.py @@ -132,7 +132,7 @@ class ConfigureGuesser(object): # Peek inside the tarball. tar = which('tar') output = tar( - "--exclude=*/*/*", "-tf", stage.archive_file, return_output=True) + "--exclude=*/*/*", "-tf", stage.archive_file, output=str) lines = output.split("\n") # Set the configure line to the one that matched. diff --git a/lib/spack/spack/cmd/deactivate.py b/lib/spack/spack/cmd/deactivate.py index a0c78bf755..d6b23d6a08 100644 --- a/lib/spack/spack/cmd/deactivate.py +++ b/lib/spack/spack/cmd/deactivate.py @@ -37,7 +37,7 @@ def setup_parser(subparser): help="Run deactivation even if spec is NOT currently activated.") subparser.add_argument( '-a', '--all', action='store_true', - help="Deactivate all extensions of an extendable pacakge, or " + help="Deactivate all extensions of an extendable package, or " "deactivate an extension AND its dependencies.") subparser.add_argument( 'spec', nargs=argparse.REMAINDER, help="spec of package extension to deactivate.") diff --git a/lib/spack/spack/cmd/location.py b/lib/spack/spack/cmd/location.py index 39c225e9b2..307ee8982d 100644 --- a/lib/spack/spack/cmd/location.py +++ b/lib/spack/spack/cmd/location.py @@ -32,7 +32,7 @@ from llnl.util.filesystem import join_path import spack import spack.cmd -description="Print out locations of various diectories used by Spack" +description="Print out locations of various directories used by Spack" def setup_parser(subparser): global directories diff --git a/lib/spack/spack/cmd/pkg.py b/lib/spack/spack/cmd/pkg.py index 448f762841..cf478d3763 100644 --- a/lib/spack/spack/cmd/pkg.py +++ b/lib/spack/spack/cmd/pkg.py @@ -79,7 +79,7 @@ def list_packages(rev): git = get_git() relpath = spack.packages_path[len(spack.prefix + os.path.sep):] + os.path.sep output = git('ls-tree', '--full-tree', '--name-only', rev, relpath, - return_output=True) + output=str) return sorted(line[len(relpath):] for line in output.split('\n') if line) diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index a665f6062d..12c02e0ea2 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -51,7 +51,7 @@ _version_cache = {} def get_compiler_version(compiler_path, version_arg, regex='(.*)'): if not compiler_path in _version_cache: compiler = Executable(compiler_path) - output = compiler(version_arg, return_output=True, error=os.devnull) + output = compiler(version_arg, output=str, error=str) match = re.search(regex, output) _version_cache[compiler_path] = match.group(1) if match else 'unknown' diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py index facc9c338b..6159ef576c 100644 --- a/lib/spack/spack/compilers/__init__.py +++ b/lib/spack/spack/compilers/__init__.py @@ -51,7 +51,7 @@ _required_instance_vars = ['cc', 'cxx', 'f77', 'fc'] if platform.system() == 'Darwin': _default_order = ['clang', 'gcc', 'intel'] else: - _default_order = ['gcc', 'intel', 'pgi', 'clang', 'xlc'] + _default_order = ['gcc', 'intel', 'pgi', 'clang', 'xlc', 'nag'] def _auto_compiler_spec(function): diff --git a/lib/spack/spack/compilers/nag.py b/lib/spack/spack/compilers/nag.py new file mode 100644 index 0000000000..f1cc6be0d5 --- /dev/null +++ b/lib/spack/spack/compilers/nag.py @@ -0,0 +1,33 @@ +from spack.compiler import * + +class Nag(Compiler): + # Subclasses use possible names of C compiler + cc_names = [] + + # Subclasses use possible names of C++ compiler + cxx_names = [] + + # Subclasses use possible names of Fortran 77 compiler + f77_names = ['nagfor'] + + # Subclasses use possible names of Fortran 90 compiler + fc_names = ['nagfor'] + + # Named wrapper links within spack.build_env_path + link_paths = { # Use default wrappers for C and C++, in case provided in compilers.yaml + 'cc' : 'cc', + 'cxx' : 'cxx', + 'f77' : 'nag/nagfor', + 'fc' : 'nag/nagfor' } + + @classmethod + def default_version(self, comp): + """The '-V' option works for nag compilers. + Output looks like this:: + + NAG Fortran Compiler Release 6.0(Hibiya) Build 1037 + Product NPL6A60NA for x86-64 Linux + Copyright 1990-2015 The Numerical Algorithms Group Ltd., Oxford, U.K. + """ + return get_compiler_version( + comp, '-V', r'NAG Fortran Compiler Release ([0-9.]+)') diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py index 0fa18db34b..9cbe7de44a 100644 --- a/lib/spack/spack/database.py +++ b/lib/spack/spack/database.py @@ -489,7 +489,7 @@ class Database(object): 1. Marks the spec as not installed. 2. Removes the spec if it has no more dependents. 3. If removed, recursively updates dependencies' ref counts - and remvoes them if they are no longer needed. + and removes them if they are no longer needed. """ # Take a lock around the entire removal. diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index 0657146bf6..337dd1e198 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -154,7 +154,7 @@ class URLFetchStrategy(FetchStrategy): # Run curl but grab the mime type from the http headers headers = spack.curl( - *curl_args, return_output=True, fail_on_error=False) + *curl_args, output=str, fail_on_error=False) if spack.curl.returncode != 0: # clean up archive on failure. @@ -375,7 +375,7 @@ class GitFetchStrategy(VCSFetchStrategy): @property def git_version(self): - vstring = self.git('--version', return_output=True).lstrip('git version ') + vstring = self.git('--version', output=str).lstrip('git version ') return Version(vstring) @@ -518,7 +518,7 @@ class SvnFetchStrategy(VCSFetchStrategy): def _remove_untracked_files(self): """Removes untracked files in an svn repository.""" - status = self.svn('status', '--no-ignore', return_output=True) + status = self.svn('status', '--no-ignore', output=str) self.svn('status', '--no-ignore') for line in status.split('\n'): if not re.match('^[I?]', line): diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py index 4188b8d550..905af28a06 100644 --- a/lib/spack/spack/test/cc.py +++ b/lib/spack/spack/test/cc.py @@ -65,17 +65,17 @@ class CompilerTest(unittest.TestCase): def check_cc(self, command, args, expected): os.environ['SPACK_TEST_COMMAND'] = command - self.assertEqual(self.cc(*args, return_output=True).strip(), expected) + self.assertEqual(self.cc(*args, output=str).strip(), expected) def check_ld(self, command, args, expected): os.environ['SPACK_TEST_COMMAND'] = command - self.assertEqual(self.ld(*args, return_output=True).strip(), expected) + self.assertEqual(self.ld(*args, output=str).strip(), expected) def check_cpp(self, command, args, expected): os.environ['SPACK_TEST_COMMAND'] = command - self.assertEqual(self.cpp(*args, return_output=True).strip(), expected) + self.assertEqual(self.cpp(*args, output=str).strip(), expected) def test_vcheck_mode(self): diff --git a/lib/spack/spack/test/make_executable.py b/lib/spack/spack/test/make_executable.py index 09efec8580..d568a28d44 100644 --- a/lib/spack/spack/test/make_executable.py +++ b/lib/spack/spack/test/make_executable.py @@ -56,47 +56,47 @@ class MakeExecutableTest(unittest.TestCase): def test_make_normal(self): make = MakeExecutable('make', 8) - self.assertEqual(make(return_output=True).strip(), '-j8') - self.assertEqual(make('install', return_output=True).strip(), '-j8 install') + self.assertEqual(make(output=str).strip(), '-j8') + self.assertEqual(make('install', output=str).strip(), '-j8 install') def test_make_explicit(self): make = MakeExecutable('make', 8) - self.assertEqual(make(parallel=True, return_output=True).strip(), '-j8') - self.assertEqual(make('install', parallel=True, return_output=True).strip(), '-j8 install') + self.assertEqual(make(parallel=True, output=str).strip(), '-j8') + self.assertEqual(make('install', parallel=True, output=str).strip(), '-j8 install') def test_make_one_job(self): make = MakeExecutable('make', 1) - self.assertEqual(make(return_output=True).strip(), '') - self.assertEqual(make('install', return_output=True).strip(), 'install') + self.assertEqual(make(output=str).strip(), '') + self.assertEqual(make('install', output=str).strip(), 'install') def test_make_parallel_false(self): make = MakeExecutable('make', 8) - self.assertEqual(make(parallel=False, return_output=True).strip(), '') - self.assertEqual(make('install', parallel=False, return_output=True).strip(), 'install') + self.assertEqual(make(parallel=False, output=str).strip(), '') + self.assertEqual(make('install', parallel=False, output=str).strip(), 'install') def test_make_parallel_disabled(self): make = MakeExecutable('make', 8) os.environ['SPACK_NO_PARALLEL_MAKE'] = 'true' - self.assertEqual(make(return_output=True).strip(), '') - self.assertEqual(make('install', return_output=True).strip(), 'install') + self.assertEqual(make(output=str).strip(), '') + self.assertEqual(make('install', output=str).strip(), 'install') os.environ['SPACK_NO_PARALLEL_MAKE'] = '1' - self.assertEqual(make(return_output=True).strip(), '') - self.assertEqual(make('install', return_output=True).strip(), 'install') + self.assertEqual(make(output=str).strip(), '') + self.assertEqual(make('install', output=str).strip(), 'install') # These don't disable (false and random string) os.environ['SPACK_NO_PARALLEL_MAKE'] = 'false' - self.assertEqual(make(return_output=True).strip(), '-j8') - self.assertEqual(make('install', return_output=True).strip(), '-j8 install') + self.assertEqual(make(output=str).strip(), '-j8') + self.assertEqual(make('install', output=str).strip(), '-j8 install') os.environ['SPACK_NO_PARALLEL_MAKE'] = 'foobar' - self.assertEqual(make(return_output=True).strip(), '-j8') - self.assertEqual(make('install', return_output=True).strip(), '-j8 install') + self.assertEqual(make(output=str).strip(), '-j8') + self.assertEqual(make('install', output=str).strip(), '-j8 install') del os.environ['SPACK_NO_PARALLEL_MAKE'] @@ -106,20 +106,20 @@ class MakeExecutableTest(unittest.TestCase): # These should work os.environ['SPACK_NO_PARALLEL_MAKE'] = 'true' - self.assertEqual(make(parallel=True, return_output=True).strip(), '') - self.assertEqual(make('install', parallel=True, return_output=True).strip(), 'install') + self.assertEqual(make(parallel=True, output=str).strip(), '') + self.assertEqual(make('install', parallel=True, output=str).strip(), 'install') os.environ['SPACK_NO_PARALLEL_MAKE'] = '1' - self.assertEqual(make(parallel=True, return_output=True).strip(), '') - self.assertEqual(make('install', parallel=True, return_output=True).strip(), 'install') + self.assertEqual(make(parallel=True, output=str).strip(), '') + self.assertEqual(make('install', parallel=True, output=str).strip(), 'install') # These don't disable (false and random string) os.environ['SPACK_NO_PARALLEL_MAKE'] = 'false' - self.assertEqual(make(parallel=True, return_output=True).strip(), '-j8') - self.assertEqual(make('install', parallel=True, return_output=True).strip(), '-j8 install') + self.assertEqual(make(parallel=True, output=str).strip(), '-j8') + self.assertEqual(make('install', parallel=True, output=str).strip(), '-j8 install') os.environ['SPACK_NO_PARALLEL_MAKE'] = 'foobar' - self.assertEqual(make(parallel=True, return_output=True).strip(), '-j8') - self.assertEqual(make('install', parallel=True, return_output=True).strip(), '-j8 install') + self.assertEqual(make(parallel=True, output=str).strip(), '-j8') + self.assertEqual(make('install', parallel=True, output=str).strip(), '-j8 install') del os.environ['SPACK_NO_PARALLEL_MAKE'] diff --git a/lib/spack/spack/test/mock_repo.py b/lib/spack/spack/test/mock_repo.py index c454b1f106..9738ba4e72 100644 --- a/lib/spack/spack/test/mock_repo.py +++ b/lib/spack/spack/test/mock_repo.py @@ -141,7 +141,7 @@ class MockGitRepo(MockVCSRepo): self.url = self.path def rev_hash(self, rev): - return git('rev-parse', rev, return_output=True).strip() + return git('rev-parse', rev, output=str).strip() class MockSvnRepo(MockVCSRepo): @@ -193,4 +193,4 @@ class MockHgRepo(MockVCSRepo): def get_rev(self): """Get current mercurial revision.""" - return hg('id', '-i', return_output=True).strip() + return hg('id', '-i', output=str).strip() diff --git a/lib/spack/spack/test/svn_fetch.py b/lib/spack/spack/test/svn_fetch.py index 2ee4748fdb..7d150b42f4 100644 --- a/lib/spack/spack/test/svn_fetch.py +++ b/lib/spack/spack/test/svn_fetch.py @@ -65,7 +65,7 @@ class SvnFetchTest(MockPackagesTest): def assert_rev(self, rev): """Check that the current revision is equal to the supplied rev.""" def get_rev(): - output = svn('info', return_output=True) + output = svn('info', output=str) self.assertTrue("Revision" in output) for line in output.split('\n'): match = re.match(r'Revision: (\d+)', line) diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py index ba765eb662..fc27b789d0 100644 --- a/lib/spack/spack/util/executable.py +++ b/lib/spack/spack/util/executable.py @@ -55,24 +55,80 @@ class Executable(object): def __call__(self, *args, **kwargs): - """Run the executable with subprocess.check_output, return output.""" - return_output = kwargs.get("return_output", False) - fail_on_error = kwargs.get("fail_on_error", True) - ignore_errors = kwargs.get("ignore_errors", ()) + """Run this executable in a subprocess. + + Arguments + args + command line arguments to the executable to run. + + Optional arguments + + fail_on_error + + Raise an exception if the subprocess returns an + error. Default is True. When not set, the return code is + avaiale as `exe.returncode`. + + ignore_errors + + An optional list/tuple of error codes that can be + *ignored*. i.e., if these codes are returned, this will + not raise an exception when `fail_on_error` is `True`. + + output, error + + These arguments allow you to specify new stdout and stderr + values. They default to `None`, which means the + subprocess will inherit the parent's file descriptors. + + You can set these to: + - python streams, e.g. open Python file objects, or os.devnull; + - filenames, which will be automatically opened for writing; or + - `str`, as in the Python string type. If you set these to `str`, + output and error will be written to pipes and returned as + a string. If both `output` and `error` are set to `str`, + then one string is returned containing output concatenated + with error. + + input + + Same as output, error, but `str` is not an allowed value. + + Deprecated arguments + + return_output[=False] + + Setting this to True is the same as setting output=str. + This argument may be removed in future Spack versions. + + """ + fail_on_error = kwargs.pop("fail_on_error", True) + ignore_errors = kwargs.pop("ignore_errors", ()) + + # TODO: This is deprecated. Remove in a future version. + return_output = kwargs.pop("return_output", False) # Default values of None says to keep parent's file descriptors. - output = kwargs.get("output", None) - error = kwargs.get("error", None) - input = kwargs.get("input", None) + if return_output: + output = str + else: + output = kwargs.pop("output", None) + + error = kwargs.pop("error", None) + input = kwargs.pop("input", None) + if input is str: + raise ValueError("Cannot use `str` as input stream.") def streamify(arg, mode): if isinstance(arg, basestring): return open(arg, mode), True + elif arg is str: + return subprocess.PIPE, False else: return arg, False - output, ostream = streamify(output, 'w') - error, estream = streamify(error, 'w') - input, istream = streamify(input, 'r') + ostream, close_ostream = streamify(output, 'w') + estream, close_estream = streamify(error, 'w') + istream, close_istream = streamify(input, 'r') # if they just want to ignore one error code, make it a tuple. if isinstance(ignore_errors, int): @@ -92,19 +148,20 @@ class Executable(object): tty.debug(cmd_line) try: - if return_output: - output = subprocess.PIPE - proc = subprocess.Popen( - cmd, stdin=input, stderr=error, stdout=output) + cmd, stdin=istream, stderr=estream, stdout=ostream) out, err = proc.communicate() rc = self.returncode = proc.returncode if fail_on_error and rc != 0 and (rc not in ignore_errors): raise ProcessError("Command exited with status %d:" % proc.returncode, cmd_line) - if return_output: - return out + + if output is str or error is str: + result = '' + if output is str: result += out + if error is str: result += err + return result except OSError, e: raise ProcessError( @@ -119,9 +176,9 @@ class Executable(object): % (proc.returncode, cmd_line)) finally: - if ostream: output.close() - if estream: error.close() - if istream: input.close() + if close_ostream: output.close() + if close_estream: error.close() + if close_istream: input.close() def __eq__(self, other): diff --git a/var/spack/repos/builtin/packages/boost/boost_11856.patch b/var/spack/repos/builtin/packages/boost/boost_11856.patch new file mode 100644 index 0000000000..3b4052ca18 --- /dev/null +++ b/var/spack/repos/builtin/packages/boost/boost_11856.patch @@ -0,0 +1,34 @@ +--- a/libs/container/src/pool_resource.cpp 2015-11-06 12:49:55.000000000 -0800 ++++ b/libs/container/src/pool_resource.cpp 2015-12-22 07:54:36.202131121 -0800 +@@ -32,11 +32,11 @@ + class pool_data_t + : public block_slist_base<> + { +- typedef block_slist_base<> block_slist_base; ++ typedef block_slist_base<> block_slist_base_t; + + public: + explicit pool_data_t(std::size_t initial_blocks_per_chunk) +- : block_slist_base(), next_blocks_per_chunk(initial_blocks_per_chunk) ++ : block_slist_base_t(), next_blocks_per_chunk(initial_blocks_per_chunk) + { slist_algo::init_header(&free_slist); } + + void *allocate_block() BOOST_NOEXCEPT +@@ -59,7 +59,7 @@ + void release(memory_resource &upstream) + { + slist_algo::init_header(&free_slist); +- this->block_slist_base::release(upstream); ++ this->block_slist_base_t::release(upstream); + next_blocks_per_chunk = pool_options_minimum_max_blocks_per_chunk; + } + +@@ -72,7 +72,7 @@ + + //Minimum block size is at least max_align, so all pools allocate sizes that are multiple of max_align, + //meaning that all blocks are max_align-aligned. +- char *p = static_cast<char *>(block_slist_base::allocate(blocks_per_chunk*pool_block, mr)); ++ char *p = static_cast<char *>(block_slist_base_t::allocate(blocks_per_chunk*pool_block, mr)); + + //Create header types. This is no-throw + for(std::size_t i = 0, max = blocks_per_chunk; i != max; ++i){ diff --git a/var/spack/repos/builtin/packages/boost/package.py b/var/spack/repos/builtin/packages/boost/package.py index a30cd7cc35..fb1f5daee7 100644 --- a/var/spack/repos/builtin/packages/boost/package.py +++ b/var/spack/repos/builtin/packages/boost/package.py @@ -87,6 +87,9 @@ class Boost(Package): depends_on('bzip2', when='+iostreams') depends_on('zlib', when='+iostreams') + # Patch fix from https://svn.boost.org/trac/boost/ticket/11856 + patch('boost_11856.patch', when='@1.60.0%gcc@4.4.7') + def url_for_version(self, version): """Handle Boost's weird URLs, which write the version two different ways.""" parts = [str(p) for p in Version(version)] diff --git a/var/spack/repos/builtin/packages/elpa/package.py b/var/spack/repos/builtin/packages/elpa/package.py new file mode 100644 index 0000000000..2ade5b0b37 --- /dev/null +++ b/var/spack/repos/builtin/packages/elpa/package.py @@ -0,0 +1,55 @@ +############################################################################## +# Copyright (c) 2013, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## + +from spack import * + + +class Elpa(Package): + """ + Eigenvalue solvers for Petaflop-Applications (ELPA) + """ + + homepage = 'http://elpa.mpcdf.mpg.de/' + url = 'http://elpa.mpcdf.mpg.de/elpa-2015.11.001.tar.gz' + + version('2015.11.001', 'de0f35b7ee7c971fd0dca35c900b87e6', url='http://elpa.mpcdf.mpg.de/elpa-2015.11.001.tar.gz') + + variant('openmp', default=False, description='Activates OpenMP support') + + depends_on('mpi') + depends_on('blas') + depends_on('lapack') + depends_on('scalapack') + + def install(self, spec, prefix): + + options = ["--prefix=%s" % prefix] + + if '+openmp' in spec: + options.append("--enable-openmp") + + configure(*options) + make() + make("install") diff --git a/var/spack/repos/builtin/packages/gcc/package.py b/var/spack/repos/builtin/packages/gcc/package.py index 61b16f3fd8..3e5895cfb8 100644 --- a/var/spack/repos/builtin/packages/gcc/package.py +++ b/var/spack/repos/builtin/packages/gcc/package.py @@ -50,7 +50,7 @@ class Gcc(Package): version('4.5.4', '27e459c2566b8209ab064570e1b378f7') variant('gold', default=True, description="Build the gold linker plugin for ld-based LTO") - + depends_on("mpfr") depends_on("gmp") depends_on("mpc") # when @4.5: @@ -102,7 +102,7 @@ class Gcc(Package): configure(*options) make() make("install") - + self.write_rpath_specs() @@ -121,7 +121,7 @@ class Gcc(Package): return gcc = Executable(join_path(self.prefix.bin, 'gcc')) - lines = gcc('-dumpspecs', return_output=True).strip().split("\n") + lines = gcc('-dumpspecs', output=str).strip().split("\n") specs_file = join_path(self.spec_dir, 'specs') with closing(open(specs_file, 'w')) as out: for line in lines: diff --git a/var/spack/repos/builtin/packages/hdf5/package.py b/var/spack/repos/builtin/packages/hdf5/package.py index 9a40164341..ac78d8e961 100644 --- a/var/spack/repos/builtin/packages/hdf5/package.py +++ b/var/spack/repos/builtin/packages/hdf5/package.py @@ -1,5 +1,31 @@ +############################################################################## +# Copyright (c) 2013, Lawrence Livermore National Security, LLC. +# Produced at the Lawrence Livermore National Laboratory. +# +# This file is part of Spack. +# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. +# LLNL-CODE-647188 +# +# For details, see https://github.com/llnl/spack +# Please also see the LICENSE file for our notice and the LGPL. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License (as published by +# the Free Software Foundation) version 2.1 dated February 1999. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and +# conditions of the GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +############################################################################## + from spack import * + class Hdf5(Package): """HDF5 is a data model, library, and file format for storing and managing data. It supports an unlimited variety of datatypes, and is designed for @@ -7,7 +33,7 @@ class Hdf5(Package): """ homepage = "http://www.hdfgroup.org/HDF5/" - url = "http://www.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8.13/src/hdf5-1.8.13.tar.gz" + url = "http://www.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8.13/src/hdf5-1.8.13.tar.gz" list_url = "http://www.hdfgroup.org/ftp/HDF5/releases" list_depth = 3 @@ -15,26 +41,53 @@ class Hdf5(Package): version('1.8.15', '03cccb5b33dbe975fdcd8ae9dc021f24') version('1.8.13', 'c03426e9e77d7766944654280b467289') + variant('debug', default=False, description='Builds a debug version of the library') + variant('cxx', default=True, description='Enable C++ support') variant('fortran', default=True, description='Enable Fortran support') + variant('unsupported', default=False, description='Enables unsupported configuration options') + variant('mpi', default=False, description='Enable MPI support') - variant('threadsafe', default=False, description='Enable multithreading') + variant('threadsafe', default=False, description='Enable thread-safe capabilities') depends_on("mpi", when='+mpi') depends_on("zlib") - # TODO: currently hard-coded to use OpenMPI + def validate(self, spec): + """ + Checks if incompatible variants have been activated at the same time + + :param spec: spec of the package + :raises RuntimeError: in case of inconsistencies + """ + if '+fortran' in spec and not self.compiler.fc: + msg = 'cannot build a fortran variant without a fortran compiler' + raise RuntimeError(msg) + + if '+threadsafe' in spec and ('+cxx' in spec or '+fortran' in spec): + raise RuntimeError("cannot use variant +threadsafe with either +cxx or +fortran") + def install(self, spec, prefix): + self.validate(spec) + # Handle compilation after spec validation extra_args = [] + if '+debug' in spec: + extra_args.append('--enable-debug=all') + else: + extra_args.append('--enable-production') + + if '+unsupported' in spec: + extra_args.append("--enable-unsupported") + if '+cxx' in spec: - extra_args.extend([ - '--enable-cxx' - ]) + extra_args.append('--enable-cxx') + if '+fortran' in spec: extra_args.extend([ '--enable-fortran', '--enable-fortran2003' ]) + if '+mpi' in spec: # The HDF5 configure script warns if cxx and mpi are enabled # together. There doesn't seem to be a real reason for this, except @@ -43,27 +96,26 @@ class Hdf5(Package): # this is not actually a problem. extra_args.extend([ "--enable-parallel", - "--enable-unsupported", "CC=%s" % spec['mpi'].prefix.bin + "/mpicc", - "CXX=%s" % spec['mpi'].prefix.bin + "/mpic++", - "FC=%s" % spec['mpi'].prefix.bin + "/mpifort", ]) - if '+threads' in spec: - if '+cxx' in spec or '+fortran' in spec: - die("Cannot use variant +threads with either +cxx or +fortran") + + if '+cxx' in spec: + extra_args.append("CXX=%s" % spec['mpi'].prefix.bin + "/mpic++") + + if '+fortran' in spec: + extra_args.append("FC=%s" % spec['mpi'].prefix.bin + "/mpifort") + + if '+threadsafe' in spec: extra_args.extend([ '--enable-threadsafe', '--disable-hl', - 'CPPFLAGS=-DHDatexit=""', - 'CFLAGS=-DHDatexit=""' ]) configure( "--prefix=%s" % prefix, "--with-zlib=%s" % spec['zlib'].prefix, - "--enable-shared", + "--enable-shared", # TODO : this should be enabled by default, remove it? *extra_args) - make() make("install") diff --git a/var/spack/repos/builtin/packages/mpfr/package.py b/var/spack/repos/builtin/packages/mpfr/package.py index 2758b0da2e..a1bd7529cf 100644 --- a/var/spack/repos/builtin/packages/mpfr/package.py +++ b/var/spack/repos/builtin/packages/mpfr/package.py @@ -33,7 +33,7 @@ class Mpfr(Package): version('3.1.3', '5fdfa3cfa5c86514ee4a241a1affa138') version('3.1.2', 'ee2c3ac63bf0c2359bf08fc3ee094c19') - depends_on('gmp@4.1.0:') + depends_on('gmp') def install(self, spec, prefix): configure("--prefix=%s" % prefix) diff --git a/var/spack/repos/builtin/packages/mumps/Makefile.inc b/var/spack/repos/builtin/packages/mumps/Makefile.inc new file mode 100644 index 0000000000..2e6a041878 --- /dev/null +++ b/var/spack/repos/builtin/packages/mumps/Makefile.inc @@ -0,0 +1,38 @@ +LPORDDIR = $(topdir)/PORD/lib/ +IPORD = -I$(topdir)/PORD/include/ +LPORD = -L$(LPORDDIR) -lpord + +ORDERINGSC = $(ORDERINGSF) +LORDERINGS = $(LMETIS) $(LPORD) $(LSCOTCH) +IORDERINGSF = $(ISCOTCH) +IORDERINGSC = $(IMETIS) $(IPORD) $(ISCOTCH) + +PLAT = +LIBEXT = .a +OUTC = -o +OUTF = -o +RM = /bin/rm -f +AR = ar vr +RANLIB = ranlib + +INCSEQ = -I$(topdir)/libseq +LIBSEQ = -L$(topdir)/libseq -lmpiseq + +INCPAR = +LIBPAR = $(SCALAP) + +LIBOTHERS = -lpthread + +#Sequential: +ifeq ($(MUMPS_TYPE),seq) +INCS = $(INCSEQ) +LIBS = $(LIBSEQ) +LIBSEQNEEDED = libseqneeded +endif + +#Parallel: +ifeq ($(MUMPS_TYPE),par) +INCS = $(INCPAR) +LIBS = $(LIBPAR) +LIBSEQNEEDED = +endif diff --git a/var/spack/repos/builtin/packages/mumps/package.py b/var/spack/repos/builtin/packages/mumps/package.py new file mode 100644 index 0000000000..44a37903cc --- /dev/null +++ b/var/spack/repos/builtin/packages/mumps/package.py @@ -0,0 +1,139 @@ +from spack import * +import os + + +class Mumps(Package): + """MUMPS: a MUltifrontal Massively Parallel sparse direct Solver""" + + homepage = "http://mumps.enseeiht.fr" + url = "http://mumps.enseeiht.fr/MUMPS_5.0.1.tar.gz" + + version('5.0.1', 'b477573fdcc87babe861f62316833db0') + + variant('mpi', default=True, description='Activate the compilation of MUMPS with the MPI support') + variant('scotch', default=False, description='Activate Scotch as a possible ordering library') + variant('ptscotch', default=False, description='Activate PT-Scotch as a possible ordering library') + variant('metis', default=False, description='Activate Metis as a possible ordering library') + variant('parmetis', default=False, description='Activate Parmetis as a possible ordering library') + variant('double', default=True, description='Activate the compilation of dmumps') + variant('float', default=True, description='Activate the compilation of smumps') + variant('complex', default=True, description='Activate the compilation of cmumps and/or zmumps') + variant('idx64', default=False, description='Use int64_t/integer*8 as default index type') + + + depends_on('scotch + esmumps', when='~ptscotch+scotch') + depends_on('scotch + esmumps + mpi', when='+ptscotch') + depends_on('metis', when='~parmetis+metis') + depends_on('parmetis', when="+parmetis") + depends_on('blas') + depends_on('lapack') + depends_on('scalapack', when='+mpi') + depends_on('mpi', when='+mpi') + + # this function is not a patch function because in case scalapack + # is needed it uses self.spec['scalapack'].fc_link set by the + # setup_dependent_environment in scalapck. This happen after patch + # end before install + # def patch(self): + def write_makefile_inc(self): + if ('+parmetis' in self.spec or '+ptscotch' in self.spec) and '+mpi' not in self.spec: + raise RuntimeError('You cannot use the variants parmetis or ptscotch without mpi') + + makefile_conf = ["LIBBLAS = -L%s -lblas" % self.spec['blas'].prefix.lib] + + orderings = ['-Dpord'] + + if '+ptscotch' in self.spec or '+scotch' in self.spec: + join_lib = ' -l%s' % ('pt' if '+ptscotch' in self.spec else '') + makefile_conf.extend( + ["ISCOTCH = -I%s" % self.spec['scotch'].prefix.include, + "LSCOTCH = -L%s %s%s" % (self.spec['scotch'].prefix.lib, + join_lib, + join_lib.join(['esmumps', 'scotch', 'scotcherr']))]) + orderings.append('-Dscotch') + if '+ptscotch' in self.spec: + orderings.append('-Dptscotch') + + if '+parmetis' in self.spec or '+metis' in self.spec: + libname = 'parmetis' if '+parmetis' in self.spec else 'metis' + makefile_conf.extend( + ["IMETIS = -I%s" % self.spec[libname].prefix.include, + "LMETIS = -L%s -l%s" % (self.spec[libname].prefix.lib, libname)]) + + orderings.append('-Dmetis') + if '+parmetis' in self.spec: + orderings.append('-Dparmetis') + + makefile_conf.append("ORDERINGSF = %s" % (' '.join(orderings))) + + # TODO: test this part, it needs a full blas, scalapack and + # partitionning environment with 64bit integers + if '+idx64' in self.spec: + makefile_conf.extend( + # the fortran compilation flags most probably are + # working only for intel and gnu compilers this is + # perhaps something the compiler should provide + ['OPTF = -O -DALLOW_NON_INIT %s' % '-fdefault-integer-8' if self.compiler.name == "gcc" else '-i8', + 'OPTL = -O ', + 'OPTC = -O -DINTSIZE64']) + else: + makefile_conf.extend( + ['OPTF = -O -DALLOW_NON_INIT', + 'OPTL = -O ', + 'OPTC = -O ']) + + + if '+mpi' in self.spec: + makefile_conf.extend( + ["CC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpicc'), + "FC = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'), + "FL = %s" % join_path(self.spec['mpi'].prefix.bin, 'mpif90'), + "SCALAP = %s" % self.spec['scalapack'].fc_link, + "MUMPS_TYPE = par"]) + else: + makefile_conf.extend( + ["CC = cc", + "FC = fc", + "FL = fc", + "MUMPS_TYPE = seq"]) + + # TODO: change the value to the correct one according to the + # compiler possible values are -DAdd_, -DAdd__ and/or -DUPPER + makefile_conf.append("CDEFS = -DAdd_") + + + makefile_inc_template = join_path(os.path.dirname(self.module.__file__), + 'Makefile.inc') + with open(makefile_inc_template, "r") as fh: + makefile_conf.extend(fh.read().split('\n')) + + with working_dir('.'): + with open("Makefile.inc", "w") as fh: + makefile_inc = '\n'.join(makefile_conf) + fh.write(makefile_inc) + + + + def install(self, spec, prefix): + make_libs = [] + + # the coice to compile ?examples is to have kind of a sanity + # check on the libraries generated. + if '+float' in spec: + make_libs.append('sexamples') + if '+complex' in spec: + make_libs.append('cexamples') + + if '+double' in spec: + make_libs.append('dexamples') + if '+complex' in spec: + make_libs.append('zexamples') + + self.write_makefile_inc() + + make(*make_libs) + + install_tree('lib', prefix.lib) + install_tree('include', prefix.include) + if '~mpi' in spec: + install('libseq/libmpiseq.a', prefix.lib) diff --git a/var/spack/repos/builtin/packages/mvapich2/package.py b/var/spack/repos/builtin/packages/mvapich2/package.py index 23a11b3171..af5ed1b088 100644 --- a/var/spack/repos/builtin/packages/mvapich2/package.py +++ b/var/spack/repos/builtin/packages/mvapich2/package.py @@ -4,15 +4,13 @@ import os class Mvapich2(Package): """MVAPICH2 is an MPI implementation for Infiniband networks.""" homepage = "http://mvapich.cse.ohio-state.edu/" + url = "http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.2b.tar.gz" - version('2.2a', 'b8ceb4fc5f5a97add9b3ff1b9cbe39d2', - url='http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.2a.tar.gz') + version('2.2b', '5651e8b7a72d7c77ca68da48f3a5d108') + version('2.2a', 'b8ceb4fc5f5a97add9b3ff1b9cbe39d2') + version('2.0', '9fbb68a4111a8b6338e476dc657388b4') + version('1.9', '5dc58ed08fd3142c260b70fe297e127c') - version('2.0', '9fbb68a4111a8b6338e476dc657388b4', - url='http://mvapich.cse.ohio-state.edu/download/mvapich/mv2/mvapich2-2.0.tar.gz') - - version('1.9', '5dc58ed08fd3142c260b70fe297e127c', - url="http://mvapich.cse.ohio-state.edu/download/mvapich2/mv2/mvapich2-1.9.tgz") patch('ad_lustre_rwcontig_open_source.patch', when='@1.9') provides('mpi@:2.2', when='@1.9') # MVAPICH2-1.9 supports MPI 2.2 @@ -41,16 +39,25 @@ class Mvapich2(Package): NEMESISIBTCP = 'nemesisibtcp' NEMESISIB = 'nemesisib' NEMESIS = 'nemesis' + MRAIL = 'mrail' SUPPORTED_NETWORKS = (PSM, SOCK, NEMESIS, NEMESISIB, NEMESISIBTCP) variant(PSM, default=False, description='Configures a build for QLogic PSM-CH3') variant(SOCK, default=False, description='Configures a build for TCP/IP-CH3') variant(NEMESISIBTCP, default=False, description='Configures a build for both OFA-IB-Nemesis and TCP/IP-Nemesis') variant(NEMESISIB, default=False, description='Configures a build for OFA-IB-Nemesis') variant(NEMESIS, default=False, description='Configures a build for TCP/IP-Nemesis') + variant(MRAIL, default=False, description='Configures a build for OFA-IB-CH3') ########## # FIXME : CUDA support is missing + def url_for_version(self, version): + base_url = "http://mvapich.cse.ohio-state.edu/download" + if version < Version('2.0'): + return "%s/mvapich2/mv2/mvapich2-%s.tar.gz" % (base_url, version) + else: + return "%s/mvapich/mv2/mvapich2-%s.tar.gz" % (base_url, version) + @staticmethod def enabled(x): """ @@ -117,7 +124,7 @@ class Mvapich2(Package): if count > 1: raise RuntimeError('network variants are mutually exclusive (only one can be selected at a time)') - # From here on I can suppose that ony one variant has been selected + # From here on I can suppose that only one variant has been selected if self.enabled(Mvapich2.PSM) in spec: network_options = ["--with-device=ch3:psm"] elif self.enabled(Mvapich2.SOCK) in spec: @@ -128,7 +135,7 @@ class Mvapich2(Package): network_options = ["--with-device=ch3:nemesis:ib"] elif self.enabled(Mvapich2.NEMESIS) in spec: network_options = ["--with-device=ch3:nemesis"] - else: + elif self.enabled(Mvapich2.MRAIL) in spec: network_options = ["--with-device=ch3:mrail", "--with-rdma=gen2"] configure_args.extend(network_options) @@ -141,7 +148,14 @@ class Mvapich2(Package): "--enable-romio", "--disable-silent-rules", ] - if not self.compiler.f77 and not self.compiler.fc: + + if self.compiler.f77 and self.compiler.fc: + configure_args.append("--enable-fortran=all") + elif self.compiler.f77: + configure_args.append("--enable-fortran=f77") + elif self.compiler.fc: + configure_args.append("--enable-fortran=fc") + else: configure_args.append("--enable-fortran=none") # Set the type of the build (debug, release) diff --git a/var/spack/repos/builtin/packages/netlib-scalapack/package.py b/var/spack/repos/builtin/packages/netlib-scalapack/package.py new file mode 100644 index 0000000000..5be91c4a40 --- /dev/null +++ b/var/spack/repos/builtin/packages/netlib-scalapack/package.py @@ -0,0 +1,50 @@ +from spack import * + +class NetlibScalapack(Package): + """ScaLAPACK is a library of high-performance linear algebra routines for parallel distributed memory machines""" + + homepage = "http://www.netlib.org/scalapack/" + url = "http://www.netlib.org/scalapack/scalapack-2.0.2.tgz" + + version('2.0.2', '2f75e600a2ba155ed9ce974a1c4b536f') + version('2.0.1', '17b8cde589ea0423afe1ec43e7499161') + version('2.0.0', '9e76ae7b291be27faaad47cfc256cbfe') + # versions before 2.0.0 are not using cmake and requires blacs as + # a separated package + + variant('shared', default=True, description='Build the shared library version') + variant('fpic', default=False, description="Build with -fpic compiler option") + + provides('scalapack') + + depends_on('mpi') + depends_on('lapack') + + def install(self, spec, prefix): + options = [ + "-DBUILD_SHARED_LIBS:BOOL=%s" % 'ON' if '+shared' in spec else 'OFF', + "-DBUILD_STATIC_LIBS:BOOL=%s" % 'OFF' if '+shared' in spec else 'ON', + "-DUSE_OPTIMIZED_LAPACK_BLAS:BOOL=ON", # forces scalapack to use find_package(LAPACK) + ] + + if '+fpic' in spec: + options.extend([ + "-DCMAKE_C_FLAGS=-fPIC", + "-DCMAKE_Fortran_FLAGS=-fPIC" + ]) + + options.extend(std_cmake_args) + + with working_dir('spack-build', create=True): + cmake('..', *options) + make() + make("install") + + def setup_dependent_environment(self, module, spec, dependent_spec): + # TODO treat OS that are not Linux... + lib_suffix = '.so' if '+shared' in spec['scalapack'] else '.a' + + spec['scalapack'].fc_link = '-L%s -lscalapack' % spec['scalapack'].prefix.lib + spec['scalapack'].cc_link = spec['scalapack'].fc_link + spec['scalapack'].libraries = [join_path(spec['scalapack'].prefix.lib, + 'libscalapack%s' % lib_suffix)] diff --git a/var/spack/repos/builtin/packages/openmpi/package.py b/var/spack/repos/builtin/packages/openmpi/package.py index 463719f9db..e4484af8c5 100644 --- a/var/spack/repos/builtin/packages/openmpi/package.py +++ b/var/spack/repos/builtin/packages/openmpi/package.py @@ -17,45 +17,47 @@ class Openmpi(Package): list_url = "http://www.open-mpi.org/software/ompi/" list_depth = 3 + version('1.10.2', 'b2f43d9635d2d52826e5ef9feb97fd4c') version('1.10.1', 'f0fcd77ed345b7eafb431968124ba16e') version('1.10.0', '280cf952de68369cebaca886c5ce0304') - version('1.8.8', '0dab8e602372da1425e9242ae37faf8c') - version('1.6.5', '03aed2a4aa4d0b27196962a2a65fc475') + version('1.8.8', '0dab8e602372da1425e9242ae37faf8c') + version('1.6.5', '03aed2a4aa4d0b27196962a2a65fc475') patch('ad_lustre_rwcontig_open_source.patch', when="@1.6.5") patch('llnl-platforms.patch', when="@1.6.5") - patch('configure.patch', when="@1.10.0:") + patch('configure.patch', when="@1.10.0:1.10.1") - variant('psm', default=False, description='Build support for the PSM library.') + variant('psm', default=False, description='Build support for the PSM library.') variant('verbs', default=False, description='Build support for OpenFabrics verbs.') + # TODO : variant support for other schedulers is missing + variant('tm', default=False, description='Build TM (Torque, PBSPro, and compatible) support') + provides('mpi@:2.2', when='@1.6.5') provides('mpi@:3.0', when='@1.7.5:') - depends_on('hwloc') - def url_for_version(self, version): return "http://www.open-mpi.org/software/ompi/v%s/downloads/openmpi-%s.tar.bz2" % (version.up_to(2), version) - def setup_dependent_environment(self, module, spec, dep_spec): """For dependencies, make mpicc's use spack wrapper.""" - os.environ['OMPI_CC'] = 'cc' + os.environ['OMPI_CC'] = 'cc' os.environ['OMPI_CXX'] = 'c++' os.environ['OMPI_FC'] = 'f90' os.environ['OMPI_F77'] = 'f77' - def install(self, spec, prefix): config_args = ["--prefix=%s" % prefix, "--with-hwloc=%s" % spec['hwloc'].prefix, - "--with-tm", # necessary for Torque support "--enable-shared", "--enable-static"] # Variants + if '+tm' in spec: + config_args.append("--with-tm") # necessary for Torque support + if '+psm' in spec: config_args.append("--with-psm") @@ -85,7 +87,6 @@ class Openmpi(Package): self.filter_compilers() - def filter_compilers(self): """Run after install to make the MPI compilers use the compilers that Spack built the package with. @@ -94,7 +95,7 @@ class Openmpi(Package): to Spack's generic cc, c++ and f90. We want them to be bound to whatever compiler they were built with. """ - kwargs = { 'ignore_absent' : True, 'backup' : False, 'string' : False } + kwargs = {'ignore_absent': True, 'backup': False, 'string': False} dir = os.path.join(self.prefix, 'share/openmpi/') cc_wrappers = ['mpicc-vt-wrapper-data.txt', 'mpicc-wrapper-data.txt', @@ -132,5 +133,3 @@ class Openmpi(Package): if not os.path.islink(path): filter_file('compiler=.*', 'compiler=%s' % self.compiler.fc, path, **kwargs) - - |