[HACK] Make concretization great again!#2590
Conversation
|
If this PR were merged, how would you forward variants? Well, for the case of gtkplus, you would have to either run: or set them in your and later discovering that it doesn't work because the dependencies were built without X support. The stance I took to address this in #1553 was to raise an error if |
davydden
left a comment
There was a problem hiding this comment.
frankly i don't understand what's dramatically wrong with
depends_on('hdf5+mpi`, when='+mpi')
depends_on('hdf5~mpi`, when='~mpi`)
So far this PR looks like shooting out of cannon into sparrows
|
|
||
| # optional dependencies | ||
| depends_on("mpi", when="+mpi") | ||
| depends_on("arpack-ng+mpi", when='+arpack+mpi') |
There was a problem hiding this comment.
this change would certainly allow to build against arpack-ng~mpi, right? if so, this is certainly not decirable effect. Same below.
There was a problem hiding this comment.
I was confused about this as well. So, according to the way it used to be, if I build +arpack~mpi it doesn't build with arpack, only when I build with +arpack+mpi? That doesn't seem... ideal. What if we raised an error when someone tries to build +arpack~mpi?
In hindsight, this wasn't the change I should have made. I should have removed arpack-ng+mpi, but not +arpack+mpi.
There was a problem hiding this comment.
if I build +arpack~mpi it doesn't build with arpack, only when I build with +arpack+mpi? That doesn't seem... ideal
correct, that's the behaviour and it is indeed not ideal, but variant description clearly say so: (only with MPI).
In this specific case of arpack, one actually can build (outside of Spack) dealii+mpi^arpack~mpi. Here it was only added for consistency. But other packages may get broken when you try this (it all depends).
| depends_on( | ||
| "[email protected]:+thread+system+serialization+iostreams+mpi+python", | ||
| when='@8.5.0:+mpi+python') | ||
| depends_on("[email protected]:+thread+system+serialization+iostreams") |
There was a problem hiding this comment.
Frankly, i don't understand why you do this. You say
Well, first of all, it doesn't forward the variants properly
but in my experience things work perfectly fine in this regards.
I agree that if you would try to specify which boost is needed here, you would need to do spack spec dealii+mpi+python ^[email protected] or alike, it's PITA but if you put your preferences to packages.yaml, then all works fine, at least from my experience.
| depends_on('boost', when='@:3.5+boost') | ||
| depends_on('metis@5:', when='+metis') | ||
|
|
||
| depends_on('hdf5+mpi', when='+hdf5+mpi') |
There was a problem hiding this comment.
this is not even different from the original, before it will use hdf5 if-and-only-if petsc is compiled with mpi. So it's not even about forwarding of variants. Same below.
There was a problem hiding this comment.
Yeah, you're right. I probably shouldn't have made this change.
|
In general, why would a package explicitly require Idea: Add a new named argument Finally, |
|
if there are any changes to contretizer coming from @tgamblin , i would not merge this PR until they are merged upstream and the problem is reassessed. |
Can you please elaborate? It should be perfectly fine to compile a serial-only |
|
@adamjstewart Thank you for writing this up and bringing the issues to our attention. My thoughts are:
|
|
|
||
| variant('shared', default=True, | ||
| description='Enables the build of shared libraries') | ||
| variant('mpi', default=False, description='Activates MPI support') |
There was a problem hiding this comment.
I am very much in favour of those changes, maybe you could put them into a separate PR as they are not controversial and would not require much discussion.
|
BTW... I've finally articulated how the multi-valued variants in #2386 are different from boolean variants; and this could guide us in deciding when to use which feature. With boolean variants, a request for |
| depends_on('oce', when='+oce') | ||
| depends_on('petsc+mpi', when='+petsc+mpi') | ||
| depends_on('petsc', when='+petsc~mpi') | ||
| depends_on('petsc', when='+petsc') |
There was a problem hiding this comment.
here you allow to build gmsh+mpi against petsc~mpi, I don't think it's a correct behaviour.
|
@davydden Let me take HDF5 as example. If configured with If the MPI package properly declared its include and library requirements to Spack, then Spack would handle this automatically. |
|
Hi all: just to clarify, the issue is really that the concretizer does not currently do backtracking for decisions made about variants. It can currently do one level of backtracking when it tries to figure out which implementation of a virtual dependency to choose. What it should do is backtrack from much deeper levels as it searches for a satisfiable configuration. The variants should just be another generalized choice in the solver. Implementing a fix for this is on my list, and I am kind of thinking (based on all the variant conflicts) that it should get moved up in priority. The dependencies in Spack have gotten more complex now that all of X11 and more fancy MPI options are in Spack. So I guess people discovered that the dependency model really does cover most of the things they want, but the concretizer needs to grow up. I think a reasonable plan is:
So my suggestion is that we put this in the Thoughts? |
This is worth another 👍 |
| depends_on("netcdf", when="+netcdf") | ||
| depends_on("netcdf-cxx", when='+netcdf') | ||
| depends_on("oce", when='+oce') | ||
| depends_on("p4est", when='+p4est+mpi') |
There was a problem hiding this comment.
this is for example wrong, p4est builds only with mpi, so in this instance deal.ii can use p4est if and only if it is build with mpi itself. I would certainly recommend splitting this PR into at least
mpi=Trueby default- the rest...
So that one could take a closer look. I am afraid you may be breaking more things that you try to fix here.
There was a problem hiding this comment.
I did separate things into 3 different commits for this reason. It sounds like the first 2 commits are popular, but the 3rd is much more controversial.
There was a problem hiding this comment.
I did separate things into 3 different commits for this reason.
please cherry-pick the first one into a separate PR, i think it can be merged almost immediately (but i would certainly like to review it). Then the second one (same here). After that this PR can be rebased and it would be easier to discuss.
|
More thoughts: to mirror what others said, it's very helpful that @adamjstewart has written this up. The changes in this PR seem like they are intended to hard-code the best "common-case" choices for things, so that for unconstrained specs, things work decently and so that had package constraints don't throw too many monkey wrenches in the path to satisfiability. We could merge this as a stop gap, but there is useful information in those constraints. I am not completely convinced that this PR is going to make things work better for most people. I think I'd need tests to see that. At a really high level, my immediate priorities right now are:
Does that sound like a reasonable set of priorities? I think (2) is necessary before we can do (3) right. Also, getting (2) working means we can start recording many of the tests cases @adamjstewart mentioned above in a set of nightly package tests. This makes (3) work that much better. |
Let's take a quick walkthrough with gtkplus variant('X', default=True)
depends_on("pango")
depends_on("pango~X", when='~X')
depends_on("pango+X", when='+X')pango variant('X', default=False)
depends_on("cairo")
depends_on("cairo~X", when='~X')
depends_on("cairo+X", when='+X')cairo variant('X', default=True)If you run If things were working properly, the concretizer would notice that I didn't specify any variants, default to What are some possible solutions? What if we set the But the following doesn't work: In an ideal world, Spack would say that since pango needs packages:
cairo:
variants: +XThat's perfectly legal right? But now |
| depends_on("petsc", when='@8.4.2:+petsc') | ||
| depends_on('python', when='@8.5.0:+python') | ||
| depends_on("slepc", when='@8.4.2:+slepc+petsc+mpi') | ||
| depends_on("petsc@:3.6.4+mpi", when='@:8.4.1+petsc+mpi') |
There was a problem hiding this comment.
here is one TODO example of variant forwarding which has to happen no matter what but it is not added yet in Spack in these packages: deal.II, petsc and trilinos can be build with 64 bit integers. So if you turn this feature on in deal.ii, it has to be also on petsc and trilinos (and a few other places). Whereas some dependencies which do not support 64bit indices have to be disabled, namely there should be something like
depends_on(package32bitOnly, when=`~64bit`)
tgamblin
left a comment
There was a problem hiding this comment.
Adding another comment to make GitHub think I put a review in. See above two comments.
|
I' m feeling really sorry as it seems I ( unintentionally ) opened a vase of pandora. I can summarize here my intended use for spack and hopefully get some hints: I' m trying to use spack to automate the building of a sw stack for remote visualization. Ideally this could be handled by a single spack install command..... but I do not expect it would be so easy. I raised the issue and the following PR thinking to just fix typos in some underneath packages. Unfortunately problems I detected involve spack internals such as concretization, and could not be solved at the package level. Many of you suggest using package.yaml: would it be possible to collect some real examples ( if it can be openly disclosed) of configuration that are really in use? As some build steps ( as qt ) are really long, even splitting install into steps ( build tools, base libraries, applications ) could be acceptable, providing some hints on how to properly set up package.yaml to avoid rebuilding dependencies in following step. |
|
Thank you for the detailed example. I question one thing in it:
In an ideal world, Spack would say that since pango needs +X, so does
gtkplus,
Let's think in terms of PATTERNS and SPECS. They both have the same
syntax, so we tend to get them confused.
I thought the way things were SUPPOSED to work is that the PATTERN
`packageA` will match the SPEC `packageA+x` or `packageA~x`. The rationale
is that if `packageB` -> `packageA` without anything else, then `packageB`
should not really care whether or not `packageA` does or does not have the
`+x` feature turned on. Boolean variants really do mean that "this is an
extra feature." If not, then maybe multi-valued variants should be used
instead (once they're merged).
So... I believe that THIS little corner works as it should for now: a non-x
gtk should work find with pango+x
|
|
Luigi, don't be sorry. This Pandora's box was already open, and we're
still grasping at what to do about it.
Many of you suggest using package.yaml: would it be possible to collect
some real examples
I use point to system-supplied Qt, Python2 and any X libraries in my
`packages.yaml`. This solves a lot of problems (unless your system doesn't
have them).
As some build steps ( as qt ) are really long
I use variants to turn off package options that use Qt --- except for
`py-matplotlib`, where I actually do care about a GUI.
…On Wed, Dec 14, 2016 at 2:39 PM, Luigi Calori ***@***.***> wrote:
I' m feeling really sorry as it seems I ( unintentionally ) opened a vase
of pandora.
I can summarize here my intended use for spack and hopefully get some
hints:
I' m trying to use spack to automate the building of a sw stack for remote
visualization.
One of the target for installation is a cluster that has no GPU available,
so one of the goal was to build Paraview with mesa.
Ideally this could be handled by a single spack install command..... but I
do not expect it would be so easy.
I raised the issue and the following PR thinking to just fix typos in some
underneath packages.
Unfortunately problems I detected involve spack internals such as
concretization, and could not be solved at the package level.
Nevertheless, as I would really like to be able to code a working recipy
in spack, any suggestion to good practice that relieve these problems would
be really welcomed.
Many of you suggest using package.yaml: would it be possible to collect
some real examples ( if it can be openly disclosed) of configuration that
are really in use?
As some build steps ( as qt ) are really long, even splitting install into
steps ( build tools, base libraries, applications ) could be acceptable,
providing some hints on how to properly set up package.yaml to avoid
rebuilding dependencies in following step.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2590 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB1cd-vm5WXFiyBfBk1ubD1MkiGNL5okks5rIEYGgaJpZM4LNODO>
.
|
thanks for explanation, now i see the problem. I would still suggest do it step-by-step. First part of your PR which makes variants consistently |
There was a problem hiding this comment.
I think, as others have already said, that this could be a stop-gap for some people (and a new gap for others).
There's much value in the clear description of the problem, but I am not sure we should merge the whole thing. Maybe more selective PRs would find a greater consensus?
is it because you have in addition to ? The last two should be sufficient. Maybe this is the root of the bug? |
No, we won't. This doesn't violate anything. Let Consider :
These are all valid builds if the only constraint is
Adding these two constraints to a package:
Just means that these are the only two valid builds:
Any concrete What is the matter with that? |
|
It sounds like everyone is on board with the first 2 commits that make sure that all It sounds like a lot of people are not on board with my last commit, which removes the depends_on variant forwarding. I'm fine with removing this commit for now if it helps get the first 2 commits in. I'm not sure how useful those depends_on statements are though. Even if it did work, it is kind of annoying to have to always say: depends_on('hdf5')
depends_on('hdf5+mpi', when='+mpi')
depends_on('hdf5~mpi', when='~mpi')I think there are two long term solutions. The universal variants/variant forwarding idea that @citibeth and I have proposed would solve the problem of having to be so annoyingly explicit on every dependency, and I think that is worth doing. As for which we go with (universal variants vs. variant forwarding) there are enough open issues discussing the pros and cons of both already. It can wait until after But the above syntax should still work. That is a bug in the concretizer that @tgamblin explained. That should also be fixed, and I'm ok with waiting until after How about I remove the last commit and we merge the first 2 commits? It's a useful stopgap, although it doesn't solve every situation. |
agreed. |
👍
The two concepts don't cover the same terrain. Having something "universal" means one single object to represent a property in the entire DAG. It could be useful for things like Variant forwarding will help in cases where you need to make a decision based on somebody else. The most relevant example is |
|
I'm not in deep enough to have a useful opinion on the details, but will contribute the datapoint that as an end user I'm comfortable with the plan and priorities that @tgamblin described up above (interim fixes and fixing the concretizer the right way in early January, if I understand). While having to do things like Between now and then, "How much can go wrong?" |
|
The constraints you're arguing against just impose a requirement on B
based on how A is built and don't allow builds where one has MPI and the
other doesn't.
What is the matter with that?
OK so it's not a change in the concretizer. But it is a change in the way
we've interpreted variants up till now. In most cases, the `+` means we
have an "added feature." Package A should almost never say it requires B
*without* an extra feature; after all, why should it care how many extra
features B has, as long as it has the features that A needs? Are we
imposing these extra constraints to cover for a shortcoming elsewhere? In
the MPI case... why should A care whether or not B links to MPI behind the
scenes?
BTW... the universal variants I've suggested would have the property I'm
arguing against here: If you turn on universal variant `mpi`, then it will
be enabled for EVERY package in the DAG that uses it.
|
|
Sure, but this is a matter of convention and interpretation. For the most part, we try to model variants this way, but I don't think that even modeling all variants as
In most cases, if So basically I want a logically complete dependency system, because that lets me express cases like these when I need to. Figuring out what the best usage conventions are on top of that depends on what's elegant, what works, and what we can do with the current state of HPC software, which has all kinds of nasty linking issues. |
|
And speaking of NP complete problems, references to this writeup about package managers and SAT came across the Hacker News radar recently. |
|
@hartzell: indeed. You're the second person to send me that today. What we're talking about here is making Spack's concretizer solve basically that problem, but with variants, compilers, and optional dependencies within each build. I would say the current concretizer is somewhere between heuristics and a full backtracking solver. The nice thing about Spack is we don't have to solve version SAT for everything that is installed at once, just within each build. Also Spack has some leeway that most PM's don't w.r.t. build dependencies (which can be RPATH'd to versions of libs separate from those in the DAG to be built). |
|
@adamjstewart remove the last commit and we can finish with this one? |
|
Git has a revert command that will apply a new commit reversing an existing
commit.
…On Dec 16, 2016 3:11 AM, "Denis Davydov" ***@***.***> wrote:
@adamjstewart <https://github.com/adamjstewart> remove the last commit
and we can finish with this one?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2590 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB1cd1yigSfvG7yCLZcHHl8uI3tkxFY1ks5rIkeigaJpZM4LNODO>
.
|
IMHO it is easier by doing |
b053bb6 to
98b581f
Compare
|
Ok, last commit removed. Should be good to go now. |
I really didn't want to have to do this, but I've been left with no other choice. Spack's concretization algorithm is so crippled at the moment that simple commands no longer work more often than I would like. This PR does not fix the concretizer, as I wouldn't even know where to begin.
So what does this PR do?
+mpiand~Xfor every packageWhy in the world would you want to do something so drastic?
Try checking out a fresh copy of Spack, and with no
packages.yaml, run the following command:The problem here is that
gtkplusandcairodefault to+Xwhilepangodefaults to~X. Spack's concretization algorithm is incapable of resolving this conflict because it settles on the default value for all dependencies. This bug has been reported over and over and over again (see #2546, #2574, #1552, etc.).The solution that I decided on in this PR is to make sure common variants like
+Xand+mpiare at least consistent. Of course, as soon as you runspack spec gtkplus+X, everything breaks again, but at leastspack spec gtkplusworks.What solutions have we used in the past?
When going through the packages, I noticed a lot of packages that looked like:
What's wrong with this? Well, first of all, it doesn't forward the variants properly, as seen with
spack spec gtkplus. Second, try running the following:With a packageA containing those two lines, it will inform you that packageA does not depend on hdf5. This is because Spack doesn't concretize default variants before it concretizes dependency versions. Either of the following commands will work:
but the original won't. So what if we always do:
Ok, first of all, that's a pain in the ass. Second of all, it doesn't work, as evidenced by
spack spec gtkplus. But what if we did:Doesn't work either. I just tried it with the
gtkplus,cairo,pangochain and you still see the problem with a conflict between+Xand~X.But won't everything be happy if we keep variant forwarding and make sure all of the variants have the same default? Nope. Things like
spack spec gtkpluswill work, butspack spec gtkplus +Xwon't. And if you decide to change the default for any package inpackages.yaml, we're right back to square one, except it's harder to debug now unless you tell us what is in yourpackages.yaml.There is another standing issue that this PR does not address. Try running the following:
This may look like the problem we just solved, but it's not that simple. Here is the dependency chain:
python+tk -> tk -> libx11 -> libxcb -> python~tk
Since libxcb has a build dependency on python~tk, it says it doesn't satisfy python+tk. Of course, if you try to fix this by setting the default to
python+tk, you end up in infinite recursion hell, as seen in #2495 and #2565. Even more fun, if you try to build py-matplotlib for Python 3, it requires python+tk, and you end up with the problem that xcb-proto, another dependency of libxcb, depends on Python 2, which is most certainly not Python 3.This will hopefully be fixed when we start resolving build dependencies separately, but for now it is an absolute nightmare.
I really hope this PR won't be merged, but it does provide immediate relief for a lot of open issues. In my opinion, these issues should block the release of
0.10. If users can't buildpython+tkorgtkpluswithout hacking up Spack, we have a real problem.