summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorbecker33 <becker33@llnl.gov>2018-03-21 18:14:01 -0700
committerscheibelp <scheibel1@llnl.gov>2018-03-21 18:14:01 -0700
commitf8657e3fd9f1dba6f8360f50e89fe81a2978207b (patch)
tree9420e5f1832bbf09d591382a3993bc511d38bb0a /lib
parent726c7e0f06b11dd3c0ce435b91569e7764f4e7f1 (diff)
downloadspack-f8657e3fd9f1dba6f8360f50e89fe81a2978207b.tar.gz
spack-f8657e3fd9f1dba6f8360f50e89fe81a2978207b.tar.bz2
spack-f8657e3fd9f1dba6f8360f50e89fe81a2978207b.tar.xz
spack-f8657e3fd9f1dba6f8360f50e89fe81a2978207b.zip
Propagate architecture information during concretization (#7412)
This updates architecture concretization to * Search for the nearest parent in the DAG for architecture information rather than defaulting to the root of the DAG * Propagate architecture settings transitively, such that if for example the target is set at the root of the dag it will set the same target on indirect dependencies (assuming no intermediate dependency specifies a separate target). Previously this occurred in general but under some conditions did not, for example if an intermediate dependency specified some subset of architecture properties.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/concretize.py34
-rw-r--r--lib/spack/spack/test/concretize.py40
2 files changed, 57 insertions, 17 deletions
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 4d1ddf7ac9..c722a5506c 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -222,27 +222,29 @@ class DefaultConcretizer(object):
DAG has an architecture, then use the root otherwise use the defaults
on the platform.
"""
- root_arch = spec.root.architecture
- sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
+ try:
+ # Get the nearest architecture with any fields set
+ nearest = next(p for p in spec.traverse(direction='parents')
+ if (p.architecture and p is not spec))
+ nearest_arch = nearest.architecture
+ except StopIteration:
+ # Default to the system architecture if nothing set
+ nearest_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
+
spec_changed = False
+ # ensure type safety for the architecture
if spec.architecture is None:
- spec.architecture = spack.spec.ArchSpec(sys_arch)
+ spec.architecture = spack.spec.ArchSpec()
spec_changed = True
- default_archs = list(x for x in [root_arch, sys_arch] if x)
- for arch in default_archs:
- if spec.architecture.concrete:
- break
-
- replacement_fields = [k for k, v in iteritems(arch.to_cmp_dict())
- if v and not getattr(spec.architecture, k)]
- for field in replacement_fields:
- setattr(spec.architecture, field, getattr(arch, field))
- spec_changed = True
-
- if not spec.architecture.concrete:
- raise InsufficientArchitectureInfoError(spec, default_archs)
+ # replace each of the fields (platform, os, target) separately
+ nearest_dict = nearest_arch.to_cmp_dict()
+ replacement_fields = [k for k, v in iteritems(nearest_dict)
+ if v and not getattr(spec.architecture, k)]
+ for field in replacement_fields:
+ setattr(spec.architecture, field, getattr(nearest_arch, field))
+ spec_changed = True
return spec_changed
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 7885ca279f..87a4e03b4d 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1,4 +1,4 @@
-##############################################################################
+#############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
@@ -31,6 +31,7 @@ from spack.concretize import find_spec
from spack.spec import Spec, CompilerSpec
from spack.spec import ConflictsInSpecError, SpecError
from spack.version import ver
+from spack.test.conftest import MockPackage, MockPackageMultiRepo
def check_spec(abstract, concrete):
@@ -204,6 +205,42 @@ class TestConcretize(object):
assert set(client.compiler_flags['fflags']) == set(['-O0'])
assert not set(cmake.compiler_flags['fflags'])
+ def test_architecture_inheritance(self):
+ """test_architecture_inheritance is likely to fail with an
+ UnavailableCompilerVersionError if the architecture is concretized
+ incorrectly.
+ """
+ spec = Spec('cmake-client %gcc@4.7.2 os=fe ^ cmake')
+ spec.concretize()
+ assert spec['cmake'].architecture == spec.architecture
+
+ def test_architecture_deep_inheritance(self):
+ """Make sure that indirect dependencies receive architecture
+ information from the root even when partial architecture information
+ is provided by an intermediate dependency.
+ """
+ saved_repo = spack.repo
+
+ default_dep = ('link', 'build')
+
+ bazpkg = MockPackage('bazpkg', [], [])
+ barpkg = MockPackage('barpkg', [bazpkg], [default_dep])
+ foopkg = MockPackage('foopkg', [barpkg], [default_dep])
+ mock_repo = MockPackageMultiRepo([foopkg, barpkg, bazpkg])
+
+ spack.repo = mock_repo
+
+ try:
+ spec = Spec('foopkg %clang@3.3 os=CNL target=footar' +
+ ' ^barpkg os=SuSE11 ^bazpkg os=be')
+ spec.concretize()
+
+ for s in spec.traverse(root=False):
+ assert s.architecture.target == spec.architecture.target
+
+ finally:
+ spack.repo = saved_repo
+
def test_compiler_flags_from_user_are_grouped(self):
spec = Spec('a%gcc cflags="-O -foo-flag foo-val" platform=test')
spec.concretize()
@@ -216,6 +253,7 @@ class TestConcretize(object):
assert s['mpi'].version == ver('1.10.3')
def test_concretize_two_virtuals(self):
+
"""Test a package with multiple virtual dependencies."""
Spec('hypre').concretize()