Skip to content
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

Best effort co-concretization (iterative algorithm) #28941

Merged
merged 25 commits into from
May 24, 2022

Conversation

alalazo
Copy link
Member

@alalazo alalazo commented Feb 15, 2022

Use case description copied from #27964

Currently, environments can either be concretized fully together or fully separately. This works well for users who create environments for interoperable software and can use concretization: together. It does not allow environments with conflicting software to be concretized for maximal interoperability.

The primary use-case for this is facilities providing system software. Facilities provide multiple MPI implementations, but all software built against a given MPI ought to be interoperable.

This PR adds a concretization option together_where_possible. When this option is used, Spack will concretize specs in the environment separately, but will optimize for minimal differences in overlapping packages.

Implementation differences

The algorithm used here is greedy, since specs are computed in multiple rounds where clingo concretizes together as many input specs as possible. The gist of the algorithm is:

https://github.com/alalazo/spack/blob/f6420eaf6eb5e10a3e4d0b0a1a6c20e4404f92c1/lib/spack/spack/solver/asp.py#L2092-L2135

To relax the requirements on input specs and allow for not solving some of them we add a new indirection:

https://github.com/alalazo/spack/blob/f6420eaf6eb5e10a3e4d0b0a1a6c20e4404f92c1/lib/spack/spack/solver/asp.py#L1787-L1802

and we give clingo the choice to solve for the input literal or not. All the input specs computed in previous rounds are then reused in later rounds to ensure the environment is as contained as possible.

Comparison with #27964
When trying out the encoding in #27964 for production environments we saw that there were huge requests:

The solve-time can very likely be improved a lot by removing the symmetry of the new encoding with some artificial rules. The memory requests during the grounding phase instead will necessarily grow linearly with the number of PSIDs needed to solve the environment. That number is not known a-priori. It is capped by the number of specs in an environment (which is computationally unfeasible) but practically is usually much less. For instance, e4s has 119 specs and needs 3 process spaces to concretize.

This PR instead takes a greedy approach and perform N solves each with a single process space. It might give a different (and "suboptimal" i.e. with a number of subprocesses greater than strictly needed) result if compared with the encoding in #27964 but it is complete, i.e. if there is at least a solution the algorithm will not give a false negative. On the bright side, due to its greedy nature, it's much faster when solving for environments (e4s is solved in 3 rounds in ~1 min.).

@spackbot-app spackbot-app bot added commands environments gitlab Issues related to gitlab integration labels Feb 15, 2022
@alalazo alalazo force-pushed the features/iterative_coconcretization branch from 93ae2cd to 253a6ab Compare February 15, 2022 12:23
@alalazo
Copy link
Member Author

alalazo commented Feb 15, 2022

@becker33 @tgamblin e4s-pr-generate took just 2 mins and a single core using together_where_possible compared to 3mins. and 16 cores when we concretize separately.

@alalazo alalazo force-pushed the features/iterative_coconcretization branch from 253a6ab to 5edd66d Compare February 17, 2022 15:59
@spackbot-app spackbot-app bot added the tests General test capability(ies) label Feb 17, 2022
lib/spack/spack/cmd/solve.py Outdated Show resolved Hide resolved
lib/spack/spack/cmd/solve.py Outdated Show resolved Hide resolved
lib/spack/spack/solver/concretize.lp Outdated Show resolved Hide resolved
lib/spack/spack/test/concretize.py Outdated Show resolved Hide resolved
lib/spack/spack/solver/asp.py Outdated Show resolved Hide resolved
lib/spack/spack/solver/asp.py Outdated Show resolved Hide resolved
lib/spack/spack/solver/asp.py Outdated Show resolved Hide resolved
@alalazo alalazo force-pushed the features/iterative_coconcretization branch from 57864b7 to c1b872b Compare February 18, 2022 11:45
@alalazo alalazo force-pushed the features/iterative_coconcretization branch from 5aa3301 to d0a2c0f Compare February 22, 2022 09:22
@spackbot-app spackbot-app bot added the documentation Improvements or additions to documentation label Feb 22, 2022
@alalazo alalazo marked this pull request as ready for review February 22, 2022 11:43
Copy link
Member

@becker33 becker33 left a comment

Choose a reason for hiding this comment

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

One request, one idea

lib/spack/spack/cmd/solve.py Outdated Show resolved Hide resolved
Comment on lines +1420 to +1704
# The algorithm is greedy, and it might decide to solve the "best"
# spec early in which case reuse is suboptimal. In this case the most
# recent version of libdwarf is selected and concretized to libelf@0.8.13
(['libdwarf@20111030^libelf@0.8.10',
'libdwarf@20130207^libelf@0.8.12',
'libdwarf@20130729'], 'libelf@0.8.12', 1),
Copy link
Member

Choose a reason for hiding this comment

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

Could we improve this by having both root literals (the literals we already use) and dependency literals (explicitly mentioned dependencies of roots) and minimizing the unsolved dependency literals as well? I think that would cause us to concretize the most specific specs first, which would increase our odds of a more minimal build.

Copy link
Member Author

Choose a reason for hiding this comment

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

Adding a comment, following a discussion with @becker33 yesterday. We can do something very similar to this by adding weights during the setup phase for the literals that are solved. Then we can minimize the sum of the weights for reuse (currently weights are uniform and equal to 1 for each literal spec).

We can experiment with different ways of computing the weights in a separate PR.

@alalazo alalazo force-pushed the features/iterative_coconcretization branch from c1f062f to 7cebbff Compare February 25, 2022 08:12
@alalazo
Copy link
Member Author

alalazo commented Feb 25, 2022

@becker33 Pending unrelated errors in pipelines I think this is done.

@alalazo alalazo force-pushed the features/iterative_coconcretization branch from 7cebbff to 9e81c86 Compare February 28, 2022 13:21
becker33
becker33 previously approved these changes Feb 28, 2022
@alalazo
Copy link
Member Author

alalazo commented Mar 4, 2022

@becker33 Is this PR waiting further review before being merged?

@alalazo
Copy link
Member Author

alalazo commented Mar 14, 2022

@becker33 It's a mystery to me how @eugeneswalker (or more likely Github on his behalf) could dismiss your review with a commit that doesn't exist anymore, but can you please ✔️ again?

I rebased the PR to double check that everything is working correctly with #28673 in develop.

@eugeneswalker
Copy link
Contributor

@becker33 It's a mystery to me how @eugeneswalker (or more likely Github on his behalf) could dismiss your review with a commit that doesn't exist anymore, but can you please ✔️ again?

What da!?! I definitely didn't mean to do this, didn't even know about this PR. If anyone knows how this could happen...

@alalazo alalazo force-pushed the features/iterative_coconcretization branch from d2a1e49 to 543eb60 Compare March 18, 2022 08:29
@alalazo alalazo force-pushed the features/iterative_coconcretization branch from 3792d93 to 08bc55e Compare May 24, 2022 08:15
Spack v0.18.0 release automation moved this from Review in progress to Reviewer approved May 24, 2022
Separate Concretization for Build Dependencies automation moved this from Review in progress to Reviewer approved May 24, 2022
@becker33 becker33 merged commit f2a81af into spack:develop May 24, 2022
Spack v0.18.0 release automation moved this from Reviewer approved to Done May 24, 2022
Separate Concretization for Build Dependencies automation moved this from Reviewer approved to Done May 24, 2022
@alalazo alalazo deleted the features/iterative_coconcretization branch May 24, 2022 19:17
iarspider pushed a commit to iarspider/spack that referenced this pull request May 30, 2022
Currently, environments can either be concretized fully together or fully separately. This works well for users who create environments for interoperable software and can use `concretizer:unify:true`. It does not allow environments with conflicting software to be concretized for maximal interoperability.

The primary use-case for this is facilities providing system software. Facilities provide multiple MPI implementations, but all software built against a given MPI ought to be interoperable.

This PR adds a concretization option `concretizer:unify:when_possible`. When this option is used, Spack will concretize specs in the environment separately, but will optimize for minimal differences in overlapping packages.

* Add a level of indirection to root specs

This commit introduce the "literal" atom, which comes with
a few different "arities". The unary "literal" contains an
integer that id the ID of a spec literal. Other "literals"
contain information on the requests made by literal ID. For
instance zlib@1.2.11 generates the following facts:

literal(0,"root","zlib").
literal(0,"node","zlib").
literal(0,"node_version_satisfies","zlib","1.2.11").

This should help with solving large environments "together
where possible" since later literals can be now solved
together in batches.

* Add a mechanism to relax the number of literals being solved

* Modify spack solve to display the new criteria

Since the new criteria is above all the build criteria,
we need to modify the way we display the output.

Originally done by Greg in spack#27964 and cherry-picked
to this branch by the co-author of the commit.

Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>

* Inject reusable specs into the solve

Instead of coupling the PyclingoDriver() object with
spack.config, inject the concrete specs that can be
reused.

A method level function takes care of reading from
the store and the buildcache.

* spack solve: show output of multi-rounds

* add tests for best-effort coconcretization

* Enforce having at least a literal being solved

Co-authored-by: Greg Becker <becker33@llnl.gov>
bhatiaharsh pushed a commit to bhatiaharsh/spack that referenced this pull request Aug 8, 2022
Currently, environments can either be concretized fully together or fully separately. This works well for users who create environments for interoperable software and can use `concretizer:unify:true`. It does not allow environments with conflicting software to be concretized for maximal interoperability.

The primary use-case for this is facilities providing system software. Facilities provide multiple MPI implementations, but all software built against a given MPI ought to be interoperable.

This PR adds a concretization option `concretizer:unify:when_possible`. When this option is used, Spack will concretize specs in the environment separately, but will optimize for minimal differences in overlapping packages.

* Add a level of indirection to root specs

This commit introduce the "literal" atom, which comes with
a few different "arities". The unary "literal" contains an
integer that id the ID of a spec literal. Other "literals"
contain information on the requests made by literal ID. For
instance zlib@1.2.11 generates the following facts:

literal(0,"root","zlib").
literal(0,"node","zlib").
literal(0,"node_version_satisfies","zlib","1.2.11").

This should help with solving large environments "together
where possible" since later literals can be now solved
together in batches.

* Add a mechanism to relax the number of literals being solved

* Modify spack solve to display the new criteria

Since the new criteria is above all the build criteria,
we need to modify the way we display the output.

Originally done by Greg in spack#27964 and cherry-picked
to this branch by the co-author of the commit.

Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>

* Inject reusable specs into the solve

Instead of coupling the PyclingoDriver() object with
spack.config, inject the concrete specs that can be
reused.

A method level function takes care of reading from
the store and the buildcache.

* spack solve: show output of multi-rounds

* add tests for best-effort coconcretization

* Enforce having at least a literal being solved

Co-authored-by: Greg Becker <becker33@llnl.gov>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
commands dependencies documentation Improvements or additions to documentation environments gitlab Issues related to gitlab integration tests General test capability(ies)
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

3 participants