summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2021-06-08 19:04:49 +0200
committerGitHub <noreply@github.com>2021-06-08 19:04:49 +0200
commitf33c4e72803a389770124cb7e7a0f1d5819d5dec (patch)
tree6d67c962d0702b234fc9df71f01ca9cc4239bf8d
parente321578bbe7489301620fded21770dd66eed6ad0 (diff)
downloadspack-f33c4e72803a389770124cb7e7a0f1d5819d5dec.tar.gz
spack-f33c4e72803a389770124cb7e7a0f1d5819d5dec.tar.bz2
spack-f33c4e72803a389770124cb7e7a0f1d5819d5dec.tar.xz
spack-f33c4e72803a389770124cb7e7a0f1d5819d5dec.zip
ASP-based solver: permit to use virtual specs in environments (#24199)
Extracting specs for the result of a solve has been factored as a method into the asp.Result class. The method account for virtual specs being passed as initial requests.
-rw-r--r--lib/spack/spack/cmd/solve.py15
-rw-r--r--lib/spack/spack/concretize.py3
-rw-r--r--lib/spack/spack/solver/asp.py37
-rw-r--r--lib/spack/spack/test/cmd/env.py12
4 files changed, 50 insertions, 17 deletions
diff --git a/lib/spack/spack/cmd/solve.py b/lib/spack/spack/cmd/solve.py
index e81161de90..d276fa3a43 100644
--- a/lib/spack/spack/cmd/solve.py
+++ b/lib/spack/spack/cmd/solve.py
@@ -116,9 +116,7 @@ def solve(parser, args):
# dump the solutions as concretized specs
if 'solutions' in dump:
- best = min(result.answers)
-
- opt, _, answer = best
+ opt, _, _ = min(result.answers)
if ("opt" in dump) and (not args.format):
tty.msg("Best of %d considered solutions." % result.nmodels)
tty.msg("Optimization Criteria:")
@@ -132,16 +130,7 @@ def solve(parser, args):
color.cprint(fmt % (i + 1, name, val))
print()
- # iterate over roots from command line
- for input_spec in specs:
- key = input_spec.name
- if input_spec.virtual:
- providers = [spec.name for spec in answer.values()
- if spec.package.provides(key)]
- key = providers[0]
-
- spec = answer[key]
-
+ for spec in result.specs:
# With -y, just print YAML to output.
if args.format == 'yaml':
# use write because to_yaml already has a newline.
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 900009e283..81af96504a 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -737,8 +737,7 @@ def _concretize_specs_together_new(*abstract_specs, **kwargs):
result.print_cores()
tty.die("Unsatisfiable spec.")
- opt, i, answer = min(result.answers)
- return [answer[s.name].copy() for s in abstract_specs]
+ return [s.copy() for s in result.specs]
def _concretize_specs_together_original(*abstract_specs, **kwargs):
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 99e556a764..5bfbf1a6a0 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -197,7 +197,7 @@ def check_packages_exist(specs):
class Result(object):
"""Result of an ASP solve."""
- def __init__(self, asp=None):
+ def __init__(self, specs, asp=None):
self.asp = asp
self.satisfiable = None
self.optimal = None
@@ -211,12 +211,45 @@ class Result(object):
# names of optimization criteria
self.criteria = []
+ # Abstract user requests
+ self.abstract_specs = specs
+
+ # Concrete specs
+ self._concrete_specs = None
+
def print_cores(self):
for core in self.cores:
tty.msg(
"The following constraints are unsatisfiable:",
*sorted(str(symbol) for symbol in core))
+ @property
+ def specs(self):
+ """List of concretized specs satisfying the initial
+ abstract request.
+ """
+ # The specs were already computed, return them
+ if self._concrete_specs:
+ return self._concrete_specs
+
+ # Assert prerequisite
+ msg = 'cannot compute specs ["satisfiable" is not True ]'
+ assert self.satisfiable, msg
+
+ self._concrete_specs = []
+ best = min(self.answers)
+ opt, _, answer = best
+ for input_spec in self.abstract_specs:
+ key = input_spec.name
+ if input_spec.virtual:
+ providers = [spec.name for spec in answer.values()
+ if spec.package.provides(key)]
+ key = providers[0]
+
+ self._concrete_specs.append(answer[key])
+
+ return self._concrete_specs
+
def _normalize_packages_yaml(packages_yaml):
normalized_yaml = copy.copy(packages_yaml)
@@ -329,7 +362,7 @@ class PyclingoDriver(object):
timer.phase("ground")
# With a grounded program, we can run the solve.
- result = Result()
+ result = Result(specs)
models = [] # stable models if things go well
cores = [] # unsatisfiable cores if they do not
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index 5aa30a9455..0c7dea4c3e 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -2561,3 +2561,15 @@ spack:
assert view_prefix not in full_contents
assert spec.prefix in full_contents
+
+
+@pytest.mark.regression('24148')
+def test_virtual_spec_concretize_together(tmpdir):
+ # An environment should permit to concretize "mpi"
+ e = ev.create('virtual_spec')
+ e.concretization = 'together'
+
+ e.add('mpi')
+ e.concretize()
+
+ assert any(s.package.provides('mpi') for _, s in e.concretized_specs())