ASP-based solver: add a generic rule for propagation (#44870)
This adds a generic propagate/2 rule to propagate any fact to children in the DAG.
This commit is contained in:
parent
8628add66b
commit
249dcb49e2
2 changed files with 44 additions and 41 deletions
|
@ -1878,11 +1878,8 @@ def _spec_clauses(
|
||||||
)
|
)
|
||||||
|
|
||||||
clauses.append(f.variant_value(spec.name, vname, value))
|
clauses.append(f.variant_value(spec.name, vname, value))
|
||||||
|
|
||||||
if variant.propagate:
|
if variant.propagate:
|
||||||
clauses.append(
|
clauses.append(f.propagate(spec.name, fn.variant_value(vname, value)))
|
||||||
f.variant_propagation_candidate(spec.name, vname, value, spec.name)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Tell the concretizer that this is a possible value for the
|
# Tell the concretizer that this is a possible value for the
|
||||||
# variant, to account for things like int/str values where we
|
# variant, to account for things like int/str values where we
|
||||||
|
@ -2737,7 +2734,7 @@ class _Head:
|
||||||
node_flag = fn.attr("node_flag_set")
|
node_flag = fn.attr("node_flag_set")
|
||||||
node_flag_source = fn.attr("node_flag_source")
|
node_flag_source = fn.attr("node_flag_source")
|
||||||
node_flag_propagate = fn.attr("node_flag_propagate")
|
node_flag_propagate = fn.attr("node_flag_propagate")
|
||||||
variant_propagation_candidate = fn.attr("variant_propagation_candidate")
|
propagate = fn.attr("propagate")
|
||||||
|
|
||||||
|
|
||||||
class _Body:
|
class _Body:
|
||||||
|
@ -2754,7 +2751,7 @@ class _Body:
|
||||||
node_flag = fn.attr("node_flag")
|
node_flag = fn.attr("node_flag")
|
||||||
node_flag_source = fn.attr("node_flag_source")
|
node_flag_source = fn.attr("node_flag_source")
|
||||||
node_flag_propagate = fn.attr("node_flag_propagate")
|
node_flag_propagate = fn.attr("node_flag_propagate")
|
||||||
variant_propagation_candidate = fn.attr("variant_propagation_candidate")
|
propagate = fn.attr("propagate")
|
||||||
|
|
||||||
|
|
||||||
class ProblemInstanceBuilder:
|
class ProblemInstanceBuilder:
|
||||||
|
|
|
@ -811,37 +811,6 @@ node_has_variant(node(ID, Package), Variant) :-
|
||||||
pkg_fact(Package, variant(Variant)),
|
pkg_fact(Package, variant(Variant)),
|
||||||
attr("node", node(ID, Package)).
|
attr("node", node(ID, Package)).
|
||||||
|
|
||||||
% Variant propagation is forwarded to dependencies
|
|
||||||
attr("variant_propagation_candidate", PackageNode, Variant, Value, Source) :-
|
|
||||||
attr("node", PackageNode),
|
|
||||||
depends_on(ParentNode, PackageNode),
|
|
||||||
attr("variant_value", node(_, Source), Variant, Value),
|
|
||||||
attr("variant_propagation_candidate", ParentNode, Variant, _, Source).
|
|
||||||
|
|
||||||
% If the node is a candidate, and it has the variant and value,
|
|
||||||
% then those variant and value should be propagated
|
|
||||||
attr("variant_propagate", node(ID, Package), Variant, Value, Source) :-
|
|
||||||
attr("variant_propagation_candidate", node(ID, Package), Variant, Value, Source),
|
|
||||||
node_has_variant(node(ID, Package), Variant),
|
|
||||||
pkg_fact(Package, variant_possible_value(Variant, Value)),
|
|
||||||
not attr("variant_set", node(ID, Package), Variant).
|
|
||||||
|
|
||||||
% Propagate the value, if there is the corresponding attribute
|
|
||||||
attr("variant_value", PackageNode, Variant, Value) :- attr("variant_propagate", PackageNode, Variant, Value, _).
|
|
||||||
|
|
||||||
% If a variant is propagated, we cannot have extraneous values (this is for multi valued variants)
|
|
||||||
variant_is_propagated(PackageNode, Variant) :- attr("variant_propagate", PackageNode, Variant, _, _).
|
|
||||||
:- variant_is_propagated(PackageNode, Variant),
|
|
||||||
attr("variant_value", PackageNode, Variant, Value),
|
|
||||||
not attr("variant_propagate", PackageNode, Variant, Value, _).
|
|
||||||
|
|
||||||
% Cannot receive different values from different sources on the same variant
|
|
||||||
error(100, "{0} and {1} cannot both propagate variant '{2}' to package {3} with values '{4}' and '{5}'", Source1, Source2, Variant, Package, Value1, Value2) :-
|
|
||||||
attr("variant_propagate", node(X, Package), Variant, Value1, Source1),
|
|
||||||
attr("variant_propagate", node(X, Package), Variant, Value2, Source2),
|
|
||||||
node_has_variant(node(X, Package), Variant),
|
|
||||||
Value1 < Value2, Source1 < Source2.
|
|
||||||
|
|
||||||
% a variant cannot be set if it is not a variant on the package
|
% a variant cannot be set if it is not a variant on the package
|
||||||
error(100, "Cannot set variant '{0}' for package '{1}' because the variant condition cannot be satisfied for the given spec", Variant, Package)
|
error(100, "Cannot set variant '{0}' for package '{1}' because the variant condition cannot be satisfied for the given spec", Variant, Package)
|
||||||
:- attr("variant_set", node(X, Package), Variant),
|
:- attr("variant_set", node(X, Package), Variant),
|
||||||
|
@ -919,7 +888,7 @@ variant_not_default(node(ID, Package), Variant, Value)
|
||||||
% variants set explicitly on the CLI don't count as non-default
|
% variants set explicitly on the CLI don't count as non-default
|
||||||
not attr("variant_set", node(ID, Package), Variant, Value),
|
not attr("variant_set", node(ID, Package), Variant, Value),
|
||||||
% variant values forced by propagation don't count as non-default
|
% variant values forced by propagation don't count as non-default
|
||||||
not attr("variant_propagate", node(ID, Package), Variant, Value, _),
|
not propagate(node(ID, Package), variant_value(Variant, Value)),
|
||||||
% variants set on externals that we could use don't count as non-default
|
% variants set on externals that we could use don't count as non-default
|
||||||
% this makes spack prefer to use an external over rebuilding with the
|
% this makes spack prefer to use an external over rebuilding with the
|
||||||
% default configuration
|
% default configuration
|
||||||
|
@ -932,7 +901,7 @@ variant_default_not_used(node(ID, Package), Variant, Value)
|
||||||
:- variant_default_value(Package, Variant, Value),
|
:- variant_default_value(Package, Variant, Value),
|
||||||
node_has_variant(node(ID, Package), Variant),
|
node_has_variant(node(ID, Package), Variant),
|
||||||
not attr("variant_value", node(ID, Package), Variant, Value),
|
not attr("variant_value", node(ID, Package), Variant, Value),
|
||||||
not attr("variant_propagate", node(ID, Package), Variant, _, _),
|
not propagate(node(ID, Package), variant_value(Variant, _)),
|
||||||
attr("node", node(ID, Package)).
|
attr("node", node(ID, Package)).
|
||||||
|
|
||||||
% The variant is set in an external spec
|
% The variant is set in an external spec
|
||||||
|
@ -989,6 +958,43 @@ pkg_fact(Package, variant_single_value("dev_path"))
|
||||||
#defined variant_default_value/3.
|
#defined variant_default_value/3.
|
||||||
#defined variant_default_value_from_packages_yaml/3.
|
#defined variant_default_value_from_packages_yaml/3.
|
||||||
|
|
||||||
|
%-----------------------------------------------------------------------------
|
||||||
|
% Propagation semantics
|
||||||
|
%-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
% Propagation roots have a corresponding attr("propagate", ...)
|
||||||
|
propagate(RootNode, PropagatedAttribute) :- attr("propagate", RootNode, PropagatedAttribute).
|
||||||
|
|
||||||
|
% Propagate an attribute along edges to child nodes
|
||||||
|
propagate(ChildNode, PropagatedAttribute) :-
|
||||||
|
propagate(ParentNode, PropagatedAttribute),
|
||||||
|
depends_on(ParentNode, ChildNode).
|
||||||
|
|
||||||
|
%-----------------------------------------------------------------------------
|
||||||
|
% Activation of propagated values
|
||||||
|
%-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
%----
|
||||||
|
% Variants
|
||||||
|
%----
|
||||||
|
|
||||||
|
% If a variant is propagated, and can be accepted, set its value
|
||||||
|
attr("variant_value", node(ID, Package), Variant, Value) :-
|
||||||
|
propagate(node(ID, Package), variant_value(Variant, Value)),
|
||||||
|
node_has_variant(node(ID, Package), Variant),
|
||||||
|
pkg_fact(Package, variant_possible_value(Variant, Value)),
|
||||||
|
not attr("variant_set", node(ID, Package), Variant).
|
||||||
|
|
||||||
|
% If a variant is propagated, we cannot have extraneous values
|
||||||
|
variant_is_propagated(PackageNode, Variant) :-
|
||||||
|
attr("variant_value", PackageNode, Variant, Value),
|
||||||
|
propagate(PackageNode, variant_value(Variant, Value)),
|
||||||
|
not attr("variant_set", PackageNode, Variant).
|
||||||
|
|
||||||
|
:- variant_is_propagated(PackageNode, Variant),
|
||||||
|
attr("variant_value", PackageNode, Variant, Value),
|
||||||
|
not propagate(PackageNode, variant_value(Variant, Value)).
|
||||||
|
|
||||||
%-----------------------------------------------------------------------------
|
%-----------------------------------------------------------------------------
|
||||||
% Platform semantics
|
% Platform semantics
|
||||||
%-----------------------------------------------------------------------------
|
%-----------------------------------------------------------------------------
|
||||||
|
@ -1496,7 +1502,7 @@ opt_criterion(45, "preferred providers (non-roots)").
|
||||||
}.
|
}.
|
||||||
|
|
||||||
% Try to minimize the number of compiler mismatches in the DAG.
|
% Try to minimize the number of compiler mismatches in the DAG.
|
||||||
opt_criterion(40, "compiler mismatches that are not from CLI").
|
opt_criterion(40, "compiler mismatches that are not required").
|
||||||
#minimize{ 0@240: #true }.
|
#minimize{ 0@240: #true }.
|
||||||
#minimize{ 0@40: #true }.
|
#minimize{ 0@40: #true }.
|
||||||
#minimize{
|
#minimize{
|
||||||
|
@ -1506,7 +1512,7 @@ opt_criterion(40, "compiler mismatches that are not from CLI").
|
||||||
not runtime(Dependency)
|
not runtime(Dependency)
|
||||||
}.
|
}.
|
||||||
|
|
||||||
opt_criterion(39, "compiler mismatches that are not from CLI").
|
opt_criterion(39, "compiler mismatches that are required").
|
||||||
#minimize{ 0@239: #true }.
|
#minimize{ 0@239: #true }.
|
||||||
#minimize{ 0@39: #true }.
|
#minimize{ 0@39: #true }.
|
||||||
#minimize{
|
#minimize{
|
||||||
|
|
Loading…
Reference in a new issue