From 81c7cf45e12e91a1e0e976ec6f3ac5f71a6a0110 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Thu, 1 Oct 2020 16:28:43 +0200 Subject: 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. --- lib/spack/spack/ci.py | 1 + lib/spack/spack/solver/asp.py | 40 ++++++++++++++++++++++-------------- lib/spack/spack/solver/concretize.lp | 14 +++++++++++++ lib/spack/spack/test/concretize.py | 4 ++-- 4 files changed, 42 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py index a3a2248238..f38ab95d96 100644 --- a/lib/spack/spack/ci.py +++ b/lib/spack/spack/ci.py @@ -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'] diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 4659a11b65..261b469709 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -165,12 +165,8 @@ class AspFunctionBuilder(object): 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 @@ class SpackSolverSetup(object): 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 @@ class SpackSolverSetup(object): 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 @@ class SpackSolverSetup(object): supported.append(target) except llnl.util.cpu.UnsupportedMicroarchitecture: continue + except ValueError: + continue return sorted(supported, reverse=True) @@ -1225,24 +1232,26 @@ class SpackSolverSetup(object): 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 @@ class SpackSolverSetup(object): self.gen.h1('General Constraints') self.available_compilers() self.compiler_defaults() + self.compiler_supports_os() # architecture defaults self.platform_defaults() @@ -1486,7 +1496,7 @@ class SpecBuilder(object): 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 diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index 64f8c6ff6c..0da95b1907 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -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) diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 80938ca50a..dccc9a8056 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -315,7 +315,7 @@ class TestConcretize(object): 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 @@ class TestConcretize(object): 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): -- cgit v1.2.3-60-g2f50