From 3f1cdbf5efb6092d806a25f35c87b7b6b3b78364 Mon Sep 17 00:00:00 2001 From: scheibelp Date: Tue, 20 Dec 2016 00:21:25 -0800 Subject: Revert #2292: use frontend compiler for build deps (#2549) The primary goal of #2292 was to use the frontend compiler to make build dependencies like cmake on HPC platforms. It turns out that while this works in some cases, it did not handle cases where a package was a link dependency of the root and of a build dependency (and could produce incorrect concretizations which would not build). --- lib/spack/spack/architecture.py | 5 ---- lib/spack/spack/concretize.py | 56 ++++++++++++++------------------------ lib/spack/spack/spec.py | 23 ++-------------- lib/spack/spack/test/concretize.py | 30 -------------------- 4 files changed, 24 insertions(+), 90 deletions(-) diff --git a/lib/spack/spack/architecture.py b/lib/spack/spack/architecture.py index c86804deda..e44e0dc109 100644 --- a/lib/spack/spack/architecture.py +++ b/lib/spack/spack/architecture.py @@ -514,8 +514,3 @@ def sys_type(): """ arch = Arch(platform(), 'default_os', 'default_target') return str(arch) - - -@memoized -def frontend_sys_type(): - return str(Arch(platform(), 'frontend', 'frontend')) diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py index 7eb05c49c9..4690691174 100644 --- a/lib/spack/spack/concretize.py +++ b/lib/spack/spack/concretize.py @@ -251,12 +251,8 @@ class DefaultConcretizer(object): DAG has an architecture, then use the root otherwise use the defaults on the platform. """ - root_arch = spec.link_root().architecture - if spec.build_dep() and spec.disjoint_build_tree(): - sys_arch = spack.spec.ArchSpec( - spack.architecture.frontend_sys_type()) - else: - sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type()) + root_arch = spec.root.architecture + sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type()) spec_changed = False if spec.architecture is None: @@ -327,21 +323,14 @@ class DefaultConcretizer(object): spec.compiler in all_compilers): return False - if spec.compiler: - other_spec = spec - elif spec.build_dep() and spec.disjoint_build_tree(): - link_root = spec.link_root() - build_subtree = list(link_root.traverse(direction='children')) - candidates = list(x for x in build_subtree if x.compiler) - other_spec = candidates[0] if candidates else link_root - else: - # Find another spec that has a compiler, or the root if none do. - # Prefer compiler info from other specs which are not build deps. - other_spec = ( - find_spec(spec, lambda x: x.compiler and not x.build_dep()) or - spec.root) + # Find the another spec that has a compiler, or the root if none do + other_spec = spec if spec.compiler else find_spec( + spec, lambda x: x.compiler) + if not other_spec: + other_spec = spec.root other_compiler = other_spec.compiler + assert(other_spec) # Check if the compiler is already fully specified if other_compiler in all_compilers: @@ -389,20 +378,16 @@ class DefaultConcretizer(object): # running. return True - def compiler_match(spec1, spec2): - return ((spec1.compiler, spec1.architecture) == - (spec2.compiler, spec2.architecture)) - ret = False for flag in spack.spec.FlagMap.valid_compiler_flags(): try: nearest = next(p for p in spec.traverse(direction='parents') - if ((p is not spec) and - compiler_match(p, spec) and + if ((p.compiler == spec.compiler and + p is not spec) and flag in p.compiler_flags)) - if (flag not in spec.compiler_flags or - (set(nearest.compiler_flags[flag]) - - set(spec.compiler_flags[flag]))): + if flag not in spec.compiler_flags or \ + not (sorted(spec.compiler_flags[flag]) >= + sorted(nearest.compiler_flags[flag])): if flag in spec.compiler_flags: spec.compiler_flags[flag] = list( set(spec.compiler_flags[flag]) | @@ -413,11 +398,10 @@ class DefaultConcretizer(object): ret = True except StopIteration: - if (compiler_match(spec.root, spec) and - flag in spec.root.compiler_flags and - ((flag not in spec.compiler_flags) or - (set(spec.root.compiler_flags[flag]) - - set(spec.compiler_flags[flag])))): + if (flag in spec.root.compiler_flags and + ((flag not in spec.compiler_flags) or + sorted(spec.compiler_flags[flag]) != + sorted(spec.root.compiler_flags[flag]))): if flag in spec.compiler_flags: spec.compiler_flags[flag] = list( set(spec.compiler_flags[flag]) | @@ -441,8 +425,10 @@ class DefaultConcretizer(object): if compiler.flags[flag] != []: ret = True else: - if (set(compiler.flags[flag]) - - set(spec.compiler_flags[flag])): + if ((sorted(spec.compiler_flags[flag]) != + sorted(compiler.flags[flag])) and + (not set(spec.compiler_flags[flag]) >= + set(compiler.flags[flag]))): ret = True spec.compiler_flags[flag] = list( set(spec.compiler_flags[flag]) | diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index a8377e324f..23212ba72b 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -1102,7 +1102,7 @@ class Spec(object): successors = deps if direction == 'parents': - successors = self.dependents_dict(deptype) + successors = self.dependents_dict() # TODO: deptype? visited.add(key) for name in sorted(successors): @@ -1323,23 +1323,6 @@ class Spec(object): except Exception as e: raise sjson.SpackJSONError("error parsing JSON spec:", str(e)) - def build_dep(self): - # If this spec is the root, it will automatically be included in - # traverse - return not (self.root in - self.traverse( - deptype=('link', 'run'), direction='parents')) - - def link_root(self): - parents = list(self.traverse(deptype=('link',), direction='parents', - order='pre')) - return parents[-1] - - def disjoint_build_tree(self): - link_root = self.link_root() - build_subtree = list(link_root.traverse(direction='children')) - return all(x.build_dep() for x in build_subtree) - def _concretize_helper(self, presets=None, visited=None): """Recursive helper function for concretize(). This concretizes everything bottom-up. As things are @@ -1358,8 +1341,8 @@ class Spec(object): # Concretize deps first -- this is a bottom-up process. for name in sorted(self._dependencies.keys()): - dep = self._dependencies[name] - changed |= dep.spec._concretize_helper(presets, visited) + changed |= self._dependencies[ + name].spec._concretize_helper(presets, visited) if self.name in presets: changed |= self.constrain(presets[self.name]) diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index e0966948fe..42ae9aa18e 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -97,36 +97,6 @@ class ConcretizeTest(MockPackagesTest): self.check_concretize('mpich debug=2') self.check_concretize('mpich') - def test_concretize_with_build_dep(self): - # Set the target as the backend. Since the cmake build dependency is - # not explicitly configured to target the backend it should target - # the frontend (whatever compiler that is, it is different) - spec = self.check_concretize('cmake-client platform=test target=be') - client_compiler = spack.compilers.compiler_for_spec( - spec.compiler, spec.architecture) - cmake_spec = spec['cmake'] - cmake_compiler = spack.compilers.compiler_for_spec( - cmake_spec.compiler, cmake_spec.architecture) - self.assertTrue(client_compiler.operating_system != - cmake_compiler.operating_system) - - def test_concretize_link_dep_of_build_dep(self): - # The link dep of the build dep should use the same compiler as - # the build dep, and both should be different from the root - spec = self.check_concretize('dttop platform=test target=be') - dttop_compiler = spack.compilers.compiler_for_spec( - spec.compiler, spec.architecture) - dtlink2_spec = spec['dtlink2'] - dtlink2_compiler = spack.compilers.compiler_for_spec( - dtlink2_spec.compiler, dtlink2_spec.architecture) - dtbuild1_spec = spec['dtbuild1'] - dtbuild1_compiler = spack.compilers.compiler_for_spec( - dtbuild1_spec.compiler, dtbuild1_spec.architecture) - self.assertTrue(dttop_compiler.operating_system != - dtlink2_compiler.operating_system) - self.assertTrue(dtbuild1_compiler.operating_system == - dtlink2_compiler.operating_system) - def test_conretize_compiler_flags(self): self.check_concretize('mpich cppflags="-O3"') -- cgit v1.2.3-60-g2f50