summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Scheibel <scheibel1@llnl.gov>2024-03-31 05:02:09 -0700
committerGitHub <noreply@github.com>2024-03-31 14:02:09 +0200
commite78484f501178cb71be363a78762c237240816aa (patch)
treebdcb0b89df8673be8123b3d085c47056b1232197
parent6fd43b4e7589461f3b0a524b2ae617bbad9c8fe1 (diff)
downloadspack-e78484f501178cb71be363a78762c237240816aa.tar.gz
spack-e78484f501178cb71be363a78762c237240816aa.tar.bz2
spack-e78484f501178cb71be363a78762c237240816aa.tar.xz
spack-e78484f501178cb71be363a78762c237240816aa.zip
Concretize `when_possible`: add failure detection and explicit message (#43202)
Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
-rw-r--r--lib/spack/spack/cmd/solve.py1
-rw-r--r--lib/spack/spack/concretize.py1
-rw-r--r--lib/spack/spack/solver/asp.py15
-rw-r--r--lib/spack/spack/spec.py1
-rw-r--r--lib/spack/spack/test/concretize.py16
5 files changed, 27 insertions, 7 deletions
diff --git a/lib/spack/spack/cmd/solve.py b/lib/spack/spack/cmd/solve.py
index 3d6968d2d9..165ede0dbc 100644
--- a/lib/spack/spack/cmd/solve.py
+++ b/lib/spack/spack/cmd/solve.py
@@ -91,7 +91,6 @@ def setup_parser(subparser):
def _process_result(result, show, required_format, kwargs):
- result.raise_if_unsat()
opt, _, _ = min(result.answers)
if ("opt" in show) and (not required_format):
tty.msg("Best of %d considered solutions." % result.nmodels)
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 86e1eb9735..e1f1170b91 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -749,7 +749,6 @@ def _concretize_specs_together_new(*abstract_specs, **kwargs):
result = solver.solve(
abstract_specs, tests=kwargs.get("tests", False), allow_deprecated=allow_deprecated
)
- result.raise_if_unsat()
return [s.copy() for s in result.specs]
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index ea2c9ddcfe..5928886bdb 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -763,7 +763,6 @@ class PyclingoDriver:
timer.stop("ground")
# With a grounded program, we can run the solve.
- result = Result(specs)
models = [] # stable models if things go well
cores = [] # unsatisfiable cores if they do not
@@ -784,6 +783,7 @@ class PyclingoDriver:
timer.stop("solve")
# once done, construct the solve result
+ result = Result(specs)
result.satisfiable = solve_result.satisfiable
if result.satisfiable:
@@ -824,6 +824,8 @@ class PyclingoDriver:
print("Statistics:")
pprint.pprint(self.control.statistics)
+ result.raise_if_unsat()
+
if result.satisfiable and result.unsolved_specs and setup.concretize_everything:
unsolved_str = Result.format_unsolved(result.unsolved_specs)
raise InternalConcretizerError(
@@ -3535,9 +3537,14 @@ class Solver:
if not result.unsolved_specs:
break
- # This means we cannot progress with solving the input
- if not result.satisfiable or not result.specs:
- break
+ if not result.specs:
+ # This is also a problem: no specs were solved for, which
+ # means we would be in a loop if we tried again
+ unsolved_str = Result.format_unsolved(result.unsolved_specs)
+ raise InternalConcretizerError(
+ "Internal Spack error: a subset of input specs could not"
+ f" be solved for.\n\t{unsolved_str}"
+ )
input_specs = list(x for (x, y) in result.unsolved_specs)
for spec in result.specs:
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index ff3248321a..d63d52a6b1 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -2968,7 +2968,6 @@ class Spec:
allow_deprecated = spack.config.get("config:deprecated", False)
solver = spack.solver.asp.Solver()
result = solver.solve([self], tests=tests, allow_deprecated=allow_deprecated)
- result.raise_if_unsat()
# take the best answer
opt, i, answer = min(result.answers)
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index f2a104afbb..cd1b189961 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1794,6 +1794,22 @@ class TestConcretize:
counter += 1
assert counter == occurances, concrete_specs
+ @pytest.mark.only_clingo("Original concretizer cannot concretize in rounds")
+ def test_solve_in_rounds_all_unsolved(self, monkeypatch, mock_packages, config):
+ specs = [Spec(x) for x in ["libdwarf%gcc", "libdwarf%clang"]]
+ solver = spack.solver.asp.Solver()
+ solver.reuse = False
+
+ simulate_unsolved_property = list((x, None) for x in specs)
+ monkeypatch.setattr(spack.solver.asp.Result, "unsolved_specs", simulate_unsolved_property)
+ monkeypatch.setattr(spack.solver.asp.Result, "specs", list())
+
+ with pytest.raises(
+ spack.solver.asp.InternalConcretizerError,
+ match="a subset of input specs could not be solved for",
+ ):
+ list(solver.solve_in_rounds(specs))
+
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
def test_coconcretize_reuse_and_virtuals(self):
reusable_specs = []