summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2024-06-26 16:02:00 +0200
committerGitHub <noreply@github.com>2024-06-26 16:02:00 +0200
commitb0b6016e1259de62ec044642456f915248817b24 (patch)
tree0e83f01ed5ecc22d8bfd766b5197cad13e9ad05c /lib
parentc24265fe7eca682dd1057e02cb6bfd95b985a28f (diff)
downloadspack-b0b6016e1259de62ec044642456f915248817b24.tar.gz
spack-b0b6016e1259de62ec044642456f915248817b24.tar.bz2
spack-b0b6016e1259de62ec044642456f915248817b24.tar.xz
spack-b0b6016e1259de62ec044642456f915248817b24.zip
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/solver/asp.py9
-rw-r--r--lib/spack/spack/solver/concretize.lp76
2 files changed, 44 insertions, 41 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index f53ae1c124..df1c733729 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -1880,11 +1880,8 @@ class SpackSolverSetup:
)
clauses.append(f.variant_value(spec.name, vname, value))
-
if variant.propagate:
- clauses.append(
- f.variant_propagation_candidate(spec.name, vname, value, spec.name)
- )
+ clauses.append(f.propagate(spec.name, fn.variant_value(vname, value)))
# Tell the concretizer that this is a possible value for the
# variant, to account for things like int/str values where we
@@ -2746,7 +2743,7 @@ class _Head:
node_flag = fn.attr("node_flag_set")
node_flag_source = fn.attr("node_flag_source")
node_flag_propagate = fn.attr("node_flag_propagate")
- variant_propagation_candidate = fn.attr("variant_propagation_candidate")
+ propagate = fn.attr("propagate")
class _Body:
@@ -2763,7 +2760,7 @@ class _Body:
node_flag = fn.attr("node_flag")
node_flag_source = fn.attr("node_flag_source")
node_flag_propagate = fn.attr("node_flag_propagate")
- variant_propagation_candidate = fn.attr("variant_propagation_candidate")
+ propagate = fn.attr("propagate")
class ProblemInstanceBuilder:
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index 8c270e1702..f41d7fafa0 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -812,37 +812,6 @@ node_has_variant(node(ID, Package), Variant) :-
pkg_fact(Package, variant(Variant)),
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
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),
@@ -920,7 +889,7 @@ variant_not_default(node(ID, Package), Variant, Value)
% variants set explicitly on the CLI don't count as non-default
not attr("variant_set", node(ID, Package), Variant, Value),
% 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
% this makes spack prefer to use an external over rebuilding with the
% default configuration
@@ -933,7 +902,7 @@ variant_default_not_used(node(ID, Package), Variant, Value)
:- variant_default_value(Package, Variant, Value),
node_has_variant(node(ID, Package), Variant),
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)).
% The variant is set in an external spec
@@ -991,6 +960,43 @@ pkg_fact(Package, variant_single_value("dev_path"))
#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
%-----------------------------------------------------------------------------
@@ -1497,7 +1503,7 @@ opt_criterion(45, "preferred providers (non-roots)").
}.
% 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@40: #true }.
#minimize{
@@ -1507,7 +1513,7 @@ opt_criterion(40, "compiler mismatches that are not from CLI").
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@39: #true }.
#minimize{