summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2019-08-11 18:01:16 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2020-11-17 10:04:13 -0800
commit60cf3fdb34da13684778bb1d4787f68d8a79387c (patch)
treefdc17cc62566c4ec1f37e45615189af1d9fa0336 /lib
parentf7dce19754057168aef1414e30319c21d24b8294 (diff)
downloadspack-60cf3fdb34da13684778bb1d4787f68d8a79387c.tar.gz
spack-60cf3fdb34da13684778bb1d4787f68d8a79387c.tar.bz2
spack-60cf3fdb34da13684778bb1d4787f68d8a79387c.tar.xz
spack-60cf3fdb34da13684778bb1d4787f68d8a79387c.zip
concretizer: add basic semantics for compilers
- This handles setting the compiler and falling back to a default compiler, as well as providing default values for compilers/compiler versions. - Versions still aren't quite right -- you can't properly override versions on compiler specs.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/solver/asp.py74
-rw-r--r--lib/spack/spack/solver/concretize.lp43
-rw-r--r--lib/spack/spack/solver/display.lp2
3 files changed, 112 insertions, 7 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 6d80b20b74..0a1bdc3057 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -20,6 +20,7 @@ import spack
import spack.cmd
import spack.spec
import spack.package
+import spack.package_prefs
import spack.repo
from spack.util.executable import which
from spack.version import ver
@@ -187,6 +188,45 @@ class AspGenerator(object):
self._or(fn.version(spec.name, v) for v in possible),
fn.node(spec.name))
+ def compiler_defaults(self):
+ """Facts about available compilers."""
+ compilers = spack.compilers.all_compiler_specs()
+
+ compiler_versions = collections.defaultdict(lambda: set())
+ for compiler in compilers:
+ compiler_versions[compiler.name].add(compiler.version)
+
+ for compiler in compiler_versions:
+ self.fact(fn.compiler(compiler))
+ self.rule(
+ self._or(
+ fn.compiler_version(compiler, v)
+ for v in sorted(compiler_versions[compiler])),
+ fn.compiler(compiler))
+
+ def package_compiler_defaults(self, pkg):
+ """Add facts about the default compiler.
+
+ TODO: integrate full set of preferences into the solve (this only
+ TODO: considers the top preference)
+ """
+ # get list of all compilers
+ compiler_list = spack.compilers.all_compiler_specs()
+ if not compiler_list:
+ raise spack.compilers.NoCompilersError()
+
+ # prefer package preferences, then latest version
+ ppk = spack.package_prefs.PackagePrefs(pkg.name, 'compiler')
+ compiler_list = sorted(
+ compiler_list, key=lambda x: (x.name, x.version), reverse=True)
+ compiler_list = sorted(compiler_list, key=ppk)
+
+ # write out default rules for this package's compilers
+ default_compiler = compiler_list[0]
+ self.fact(fn.node_compiler_default(pkg.name, default_compiler.name))
+ self.fact(fn.node_compiler_default_version(
+ pkg.name, default_compiler.name, default_compiler.version))
+
def pkg_rules(self, pkg):
pkg = packagize(pkg)
@@ -215,6 +255,9 @@ class AspGenerator(object):
fn.node(pkg.name))
self.out.write('\n')
+ # default compilers for this package
+ self.package_compiler_defaults(pkg)
+
# dependencies
for name, conditions in pkg.dependencies.items():
for cond, dep in conditions.items():
@@ -239,14 +282,28 @@ class AspGenerator(object):
for vname, variant in spec.variants.items():
self.fact(fn.variant_set(spec.name, vname, variant.value))
+ # compiler and compiler version
+ if spec.compiler:
+ self.fact(fn.node_compiler_set(spec.name, spec.compiler.name))
+ if spec.compiler.concrete:
+ self.fact(fn.node_compiler_version_set(
+ spec.name, spec.compiler.name, spec.compiler.version))
+
# TODO
# dependencies
- # compiler
# external_path
# external_module
# compiler_flags
# namespace
+ def arch_defaults(self):
+ """Add facts about the default architecture for a package."""
+ self.h2('Default architecture')
+ default_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
+ self.fact(fn.arch_platform_default(default_arch.platform))
+ self.fact(fn.arch_os_default(default_arch.os))
+ self.fact(fn.arch_target_default(default_arch.target))
+
def generate_asp_program(self, specs):
"""Write an ASP program for specs.
@@ -265,12 +322,8 @@ class AspGenerator(object):
self.out.write(concretize_lp.decode("utf-8"))
self.h1('General Constraints')
-
- self.h2('Default architecture')
- default_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
- self.fact(fn.arch_platform_default(default_arch.platform))
- self.fact(fn.arch_os_default(default_arch.os))
- self.fact(fn.arch_target_default(default_arch.target))
+ self.compiler_defaults()
+ self.arch_defaults()
self.h1('Package Constraints')
for pkg in pkgs:
@@ -321,6 +374,13 @@ class ResultParser(object):
def version(self, pkg, version):
self._specs[pkg].versions = ver([version])
+ def node_compiler(self, pkg, compiler):
+ self._specs[pkg].compiler = spack.spec.CompilerSpec(compiler)
+
+ def node_compiler_version(self, pkg, compiler, version):
+ self._specs[pkg].compiler.versions = spack.version.VersionList(
+ [version])
+
def depends_on(self, pkg, dep):
self._specs[pkg]._add_dependency(
self._specs[dep], ('link', 'run'))
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index b416b35e2b..bb4b22897f 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -6,6 +6,9 @@
{ arch_platform(P, A) : arch_platform(P, A) } = 1 :- node(P).
{ arch_os(P, A) : arch_os(P, A) } = 1 :- node(P).
{ arch_target(P, T) : arch_target(P, T) } = 1 :- node(P).
+{ node_compiler(P, C) : node_compiler(P, C) } = 1 :- node(P).
+{ node_compiler_version(P, C, V) :
+ node_compiler_version(P, C, V) } = 1 :- node(P).
% one variant value for single-valued variants.
{ variant_value(P, V, X) : variant_value(P, V, X) } = 1
@@ -65,3 +68,43 @@ arch_target(P, A) :- node(P), not arch_target_set(P), arch_target_default(A).
arch_platform_set(D, A) :- node(D), depends_on(P, D), arch_platform_set(P, A).
arch_os_set(D, A) :- node(D), depends_on(P, D), arch_os_set(P, A).
arch_target_set(D, A) :- node(D), depends_on(P, D), arch_target_set(P, A).
+
+%-----------------------------------------------------------------------------
+% Compiler semantics
+%-----------------------------------------------------------------------------
+
+% compiler fields are set if set to anything
+node_compiler_set(P) :- node_compiler_set(P, _).
+node_compiler_version_set(P, C) :- node_compiler_version_set(P, C, _).
+
+% avoid warnings: these are set by generated code and it's ok if they're not
+#defined node_compiler_set/2.
+#defined node_compiler_version_set/3.
+
+% if compiler value of node is set to anything, it's the value.
+node_compiler(P, C)
+ :- node(P), compiler(C), node_compiler_set(P, C).
+node_compiler_version(P, C, V)
+ :- node(P), compiler(C), compiler_version(C, V), node_compiler(P, C),
+ node_compiler_version_set(P, C, V).
+
+% node compiler versions can only be from the available compiler versions
+node_compiler_version(P, C, V)
+ :- node(P), compiler(C), node_compiler(P, C),
+ compiler_version(C, V).
+
+% if no compiler is set, fall back to default.
+node_compiler(P, C)
+ :- node(P), compiler(C), not node_compiler_set(P),
+ node_compiler_default(P, C).
+node_compiler_version(P, C, V)
+ :- node(P), compiler(C), compiler_version(C, V),
+ not node_compiler_version_set(P, C, V),
+ node_compiler_default_version(P, C, V).
+
+% propagate compiler, compiler version to dependencies
+node_compiler_set(D, C)
+ :- node(D), compiler(C), depends_on(P, D), node_compiler_set(P, C).
+node_compiler_version_set(D, C, V)
+ :- node(D), compiler(C), depends_on(P, D), node_compiler(D, C),
+ node_compiler_version_set(P, C, V).
diff --git a/lib/spack/spack/solver/display.lp b/lib/spack/spack/solver/display.lp
index 61f12cd6fd..4c94720fc7 100644
--- a/lib/spack/spack/solver/display.lp
+++ b/lib/spack/spack/solver/display.lp
@@ -10,3 +10,5 @@
#show arch_platform/2.
#show arch_os/2.
#show arch_target/2.
+#show node_compiler/2.
+#show node_compiler_version/3.