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).
This commit is contained in:
scheibelp 2016-12-20 00:21:25 -08:00 committed by Todd Gamblin
parent 3ce3165ae6
commit 3f1cdbf5ef
4 changed files with 24 additions and 90 deletions

View File

@ -514,8 +514,3 @@ def sys_type():
""" """
arch = Arch(platform(), 'default_os', 'default_target') arch = Arch(platform(), 'default_os', 'default_target')
return str(arch) return str(arch)
@memoized
def frontend_sys_type():
return str(Arch(platform(), 'frontend', 'frontend'))

View File

@ -251,12 +251,8 @@ def concretize_architecture(self, spec):
DAG has an architecture, then use the root otherwise use the defaults DAG has an architecture, then use the root otherwise use the defaults
on the platform. on the platform.
""" """
root_arch = spec.link_root().architecture root_arch = spec.root.architecture
if spec.build_dep() and spec.disjoint_build_tree(): sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
sys_arch = spack.spec.ArchSpec(
spack.architecture.frontend_sys_type())
else:
sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
spec_changed = False spec_changed = False
if spec.architecture is None: if spec.architecture is None:
@ -327,21 +323,14 @@ def _proper_compiler_style(cspec, aspec):
spec.compiler in all_compilers): spec.compiler in all_compilers):
return False return False
if spec.compiler: # Find the another spec that has a compiler, or the root if none do
other_spec = spec other_spec = spec if spec.compiler else find_spec(
elif spec.build_dep() and spec.disjoint_build_tree(): spec, lambda x: x.compiler)
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)
if not other_spec:
other_spec = spec.root
other_compiler = other_spec.compiler other_compiler = other_spec.compiler
assert(other_spec)
# Check if the compiler is already fully specified # Check if the compiler is already fully specified
if other_compiler in all_compilers: if other_compiler in all_compilers:
@ -389,20 +378,16 @@ def concretize_compiler_flags(self, spec):
# running. # running.
return True return True
def compiler_match(spec1, spec2):
return ((spec1.compiler, spec1.architecture) ==
(spec2.compiler, spec2.architecture))
ret = False ret = False
for flag in spack.spec.FlagMap.valid_compiler_flags(): for flag in spack.spec.FlagMap.valid_compiler_flags():
try: try:
nearest = next(p for p in spec.traverse(direction='parents') nearest = next(p for p in spec.traverse(direction='parents')
if ((p is not spec) and if ((p.compiler == spec.compiler and
compiler_match(p, spec) and p is not spec) and
flag in p.compiler_flags)) flag in p.compiler_flags))
if (flag not in spec.compiler_flags or if flag not in spec.compiler_flags or \
(set(nearest.compiler_flags[flag]) - not (sorted(spec.compiler_flags[flag]) >=
set(spec.compiler_flags[flag]))): sorted(nearest.compiler_flags[flag])):
if flag in spec.compiler_flags: if flag in spec.compiler_flags:
spec.compiler_flags[flag] = list( spec.compiler_flags[flag] = list(
set(spec.compiler_flags[flag]) | set(spec.compiler_flags[flag]) |
@ -413,11 +398,10 @@ def compiler_match(spec1, spec2):
ret = True ret = True
except StopIteration: except StopIteration:
if (compiler_match(spec.root, spec) and if (flag in spec.root.compiler_flags and
flag in spec.root.compiler_flags and ((flag not in spec.compiler_flags) or
((flag not in spec.compiler_flags) or sorted(spec.compiler_flags[flag]) !=
(set(spec.root.compiler_flags[flag]) - sorted(spec.root.compiler_flags[flag]))):
set(spec.compiler_flags[flag])))):
if flag in spec.compiler_flags: if flag in spec.compiler_flags:
spec.compiler_flags[flag] = list( spec.compiler_flags[flag] = list(
set(spec.compiler_flags[flag]) | set(spec.compiler_flags[flag]) |
@ -441,8 +425,10 @@ def compiler_match(spec1, spec2):
if compiler.flags[flag] != []: if compiler.flags[flag] != []:
ret = True ret = True
else: else:
if (set(compiler.flags[flag]) - if ((sorted(spec.compiler_flags[flag]) !=
set(spec.compiler_flags[flag])): sorted(compiler.flags[flag])) and
(not set(spec.compiler_flags[flag]) >=
set(compiler.flags[flag]))):
ret = True ret = True
spec.compiler_flags[flag] = list( spec.compiler_flags[flag] = list(
set(spec.compiler_flags[flag]) | set(spec.compiler_flags[flag]) |

View File

@ -1102,7 +1102,7 @@ def return_val(res):
successors = deps successors = deps
if direction == 'parents': if direction == 'parents':
successors = self.dependents_dict(deptype) successors = self.dependents_dict() # TODO: deptype?
visited.add(key) visited.add(key)
for name in sorted(successors): for name in sorted(successors):
@ -1323,23 +1323,6 @@ def from_json(stream):
except Exception as e: except Exception as e:
raise sjson.SpackJSONError("error parsing JSON spec:", str(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): def _concretize_helper(self, presets=None, visited=None):
"""Recursive helper function for concretize(). """Recursive helper function for concretize().
This concretizes everything bottom-up. As things are This concretizes everything bottom-up. As things are
@ -1358,8 +1341,8 @@ def _concretize_helper(self, presets=None, visited=None):
# Concretize deps first -- this is a bottom-up process. # Concretize deps first -- this is a bottom-up process.
for name in sorted(self._dependencies.keys()): for name in sorted(self._dependencies.keys()):
dep = self._dependencies[name] changed |= self._dependencies[
changed |= dep.spec._concretize_helper(presets, visited) name].spec._concretize_helper(presets, visited)
if self.name in presets: if self.name in presets:
changed |= self.constrain(presets[self.name]) changed |= self.constrain(presets[self.name])

View File

@ -97,36 +97,6 @@ def test_concretize_variant(self):
self.check_concretize('mpich debug=2') self.check_concretize('mpich debug=2')
self.check_concretize('mpich') 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): def test_conretize_compiler_flags(self):
self.check_concretize('mpich cppflags="-O3"') self.check_concretize('mpich cppflags="-O3"')