compiler flags: fix multiple compilers with different flags (#35721)

Currently, if two compilers with the same spec differ on the flags, the concretizer will:

1. mix both sets of flags for the spec in the ASP program
2. error noting that the set of flags from the compiler (both of them) doesn't match the set from the lower priority compiler

This PR fixes both -- only flags from the highest priority compiler with a given spec are considered.
This commit is contained in:
Greg Becker 2023-03-06 10:29:48 -08:00 committed by GitHub
parent f3841774f7
commit 2ff337a2a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 2 deletions

View File

@ -84,7 +84,7 @@ def _to_dict(compiler):
d = {}
d["spec"] = str(compiler.spec)
d["paths"] = dict((attr, getattr(compiler, attr, None)) for attr in _path_instance_vars)
d["flags"] = dict((fname, fvals) for fname, fvals in compiler.flags)
d["flags"] = dict((fname, " ".join(fvals)) for fname, fvals in compiler.flags.items())
d["flags"].update(
dict(
(attr, getattr(compiler, attr, None))

View File

@ -1402,7 +1402,12 @@ def flag_defaults(self):
# flags from compilers.yaml
compilers = all_compilers_in_config()
seen = set()
for compiler in compilers:
# if there are multiple with the same spec, only use the first
if compiler.spec in seen:
continue
seen.add(compiler.spec)
for name, flags in compiler.flags.items():
for flag in flags:
self.gen.fact(
@ -2287,7 +2292,8 @@ def reorder_flags(self):
The solver determines wihch flags are on nodes; this routine
imposes order afterwards.
"""
compilers = dict((c.spec, c) for c in all_compilers_in_config())
# reverse compilers so we get highest priority compilers that share a spec
compilers = dict((c.spec, c) for c in reversed(all_compilers_in_config()))
cmd_specs = dict((s.name, s) for spec in self._command_line_specs for s in spec.traverse())
for spec in self._specs.values():

View File

@ -2,6 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import copy
import os
import sys
@ -330,6 +331,24 @@ def test_compiler_flags_from_compiler_and_dependent(self):
for spec in [client, cmake]:
assert spec.compiler_flags["cflags"] == ["-O3", "-g"]
def test_compiler_flags_differ_identical_compilers(self):
# Correct arch to use test compiler that has flags
spec = Spec("a %clang@12.2.0 platform=test os=fe target=fe")
# Get the compiler that matches the spec (
compiler = spack.compilers.compiler_for_spec("clang@12.2.0", spec.architecture)
# Clear cache for compiler config since it has its own cache mechanism outside of config
spack.compilers._cache_config_file = []
# Configure spack to have two identical compilers with different flags
default_dict = spack.compilers._to_dict(compiler)
different_dict = copy.deepcopy(default_dict)
different_dict["compiler"]["flags"] = {"cflags": "-O2"}
with spack.config.override("compilers", [different_dict]):
spec.concretize()
assert spec.satisfies("cflags=-O2")
def test_concretize_compiler_flag_propagate(self):
spec = Spec("hypre cflags=='-g' ^openblas")
spec.concretize()