-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a "sticky" property to variants #28630
Conversation
The concretizer thus is not free to pick an arbitrary value to work | ||
around conflicts, but will error out instead. | ||
Setting this property on a variant is useful in cases where the | ||
variant allows some dangerous or controversial options (e.g. using unsupported versions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not very dangerous, is it? It's more about enforcing pedantic rules by default, but still allowing the user to opt out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's useful when the variant can be dangerous, not that making it sticky is dangerous
Should it also be tested that packages.yaml values for sticky variants are still preferences, not constraints? E.g. prefer |
@haampie Settings in |
def test_sticky_variant_accounts_for_packages_yaml(self): | ||
with spack.config.override( | ||
'packages:sticky-variant', { | ||
'variants': '+allow-gcc' | ||
} | ||
): | ||
s = Spec('sticky-variant %gcc').concretized() | ||
assert s.satisfies('%gcc') and s.satisfies('+allow-gcc') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test checks that we account for packages.yaml
to override the default in package.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I meant the other way around.
In my understanding packages.yaml specifies preferences, whereas the abstract spec input specifies constraints.
Now suppose the expressed preference in packages.yaml for the value of a sticky variant would be unsatisfiable, then I would find it consistent if the value toggled back.
So:
class MyPkg:
variant('x', default=False, sticky=True)
conflicts('+x')
packages:
mypkg:
variants: '+x'
should concretize to ~x
instead of failing?
The reason being: (a) the stickiness applies to the particular variant default value the package author sets, and (b) if we later add support for discriminating between hard constraints in packages.yaml vs soft preferences (as we currently only have), it'd be consistent if everything in packages.yaml remains a preference until then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stickiness applies to the variant, packages.yaml can override the default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, then I'll stop saying packages.yaml specifies preferences 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I share some of @haampie's concerns here. In all other cases, packages.yaml is a soft preference, I'm not sure it's intuitive that it becomes a hard preference for sticky variants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So here's how I see it:
- The preference is due to the fact that
packages.yaml
overrides the default inpackage.py
(even when the variant is not sticky) - If the variant is sticky the default value cannot be changed by clingo
The claim in point 1. follows by:
spack/lib/spack/spack/solver/concretize.lp
Lines 485 to 501 in bae2a26
% The default value for a variant in a package is what is prescribed: | |
% | |
% 1. On the command line | |
% 2. In packages.yaml (if there's no command line settings) | |
% 3. In the package.py file (if there are no settings in | |
% packages.yaml and the command line) | |
% | |
variant_default_value(Package, Variant, Value) | |
:- variant_default_value_from_package_py(Package, Variant, Value), | |
not variant_default_value_from_packages_yaml(Package, Variant, _), | |
not variant_default_value_from_cli(Package, Variant, _). | |
variant_default_value(Package, Variant, Value) | |
:- variant_default_value_from_packages_yaml(Package, Variant, Value), | |
not variant_default_value_from_cli(Package, Variant, _). | |
variant_default_value(Package, Variant, Value) :- variant_default_value_from_cli(Package, Variant, Value). |
Furthermore, if we use the semantics currently proposed here the variant can be sticky whether the packager selects the "permissive" or the "restrictive" behavior as a default in package.py
. Think of having:
variant('allow-all-compilers', default=True, sticky=True)
I might want to say:
packages:
foo:
variants: ~allow-all-compilers
to prefer the restrictive default. With the semantic you propose instead that would be impossible from packages.yaml
(if the permissive semantics is the default in package.py
clingo would be happy to switch it in case I try to reset it in packages.yaml
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see what @haampie is saying... kind of. I'm having a hard time coming up with a use case for the soft preference for a sticky variant, though. It seems inconsistent to me that if the variant is sticky, and you override it, that it would not still be sticky. I've always thought of packages.yaml
as overriding preferences and not semantics.
Do you have a use case for preference semantics for sticky variants @haampie?
With the hard constraints we are proposing in #27987, you'd be able to do:
packages:
all:
require:[+allow-all-compilers]
So we could wait for that.
I do think people will be very confused when they set the value for a sticky variant the current way, and it's no longer sticky when they do that. Also, I can't tell if @haampie expects the soft preferences to only fall back to the sticky default, or if he wants all options to be open to the concretizer once you specify a package preference for a sticky variant.
Personally I think sticky variants always being sticky is fine, because if the user wants soft preference semantics for them in packages.yaml
, they can put a list of values instead of a single value. I wouldn't say that for regular variants, because I don't expect the user to list out all values of all variants. But I think it's more intuitive to me if the stickiness is preserved. You have to know the semantics of other variants to use them... why are these different?
But maybe a use case could convince me otherwise?
2983fcf
to
97020e2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @haampie's concern is the main issue going forward with this.
def test_sticky_variant_accounts_for_packages_yaml(self): | ||
with spack.config.override( | ||
'packages:sticky-variant', { | ||
'variants': '+allow-gcc' | ||
} | ||
): | ||
s = Spec('sticky-variant %gcc').concretized() | ||
assert s.satisfies('%gcc') and s.satisfies('+allow-gcc') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I share some of @haampie's concerns here. In all other cases, packages.yaml is a soft preference, I'm not sure it's intuitive that it becomes a hard preference for sticky variants
@corbett5 I have seen your comment in #26721 In case you want to try this PR to leave feedback, it should solve the issues seen in #19736 with packages:
cuda:
variants: '+allow-unsupported-compilers' to your |
* Add sticky variants * Add unit tests for sticky variants * Add documentation for sticky variants * Revert "Revert 19736 because conflicts are avoided by clingo by default (spack#26721)" This reverts commit 33ef7d5. * Add stickiness to "allow-unsupported-compiler"
* Add sticky variants * Add unit tests for sticky variants * Add documentation for sticky variants * Revert "Revert 19736 because conflicts are avoided by clingo by default (spack#26721)" This reverts commit 33ef7d5. * Add stickiness to "allow-unsupported-compiler"
* Add sticky variants * Add unit tests for sticky variants * Add documentation for sticky variants * Revert "Revert 19736 because conflicts are avoided by clingo by default (spack#26721)" This reverts commit 33ef7d5. * Add stickiness to "allow-unsupported-compiler"
* Add sticky variants * Add unit tests for sticky variants * Add documentation for sticky variants * Revert "Revert 19736 because conflicts are avoided by clingo by default (spack#26721)" This reverts commit 33ef7d5. * Add stickiness to "allow-unsupported-compiler"
* Add a "sticky" property to variants (spack#28630) * cuda, nvhpc: update recipes from upstream/develop. * nvhpc: deploy 22.3, drop 21.2 and 22.1 * cuda: deploy 11.6.1 to match nvhpc 22.3 * py-pytorch: update patch checksum. Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
Refers to #19736
Refers to #26721
This PR adds a new
sticky
argument to the variant directive. The argument is set toFalse
by default, in which case the semantics of variants during concretization is the usual one. If set toTrue
the variant being marked sticky cannot be changed byclingo
during concretization and will either be set to:package.py
or inpackages.yaml
Modifications:
sticky
argument to the variant directivesticky
allow-unsupported-compiler
sticky