concretizer: split platforms, OS, and targets apart in Python and ASP

This commit is contained in:
Todd Gamblin 2020-04-19 00:22:30 -07:00
parent cb919c2e39
commit 43e7255e19
2 changed files with 70 additions and 26 deletions

View File

@ -14,6 +14,7 @@
import types import types
from six import string_types from six import string_types
import llnl.util.cpu
import llnl.util.tty as tty import llnl.util.tty as tty
import llnl.util.tty.color as color import llnl.util.tty.color as color
@ -46,9 +47,10 @@ def listify(args):
def packagize(pkg): def packagize(pkg):
if isinstance(pkg, spack.package.PackageMeta): if isinstance(pkg, string_types):
return spack.repo.path.get_pkg_class(pkg)
else:
return pkg return pkg
return spack.repo.path.get_pkg_class(pkg)
def specify(spec): def specify(spec):
@ -138,9 +140,12 @@ def __getattr__(self, name):
fn = AspFunctionBuilder() fn = AspFunctionBuilder()
def default_arch():
return spack.spec.ArchSpec(spack.architecture.sys_type())
def compilers_for_default_arch(): def compilers_for_default_arch():
default_arch = spack.spec.ArchSpec(spack.architecture.sys_type()) return spack.compilers.compilers_for_arch(default_arch())
return spack.compilers.compilers_for_arch(default_arch)
def extend_flag_list(flag_list, new_flags): def extend_flag_list(flag_list, new_flags):
@ -606,13 +611,21 @@ def _supported_targets(self, compiler, targets):
return sorted(supported, reverse=True) return sorted(supported, reverse=True)
def arch_defaults(self): def platform_defaults(self):
"""Add facts about the default architecture for a package.""" self.h2('Default platform')
self.h2('Default architecture') default = default_arch()
default = spack.spec.ArchSpec(spack.architecture.sys_type())
self.fact(fn.node_platform_default(default.platform)) self.fact(fn.node_platform_default(default.platform))
def os_defaults(self, specs):
self.h2('Default operating system')
default = default_arch()
self.fact(fn.node_os_default(default.os)) self.fact(fn.node_os_default(default.os))
self.fact(fn.node_target_default(default.target))
def target_defaults(self, specs):
"""Add facts about targets and target compatibility."""
self.h2('Default target')
default = default_arch()
self.fact(fn.node_target_default(default_arch().target))
uarch = default.target.microarchitecture uarch = default.target.microarchitecture
@ -642,6 +655,17 @@ def arch_defaults(self):
self.fact(fn.compiler_supports_target( self.fact(fn.compiler_supports_target(
compiler.name, compiler.version, uarch.family.name)) compiler.name, compiler.version, uarch.family.name))
# add any targets explicitly mentioned in specs
for spec in specs:
if not spec.architecture or not spec.architecture.target:
continue
target = llnl.util.cpu.targets.get(spec.target.name)
if not target:
raise ValueError("Invalid target: ", spec.target.name)
if target not in compatible_targets:
compatible_targets.append(target)
i = 0 i = 0
for target in compatible_targets: for target in compatible_targets:
self.fact(fn.target(target.name)) self.fact(fn.target(target.name))
@ -726,7 +750,12 @@ def generate_asp_program(self, specs):
self.h1('General Constraints') self.h1('General Constraints')
self.available_compilers() self.available_compilers()
self.compiler_defaults() self.compiler_defaults()
self.arch_defaults()
# architecture defaults
self.platform_defaults()
self.os_defaults(specs)
self.target_defaults(specs)
self.virtual_providers() self.virtual_providers()
self.provider_defaults() self.provider_defaults()
self.flag_defaults() self.flag_defaults()
@ -824,7 +853,7 @@ def depends_on(self, pkg, dep, type):
dependency.add_type(type) dependency.add_type(type)
def reorder_flags(self): def reorder_flags(self):
"""Order compiler flags on specsaccord in predefined order. """Order compiler flags on specs in predefined order.
We order flags so that any node's flags will take priority over We order flags so that any node's flags will take priority over
those of its dependents. That is, the deepest node in the DAG's those of its dependents. That is, the deepest node in the DAG's

View File

@ -144,33 +144,48 @@ variant_not_default(Package, Variant, Value, 0)
#defined variant_possible_value/3. #defined variant_possible_value/3.
%----------------------------------------------------------------------------- %-----------------------------------------------------------------------------
% Platform/OS semantics % Platform semantics
%----------------------------------------------------------------------------- %-----------------------------------------------------------------------------
% one platform, os per node % one platform per node
% TODO: convert these to use optimization, like targets.
1 { node_platform(Package, Platform) : node_platform(Packagee, Platform) } 1 1 { node_platform(Package, Platform) : node_platform(Packagee, Platform) } 1
:- node(Package). :- node(Package).
1 { node_os(Package, OS) : node_os(Package, OS) } 1 :- node(Package).
% arch fields for pkg P are set if set to anything % if no platform is set, fall back to the default
node_platform_set(Package) :- node_platform_set(Package, _).
node_os_set(Package) :- node_os_set(Package, _).
% if no platform/os is set, fall back to the defaults
node_platform(Package, Platform) node_platform(Package, Platform)
:- node(Package), :- node(Package),
not node_platform_set(Package), not node_platform_set(Package),
node_platform_default(Platform). node_platform_default(Platform).
% setting platform on a node is a hard constraint
node_platform(Package, Platform)
:- node(Package), node_platform_set(Package, Platform).
% platform is set if set to anything
node_platform_set(Package) :- node_platform_set(Package, _).
#defined node_platform_set/2. % avoid warnings
%-----------------------------------------------------------------------------
% OS semantics
%-----------------------------------------------------------------------------
% one os per node
1 { node_os(Package, OS) : node_os(Package, OS) } 1 :- node(Package).
% node_os_set implies that the node has that os
node_os(Package, OS) :- node(Package), node_os_set(Package, OS).
node_os_set(Package) :- node_os_set(Package, _).
% fall back to default if not set
node_os(Package, OS) node_os(Package, OS)
:- node(Package), not node_os_set(Package), node_os_default(OS). :- node(Package), not node_os_set(Package), node_os_default(OS).
% setting os/platform on a node is a hard constraint % same OS throughout DAG (can currently only set one OS)
node_platform(Package, Platform) % TODO make this smarter; build env may have a different os from run env
:- node(Package), node_platform_set(Package, Platform). node_os_set(Package, OS)
node_os(Package, OS) :- node(Package), node_os_set(Package, OS). :- depends_on(Package, Dependency), node_os_set(Dependency, OS).
node_os_set(Dependency, OS)
:- depends_on(Package, Dependency), node_os_set(Package, OS).
% avoid info warnings (see variants)
#defined node_platform_set/2.
#defined node_os_set/2. #defined node_os_set/2.
%----------------------------------------------------------------------------- %-----------------------------------------------------------------------------