Hotfix/namespace (#33870)

Concretize namespaces

Add new concretizer option `enable_node_namespace` that enables namespace-specific concretization
This commit is contained in:
Greg Becker 2022-11-13 03:08:39 -08:00 committed by GitHub
parent cd94827c5f
commit a86911246a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 5 deletions

View File

@ -15,6 +15,7 @@
"additionalProperties": False,
"properties": {
"reuse": {"type": "boolean"},
"enable_node_namespace": {"type": "boolean"},
"targets": {
"type": "object",
"properties": {

View File

@ -595,13 +595,14 @@ def fact(self, head):
if choice:
self.assumptions.append(atom)
def solve(self, setup, specs, reuse=None, output=None, control=None):
def solve(self, setup, specs, reuse=None, namespace=False, output=None, control=None):
"""Set up the input and solve for dependencies of ``specs``.
Arguments:
setup (SpackSolverSetup): An object to set up the ASP problem.
specs (list): List of ``Spec`` objects to solve for.
reuse (None or list): list of concrete specs that can be reused
namespace (bool): enable node namespacing
output (None or OutputConfiguration): configuration object to set
the output of this solve.
control (clingo.Control): configuration for the solver. If None,
@ -624,7 +625,7 @@ def solve(self, setup, specs, reuse=None, output=None, control=None):
self.assumptions = []
with self.control.backend() as backend:
self.backend = backend
setup.setup(self, specs, reuse=reuse)
setup.setup(self, specs, reuse=reuse, namespace=namespace)
timer.phase("setup")
# read in the main ASP program and display logic -- these are
@ -760,6 +761,10 @@ def __init__(self, tests=False):
# whether to add installed/binary hashes to the solve
self.tests = tests
# whether to namespace nodes in the solve
# set by setup()
self.namespace = None
# If False allows for input specs that are not solved
self.concretize_everything = True
@ -1348,6 +1353,7 @@ def _spec_clauses(
# TODO: do this with consistent suffixes.
class Head(object):
node = fn.node
node_namespace = fn.node_namespace
virtual_node = fn.virtual_node
node_platform = fn.node_platform_set
node_os = fn.node_os_set
@ -1361,6 +1367,7 @@ class Head(object):
class Body(object):
node = fn.node
node_namespace = fn.node_namespace
virtual_node = fn.virtual_node
node_platform = fn.node_platform
node_os = fn.node_os
@ -1377,6 +1384,9 @@ class Body(object):
if spec.name:
clauses.append(f.node(spec.name) if not spec.virtual else f.virtual_node(spec.name))
if self.namespace and spec.namespace:
clauses.append(f.node_namespace(spec.name, spec.namespace))
clauses.extend(self.spec_versions(spec))
# seed architecture at the root (we'll propagate later)
@ -1917,7 +1927,7 @@ def define_concrete_input_specs(self, specs, possible):
if spec.concrete:
self._facts_from_concrete_spec(spec, possible)
def setup(self, driver, specs, reuse=None):
def setup(self, driver, specs, reuse=None, namespace=False):
"""Generate an ASP program with relevant constraints for specs.
This calls methods on the solve driver to set up the problem with
@ -1928,6 +1938,7 @@ def setup(self, driver, specs, reuse=None):
driver (PyclingoDriver): driver instance of this solve
specs (list): list of Specs to solve
reuse (None or list): list of concrete specs that can be reused
namespace (bool): enable namespace matching in the solve
"""
self._condition_id_counter = itertools.count()
@ -1980,6 +1991,10 @@ def setup(self, driver, specs, reuse=None):
self.gen.h1("Concrete input spec definitions")
self.define_concrete_input_specs(specs, possible)
self.namespace = namespace
if namespace:
self.gen.fact(fn.enable_node_namespace())
if reuse:
self.gen.h1("Reusable specs")
self.gen.fact(fn.optimize_for_reuse())
@ -2073,6 +2088,9 @@ def node(self, pkg):
if pkg not in self._specs:
self._specs[pkg] = spack.spec.Spec(pkg)
def node_namespace(self, pkg, namespace):
self._specs[pkg].namespace = namespace
def _arch(self, pkg):
arch = self._specs[pkg].architecture
if not arch:
@ -2368,6 +2386,7 @@ def __init__(self):
# These properties are settable via spack configuration, and overridable
# by setting them directly as properties.
self.reuse = spack.config.get("concretizer:reuse", False)
self.namespace = spack.config.get("concretizer:enable_node_namespace", False)
@staticmethod
def _check_input_and_extract_concrete_specs(specs):
@ -2430,7 +2449,9 @@ def solve(
reusable_specs.extend(self._reusable_specs())
setup = SpackSolverSetup(tests=tests)
output = OutputConfiguration(timers=timers, stats=stats, out=out, setup_only=setup_only)
result, _, _ = self.driver.solve(setup, specs, reuse=reusable_specs, output=output)
result, _, _ = self.driver.solve(
setup, specs, reuse=reusable_specs, namespace=self.namespace, output=output
)
return result
def solve_in_rounds(
@ -2467,7 +2488,7 @@ def solve_in_rounds(
output = OutputConfiguration(timers=timers, stats=stats, out=out, setup_only=False)
while True:
result, _, _ = self.driver.solve(
setup, input_specs, reuse=reusable_specs, output=output
setup, input_specs, reuse=reusable_specs, namespace=self.namespace, output=output
)
yield result

View File

@ -210,6 +210,14 @@ attr(Name, A1, A2, A3, A4) :- impose(ID), imposed_constraint(ID, Name, A1, A2, A
not imposed_constraint(Hash, "node_flag", Package, FlagType, Flag),
internal_error("imposed hash without imposing all flag values").
% cannot have multiple namespaces for a package
:- node(Package),
node_namespace(Package, Namespace1),
node_namespace(Package, Namespace2),
Namespace1 < Namespace2,
enable_node_namespace().
#defined enable_node_namespace/0.
#defined condition/2.
#defined condition_requirement/3.
#defined condition_requirement/4.
@ -405,6 +413,7 @@ possible_provider_weight(Dependency, Virtual, 100, "fallback") :- provider(Depen
% These allow us to easily define conditional dependency and conflict rules
% without enumerating all spec attributes every time.
node(Package) :- attr("node", Package).
node_namespace(Package, Namespace) :- attr("node_namespace", Package, Namespace).
virtual_node(Virtual) :- attr("virtual_node", Virtual).
hash(Package, Hash) :- attr("hash", Package, Hash).
version(Package, Version) :- attr("version", Package, Version).
@ -427,6 +436,7 @@ node_flag_propagate(Package, FlagType)
:- attr("node_flag_propagate", Package, FlagType).
attr("node", Package) :- node(Package).
attr("node_namespace", Package, Namespace) :- node_namespace(Package, Namespace).
attr("virtual_node", Virtual) :- virtual_node(Virtual).
attr("hash", Package, Hash) :- hash(Package, Hash).
attr("version", Package, Version) :- version(Package, Version).
@ -464,6 +474,7 @@ attr("node_flag_propagate", Package, FlagType)
#defined node_version_satisfies/2.
#defined node_compiler_version_satisfies/3.
#defined root/1.
#defined node_namespace/2.
%-----------------------------------------------------------------------------
% External semantics

View File

@ -12,6 +12,7 @@
% Spec-related functions.
% Used to build the result of the solve.
#show node/1.
#show node_namespace/2.
#show hash/2.
#show depends_on/3.
#show version/2.