summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2015-06-07 16:10:32 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2015-06-07 16:10:32 -0700
commit1857b7736f1c416ebadbe2d49d5297d31e235365 (patch)
tree24a179c9b44a5f877cc65d6f6f27d6c8fe39b23a
parentab31f989db4de515aafd900c9235161ce45993b3 (diff)
parentbde9c7eee3fb55258b6c5e0ddb143882ebe0cca3 (diff)
downloadspack-1857b7736f1c416ebadbe2d49d5297d31e235365.tar.gz
spack-1857b7736f1c416ebadbe2d49d5297d31e235365.tar.bz2
spack-1857b7736f1c416ebadbe2d49d5297d31e235365.tar.xz
spack-1857b7736f1c416ebadbe2d49d5297d31e235365.zip
Merge Kevin, Ben, and Saravan's contributions into develop
- includes ATLAS, BLAS, LAPACK, other FastMATH packages.
-rwxr-xr-xbin/spack9
-rw-r--r--lib/spack/llnl/util/filesystem.py12
-rw-r--r--lib/spack/spack/build_environment.py4
-rw-r--r--lib/spack/spack/concretize.py24
-rw-r--r--lib/spack/spack/error.py15
-rw-r--r--lib/spack/spack/package.py46
-rw-r--r--lib/spack/spack/spec.py33
-rw-r--r--lib/spack/spack/test/concretize.py9
-rw-r--r--lib/spack/spack/test/directory_layout.py3
-rw-r--r--lib/spack/spack/test/spec_semantics.py61
-rw-r--r--lib/spack/spack/util/executable.py5
-rw-r--r--var/spack/packages/arpack/package.py41
-rw-r--r--var/spack/packages/atlas/package.py60
-rw-r--r--var/spack/packages/boxlib/package.py25
-rw-r--r--var/spack/packages/cblas/package.py32
-rw-r--r--var/spack/packages/cgm/package.py30
-rw-r--r--var/spack/packages/hypre/package.py32
-rw-r--r--var/spack/packages/lapack/package.py45
-rw-r--r--var/spack/packages/metis/package.py29
-rw-r--r--var/spack/packages/netlib-blas/package.py40
-rw-r--r--var/spack/packages/parpack/package.py43
-rw-r--r--var/spack/packages/petsc/package.py40
22 files changed, 580 insertions, 58 deletions
diff --git a/bin/spack b/bin/spack
index 354754594e..5c042edd2d 100755
--- a/bin/spack
+++ b/bin/spack
@@ -126,14 +126,7 @@ def main():
try:
return_val = command(parser, args)
except SpackError, e:
- if spack.debug:
- # In debug mode, raise with a full stack trace.
- raise
- elif e.long_message:
- tty.die(e.message, e.long_message)
- else:
- tty.die(e.message)
-
+ e.die()
except KeyboardInterrupt:
sys.stderr.write('\n')
tty.die("Keyboard interrupt.")
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index 3b34e04740..029a7536df 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -25,7 +25,7 @@
__all__ = ['set_install_permissions', 'install', 'install_tree', 'traverse_tree',
'expand_user', 'working_dir', 'touch', 'touchp', 'mkdirp',
'force_remove', 'join_path', 'ancestor', 'can_access', 'filter_file',
- 'change_sed_delimiter', 'is_exe', 'force_symlink']
+ 'FileFilter', 'change_sed_delimiter', 'is_exe', 'force_symlink']
import os
import sys
@@ -40,7 +40,6 @@ from tempfile import NamedTemporaryFile
import llnl.util.tty as tty
from spack.util.compression import ALLOWED_ARCHIVE_TYPES
-
def filter_file(regex, repl, *filenames, **kwargs):
"""Like sed, but uses python regular expressions.
@@ -97,6 +96,15 @@ def filter_file(regex, repl, *filenames, **kwargs):
shutil.rmtree(backup, ignore_errors=True)
+class FileFilter(object):
+ """Convenience class for calling filter_file a lot."""
+ def __init__(self, *filenames):
+ self.filenames = filenames
+
+ def filter(self, regex, repl, **kwargs):
+ return filter_file(regex, repl, *self.filenames, **kwargs)
+
+
def change_sed_delimiter(old_delim, new_delim, *filenames):
"""Find all sed search/replace commands and change the delimiter.
e.g., if the file contains seds that look like 's///', you can
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index f9e795ac42..81fbedc689 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -280,6 +280,10 @@ def fork(pkg, function):
# Use os._exit here to avoid raising a SystemExit exception,
# which interferes with unit tests.
os._exit(0)
+
+ except spack.error.SpackError, e:
+ e.die()
+
except:
# Child doesn't raise or return to main spack code.
# Just runs default exception handler and exits.
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 15e886ad3c..2e1d5d7f03 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -75,7 +75,23 @@ class DefaultConcretizer(object):
if valid_versions:
spec.versions = ver([valid_versions[-1]])
else:
- raise NoValidVersionError(spec)
+ # We don't know of any SAFE versions that match the given
+ # spec. Grab the spec's versions and grab the highest
+ # *non-open* part of the range of versions it specifies.
+ # Someone else can raise an error if this happens,
+ # e.g. when we go to fetch it and don't know how. But it
+ # *might* work.
+ if not spec.versions or spec.versions == VersionList([':']):
+ raise NoValidVersionError(spec)
+ else:
+ last = spec.versions[-1]
+ if isinstance(last, VersionRange):
+ if last.end:
+ spec.versions = ver([last.end])
+ else:
+ spec.versions = ver([last.start])
+ else:
+ spec.versions = ver([last])
def concretize_architecture(self, spec):
@@ -174,8 +190,8 @@ class UnavailableCompilerVersionError(spack.error.SpackError):
class NoValidVersionError(spack.error.SpackError):
- """Raised when there is no available version for a package that
- satisfies a spec."""
+ """Raised when there is no way to have a concrete version for a
+ particular spec."""
def __init__(self, spec):
super(NoValidVersionError, self).__init__(
- "No available version of %s matches '%s'" % (spec.name, spec.versions))
+ "There are no valid versions for %s that match '%s'" % (spec.name, spec.versions))
diff --git a/lib/spack/spack/error.py b/lib/spack/spack/error.py
index e8fa756682..bfa7951a47 100644
--- a/lib/spack/spack/error.py
+++ b/lib/spack/spack/error.py
@@ -22,6 +22,10 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
+import os
+import sys
+import llnl.util.tty as tty
+import spack
class SpackError(Exception):
"""This is the superclass for all Spack errors.
@@ -38,6 +42,17 @@ class SpackError(Exception):
return self._long_message
+ def die(self):
+ if spack.debug:
+ sys.excepthook(*sys.exc_info())
+ os._exit(1)
+ else:
+ tty.error(self.message)
+ if self.long_message:
+ print self.long_message
+ os._exit(1)
+
+
def __str__(self):
msg = self.message
if self.long_message:
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 5dd410d0e4..5abf2a6bb3 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -471,13 +471,18 @@ class Package(object):
"""Spec of the extendee of this package, or None if it is not an extension."""
if not self.extendees:
return None
+
+ # TODO: allow more than one extendee.
name = next(iter(self.extendees))
- if not name in self.spec:
- spec, kwargs = self.extendees[name]
- return spec
- # Need to do this to get the concrete version of the spec
- return self.spec[name]
+ # If the extendee is in the spec's deps already, return that.
+ for dep in self.spec.traverse():
+ if name == dep.name:
+ return dep
+
+ # Otherwise return the spec from the extends() directive
+ spec, kwargs = self.extendees[name]
+ return spec
@property
@@ -542,7 +547,7 @@ class Package(object):
def provides(self, vpkg_name):
"""True if this package provides a virtual package with the specified name."""
- return vpkg_name in self.provided
+ return any(s.name == vpkg_name for s in self.provided)
def virtual_dependencies(self, visited=None):
@@ -561,8 +566,11 @@ class Package(object):
on this one."""
dependents = []
for spec in spack.db.installed_package_specs():
- if self.name != spec.name and self.spec in spec:
- dependents.append(spec)
+ if self.name == spec.name:
+ continue
+ for dep in spec.traverse():
+ if spec == dep:
+ dependents.append(spec)
return dependents
@@ -816,17 +824,8 @@ class Package(object):
except ProcessError, e:
# Annotate with location of build log.
e.build_log = log_path
-
- # One of the processes returned an error code.
- # Suppress detailed stack trace here unless in debug mode
- if spack.debug:
- raise e
- else:
- tty.error(e)
-
- # Still need to clean up b/c there was an error.
cleanup()
- os._exit(1)
+ raise e
except:
# other exceptions just clean up and raise.
@@ -994,10 +993,13 @@ class Package(object):
activated = spack.install_layout.extension_map(self.extendee_spec)
for name, aspec in activated.items():
- if aspec != self.spec and self.spec in aspec:
- raise ActivationError(
- "Cannot deactivate %s beacuse %s is activated and depends on it."
- % (self.spec.short_spec, aspec.short_spec))
+ if aspec == self.spec:
+ continue
+ for dep in aspec.traverse():
+ if self.spec == dep:
+ raise ActivationError(
+ "Cannot deactivate %s beacuse %s is activated and depends on it."
+ % (self.spec.short_spec, aspec.short_spec))
self.extendee_spec.package.deactivate(self, **self.extendee_args)
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index aa13f0422c..5876fc6cf8 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -498,7 +498,13 @@ class Spec(object):
Possible idea: just use conventin and make virtual deps all
caps, e.g., MPI vs mpi.
"""
- return not spack.db.exists(self.name)
+ return Spec.is_virtual(self.name)
+
+
+ @staticmethod
+ def is_virtual(name):
+ """Test if a name is virtual without requiring a Spec."""
+ return not spack.db.exists(name)
@property
@@ -1224,7 +1230,17 @@ class Spec(object):
"""
other = self._autospec(other)
- # First thing we care about is whether the name matches
+ # A concrete provider can satisfy a virtual dependency.
+ if not self.virtual and other.virtual:
+ pkg = spack.db.get(self.name)
+ if pkg.provides(other.name):
+ for provided, when_spec in pkg.provided.items():
+ if self.satisfies(when_spec, deps=False, strict=strict):
+ if provided.satisfies(other):
+ return True
+ return False
+
+ # Otherwise, first thing we care about is whether the name matches
if self.name != other.name:
return False
@@ -1364,11 +1380,21 @@ class Spec(object):
def __getitem__(self, name):
- """TODO: reconcile __getitem__, _add_dependency, __contains__"""
+ """Get a dependency from the spec by its name."""
for spec in self.traverse():
if spec.name == name:
return spec
+ if Spec.is_virtual(name):
+ # TODO: this is a kind of kludgy way to find providers
+ # TODO: should we just keep virtual deps in the DAG instead of
+ # TODO: removing them on concretize?
+ for spec in self.traverse():
+ if spec.virtual:
+ continue
+ if spec.package.provides(name):
+ return spec
+
raise KeyError("No spec with name %s in %s" % (name, self))
@@ -1380,6 +1406,7 @@ class Spec(object):
for s in self.traverse():
if s.satisfies(spec, strict=True):
return True
+
return False
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index cc839a2340..b3a77d076a 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -152,7 +152,10 @@ class ConcretizeTest(MockPackagesTest):
spec.concretize()
self.assertTrue('zmpi' in spec.dependencies)
- self.assertFalse('mpi' in spec)
+ self.assertTrue(all(not 'mpi' in d.dependencies for d in spec.traverse()))
+ self.assertTrue('zmpi' in spec)
+ self.assertTrue('mpi' in spec)
+
self.assertTrue('fake' in spec.dependencies['zmpi'])
@@ -168,7 +171,9 @@ class ConcretizeTest(MockPackagesTest):
self.assertTrue('zmpi' in spec.dependencies['callpath'].dependencies)
self.assertTrue('fake' in spec.dependencies['callpath'].dependencies['zmpi'].dependencies)
- self.assertFalse('mpi' in spec)
+ self.assertTrue(all(not 'mpi' in d.dependencies for d in spec.traverse()))
+ self.assertTrue('zmpi' in spec)
+ self.assertTrue('mpi' in spec)
def test_my_dep_depends_on_provider_of_my_virtual_dep(self):
diff --git a/lib/spack/spack/test/directory_layout.py b/lib/spack/spack/test/directory_layout.py
index beac038410..b3ad8efec4 100644
--- a/lib/spack/spack/test/directory_layout.py
+++ b/lib/spack/spack/test/directory_layout.py
@@ -167,12 +167,15 @@ class DirectoryLayoutTest(unittest.TestCase):
def test_find(self):
"""Test that finding specs within an install layout works."""
packages = list(spack.db.all_packages())[:max_packages]
+
+ # Create install prefixes for all packages in the list
installed_specs = {}
for pkg in packages:
spec = pkg.spec.concretized()
installed_specs[spec.name] = spec
self.layout.create_install_directory(spec)
+ # Make sure all the installed specs appear in DirectoryLayout.all_specs()
found_specs = dict((s.name, s) for s in self.layout.all_specs())
for name, spec in found_specs.items():
self.assertTrue(name in found_specs)
diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py
index 20df2603f5..6666dbbb52 100644
--- a/lib/spack/spack/test/spec_semantics.py
+++ b/lib/spack/spack/test/spec_semantics.py
@@ -189,6 +189,67 @@ class SpecSematicsTest(MockPackagesTest):
self.check_unsatisfiable('mpich+foo', 'mpich~foo')
+ def test_satisfies_virtual(self):
+ self.assertTrue(Spec('mpich').satisfies(Spec('mpi')))
+ self.assertTrue(Spec('mpich2').satisfies(Spec('mpi')))
+ self.assertTrue(Spec('zmpi').satisfies(Spec('mpi')))
+
+
+ # ================================================================================
+ # Indexing specs
+ # ================================================================================
+ def test_self_index(self):
+ s = Spec('callpath')
+ self.assertTrue(s['callpath'] == s)
+
+
+ def test_dep_index(self):
+ s = Spec('callpath')
+ s.normalize()
+
+ self.assertTrue(s['callpath'] == s)
+ self.assertTrue(type(s['dyninst']) == Spec)
+ self.assertTrue(type(s['libdwarf']) == Spec)
+ self.assertTrue(type(s['libelf']) == Spec)
+ self.assertTrue(type(s['mpi']) == Spec)
+
+ self.assertTrue(s['dyninst'].name == 'dyninst')
+ self.assertTrue(s['libdwarf'].name == 'libdwarf')
+ self.assertTrue(s['libelf'].name == 'libelf')
+ self.assertTrue(s['mpi'].name == 'mpi')
+
+
+ def test_spec_contains_deps(self):
+ s = Spec('callpath')
+ s.normalize()
+ self.assertTrue('dyninst' in s)
+ self.assertTrue('libdwarf' in s)
+ self.assertTrue('libelf' in s)
+ self.assertTrue('mpi' in s)
+
+
+ def test_virtual_index(self):
+ s = Spec('callpath')
+ s.concretize()
+
+ s_mpich = Spec('callpath ^mpich')
+ s_mpich.concretize()
+
+ s_mpich2 = Spec('callpath ^mpich2')
+ s_mpich2.concretize()
+
+ s_zmpi = Spec('callpath ^zmpi')
+ s_zmpi.concretize()
+
+
+ self.assertTrue(s['mpi'].name != 'mpi')
+ self.assertTrue(s_mpich['mpi'].name == 'mpich')
+ self.assertTrue(s_mpich2['mpi'].name == 'mpich2')
+ self.assertTrue(s_zmpi['zmpi'].name == 'zmpi')
+
+ for spec in [s, s_mpich, s_mpich2, s_zmpi]:
+ self.assertTrue('mpi' in spec)
+
# ================================================================================
# Constraints
diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py
index 6eede0f78e..1dcda0d87f 100644
--- a/lib/spack/spack/util/executable.py
+++ b/lib/spack/spack/util/executable.py
@@ -124,6 +124,11 @@ class Executable(object):
return "<exe: %s>" % self.exe
+ def __str__(self):
+ return ' '.join(self.exe)
+
+
+
def which(name, **kwargs):
"""Finds an executable in the path like command-line which."""
path = kwargs.get('path', os.environ.get('PATH', '').split(os.pathsep))
diff --git a/var/spack/packages/arpack/package.py b/var/spack/packages/arpack/package.py
new file mode 100644
index 0000000000..8c67c536f3
--- /dev/null
+++ b/var/spack/packages/arpack/package.py
@@ -0,0 +1,41 @@
+from spack import *
+import os
+import shutil
+
+class Arpack(Package):
+ """A collection of Fortran77 subroutines designed to solve large scale
+ eigenvalue problems.
+ """
+ homepage = "http://www.caam.rice.edu/software/ARPACK/"
+ url = "http://www.caam.rice.edu/software/ARPACK/SRC/arpack96.tar.gz"
+
+ version('96', 'fffaa970198b285676f4156cebc8626e')
+
+ depends_on('blas')
+ depends_on('lapack')
+
+ def patch(self):
+ # Filter the cray makefile to make a spack one.
+ shutil.move('ARMAKES/ARmake.CRAY', 'ARmake.inc')
+ makefile = FileFilter('ARmake.inc')
+
+ # Be sure to use Spack F77 wrapper
+ makefile.filter('^FC.*', 'FC = f77')
+ makefile.filter('^FFLAGS.*', 'FFLAGS = -O2 -g')
+
+ # Set up some variables.
+ makefile.filter('^PLAT.*', 'PLAT = ')
+ makefile.filter('^home.*', 'home = %s' % os.getcwd())
+ makefile.filter('^BLASdir.*', 'BLASdir = %s' % self.spec['blas'].prefix)
+ makefile.filter('^LAPACKdir.*', 'LAPACKdir = %s' % self.spec['lapack'].prefix)
+
+ # build the library in our own prefix.
+ makefile.filter('^ARPACKLIB.*', 'ARPACKLIB = %s/libarpack.a' % os.getcwd())
+
+
+ def install(self, spec, prefix):
+ with working_dir('SRC'):
+ make('all')
+
+ mkdirp(prefix.lib)
+ install('libarpack.a', prefix.lib)
diff --git a/var/spack/packages/atlas/package.py b/var/spack/packages/atlas/package.py
new file mode 100644
index 0000000000..fc683363a7
--- /dev/null
+++ b/var/spack/packages/atlas/package.py
@@ -0,0 +1,60 @@
+from spack import *
+from spack.util.executable import Executable
+import os
+
+class Atlas(Package):
+ """
+ Automatically Tuned Linear Algebra Software, generic shared
+ ATLAS is an approach for the automatic generation and optimization of
+ numerical software. Currently ATLAS supplies optimized versions for the
+ complete set of linear algebra kernels known as the Basic Linear Algebra
+ Subroutines (BLAS), and a subset of the linear algebra routines in the
+ LAPACK library.
+ """
+ homepage = "http://math-atlas.sourceforge.net/"
+
+ version('3.11.34', '0b6c5389c095c4c8785fd0f724ec6825',
+ url='http://sourceforge.net/projects/math-atlas/files/Developer%20%28unstable%29/3.11.34/atlas3.11.34.tar.bz2/download')
+ version('3.10.2', 'a4e21f343dec8f22e7415e339f09f6da',
+ url='http://downloads.sourceforge.net/project/math-atlas/Stable/3.10.2/atlas3.10.2.tar.bz2')
+
+ # TODO: make this provide BLAS once it works better. Create a way
+ # TODO: to mark "beta" packages and require explicit invocation.
+
+ # provides('blas')
+
+
+ def patch(self):
+ # Disable thraed check. LLNL's environment does not allow
+ # disabling of CPU throttling in a way that ATLAS actually
+ # understands.
+ filter_file(r'^\s+if \(thrchk\) exit\(1\);', 'if (0) exit(1);',
+ 'CONFIG/src/config.c')
+ # TODO: investigate a better way to add the check back in
+ # TODO: using, say, MSRs. Or move this to a variant.
+
+ @when('@:3.10')
+ def install(self, spec, prefix):
+ with working_dir('ATLAS-Build', create=True):
+ configure = Executable('../configure')
+ configure('--prefix=%s' % prefix, '-C', 'ic', 'cc', '-C', 'if', 'f77', "--dylibs")
+ make()
+ make('check')
+ make('ptcheck')
+ make('time')
+ make("install")
+
+
+ def install(self, spec, prefix):
+ with working_dir('ATLAS-Build', create=True):
+ configure = Executable('../configure')
+ configure('--incdir=%s' % prefix.include,
+ '--libdir=%s' % prefix.lib,
+ '--cc=cc',
+ "--shared")
+
+ make()
+ make('check')
+ make('ptcheck')
+ make('time')
+ make("install")
diff --git a/var/spack/packages/boxlib/package.py b/var/spack/packages/boxlib/package.py
new file mode 100644
index 0000000000..4f1b71132f
--- /dev/null
+++ b/var/spack/packages/boxlib/package.py
@@ -0,0 +1,25 @@
+from spack import *
+
+class Boxlib(Package):
+ """BoxLib, a software framework for massively parallel
+ block-structured adaptive mesh refinement (AMR) codes."""
+
+ homepage = "https://ccse.lbl.gov/BoxLib/"
+ url = "https://ccse.lbl.gov/pub/Downloads/BoxLib.git";
+
+ # TODO: figure out how best to version this. No tags in the repo!
+ version('master', git='https://ccse.lbl.gov/pub/Downloads/BoxLib.git')
+
+ depends_on('mpi')
+
+ def install(self, spec, prefix):
+ args = std_cmake_args
+ args += ['-DCCSE_ENABLE_MPI=1',
+ '-DCMAKE_C_COMPILER=%s' % which('mpicc'),
+ '-DCMAKE_CXX_COMPILER=%s' % which('mpicxx'),
+ '-DCMAKE_Fortran_COMPILER=%s' % which('mpif90')]
+
+ cmake('.', *args)
+ make()
+ make("install")
+
diff --git a/var/spack/packages/cblas/package.py b/var/spack/packages/cblas/package.py
new file mode 100644
index 0000000000..93cf5fb7b8
--- /dev/null
+++ b/var/spack/packages/cblas/package.py
@@ -0,0 +1,32 @@
+from spack import *
+import os
+
+class Cblas(Package):
+ """The BLAS (Basic Linear Algebra Subprograms) are routines that
+ provide standard building blocks for performing basic vector and
+ matrix operations."""
+
+ homepage = "http://www.netlib.org/blas/_cblas/"
+
+ # tarball has no version, but on the date below, this MD5 was correct.
+ version('2015-06-06', '1e8830f622d2112239a4a8a83b84209a',
+ url='http://www.netlib.org/blas/blast-forum/cblas.tgz')
+
+ depends_on('blas')
+ parallel = False
+
+ def patch(self):
+ mf = FileFilter('Makefile.in')
+
+ mf.filter('^BLLIB =.*', 'BLLIB = %s/libblas.a' % self.spec['blas'].prefix.lib)
+ mf.filter('^CC =.*', 'CC = cc')
+ mf.filter('^FC =.*', 'FC = f90')
+
+
+ def install(self, spec, prefix):
+ make('all')
+ mkdirp(prefix.lib)
+
+ # Rename the generated lib file to libcblas.a
+ install('./lib/cblas_LINUX.a', '%s/libcblas.a' % prefix.lib)
+
diff --git a/var/spack/packages/cgm/package.py b/var/spack/packages/cgm/package.py
new file mode 100644
index 0000000000..05d6395c5a
--- /dev/null
+++ b/var/spack/packages/cgm/package.py
@@ -0,0 +1,30 @@
+from spack import *
+
+class Cgm(Package):
+ """The Common Geometry Module, Argonne (CGMA) is a code library
+ which provides geometry functionality used for mesh generation and
+ other applications."""
+ homepage = "http://trac.mcs.anl.gov/projects/ITAPS/wiki/CGM"
+ url = "http://ftp.mcs.anl.gov/pub/fathom/cgm13.1.1.tar.gz"
+
+ version('13.1.1', '4e8dbc4ba8f65767b29f985f7a23b01f')
+ version('13.1.0', 'a6c7b22660f164ce893fb974f9cb2028')
+ version('13.1' , '95f724bda04919fc76818a5b7bc0b4ed')
+
+ depends_on("mpi")
+
+ def patch(self):
+ filter_file('^(#include "CGMParallelConventions.h")',
+ '//\1',
+ 'geom/parallel/CGMReadParallel.cpp')
+
+
+ def install(self, spec, prefix):
+ configure("--with-mpi",
+ "--prefix=%s" % prefix,
+ "CFLAGS=-static",
+ "CXXFLAGS=-static",
+ "FCFLAGS=-static")
+
+ make()
+ make("install")
diff --git a/var/spack/packages/hypre/package.py b/var/spack/packages/hypre/package.py
new file mode 100644
index 0000000000..198b3f00dc
--- /dev/null
+++ b/var/spack/packages/hypre/package.py
@@ -0,0 +1,32 @@
+from spack import *
+
+class Hypre(Package):
+ """Hypre is a library of high performance preconditioners that
+ features parallel multigrid methods for both structured and
+ unstructured grid problems."""
+
+ homepage = "https://computation.llnl.gov/project/linear_solvers/software.php"
+ url = "https://computation.llnl.gov/project/linear_solvers/download/hypre-2.10.0b.tar.gz"
+
+ version('2.10.0b', '768be38793a35bb5d055905b271f5b8e')
+
+ depends_on("mpi")
+ depends_on("blas")
+ depends_on("lapack")
+
+ def install(self, spec, prefix):
+ blas_dir = spec['blas'].prefix
+ lapack_dir = spec['lapack'].prefix
+
+ # Hypre's source is staged under ./src so we'll have to manually
+ # cd into it.
+ with working_dir("src"):
+ configure(
+ "--prefix=%s" % prefix,
+ "--with-blas-libs=blas",
+ "--with-blas-lib-dirs=%s/lib" % blas_dir,
+ "--with-lapack-libs=\"lapack blas\"",
+ "--with-lapack-lib-dirs=%s/lib" % lapack_dir,
+ "--with-MPI")
+ make()
+ make("install")
diff --git a/var/spack/packages/lapack/package.py b/var/spack/packages/lapack/package.py
new file mode 100644
index 0000000000..d9d37e3e4a
--- /dev/null
+++ b/var/spack/packages/lapack/package.py
@@ -0,0 +1,45 @@
+from spack import *
+
+class Lapack(Package):
+ """
+ LAPACK version 3.X is a comprehensive FORTRAN library that does
+ linear algebra operations including matrix inversions, least
+ squared solutions to linear sets of equations, eigenvector
+ analysis, singular value decomposition, etc. It is a very
+ comprehensive and reputable package that has found extensive
+ use in the scientific community.
+ """
+ homepage = "http://www.netlib.org/lapack/"
+ url = "http://www.netlib.org/lapack/lapack-3.5.0.tgz"
+
+ version('3.5.0', 'b1d3e3e425b2e44a06760ff173104bdf')
+ version('3.4.2', '61bf1a8a4469d4bdb7604f5897179478')
+ version('3.4.1', '44c3869c38c8335c2b9c2a8bb276eb55')
+ version('3.4.0', '02d5706ec03ba885fc246e5fa10d8c70')
+ version('3.3.1', 'd0d533ec9a5b74933c2a1e84eedc58b4')
+
+ # blas is a virtual dependency.
+ depends_on('blas')
+
+ # Doesn't always build correctly in parallel
+ parallel = False
+
+ @when('^netlib-blas')
+ def get_blas_libs(self):
+ blas = self.spec['netlib-blas']
+ return [join_path(blas.prefix.lib, 'blas.a')]
+
+
+ @when('^atlas')
+ def get_blas_libs(self):
+ blas = self.spec['atlas']
+ return [join_path(blas.prefix.lib, l)
+ for l in ('libf77blas.a', 'libatlas.a')]
+
+
+ def install(self, spec, prefix):
+ blas_libs = ";".join(self.get_blas_libs())
+ cmake(".", '-DBLAS_LIBRARIES=' + blas_libs, *std_cmake_args)
+ make()
+ make("install")
+
diff --git a/var/spack/packages/metis/package.py b/var/spack/packages/metis/package.py
index fa13d52127..7ce5ae1925 100644
--- a/var/spack/packages/metis/package.py
+++ b/var/spack/packages/metis/package.py
@@ -5,28 +5,23 @@ class Metis(Package):
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
- developed in our lab."""
+ 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"
version('5.1.0', '5465e67079419a69e0116de24fce58fe')
- # FIXME: Add dependencies if this package requires them.
- # depends_on("foo")
-
- def patch(self):
- filter_file(r'#define IDXTYPEWIDTH 32', '#define IDXTYPEWIDTH 64', 'include/metis.h',
- string=True)
-
+ depends_on('mpi')
def install(self, spec, prefix):
- with working_dir('spack-build', create=True):
- cmake('..',
- '-DGKLIB_PATH=../GKlib',
- '-DBUILD_SHARED_LIBS=TRUE',
- *std_cmake_args)
- make()
- make("install")
-
+ cmake(".",
+ '-DGKLIB_PATH=%s/GKlib' % pwd(),
+ '-DSHARED=1',
+ '-DCMAKE_C_COMPILER=mpicc',
+ '-DCMAKE_CXX_COMPILER=mpicxx',
+ '-DSHARED=1',
+ *std_cmake_args)
+
+ make()
+ make("install")
diff --git a/var/spack/packages/netlib-blas/package.py b/var/spack/packages/netlib-blas/package.py
new file mode 100644
index 0000000000..0a6cdb0442
--- /dev/null
+++ b/var/spack/packages/netlib-blas/package.py
@@ -0,0 +1,40 @@
+from spack import *
+import os
+
+
+class NetlibBlas(Package):
+ """Netlib reference BLAS"""
+ homepage = "http://www.netlib.org/lapack/"
+ url = "http://www.netlib.org/lapack/lapack-3.5.0.tgz"
+
+ version('3.5.0', 'b1d3e3e425b2e44a06760ff173104bdf')
+
+ # virtual dependency
+ provides('blas')
+
+ # Doesn't always build correctly in parallel
+ parallel = False
+
+ def patch(self):
+ os.symlink('make.inc.example', 'make.inc')
+
+ mf = FileFilter('make.inc')
+ mf.filter('^FORTRAN.*', 'FORTRAN = f90')
+ mf.filter('^LOADER.*', 'LOADER = f90')
+ mf.filter('^CC =.*', 'CC = cc')
+
+
+ def install(self, spec, prefix):
+ make('blaslib')
+
+ # Tests that blas builds correctly
+ make('blas_testing')
+
+ # No install provided
+ mkdirp(prefix.lib)
+ install('librefblas.a', prefix.lib)
+
+ # Blas virtual package should provide blas.a and libblas.a
+ with working_dir(prefix.lib):
+ symlink('librefblas.a', 'blas.a')
+ symlink('librefblas.a', 'libblas.a')
diff --git a/var/spack/packages/parpack/package.py b/var/spack/packages/parpack/package.py
new file mode 100644
index 0000000000..622aceca04
--- /dev/null
+++ b/var/spack/packages/parpack/package.py
@@ -0,0 +1,43 @@
+from spack import *
+import os
+import shutil
+
+class Parpack(Package):
+ """ARPACK is a collection of Fortran77 subroutines designed to solve large
+ scale eigenvalue problems."""
+
+ homepage = "http://www.caam.rice.edu/software/ARPACK/download.html"
+ url = "http://www.caam.rice.edu/software/ARPACK/SRC/parpack96.tar.Z"
+
+ version('96', 'a175f70ff71837a33ff7e4b0b6054f43')
+
+ depends_on('mpi')
+ depends_on('blas')
+ depends_on('lapack')
+
+ def patch(self):
+ # Filter the CJ makefile to make a spack one.
+ shutil.move('ARMAKES/ARmake.CJ', 'ARmake.inc')
+ mf = FileFilter('ARmake.inc')
+
+ # Be sure to use Spack F77 wrapper
+ mf.filter('^FC.*', 'FC = f77')
+ mf.filter('^FFLAGS.*', 'FFLAGS = -O2 -g')
+
+ # Set up some variables.
+ mf.filter('^PLAT.*', 'PLAT = ')
+ mf.filter('^home.*', 'home = %s' % os.getcwd())
+ mf.filter('^BLASdir.*', 'BLASdir = %s' % self.spec['blas'].prefix)
+ mf.filter('^LAPACKdir.*', 'LAPACKdir = %s' % self.spec['lapack'].prefix)
+ mf.filter('^MAKE.*', 'MAKE = make')
+
+ # build the library in our own prefix.
+ mf.filter('^ARPACKLIB.*', 'PARPACKLIB = %s/libparpack.a' % os.getcwd())
+
+
+ def install(self, spec, prefix):
+ with working_dir('PARPACK/SRC/MPI'):
+ make('all')
+
+ mkdirp(prefix.lib)
+ install('libparpack.a', prefix.lib)
diff --git a/var/spack/packages/petsc/package.py b/var/spack/packages/petsc/package.py
new file mode 100644
index 0000000000..4864e39bf1
--- /dev/null
+++ b/var/spack/packages/petsc/package.py
@@ -0,0 +1,40 @@
+from spack import *
+
+class Petsc(Package):
+ """PETSc is a suite of data structures and routines for the
+ scalable (parallel) solution of scientific applications modeled by
+ partial differential equations."""
+
+ homepage = "http://www.mcs.anl.gov/petsc/index.html"
+ url = "http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.5.3.tar.gz"
+
+ version('3.5.3', 'd4fd2734661e89f18ac6014b5dd1ef2f')
+ version('3.5.2', 'ad170802b3b058b5deb9cd1f968e7e13')
+ version('3.5.1', 'a557e029711ebf425544e117ffa44d8f')
+
+ depends_on("boost")
+ depends_on("blas")
+ depends_on("lapack")
+ depends_on("hypre")
+ depends_on("parmetis")
+ depends_on("metis")
+ depends_on("hdf5")
+ depends_on("mpi")
+
+ def install(self, spec, prefix):
+ configure("--prefix=%s" % prefix,
+ "CC=cc",
+ "CXX=c++",
+ "FC=f90",
+ "--with-blas-lib=%s/libblas.a" % spec['blas'].prefix.lib,
+ "--with-lapack-lib=%s/liblapack.a" % spec['lapack'].prefix.lib,
+ "--with-boost-dir=%s" % spec['boost'].prefix,
+ "--with-hypre-dir=%s" % spec['hypre'].prefix,
+ "--with-parmetis-dir=%s" % spec['parmetis'].prefix,
+ "--with-metis-dir=%s" % spec['metis'].prefix,
+ "--with-hdf5-dir=%s" % spec['hdf5'].prefix,
+ "--with-shared-libraries=0")
+
+ # PETSc has its own way of doing parallel make.
+ make('MAKE_NP=%s' % make_jobs, parallel=False)
+ make("install")