Compare commits
1 Commits
v0.19.0
...
minimal-co
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3985b307a1 |
@@ -15,22 +15,38 @@ concretizer:
|
||||
# as possible, rather than building. If `false`, we'll always give you a fresh
|
||||
# concretization.
|
||||
reuse: true
|
||||
|
||||
# If `true`, Spack will consider minimizing builds its *topmost* priority.
|
||||
# Note that this can result in weird package configurations. In particular,
|
||||
# Spack will disable variants and might downgrade versions to avoid building
|
||||
# new packages for an install. By default, Spack respects defaults from
|
||||
# packages and preferences *before* minimizing the number of builds.
|
||||
#
|
||||
# Example for intuition: `cmake` can optionally build without openssl, but
|
||||
# it's enabled by default because many builds use that functionality. Using
|
||||
# `minimal: true` will build `cmake~openssl` unless the user asks for
|
||||
# `cmake+openssl` explicitly.
|
||||
minimal: false
|
||||
|
||||
# Options that tune which targets are considered for concretization. The
|
||||
# concretization process is very sensitive to the number targets, and the time
|
||||
# needed to reach a solution increases noticeably with the number of targets
|
||||
# considered.
|
||||
targets:
|
||||
|
||||
# Determine whether we want to target specific or generic microarchitectures.
|
||||
# An example of the first kind might be for instance "skylake" or "bulldozer",
|
||||
# while generic microarchitectures are for instance "aarch64" or "x86_64_v4".
|
||||
granularity: microarchitectures
|
||||
|
||||
# If "false" allow targets that are incompatible with the current host (for
|
||||
# instance concretize with target "icelake" while running on "haswell").
|
||||
# If "true" only allow targets that are compatible with the host.
|
||||
host_compatible: true
|
||||
|
||||
# When "true" concretize root specs of environments together, so that each unique
|
||||
# package in an environment corresponds to one concrete spec. This ensures
|
||||
# environments can always be activated. When "false" perform concretization separately
|
||||
# on each root spec, allowing different versions and variants of the same package in
|
||||
# an environment.
|
||||
unify: false
|
||||
unify: false
|
||||
|
@@ -380,6 +380,11 @@ def add_concretizer_args(subparser):
|
||||
const=False, default=None,
|
||||
help='do not reuse installed deps; build newest configuration'
|
||||
)
|
||||
subgroup.add_argument(
|
||||
'--minimal', action=ConfigSetAction, dest="concretizer:minimal",
|
||||
const=True, default=None,
|
||||
help='minimize builds (disables default variants, may choose older versions)'
|
||||
)
|
||||
subgroup.add_argument(
|
||||
'--reuse', action=ConfigSetAction, dest="concretizer:reuse",
|
||||
const=True, default=None,
|
||||
|
@@ -15,6 +15,7 @@
|
||||
'additionalProperties': False,
|
||||
'properties': {
|
||||
'reuse': {'type': 'boolean'},
|
||||
'minimal': {'type': 'boolean'},
|
||||
'targets': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
|
@@ -654,7 +654,7 @@ def stringify(x):
|
||||
class SpackSolverSetup(object):
|
||||
"""Class to set up and run a Spack concretization solve."""
|
||||
|
||||
def __init__(self, reuse=False, tests=False):
|
||||
def __init__(self, reuse=None, minimal=None, tests=False):
|
||||
self.gen = None # set by setup()
|
||||
|
||||
self.declared_versions = {}
|
||||
@@ -679,10 +679,11 @@ def __init__(self, reuse=False, tests=False):
|
||||
# Caches to optimize the setup phase of the solver
|
||||
self.target_specs_cache = None
|
||||
|
||||
# whether to add installed/binary hashes to the solve
|
||||
self.reuse = reuse
|
||||
|
||||
# whether to add installed/binary hashes to the solve
|
||||
# Solver paramters that affect setup -- see Solver documentation
|
||||
self.reuse = spack.config.get(
|
||||
"concretizer:reuse", False) if reuse is None else reuse
|
||||
self.minimal = spack.config.get(
|
||||
"concretizer:minimal", False) if minimal is None else minimal
|
||||
self.tests = tests
|
||||
|
||||
def pkg_version_rules(self, pkg):
|
||||
@@ -827,7 +828,7 @@ def package_compiler_defaults(self, pkg):
|
||||
pkg.name, cspec.name, cspec.version, -i * 100
|
||||
))
|
||||
|
||||
def pkg_rules(self, pkg, tests):
|
||||
def pkg_rules(self, pkg):
|
||||
pkg = packagize(pkg)
|
||||
|
||||
# versions
|
||||
@@ -1809,10 +1810,14 @@ def setup(self, driver, specs):
|
||||
self.gen.h1("Concrete input spec definitions")
|
||||
self.define_concrete_input_specs(specs, possible)
|
||||
|
||||
self.gen.h1("Concretizer options")
|
||||
if self.reuse:
|
||||
self.gen.fact(fn.optimize_for_reuse())
|
||||
if self.minimal:
|
||||
self.gen.fact(fn.minimal_installs())
|
||||
|
||||
if self.reuse:
|
||||
self.gen.h1("Installed packages")
|
||||
self.gen.fact(fn.optimize_for_reuse())
|
||||
self.gen.newline()
|
||||
self.define_installed_packages(specs, possible)
|
||||
|
||||
self.gen.h1('General Constraints')
|
||||
@@ -1833,7 +1838,7 @@ def setup(self, driver, specs):
|
||||
self.gen.h1('Package Constraints')
|
||||
for pkg in sorted(pkgs):
|
||||
self.gen.h2('Package rules: %s' % pkg)
|
||||
self.pkg_rules(pkg, tests=self.tests)
|
||||
self.pkg_rules(pkg)
|
||||
self.gen.h2('Package preferences: %s' % pkg)
|
||||
self.preferred_variants(pkg)
|
||||
self.preferred_targets(pkg)
|
||||
@@ -2191,6 +2196,10 @@ class Solver(object):
|
||||
``reuse (bool)``
|
||||
Whether to try to reuse existing installs/binaries
|
||||
|
||||
``minimal (bool)``
|
||||
If ``True`` make minimizing nodes the top priority, even higher
|
||||
than defaults from packages and preferences.
|
||||
|
||||
"""
|
||||
def __init__(self):
|
||||
self.driver = PyclingoDriver()
|
||||
@@ -2198,6 +2207,7 @@ def __init__(self):
|
||||
# These properties are settable via spack configuration, and overridable
|
||||
# by setting them directly as properties.
|
||||
self.reuse = spack.config.get("concretizer:reuse", False)
|
||||
self.minimal = spack.config.get("concretizer:minimal", False)
|
||||
|
||||
def solve(
|
||||
self,
|
||||
@@ -2228,7 +2238,7 @@ def solve(
|
||||
continue
|
||||
spack.spec.Spec.ensure_valid_variants(s)
|
||||
|
||||
setup = SpackSolverSetup(reuse=self.reuse, tests=tests)
|
||||
setup = SpackSolverSetup(reuse=self.reuse, minimal=self.minimal, tests=tests)
|
||||
return self.driver.solve(
|
||||
setup,
|
||||
specs,
|
||||
|
@@ -962,26 +962,36 @@ impose(Hash) :- hash(Package, Hash).
|
||||
% if we haven't selected a hash for a package, we'll be building it
|
||||
build(Package) :- not hash(Package, _), node(Package).
|
||||
|
||||
% Minimizing builds is tricky. We want a minimizing criterion
|
||||
|
||||
% because we want to reuse what is avaialble, but
|
||||
% we also want things that are built to stick to *default preferences* from
|
||||
% the package and from the user. We therefore treat built specs differently and apply
|
||||
% a different set of optimization criteria to them. Spack's *first* priority is to
|
||||
% reuse what it *can*, but if it builds something, the built specs will respect
|
||||
% defaults and preferences. This is implemented by bumping the priority of optimization
|
||||
% criteria for built specs -- so that they take precedence over the otherwise
|
||||
% topmost-priority criterion to reuse what is installed.
|
||||
% Minimizing builds is tricky. We want a minimizing criterion because we want to reuse
|
||||
% what is avaialble, but we also want things that are built to stick to *default
|
||||
% preferences* from the package and from the user. We therefore treat built specs
|
||||
% differently and apply a different set of optimization criteria to them. Spack's first
|
||||
% priority is to reuse what it can, but if it builds something, the built specs will
|
||||
% respect defaults and preferences.
|
||||
%
|
||||
% This is implemented by bumping the priority of optimization criteria for built specs
|
||||
% -- so that they take precedence over the otherwise topmost-priority criterion to reuse
|
||||
% what is installed.
|
||||
%
|
||||
% If the user explicitly asks for *minimal* installs, we don't differentiate between
|
||||
% built and reused specs - the top priority is just minimizing builds.
|
||||
%
|
||||
% The priority ranges are:
|
||||
% 200+ Shifted priorities for build nodes; correspond to priorities 0 - 99.
|
||||
% 100 - 199 Unshifted priorities. Currently only includes minimizing #builds.
|
||||
% 0 - 99 Priorities for non-built nodes.
|
||||
build_priority(Package, 200) :- build(Package), node(Package), optimize_for_reuse().
|
||||
build_priority(Package, 0) :- not build(Package), node(Package), optimize_for_reuse().
|
||||
build_priority(Package, 200) :- node(Package), build(Package), optimize_for_reuse(),
|
||||
not minimal_installs().
|
||||
build_priority(Package, 0) :- node(Package), not build(Package), optimize_for_reuse().
|
||||
|
||||
% don't adjust build priorities if reuse is not enabled
|
||||
% Don't adjust build priorities if reusing, or if doing minimal installs
|
||||
% With minimal, minimizing builds is the TOP priority
|
||||
build_priority(Package, 0) :- node(Package), not optimize_for_reuse().
|
||||
build_priority(Package, 0) :- node(Package), minimal_installs().
|
||||
|
||||
% Minimize builds with both --reuse and with --minimal
|
||||
minimize_builds() :- optimize_for_reuse().
|
||||
minimize_builds() :- minimal_installs().
|
||||
|
||||
% don't assign versions from installed packages unless reuse is enabled
|
||||
% NOTE: that "installed" means the declared version was only included because
|
||||
@@ -1000,6 +1010,7 @@ build_priority(Package, 0) :- node(Package), not optimize_for_reuse().
|
||||
not optimize_for_reuse().
|
||||
|
||||
#defined installed_hash/2.
|
||||
#defined minimal_installs/0.
|
||||
|
||||
%-----------------------------------------------------------------
|
||||
% Optimization to avoid errors
|
||||
@@ -1029,7 +1040,7 @@ build_priority(Package, 0) :- node(Package), not optimize_for_reuse().
|
||||
% Try hard to reuse installed packages (i.e., minimize the number built)
|
||||
opt_criterion(100, "number of packages to build (vs. reuse)").
|
||||
#minimize { 0@100: #true }.
|
||||
#minimize { 1@100,Package : build(Package), optimize_for_reuse() }.
|
||||
#minimize { 1@100,Package : build(Package), minimize_builds() }.
|
||||
#defined optimize_for_reuse/0.
|
||||
|
||||
% Minimize the number of deprecated versions being used
|
||||
|
@@ -120,11 +120,19 @@ def test_concretizer_arguments(mutable_config, mock_packages):
|
||||
spec = spack.main.SpackCommand("spec")
|
||||
|
||||
assert spack.config.get("concretizer:reuse", None) is None
|
||||
assert spack.config.get("concretizer:minimal", None) is None
|
||||
|
||||
spec("--reuse", "zlib")
|
||||
|
||||
assert spack.config.get("concretizer:reuse", None) is True
|
||||
assert spack.config.get("concretizer:minimal", None) is None
|
||||
|
||||
spec("--fresh", "zlib")
|
||||
|
||||
assert spack.config.get("concretizer:reuse", None) is False
|
||||
assert spack.config.get("concretizer:minimal", None) is None
|
||||
|
||||
spec("--minimal", "zlib")
|
||||
|
||||
assert spack.config.get("concretizer:reuse", None) is False
|
||||
assert spack.config.get("concretizer:minimal", None) is True
|
||||
|
Reference in New Issue
Block a user