concretizer: refine compiler logic

Concrete versions for compilers are respected
verbatim.

Permit to use a non-existing compiler if the
appropriate configuration option has been
set.
This commit is contained in:
Massimiliano Culpo 2020-10-01 16:28:43 +02:00 committed by Todd Gamblin
parent c065245f14
commit 81c7cf45e1
4 changed files with 42 additions and 17 deletions

View file

@ -597,6 +597,7 @@ def generate_gitlab_ci_yaml(env, print_summary, output_file,
max_length_needs = 0
max_needs_job = ''
before_script, after_script = None, None
for phase in phases:
phase_name = phase['name']
strip_compilers = phase['strip-compilers']

View file

@ -165,12 +165,8 @@ def __getattr__(self, name):
fn = AspFunctionBuilder()
def default_arch():
return spack.spec.ArchSpec(spack.architecture.sys_type())
def compilers_for_default_arch():
return spack.compilers.compilers_for_arch(default_arch())
def all_compilers_in_config():
return spack.compilers.all_compilers()
def extend_flag_list(flag_list, new_flags):
@ -781,6 +777,15 @@ def compiler_defaults(self):
f = fn.default_compiler_preference(cspec.name, cspec.version, i)
self.gen.fact(f)
def compiler_supports_os(self):
compilers_yaml = spack.compilers.all_compilers_config()
for entry in compilers_yaml:
c = spack.spec.CompilerSpec(entry['compiler']['spec'])
operating_system = entry['compiler']['operating_system']
self.gen.fact(fn.compiler_supports_os(
c.name, c.version, operating_system
))
def package_compiler_defaults(self, pkg):
"""Facts about packages' compiler prefs."""
@ -997,7 +1002,7 @@ def flag_defaults(self):
self.gen.newline()
# flags from compilers.yaml
compilers = compilers_for_default_arch()
compilers = all_compilers_in_config()
for compiler in compilers:
for name, flags in compiler.flags.items():
for flag in flags:
@ -1116,6 +1121,8 @@ def _supported_targets(self, compiler, targets):
supported.append(target)
except llnl.util.cpu.UnsupportedMicroarchitecture:
continue
except ValueError:
continue
return sorted(supported, reverse=True)
@ -1225,24 +1232,26 @@ def virtual_providers(self):
self.gen.newline()
def generate_possible_compilers(self, specs):
compilers = compilers_for_default_arch()
compilers = all_compilers_in_config()
cspecs = set([c.spec for c in compilers])
# add compiler specs from the input line to possibilities if we
# don't require compilers to exist.
strict = spack.concretize.Concretizer.check_for_compiler_existence
strict = spack.concretize.Concretizer().check_for_compiler_existence
for spec in specs:
for s in spec.traverse():
if (not s.compiler
or s.compiler in cspecs
or not s.compiler.concrete):
if not s.compiler or not s.compiler.concrete:
continue
if strict:
if strict and s.compiler not in cspecs:
raise spack.concretize.UnavailableCompilerVersionError(
s.compiler)
s.compiler
)
else:
cspecs.add(s.compiler)
self.gen.fact(fn.allow_compiler(
s.compiler.name, s.compiler.version
))
return cspecs
@ -1345,6 +1354,7 @@ def setup(self, driver, specs):
self.gen.h1('General Constraints')
self.available_compilers()
self.compiler_defaults()
self.compiler_supports_os()
# architecture defaults
self.platform_defaults()
@ -1486,7 +1496,7 @@ def reorder_flags(self):
imposes order afterwards.
"""
# nodes with no flags get flag order from compiler
compilers = dict((c.spec, c) for c in compilers_for_default_arch())
compilers = dict((c.spec, c) for c in all_compilers_in_config())
for pkg in self._flag_compiler_defaults:
spec = self._specs[pkg]
compiler_flags = compilers[spec.compiler].flags

View file

@ -260,6 +260,17 @@ node_target_match(Package, 1)
1 { compiler_weight(Package, Weight) : compiler_weight(Package, Weight) } 1
:- node(Package).
% If the compiler version was set from the command line,
% respect it verbatim
node_compiler_version(Package, Compiler, Version) :- node_compiler_version_hard(Package, Compiler, Version).
% Cannot select a compiler if it is not supported on the OS
% Compilers that are explicitly marked as allowed
% are excluded from this check
:- node_compiler_version(Package, Compiler, Version), node_os(Package, OS),
not compiler_supports_os(Compiler, Version, OS),
not allow_compiler(Compiler, Version).
% dependencies imply we should try to match hard compiler constraints
% todo: look at what to do about intersecting constraints here. we'd
% ideally go with the "lowest" pref in the DAG
@ -285,6 +296,9 @@ compiler_version_match(Package, 1)
node_compiler_version_match_pref(Package, Compiler, V).
#defined node_compiler_hard/2.
#defined node_compiler_version_hard/3.
#defined compiler_supports_os/3.
#defined allow_compiler/2.
% compilers weighted by preference acccording to packages.yaml
compiler_weight(Package, Weight)

View file

@ -315,7 +315,7 @@ def test_no_matching_compiler_specs(self, mock_low_high_config):
def test_no_compilers_for_arch(self):
s = Spec('a arch=linux-rhel0-x86_64')
with pytest.raises(spack.concretize.NoCompilersForArchError):
with pytest.raises(spack.error.SpackError):
s.concretize()
def test_virtual_is_fully_expanded_for_callpath(self):
@ -634,7 +634,7 @@ def test_adjusting_default_target_based_on_compiler(
else current_host
with spack.concretize.disable_compiler_existence_check():
s = Spec(spec).concretized()
assert str(s.architecture.target) == str(expected), str(best_achievable)
assert str(s.architecture.target) == str(expected)
@pytest.mark.regression('8735,14730')
def test_compiler_version_matches_any_entry_in_compilers_yaml(self):