This reverts commit babd29da50
.
This commit is contained in:
parent
eee8fdc438
commit
d7b5a27d1d
@ -176,29 +176,17 @@ def solve(parser, args):
|
||||
output = sys.stdout if "asp" in show else None
|
||||
setup_only = set(show) == {"asp"}
|
||||
unify = spack.config.get("concretizer:unify")
|
||||
allow_deprecated = spack.config.get("config:deprecated", False)
|
||||
if unify != "when_possible":
|
||||
# set up solver parameters
|
||||
# Note: reuse and other concretizer prefs are passed as configuration
|
||||
result = solver.solve(
|
||||
specs,
|
||||
out=output,
|
||||
timers=args.timers,
|
||||
stats=args.stats,
|
||||
setup_only=setup_only,
|
||||
deprecated=allow_deprecated,
|
||||
specs, out=output, timers=args.timers, stats=args.stats, setup_only=setup_only
|
||||
)
|
||||
if not setup_only:
|
||||
_process_result(result, show, required_format, kwargs)
|
||||
else:
|
||||
for idx, result in enumerate(
|
||||
solver.solve_in_rounds(
|
||||
specs,
|
||||
out=output,
|
||||
timers=args.timers,
|
||||
stats=args.stats,
|
||||
deprecated=allow_deprecated,
|
||||
)
|
||||
solver.solve_in_rounds(specs, out=output, timers=args.timers, stats=args.stats)
|
||||
):
|
||||
if "solutions" in show:
|
||||
tty.msg("ROUND {0}".format(idx))
|
||||
|
@ -744,11 +744,8 @@ def concretize_specs_together(*abstract_specs, **kwargs):
|
||||
def _concretize_specs_together_new(*abstract_specs, **kwargs):
|
||||
import spack.solver.asp
|
||||
|
||||
allow_deprecated = spack.config.get("config:deprecated", False)
|
||||
solver = spack.solver.asp.Solver()
|
||||
result = solver.solve(
|
||||
abstract_specs, tests=kwargs.get("tests", False), deprecated=allow_deprecated
|
||||
)
|
||||
result = solver.solve(abstract_specs, tests=kwargs.get("tests", False))
|
||||
result.raise_if_unsat()
|
||||
return [s.copy() for s in result.specs]
|
||||
|
||||
|
@ -1395,10 +1395,7 @@ def _concretize_together_where_possible(
|
||||
|
||||
result_by_user_spec = {}
|
||||
solver = spack.solver.asp.Solver()
|
||||
allow_deprecated = spack.config.get("config:deprecated", False)
|
||||
for result in solver.solve_in_rounds(
|
||||
specs_to_concretize, tests=tests, deprecated=allow_deprecated
|
||||
):
|
||||
for result in solver.solve_in_rounds(specs_to_concretize, tests=tests):
|
||||
result_by_user_spec.update(result.specs_by_input)
|
||||
|
||||
result = []
|
||||
|
@ -13,7 +13,7 @@
|
||||
import re
|
||||
import types
|
||||
import warnings
|
||||
from typing import List, NamedTuple, Optional, Sequence, Tuple, Union
|
||||
from typing import List, NamedTuple, Tuple, Union
|
||||
|
||||
import archspec.cpu
|
||||
|
||||
@ -137,15 +137,7 @@ class RequirementKind(enum.Enum):
|
||||
PACKAGE = enum.auto()
|
||||
|
||||
|
||||
class DeclaredVersion(NamedTuple):
|
||||
"""Data class to contain information on declared versions used in the solve"""
|
||||
|
||||
#: String representation of the version
|
||||
version: str
|
||||
#: Unique index assigned to this version
|
||||
idx: int
|
||||
#: Provenance of the version
|
||||
origin: Provenance
|
||||
DeclaredVersion = collections.namedtuple("DeclaredVersion", ["version", "idx", "origin"])
|
||||
|
||||
|
||||
# Below numbers are used to map names of criteria to the order
|
||||
@ -792,7 +784,7 @@ def fact(self, head):
|
||||
if choice:
|
||||
self.assumptions.append(atom)
|
||||
|
||||
def solve(self, setup, specs, reuse=None, output=None, control=None, deprecated=False):
|
||||
def solve(self, setup, specs, reuse=None, output=None, control=None):
|
||||
"""Set up the input and solve for dependencies of ``specs``.
|
||||
|
||||
Arguments:
|
||||
@ -803,7 +795,6 @@ def solve(self, setup, specs, reuse=None, output=None, control=None, deprecated=
|
||||
the output of this solve.
|
||||
control (clingo.Control): configuration for the solver. If None,
|
||||
default values will be used
|
||||
deprecated: if True, allow deprecated versions in the solve
|
||||
|
||||
Return:
|
||||
A tuple of the solve result, the timer for the different phases of the
|
||||
@ -823,7 +814,7 @@ def solve(self, setup, specs, reuse=None, output=None, control=None, deprecated=
|
||||
timer.start("setup")
|
||||
with self.control.backend() as backend:
|
||||
self.backend = backend
|
||||
setup.setup(self, specs, reuse=reuse, deprecated=deprecated)
|
||||
setup.setup(self, specs, reuse=reuse)
|
||||
timer.stop("setup")
|
||||
|
||||
timer.start("load")
|
||||
@ -1903,7 +1894,7 @@ class Body:
|
||||
return clauses
|
||||
|
||||
def define_package_versions_and_validate_preferences(
|
||||
self, possible_pkgs, *, require_checksum: bool, deprecated: bool
|
||||
self, possible_pkgs, require_checksum: bool
|
||||
):
|
||||
"""Declare any versions in specs not declared in packages."""
|
||||
packages_yaml = spack.config.get("packages")
|
||||
@ -1923,15 +1914,13 @@ def define_package_versions_and_validate_preferences(
|
||||
]
|
||||
|
||||
for idx, (v, version_info) in enumerate(package_py_versions):
|
||||
if version_info.get("deprecated", False):
|
||||
self.deprecated_versions[pkg_name].add(v)
|
||||
if not deprecated:
|
||||
continue
|
||||
|
||||
self.possible_versions[pkg_name].add(v)
|
||||
self.declared_versions[pkg_name].append(
|
||||
DeclaredVersion(version=v, idx=idx, origin=Provenance.PACKAGE_PY)
|
||||
)
|
||||
deprecated = version_info.get("deprecated", False)
|
||||
if deprecated:
|
||||
self.deprecated_versions[pkg_name].add(v)
|
||||
|
||||
if pkg_name not in packages_yaml or "version" not in packages_yaml[pkg_name]:
|
||||
continue
|
||||
@ -1960,7 +1949,7 @@ def define_package_versions_and_validate_preferences(
|
||||
)
|
||||
self.possible_versions[pkg_name].add(vdef)
|
||||
|
||||
def define_ad_hoc_versions_from_specs(self, specs, origin, *, require_checksum: bool):
|
||||
def define_ad_hoc_versions_from_specs(self, specs, origin, require_checksum: bool):
|
||||
"""Add concrete versions to possible versions from lists of CLI/dev specs."""
|
||||
for s in traverse.traverse_nodes(specs):
|
||||
# If there is a concrete version on the CLI *that we know nothing
|
||||
@ -2340,14 +2329,7 @@ def define_concrete_input_specs(self, specs, possible):
|
||||
if spec.concrete:
|
||||
self._facts_from_concrete_spec(spec, possible)
|
||||
|
||||
def setup(
|
||||
self,
|
||||
driver: PyclingoDriver,
|
||||
specs: Sequence[spack.spec.Spec],
|
||||
*,
|
||||
reuse: Optional[List[spack.spec.Spec]] = None,
|
||||
deprecated: bool = False,
|
||||
):
|
||||
def setup(self, driver, specs, reuse=None):
|
||||
"""Generate an ASP program with relevant constraints for specs.
|
||||
|
||||
This calls methods on the solve driver to set up the problem with
|
||||
@ -2355,10 +2337,9 @@ def setup(
|
||||
specs, as well as constraints from the specs themselves.
|
||||
|
||||
Arguments:
|
||||
driver: driver instance of this solve
|
||||
specs: list of Specs to solve
|
||||
reuse: list of concrete specs that can be reused
|
||||
deprecated: if True adds deprecated versions into the solve
|
||||
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
|
||||
"""
|
||||
self._condition_id_counter = itertools.count()
|
||||
|
||||
@ -2387,7 +2368,7 @@ def setup(
|
||||
# Calculate develop specs
|
||||
# they will be used in addition to command line specs
|
||||
# in determining known versions/targets/os
|
||||
dev_specs: Tuple[spack.spec.Spec, ...] = ()
|
||||
dev_specs = ()
|
||||
env = ev.active_environment()
|
||||
if env:
|
||||
dev_specs = tuple(
|
||||
@ -2433,17 +2414,11 @@ def setup(
|
||||
self.external_packages()
|
||||
|
||||
# TODO: make a config option for this undocumented feature
|
||||
checksummed = "SPACK_CONCRETIZER_REQUIRE_CHECKSUM" in os.environ
|
||||
self.define_package_versions_and_validate_preferences(
|
||||
self.pkgs, deprecated=deprecated, require_checksum=checksummed
|
||||
)
|
||||
self.define_ad_hoc_versions_from_specs(
|
||||
specs, Provenance.SPEC, require_checksum=checksummed
|
||||
)
|
||||
self.define_ad_hoc_versions_from_specs(
|
||||
dev_specs, Provenance.DEV_SPEC, require_checksum=checksummed
|
||||
)
|
||||
self.validate_and_define_versions_from_requirements(require_checksum=checksummed)
|
||||
require_checksum = "SPACK_CONCRETIZER_REQUIRE_CHECKSUM" in os.environ
|
||||
self.define_package_versions_and_validate_preferences(self.pkgs, require_checksum)
|
||||
self.define_ad_hoc_versions_from_specs(specs, Provenance.SPEC, require_checksum)
|
||||
self.define_ad_hoc_versions_from_specs(dev_specs, Provenance.DEV_SPEC, require_checksum)
|
||||
self.validate_and_define_versions_from_requirements(require_checksum)
|
||||
|
||||
self.gen.h1("Package Constraints")
|
||||
for pkg in sorted(self.pkgs):
|
||||
@ -2492,7 +2467,7 @@ def literal_specs(self, specs):
|
||||
if self.concretize_everything:
|
||||
self.gen.fact(fn.solve_literal(idx))
|
||||
|
||||
def validate_and_define_versions_from_requirements(self, *, require_checksum: bool):
|
||||
def validate_and_define_versions_from_requirements(self, require_checksum: bool):
|
||||
"""If package requirements mention concrete versions that are not mentioned
|
||||
elsewhere, then we need to collect those to mark them as possible
|
||||
versions. If they are abstract and statically have no match, then we
|
||||
@ -2957,16 +2932,7 @@ def _reusable_specs(self, specs):
|
||||
|
||||
return reusable_specs
|
||||
|
||||
def solve(
|
||||
self,
|
||||
specs,
|
||||
out=None,
|
||||
timers=False,
|
||||
stats=False,
|
||||
tests=False,
|
||||
setup_only=False,
|
||||
deprecated=False,
|
||||
):
|
||||
def solve(self, specs, out=None, timers=False, stats=False, tests=False, setup_only=False):
|
||||
"""
|
||||
Arguments:
|
||||
specs (list): List of ``Spec`` objects to solve for.
|
||||
@ -2977,7 +2943,6 @@ def solve(
|
||||
If a tuple of package names, concretize test dependencies for named
|
||||
packages (defaults to False: do not concretize test dependencies).
|
||||
setup_only (bool): if True, stop after setup and don't solve (default False).
|
||||
deprecated (bool): allow deprecated version in the solve
|
||||
"""
|
||||
# Check upfront that the variants are admissible
|
||||
specs = [s.lookup_hash() for s in specs]
|
||||
@ -2985,14 +2950,10 @@ def solve(
|
||||
reusable_specs.extend(self._reusable_specs(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, deprecated=deprecated
|
||||
)
|
||||
result, _, _ = self.driver.solve(setup, specs, reuse=reusable_specs, output=output)
|
||||
return result
|
||||
|
||||
def solve_in_rounds(
|
||||
self, specs, out=None, timers=False, stats=False, tests=False, deprecated=False
|
||||
):
|
||||
def solve_in_rounds(self, specs, out=None, timers=False, stats=False, tests=False):
|
||||
"""Solve for a stable model of specs in multiple rounds.
|
||||
|
||||
This relaxes the assumption of solve that everything must be consistent and
|
||||
@ -3007,7 +2968,6 @@ def solve_in_rounds(
|
||||
timers (bool): print timing if set to True
|
||||
stats (bool): print internal statistics if set to True
|
||||
tests (bool): add test dependencies to the solve
|
||||
deprecated (bool): allow deprecated version in the solve
|
||||
"""
|
||||
specs = [s.lookup_hash() for s in specs]
|
||||
reusable_specs = self._check_input_and_extract_concrete_specs(specs)
|
||||
@ -3021,7 +2981,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, deprecated=deprecated
|
||||
setup, input_specs, reuse=reusable_specs, output=output
|
||||
)
|
||||
yield result
|
||||
|
||||
|
@ -1361,6 +1361,16 @@ opt_criterion(75, "requirement weight").
|
||||
build_priority(PackageNode, Priority)
|
||||
}.
|
||||
|
||||
% Minimize the number of deprecated versions being used
|
||||
opt_criterion(73, "deprecated versions used").
|
||||
#minimize{ 0@273: #true }.
|
||||
#minimize{ 0@73: #true }.
|
||||
#minimize{
|
||||
1@73+Priority,PackageNode
|
||||
: attr("deprecated", PackageNode, _),
|
||||
build_priority(PackageNode, Priority)
|
||||
}.
|
||||
|
||||
% Minimize the:
|
||||
% 1. Version weight
|
||||
% 2. Number of variants with a non default value, if not set
|
||||
|
@ -2963,9 +2963,8 @@ def _new_concretize(self, tests=False):
|
||||
if self._concrete:
|
||||
return
|
||||
|
||||
allow_deprecated = spack.config.get("config:deprecated", False)
|
||||
solver = spack.solver.asp.Solver()
|
||||
result = solver.solve([self], tests=tests, deprecated=allow_deprecated)
|
||||
result = solver.solve([self], tests=tests)
|
||||
result.raise_if_unsat()
|
||||
|
||||
# take the best answer
|
||||
|
@ -1356,7 +1356,7 @@ def test_multivalued_variants_from_cli(self, spec_str, expected_dict):
|
||||
# Version 1.1.0 is deprecated and should not be selected, unless we
|
||||
# explicitly asked for that
|
||||
("deprecated-versions", ["deprecated-versions@1.0.0"]),
|
||||
("deprecated-versions@=1.1.0", ["deprecated-versions@1.1.0"]),
|
||||
("deprecated-versions@1.1.0", ["deprecated-versions@1.1.0"]),
|
||||
],
|
||||
)
|
||||
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
|
||||
|
@ -545,13 +545,13 @@ def test_reuse_oneof(concretize_scope, create_test_repo, mutable_database, fake_
|
||||
|
||||
def test_requirements_are_higher_priority_than_deprecation(concretize_scope, test_repo):
|
||||
"""Test that users can override a deprecated version with a requirement."""
|
||||
# 2.3 is a deprecated versions. Ensure that any_of picks both constraints,
|
||||
# @2.3 is a deprecated versions. Ensure that any_of picks both constraints,
|
||||
# since they are possible
|
||||
conf_str = """\
|
||||
packages:
|
||||
y:
|
||||
require:
|
||||
- any_of: ["@=2.3", "%gcc"]
|
||||
- any_of: ["@2.3", "%gcc"]
|
||||
"""
|
||||
update_packages_config(conf_str)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user