summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/solver/asp.py4
-rw-r--r--lib/spack/spack/solver/concretize.lp45
-rw-r--r--lib/spack/spack/solver/display.lp4
-rw-r--r--lib/spack/spack/test/concretize.py11
-rw-r--r--var/spack/repos/builtin.mock/packages/conditional-virtual-dependency/package.py15
-rw-r--r--var/spack/repos/builtin.mock/packages/transitive-conditional-virtual-dependency/package.py12
6 files changed, 56 insertions, 35 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index f0f2b410e8..da24486c5c 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -634,7 +634,7 @@ class PyclingoDriver(object):
# With a grounded program, we can run the solve.
result = Result()
- models = [] # stable moodels if things go well
+ models = [] # stable models if things go well
cores = [] # unsatisfiable cores if they do not
def on_model(model):
@@ -973,7 +973,7 @@ class SpackSolverSetup(object):
continue
for i, provider in enumerate(providers):
- func(vspec, provider, i)
+ func(vspec, provider, i + 10)
def provider_defaults(self):
self.gen.h2("Default virtual providers")
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index baf1c5239f..b27b80dc6e 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -57,10 +57,11 @@ provider(Package, Virtual)
:- node(Package), provides_virtual(Package, Virtual).
% for any virtual, there can be at most one provider in the DAG
-0 { provider(Package, Virtual) : node(Package) } 1 :- virtual(Virtual).
+0 { provider(Package, Virtual) :
+ node(Package), provides_virtual(Package, Virtual) } 1 :- virtual(Virtual).
% give dependents the virtuals they want
-provider_weight(Dependency, -10)
+provider_weight(Dependency, 0)
:- virtual(Virtual), depends_on(Package, Dependency),
provider(Dependency, Virtual),
external(Dependency).
@@ -84,6 +85,7 @@ provider_weight(Dependency, 100)
:- virtual(Virtual),
provider(Dependency, Virtual),
depends_on(Package, Dependency),
+ not external(Dependency),
not pkg_provider_preference(Package, Virtual, Dependency, _),
not default_provider_preference(Virtual, Dependency, _).
@@ -355,37 +357,27 @@ node_compiler_version(Package, Compiler, Version) :- node_compiler_version_hard(
not compiler_supports_os(Compiler, Version, OS),
not allow_compiler(Compiler, Version).
-% dependencies imply we should try to match hard compiler constraints
-% todo: look at what to do about intersecting constraints here. we'd
-% ideally go with the "lowest" pref in the DAG
-node_compiler_match_pref(Package, Compiler)
- :- node_compiler_hard(Package, Compiler).
-node_compiler_match_pref(Dependency, Compiler)
- :- depends_on(Package, Dependency),
- node_compiler_match_pref(Package, Compiler),
- not node_compiler_hard(Dependency, _).
-compiler_match(Package, 1)
- :- node_compiler(Package, Compiler),
- node_compiler_match_pref(Package, Compiler).
-
% If the compiler is what was prescribed from command line etc.
% or is the same as a root node, there is a version match
-% Compiler prescribed from command line
+% Compiler prescribed in the root spec
node_compiler_version_match_pref(Package, Compiler, V)
:- node_compiler_hard(Package, Compiler),
- node_compiler_version(Package, Compiler, V).
+ node_compiler_version(Package, Compiler, V),
+ not external(Package).
-% Compiler inherited from a root node
+% Compiler inherited from a parent node
node_compiler_version_match_pref(Dependency, Compiler, V)
:- depends_on(Package, Dependency),
node_compiler_version_match_pref(Package, Compiler, V),
+ node_compiler_version(Dependency, Compiler, V),
not node_compiler_hard(Dependency, Compiler).
% Compiler inherited from the root package
node_compiler_version_match_pref(Dependency, Compiler, V)
:- depends_on(Package, Dependency),
node_compiler_version(Package, Compiler, V), root(Package),
+ node_compiler_version(Dependency, Compiler, V),
not node_compiler_hard(Dependency, Compiler).
compiler_version_match(Package, 1)
@@ -516,25 +508,18 @@ root(Dependency, 1) :- not root(Dependency), node(Dependency).
: provider_weight(Provider, Weight), root(Provider)
}.
-% Next, we want to minimize:
-% 1. The weights of the providers
-% 2. The version weight of the providers
-% i.e. use as much as possible the most preferred
-% providers at latest versions
+% Next, we want to minimize the weights of the providers
+% i.e. use as much as possible the most preferred providers
#minimize{
Weight@11,Provider
: provider_weight(Provider, Weight), not root(Provider)
}.
-#minimize{
- Weight@10,Provider
- : provider_weight(Provider, _), version_weight(Provider, Weight)
-}.
% For external packages it's more important than for others
-% to match the compiler
-#minimize{
+% to match the compiler with their parent node
+#maximize{
Weight@10,Package
- : compiler_weight(Package, Weight), external(Package)
+ : compiler_version_match(Package, Weight), external(Package)
}.
% Then try to use as much as possible:
diff --git a/lib/spack/spack/solver/display.lp b/lib/spack/spack/solver/display.lp
index 40f6acdb05..22642e2602 100644
--- a/lib/spack/spack/solver/display.lp
+++ b/lib/spack/spack/solver/display.lp
@@ -17,12 +17,10 @@
#show node_flag_source/2.
#show no_flags/2.
-
-
#show variant_not_default/4.
#show provider_weight/2.
#show version_weight/2.
-#show compiler_match/2.
+#show compiler_version_match/2.
#show compiler_weight/2.
#show node_target_match/2.
#show node_target_weight/2.
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 496153aab6..761641035f 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -872,3 +872,14 @@ class TestConcretize(object):
assert s.external
assert 'stuff' not in s
+
+ def test_transitive_conditional_virtual_dependency(self):
+ s = Spec('transitive-conditional-virtual-dependency').concretized()
+
+ # The default for conditional-virtual-dependency is to have
+ # +stuff~mpi, so check that these defaults are respected
+ assert '+stuff' in s['conditional-virtual-dependency']
+ assert '~mpi' in s['conditional-virtual-dependency']
+
+ # 'stuff' is provided by an external package, so check it's present
+ assert 'externalvirtual' in s
diff --git a/var/spack/repos/builtin.mock/packages/conditional-virtual-dependency/package.py b/var/spack/repos/builtin.mock/packages/conditional-virtual-dependency/package.py
new file mode 100644
index 0000000000..8cfbfa0c1a
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/conditional-virtual-dependency/package.py
@@ -0,0 +1,15 @@
+# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+class ConditionalVirtualDependency(Package):
+ """Brings in a virtual dependency if certain conditions are met."""
+ homepage = "https://dev.null"
+
+ version('1.0')
+
+ variant('stuff', default=True, description='nope')
+ variant('mpi', default=False, description='nope')
+
+ depends_on('stuff', when='+stuff')
+ depends_on('mpi', when='+mpi')
diff --git a/var/spack/repos/builtin.mock/packages/transitive-conditional-virtual-dependency/package.py b/var/spack/repos/builtin.mock/packages/transitive-conditional-virtual-dependency/package.py
new file mode 100644
index 0000000000..9b1b66df7f
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/transitive-conditional-virtual-dependency/package.py
@@ -0,0 +1,12 @@
+# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+class TransitiveConditionalVirtualDependency(Package):
+ """Depends on a package with a conditional virtual dependency."""
+ homepage = "https://dev.null"
+ has_code = False
+ phases = []
+
+ version('1.0')
+ depends_on('conditional-virtual-dependency')