also break circular import concretize.py and solver/asp.py

This commit is contained in:
Harmen Stoppels 2024-12-07 21:32:20 +01:00 committed by Harmen Stoppels
parent 4e9fe1fc5d
commit 0239d77842
7 changed files with 65 additions and 67 deletions

View File

@ -33,7 +33,6 @@
import spack
import spack.binary_distribution as bindist
import spack.builder
import spack.concretize
import spack.config as cfg
import spack.error
import spack.main
@ -41,6 +40,7 @@
import spack.mirrors.utils
import spack.paths
import spack.repo
import spack.solver.asp
import spack.spec
import spack.util.git
import spack.util.gpg as gpg_util
@ -707,7 +707,7 @@ def generate_gitlab_ci_yaml(
files (spack.yaml, spack.lock), etc should be written. GitLab
requires this to be within the project directory.
"""
with spack.concretize.disable_compiler_existence_check():
with spack.solver.asp.disable_compiler_existence_check():
with env.write_transaction():
env.concretize()
env.write()

View File

@ -17,6 +17,7 @@
import spack.mirrors.mirror
import spack.mirrors.utils
import spack.repo
import spack.solver.asp
import spack.spec
import spack.util.web as web_util
from spack.cmd.common import arguments
@ -516,7 +517,7 @@ def extend_with_dependencies(specs):
def concrete_specs_from_cli_or_file(args):
tty.msg("Concretizing input specs")
with spack.concretize.disable_compiler_existence_check():
with spack.solver.asp.disable_compiler_existence_check():
if args.specs:
specs = spack.cmd.parse_specs(args.specs, concretize=True)
if not specs:

View File

@ -5,8 +5,7 @@
"""High-level functions to concretize list of specs"""
import sys
import time
from contextlib import contextmanager
from typing import Iterable, Optional, Sequence, Tuple, Union
from typing import Iterable, Sequence, Tuple, Union
import llnl.util.tty as tty
@ -15,26 +14,7 @@
import spack.error
import spack.repo
import spack.util.parallel
from spack.spec import ArchSpec, CompilerSpec, Spec
CHECK_COMPILER_EXISTENCE = True
@contextmanager
def disable_compiler_existence_check():
global CHECK_COMPILER_EXISTENCE
CHECK_COMPILER_EXISTENCE, saved = False, CHECK_COMPILER_EXISTENCE
yield
CHECK_COMPILER_EXISTENCE = saved
@contextmanager
def enable_compiler_existence_check():
global CHECK_COMPILER_EXISTENCE
CHECK_COMPILER_EXISTENCE, saved = True, CHECK_COMPILER_EXISTENCE
yield
CHECK_COMPILER_EXISTENCE = saved
from spack.spec import Spec
SpecPair = Tuple[Spec, Spec]
SpecLike = Union[Spec, str]
@ -51,11 +31,10 @@ def concretize_specs_together(
tests: list of package names for which to consider tests dependencies. If True, all nodes
will have test dependencies. If False, test dependencies will be disregarded.
"""
import spack.solver.asp
from spack.solver.asp import Solver
allow_deprecated = spack.config.get("config:deprecated", False)
solver = spack.solver.asp.Solver()
result = solver.solve(abstract_specs, tests=tests, allow_deprecated=allow_deprecated)
result = Solver().solve(abstract_specs, tests=tests, allow_deprecated=allow_deprecated)
return [s.copy() for s in result.specs]
@ -90,7 +69,7 @@ def concretize_together_when_possible(
tests: list of package names for which to consider tests dependencies. If True, all nodes
will have test dependencies. If False, test dependencies will be disregarded.
"""
import spack.solver.asp
from spack.solver.asp import Solver
to_concretize = [concrete if concrete else abstract for abstract, concrete in spec_list]
old_concrete_to_abstract = {
@ -98,9 +77,8 @@ def concretize_together_when_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(
for result in Solver().solve_in_rounds(
to_concretize, tests=tests, allow_deprecated=allow_deprecated
):
result_by_user_spec.update(result.specs_by_input)
@ -124,7 +102,7 @@ def concretize_separately(
tests: list of package names for which to consider tests dependencies. If True, all nodes
will have test dependencies. If False, test dependencies will be disregarded.
"""
import spack.bootstrap
from spack.bootstrap import ensure_bootstrap_configuration, ensure_clingo_importable_or_raise
to_concretize = [abstract for abstract, concrete in spec_list if not concrete]
args = [
@ -134,8 +112,8 @@ def concretize_separately(
]
ret = [(i, abstract) for i, abstract in enumerate(to_concretize) if abstract.concrete]
# Ensure we don't try to bootstrap clingo in parallel
with spack.bootstrap.ensure_bootstrap_configuration():
spack.bootstrap.ensure_clingo_importable_or_raise()
with ensure_bootstrap_configuration():
ensure_clingo_importable_or_raise()
# Ensure all the indexes have been built or updated, since
# otherwise the processes in the pool may timeout on waiting
@ -201,6 +179,8 @@ def concretized(spec: Spec, tests: Union[bool, Iterable[str]] = False) -> Spec:
tests: if False disregard 'test' dependencies, if a list of names activate them for
the packages in the list, if True activate 'test' dependencies for all packages.
"""
from spack.solver.asp import Solver, SpecBuilder
spec.replace_hash()
for node in spec.traverse():
@ -213,8 +193,7 @@ def concretized(spec: Spec, tests: Union[bool, Iterable[str]] = False) -> Spec:
return spec.copy()
allow_deprecated = spack.config.get("config:deprecated", False)
solver = spack.solver.asp.Solver()
result = solver.solve([spec], tests=tests, allow_deprecated=allow_deprecated)
result = Solver().solve([spec], tests=tests, allow_deprecated=allow_deprecated)
# take the best answer
opt, i, answer = min(result.answers)
@ -224,27 +203,10 @@ def concretized(spec: Spec, tests: Union[bool, Iterable[str]] = False) -> Spec:
providers = [s.name for s in answer.values() if s.package.provides(name)]
name = providers[0]
node = spack.solver.asp.SpecBuilder.make_node(pkg=name)
node = SpecBuilder.make_node(pkg=name)
assert (
node in answer
), f"cannot find {name} in the list of specs {','.join([n.pkg for n in answer.keys()])}"
concretized = answer[node]
return concretized
class UnavailableCompilerVersionError(spack.error.SpackError):
"""Raised when there is no available compiler that satisfies a
compiler spec."""
def __init__(self, compiler_spec: CompilerSpec, arch: Optional[ArchSpec] = None) -> None:
err_msg = f"No compilers with spec {compiler_spec} found"
if arch:
err_msg += f" for operating system {arch.os} and target {arch.target}."
super().__init__(
err_msg,
"Run 'spack compiler find' to add compilers or "
"'spack compilers' to see which compilers are already recognized"
" by spack.",
)

View File

@ -29,7 +29,6 @@
import spack.binary_distribution
import spack.compiler
import spack.compilers
import spack.concretize
import spack.config
import spack.deptypes as dt
import spack.environment as ev
@ -48,6 +47,7 @@
import spack.version as vn
import spack.version.git_ref_lookup
from spack import traverse
from spack.spec import ArchSpec, CompilerSpec
from .core import (
AspFunction,
@ -66,6 +66,8 @@
from .requirements import RequirementKind, RequirementParser, RequirementRule
from .version_order import concretization_version_order
CHECK_COMPILER_EXISTENCE = True
GitOrStandardVersion = Union[spack.version.GitVersion, spack.version.StandardVersion]
TransformFunction = Callable[["spack.spec.Spec", List[AspFunction]], List[AspFunction]]
@ -3103,7 +3105,6 @@ def with_input_specs(self, input_specs: List["spack.spec.Spec"]) -> "CompilerPar
Args:
input_specs: specs to be concretized
"""
strict = spack.concretize.CHECK_COMPILER_EXISTENCE
default_os = str(spack.platforms.host().default_os)
default_target = str(archspec.cpu.host().family)
for s in traverse.traverse_nodes(input_specs):
@ -3117,8 +3118,8 @@ def with_input_specs(self, input_specs: List["spack.spec.Spec"]) -> "CompilerPar
continue
# Error when a compiler is not found and strict mode is enabled
if strict:
raise spack.concretize.UnavailableCompilerVersionError(s.compiler)
if CHECK_COMPILER_EXISTENCE:
raise UnavailableCompilerVersionError(s.compiler)
# Make up a compiler matching the input spec. This is for bootstrapping.
compiler_cls = spack.compilers.class_for_compiler_name(s.compiler.name)
@ -4012,6 +4013,22 @@ def _specs_from_environment_included_concrete(env, included_concrete):
return []
@contextmanager
def disable_compiler_existence_check():
global CHECK_COMPILER_EXISTENCE
CHECK_COMPILER_EXISTENCE, saved = False, CHECK_COMPILER_EXISTENCE
yield
CHECK_COMPILER_EXISTENCE = saved
@contextmanager
def enable_compiler_existence_check():
global CHECK_COMPILER_EXISTENCE
CHECK_COMPILER_EXISTENCE, saved = True, CHECK_COMPILER_EXISTENCE
yield
CHECK_COMPILER_EXISTENCE = saved
class ReuseStrategy(enum.Enum):
ROOTS = enum.auto()
DEPENDENCIES = enum.auto()
@ -4295,3 +4312,20 @@ def __init__(self, provided, conflicts):
class InvalidSpliceError(spack.error.SpackError):
"""For cases in which the splice configuration is invalid."""
class UnavailableCompilerVersionError(spack.error.SpackError):
"""Raised when there is no available compiler that satisfies a
compiler spec."""
def __init__(self, compiler_spec: CompilerSpec, arch: Optional[ArchSpec] = None) -> None:
err_msg = f"No compilers with spec {compiler_spec} found"
if arch:
err_msg += f" for operating system {arch.os} and target {arch.target}."
super().__init__(
err_msg,
"Run 'spack compiler find' to add compilers or "
"'spack compilers' to see which compilers are already recognized"
" by spack.",
)

View File

@ -11,6 +11,7 @@
import spack.concretize
import spack.operating_systems
import spack.platforms
import spack.solver.asp
from spack.spec import ArchSpec, Spec
@ -133,6 +134,6 @@ def test_concretize_target_ranges(root_target_range, dep_target_range, result, m
spec = Spec(
f"pkg-a %gcc@10 foobar=bar target={root_target_range} ^pkg-b target={dep_target_range}"
)
with spack.concretize.disable_compiler_existence_check():
with spack.solver.asp.disable_compiler_existence_check():
spec = spack.concretize.concretized(spec)
assert spec.target == spec["pkg-b"].target == result

View File

@ -348,11 +348,11 @@ def test_concretize_with_restricted_virtual(self):
assert concrete["mpich2"].satisfies("mpich2@1.3.1:1.4")
def test_concretize_enable_disable_compiler_existence_check(self):
with spack.concretize.enable_compiler_existence_check():
with pytest.raises(spack.concretize.UnavailableCompilerVersionError):
with spack.solver.asp.enable_compiler_existence_check():
with pytest.raises(spack.solver.asp.UnavailableCompilerVersionError):
check_concretize("dttop %gcc@=100.100")
with spack.concretize.disable_compiler_existence_check():
with spack.solver.asp.disable_compiler_existence_check():
spec = check_concretize("dttop %gcc@=100.100")
assert spec.satisfies("%gcc@100.100")
assert spec["dtlink3"].satisfies("%gcc@100.100")
@ -723,9 +723,9 @@ def test_concretize_propagate_variant_second_level_dep_not_in_source(self):
def test_no_matching_compiler_specs(self, mock_low_high_config):
# only relevant when not building compilers as needed
with spack.concretize.enable_compiler_existence_check():
with spack.solver.asp.enable_compiler_existence_check():
s = Spec("pkg-a %gcc@=0.0.0")
with pytest.raises(spack.concretize.UnavailableCompilerVersionError):
with pytest.raises(spack.solver.asp.UnavailableCompilerVersionError):
s = spack.concretize.concretized(s)
def test_no_compilers_for_arch(self):
@ -951,7 +951,7 @@ def test_adjusting_default_target_based_on_compiler(
):
best_achievable = archspec.cpu.TARGETS[best_achievable]
expected = best_achievable if best_achievable < current_host else current_host
with spack.concretize.disable_compiler_existence_check():
with spack.solver.asp.disable_compiler_existence_check():
s = spack.concretize.concretized(Spec(spec))
assert str(s.architecture.target) == str(expected)
@ -966,7 +966,7 @@ def test_compiler_version_matches_any_entry_in_compilers_yaml(self):
)
# This compiler does not exist
with pytest.raises(spack.concretize.UnavailableCompilerVersionError):
with pytest.raises(spack.solver.asp.UnavailableCompilerVersionError):
spack.concretize.concretized(Spec("mpileaks %gcc@=10.2"))
def test_concretize_anonymous(self):

View File

@ -7,8 +7,8 @@
import spack.compilers
import spack.spec
from spack.concretize import UnavailableCompilerVersionError
from spack.solver import asp
from spack.solver.asp import UnavailableCompilerVersionError
class TestCompilerParser: