Skip to content

Configure requirements for a package#27987

Merged
scheibelp merged 75 commits intospack:developfrom
scheibelp:features/config-required-versions
Aug 16, 2022
Merged

Configure requirements for a package#27987
scheibelp merged 75 commits intospack:developfrom
scheibelp:features/config-required-versions

Conversation

@scheibelp
Copy link
Copy Markdown
Member

@scheibelp scheibelp commented Dec 14, 2021

Spack doesn't have an easy way to say something like "If I build package X, then I want need version Y":

  • If you specify something on the command line, then you ensure that the constraints are applied, but the package is always built
    • Likewise if you spack add X... to your environment, the constraints are guaranteed to hold, but the environment always builds the package
  • Conversely, you can add preferences to packages.yaml, but these are not guaranteed (Spack can choose other settings)

For example, you might want to specify that when you build openmpi, that you build @4.0.1: you want to allow building with other specs, but always use @4.0.1 if building openmpi.

This PR adds ASP rules (and logic to asp.py) which can generate conditional constraints. My current guess is that it should be "consolidated" with asp_spec_clauses (or rather, that function should be made more generic to support this case). (EDIT: this last part is now addressed)

(Update from Jan) The schema for expressing this is a new packages.yaml section:

packages:
  zlib:
    require: '@1.2.12'                             # Only zlib 1.2.12 can be used
  libpng:
    require:
    - one_of: ['%[email protected]', '%[email protected]']       # libpng can only build with one of these two compilers
    - one_of: ["@versionx", "@versiony"]

For any given <package> subsection, you can now add a require subsection, where you can add demands for the spec. The details you add there must be respected by Spack (i.e. it will either match the spec there, or fail to concretize).

TODOs:

  • This will require updating the YAML schema in packages.yaml (or some config file). (EDIT 1/7/22: that is now done) For now, since I'm experimenting with the ASP rules, I am manually generating what would be parsed from the config
  • Tests

@scheibelp scheibelp added the WIP label Dec 14, 2021
…s (so I don't need to redefine individual constraints for version, compiler, etc.)
…ill be that multiple specs in a group can still match since the spec matching doesn't imply cfg_required (only the other way around)
@scheibelp
Copy link
Copy Markdown
Member Author

At this point concretize.lp is sufficiently simple, and #27987 (comment) proposes a schema structure. So @tgamblin @becker33 if that seems agreeable I can update the schema validation and tests.

@scheibelp
Copy link
Copy Markdown
Member Author

This now

  • Implements the schema discussed in Configure requirements for a package #27987 (comment) (currently there are examples placed in a test-cfgs/ directory which will be updated to unit tests
  • Implements preferences for condition groups (for a set of specs in a one_of specification, the earlier ones are preferred)
    • I still don't fully understand some of the logic around minimization (e.g. why do most of the minimization criteria have a build_priority - what is that?)

@scheibelp
Copy link
Copy Markdown
Member Author

@becker33 this appears to be passing unit tests and I have mostly addressed #27987 (review) minus a couple issues I have questions about:

  • I added preference weighting for conditions in condition groups, but wasn't sure about some of the mechanisms used to control/influence that like build_priority
  • There was a request that member_id and stanza_id (now condition_group_id) be consolidated in Configure requirements for a package #27987 (comment) but I didn't think that was possible (which I explained in my response to that comment)

This still needs tests, but I wanted to make sure we agreed on the schema (now added with examples) and overall implementation first.

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Jan 8, 2022

@scheibelp:

I still don't fully understand some of the logic around minimization (e.g. why do most of the minimization criteria have a build_priority - what is that?)

See the explanation here: abda8a4

If reuse is enabled, build_priority is set to some number greater than the number of optimization criteria, and it gets added to the priority of each criterion for packages that will be built. So if a package is to be built, we prioritize its defaults higher than minimizing the total number of builds. If a package is being reused and it satisfies any other imposed constraints, we prefer to take it as-is than to force its variants, versions, etc. to be the preferred/default ones.

For some intuition: if you don’t do this, and instead make minimizing total builds the absolute top priority, then if you have to build, say, CMake, then the solver will disable variants on the new CMake to reduce the total dependencies. E.g. it’ll give you a CMake without openssl and with other optional but still default features disabled. This is different than what a typical spack install cmake would do. build_priority ensures that new builds act more like typical spack installs when reuse is enabled.

@scheibelp
Copy link
Copy Markdown
Member Author

scheibelp commented Aug 12, 2022

@alalazo I added scheibelp#21 here, added a test which reproduces #27987 (comment), and fixed it in 1d733af

That commit however breaks reuse tests that check that you can reuse a package installation when the underlying package.py is changed (e.g. test_reuse_installed_packages_when_package_def_changes), so I'd need to investigate this more tomorrow/Monday.

@scheibelp
Copy link
Copy Markdown
Member Author

I don't think 1d733af makes sense (or at least, it doesn't seem like it should be necessary to enforce the constraints we want). The test should still be useful (I'll be using it to debug the issue with "one_of").

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Aug 12, 2022

I don't think 1d733af makes sense (or at least, it doesn't seem like it should be necessary to enforce the constraints we want).

I agree. Concrete specs derive the impose(Hash) from the hash(Package, Hash) atom, which is a choice of clingo to pop into existence if possible. Abstract specs instead derive impose(ID) from the fact that condition_holds(ID), without any choice involved. I think we just need to reconstruct some intermediate atoms which are not in the answer set for concrete specs.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Aug 12, 2022

These modifications should fix the unit-tests and take care of #27987 (comment) : scheibelp#23

@spackbot-app spackbot-app bot added the documentation Improvements or additions to documentation label Aug 13, 2022
alalazo
alalazo previously approved these changes Aug 15, 2022
Copy link
Copy Markdown
Member

@tgamblin tgamblin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scheibelp this looks great -- thanks!

require: "@1.13.2"
openmpi:
require:
- any_of: ["~cuda", "gcc"]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- any_of: ["~cuda", "gcc"]
- any_of: ["~cuda", "%gcc"]

@haampie
Copy link
Copy Markdown
Member

haampie commented Aug 16, 2022

I'm afraid one_of/any_of can be somewhat confusing. Maybe what's missing is some docs on how to combine one_of/any_of with unconditional requirements, like always use @4:.

@scheibelp
Copy link
Copy Markdown
Member Author

Close/reopen to restart docs build

@scheibelp scheibelp closed this Aug 16, 2022
@scheibelp scheibelp reopened this Aug 16, 2022
@tgamblin
Copy link
Copy Markdown
Member

We should do a follow-on doc PR to address @haampie's concerns, but this LGTM.

@scheibelp scheibelp merged commit 8281a0c into spack:develop Aug 16, 2022
ma595 pushed a commit to ma595/spack that referenced this pull request Sep 13, 2022
)

Spack doesn't have an easy way to say something like "If I build
package X, then I *need* version Y":

* If you specify something on the command line, then you ensure
  that the constraints are applied, but the package is always built
* Likewise if you `spack add X...`` to your environment, the
  constraints are guaranteed to hold, but the environment always
  builds the package
* You can add preferences to packages.yaml, but these are not
  guaranteed to hold (Spack can choose other settings)

This commit adds a 'require' subsection to packages.yaml: the
specs added there are guaranteed to hold. The commit includes
documentation for the feature.

Co-authored-by: Massimiliano Culpo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core PR affects Spack core functionality dependencies documentation Improvements or additions to documentation new-variant new-version tests General test capability(ies)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants