Skip to content

[HACK] Make concretization great again!#2590

Merged
tgamblin merged 2 commits intospack:developfrom
adamjstewart:hacks/concretization
Dec 16, 2016
Merged

[HACK] Make concretization great again!#2590
tgamblin merged 2 commits intospack:developfrom
adamjstewart:hacks/concretization

Conversation

@adamjstewart
Copy link
Copy Markdown
Member

@adamjstewart adamjstewart commented Dec 14, 2016

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?

  • Always default to +mpi and ~X for every package
  • Never even try to forward variants, as it doesn't work anyway

Why 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:

$ spack spec gtkplus
...
==> Error: Invalid spec: '[email protected]%[email protected]~X arch=linux-fedora25-x86_64'. Package pango requires variant +X, but spec asked for ~X

The problem here is that gtkplus and cairo default to +X while pango defaults 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 +X and +mpi are at least consistent. Of course, as soon as you run spack spec gtkplus+X, everything breaks again, but at least spack spec gtkplus works.

What solutions have we used in the past?

When going through the packages, I noticed a lot of packages that looked like:

depends_on('hdf5+mpi', when='+mpi')
depends_on('hdf5~mpi', when='~mpi')

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:

spack spec packageA ^[email protected]

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:

spack spec packageA +mpi ^[email protected]
spack spec packageA -mpi ^[email protected]

but the original won't. So what if we always do:

depends_on('hdf5')
depends_on('hdf5+mpi', when='+mpi')
depends_on('hdf5~mpi', when='~mpi')

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:

depends_on('hdf5')
depends_on('hdf5+mpi', when='+mpi')

Doesn't work either. I just tried it with the gtkplus, cairo, pango chain and you still see the problem with a conflict between +X and ~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 gtkplus will work, but spack spec gtkplus +X won't. And if you decide to change the default for any package in packages.yaml, we're right back to square one, except it's harder to debug now unless you tell us what is in your packages.yaml.

There is another standing issue that this PR does not address. Try running the following:

spack spec python+tk
...
==> Error: +tk does not satisfy ~tk

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 build python+tk or gtkplus without hacking up Spack, we have a real problem.

@adamjstewart
Copy link
Copy Markdown
Member Author

If this PR were merged, how would you forward variants?

Well, for the case of gtkplus, you would have to either run:

spack install gtkplus+X ^cairo+X ^pango+X

or set them in your packages.yaml. But at least it wouldn't crash! The danger then becomes there is nothing stopping someone from running:

spack install gtkplus+X

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 gtkplus+X is being built with cairo~X or pango~X. This is obviously not ideal.

Copy link
Copy Markdown
Member

@davydden davydden left a comment

Choose a reason for hiding this comment

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

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')
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.

this change would certainly allow to build against arpack-ng~mpi, right? if so, this is certainly not decirable effect. Same below.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

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.

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")
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.

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')
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.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, you're right. I probably shouldn't have made this change.

@eschnett
Copy link
Copy Markdown
Contributor

In general, why would a package explicitly require otherpackage~feature, unless that package really doesn't build in that case? It seems that half the confusion that this PR addresses is that some packages say hdf5~mpi when they mean "I need HDF5, but I don't need MPI". That's wrong, as hdf5~mpi means "I need HDF5, and I really cannot handle an HDF5 with MPI at all". Grepping for the character ~ in dependencies should find most of these; one would assume that there's always a comment explaining the situation. (I assume that some cases were added merely out of desperation to make concretization work.)

Idea: Add a new named argument why_not to depends, and require it to be set to an explanatory string when the ~ character is used to exclude a feature from a dependency...

Finally, mpi is a special case since if there's MPI anywhere in the dependency chain, there's a good chance that cc will fail and mpicc needs to be used. I say that's a bug in the MPI package; it should probably change Spack's cc setting to its mpicc, or -- even better -- should declare its include and library requirements in a transparent manner instead of pointing to an opaque mpicc script. (I know that I volunteered to fix this, but sadly didn't have the time to do so yet.)

@davydden
Copy link
Copy Markdown
Member

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.

@davydden
Copy link
Copy Markdown
Member

@eschnett :

if there's MPI anywhere in the dependency chain, there's a good chance that cc will fail and mpicc needs to be used.

Can you please elaborate? It should be perfectly fine to compile a serial-only packageA with GCC and then use it in another packagesB that utilize some MPI (say Openmpi compiled with GCC).

@citibeth
Copy link
Copy Markdown
Member

@adamjstewart Thank you for writing this up and bringing the issues to our attention. My thoughts are:

  1. The write-up is valuable. But as @davydden said, it feels a bit all over the place. It's clear that things are broken and that this is frustrating, but it's not clear yet exactly what is broken or how we think it should be fixed. I think some editing of it would do us all service: to try to be more specific about WHAT the problems are, WHAT doesn't work, and HOW those things don't work. Maybe I could take some time with what you've written and a bunch of spack spec tries to flesh this out?

  2. I'm wondering why you don't think this PR should be merged, since it looks to me like it does some good things. Namely:
    a) Variants should generally default the same way in different packages.
    b) As you point out, the ubiquitous attempts at manual variant forwarding are not working --- and they introduce at least as many problems as they solve. I think that getting rid of them is a good start. Clearly, we need to finish the job with Spack-supported variant forwarding or universal variants. But either way, we need to clear out the manual attempts.


variant('shared', default=True,
description='Enables the build of shared libraries')
variant('mpi', default=False, description='Activates MPI support')
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.

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.

@citibeth
Copy link
Copy Markdown
Member

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 pkg will match pkg+x. But with multi-valued variants, I presume that a request for pkg-x=y will only match pkg-x=y.

depends_on('oce', when='+oce')
depends_on('petsc+mpi', when='+petsc+mpi')
depends_on('petsc', when='+petsc~mpi')
depends_on('petsc', when='+petsc')
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.

here you allow to build gmsh+mpi against petsc~mpi, I don't think it's a correct behaviour.

@eschnett
Copy link
Copy Markdown
Contributor

@davydden Let me take HDF5 as example. If configured with +mpi, the HDF5 header files contain an #include <mpi.h>, and (obviously) also require the MPI libraries for linking. If you build another serial package against this HDF5 version, then you need to build and link it (although it is serial!) with mpicc.

If the MPI package properly declared its include and library requirements to Spack, then Spack would handle this automatically.

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Dec 14, 2016

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:

  1. Finish the stuff left for 0.10 and get it out the door.
  2. I already pushed the exact versions stuff from 0.10 off to 1.0 because the changes to the concretizer were more sweeping that I would've liked. There are some concepts that have become conflated over time in the constraint solve ("satisfies" vs. "could satisfy") that need refactoring, and I don't trust the refactor without better package testing.
  3. This change should probably be done concurrently with (2), as it affects the main part of the concretization algorithm.

So my suggestion is that we put this in the 1.0 bin and I can focus on it with @mathstuf @becker33 and @scheibelp between now and January-ish.

Thoughts?

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Dec 14, 2016

There are some concepts that have become conflated over time in the constraint solve ("satisfies" vs. "could satisfy") that need refactoring, and I don't trust the refactor without better package testing.

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')
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.

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

  1. mpi=True by default
  2. 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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

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.

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.

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Dec 14, 2016

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:

  1. Get the last few bugs out the door for 0.10
  2. Getting a CDash site set up with a reasonably comprehensive set of package builds so that we can see what works and what does not. Right now we are playing whack-a-mole with github issues and we need a dashboard so we can make the thing converge to green.
  3. Get the concretizer fixes in.

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.

@adamjstewart
Copy link
Copy Markdown
Member Author

frankly i don't understand what's dramatically wrong with

depends_on('hdf5+mpi`, when='+mpi')
depends_on('hdf5~mpi`, when='~mpi')

Let's take a quick walkthrough with gtkplus, as it is the simplest problem to understand. Currently in develop, we have this set of conditions:

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 spack spec gtkplus with no packages.yaml, you get:

==> Error: Invalid spec: '[email protected]%[email protected]~X arch=linux-fedora25-x86_64'. Package pango requires variant +X, but spec asked for ~X

If things were working properly, the concretizer would notice that I didn't specify any variants, default to gtkplus+X, and propagate +X down the line with the depends_on statements. But it isn't.

What are some possible solutions? What if we set the ~X to be the default for all 3 packages? Now, the following commands work:

spack spec gtkplus
spack spec gtkplus +X

But the following doesn't work:

spack spec gtkplus ^pango+X

In an ideal world, Spack would say that since pango needs +X, so does gtkplus, but it doesn't work. What about another scenario. If we set ~X to be the default for all packages, and a user happens to always need cairo+X, they could modify their packages.yaml like so:

packages:
  cairo:
    variants: +X

That's perfectly legal right? But now spack spec gtkplus no longer works.

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')
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.

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`)

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.

Adding another comment to make GitHub think I put a review in. See above two comments.

@luigi-calori
Copy link
Copy Markdown
Contributor

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.

@citibeth
Copy link
Copy Markdown
Member

citibeth commented Dec 14, 2016 via email

@citibeth
Copy link
Copy Markdown
Member

citibeth commented Dec 14, 2016 via email

@davydden
Copy link
Copy Markdown
Member

@adamjstewart

But the following doesn't work:
spack spec gtkplus ^pango+X
In an ideal world, Spack would say that since pango needs +X, so does gtkplus, but it doesn't work.

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 true by default. This can go into 0.10 as it is won't break things. The rest needs to be tested, preferably grouped into suites, say all PDE packages like petsc, deal.ii, p4est, fenics, gmsh.

Copy link
Copy Markdown
Member

@alalazo alalazo left a comment

Choose a reason for hiding this comment

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

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?

@davydden
Copy link
Copy Markdown
Member

davydden commented Dec 14, 2016

@adamjstewart :

But the following doesn't work:
spack spec gtkplus ^pango+X

is it because you have

depends_on("pango")                        

in addition to

depends_on("pango~X", when='~X')                                            
depends_on("pango+X", when='+X')

? The last two should be sufficient. Maybe this is the root of the bug?

@tgamblin
Copy link
Copy Markdown
Member

@citibeth:

@tgamblin Then we will need to change a fundamental way that pattern-matching currently works.

No, we won't. This doesn't violate anything.

Let -> mean depends_on.

Consider :

  • A -> B means A requires B but doesn't care how it is built. A+mpi or A~mpi will do.
  • A -> B+mpi means that the B used to satisfy A must have +mpi.
  • A -> B~mpi means that the B used to satisfy A must have ~mpi.

These are all valid builds if the only constraint is A -> B:

  • A+mpi ^B+mpi
  • A~mpi ^B+mpi
  • A+mpi ^B~mpi
  • A~mpi ^B~mpi

Adding these two constraints to a package:

  • A -> B+mpi when A+mpi
  • A -> B~mpi when A~mpi

Just means that these are the only two valid builds:

  • A+mpi ^B+mpi
  • A~mpi ^B~mpi

Any concrete A MUST have a value for the mpi variant, so A, concretized, will become either A+mpi or A~mpi. There is no "don't care" build -- it either has MPI or it doesn't when it's actually built. 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?

@adamjstewart
Copy link
Copy Markdown
Member Author

It sounds like everyone is on board with the first 2 commits that make sure that all mpi and X variants have the same default. Are there any other common variants that should be aligned? Of course, things quickly break if you change any of the defaults in packages.yaml, but there doesn't seem to be anything we can do about that until the underlying issue (the concretizer) is fixed.

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 0.10 I guess.

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 0.10 I guess. The bug has always been present. It's just been exacerbated now that software stacks are getting deeper and X11 support has been proliferated.

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.

@davydden
Copy link
Copy Markdown
Member

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.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Dec 14, 2016

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.

👍

As for which we go with (universal variants vs. variant forwarding) there are enough open issues discussing the pros and cons of both already.

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 shared and static (even though you will lose the opportunity to have them mixed) or other properties that should be uniform across any given build.

Variant forwarding will help in cases where you need to make a decision based on somebody else. The most relevant example is openmp: if multiple packages in a DAG can be OpenMP multi-threaded what you usually want is to activate only one of those and avoid multiple nested regions.

@hartzell
Copy link
Copy Markdown
Contributor

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 [email protected] ^pango+X is magical and a bit annoying, there aren't that many new users arriving on a daily basis so just helping them (us...) over the hump as needed and fixing the problem well in a timely manner seems perfectly reasonable.

Between now and then, "How much can go wrong?"

@citibeth
Copy link
Copy Markdown
Member

citibeth commented Dec 14, 2016 via email

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Dec 14, 2016

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.

mpi as a universal variant is a wrong example: what if I always use serial arpack-ng or serial hdf5 as part of a software, regardless of whether this software was compiled with +mpi or ~mpi?

@tgamblin
Copy link
Copy Markdown
Member

But it is a change in the way we've interpreted variants up till now.

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 +feature results in what you're asking for. Consider @alalazo's OpenMP case. Some packages can build with OpenMP. That is a feature. You may need A+openmp -> B~openmp to enforce mutual exclusion and to avoid nested OpenMP regions, because OpenMP in B actually conflicts with OpenMP in A.

In the MPI case... why should A care whether or not B links to MPI behind the scenes?

In most cases, if B -> mpi and A -> B but A !-> mpi , A wasn't intended to be run with mpirun. If A isn't run with mpirun, and some routine from B calls something that calls an MPI routine, things break because the code isn't run in parallel. You'll likely just get an error that some MPI routine was called before MPI_Init(). I believe this is the case with HDF5. You can have an MPI program that links either the serial or parallel HDF5 library but I do not believe you can link a serial program to hdf5+mpi and expect it to run correctly. They may have fixed this in more recent HDF5 versions, but this is always the annoyance with HDF5 libs. So depending on hdf5~mpi is basically depending on serial HDF5.

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.

@hartzell
Copy link
Copy Markdown
Contributor

And speaking of NP complete problems, references to this writeup about package managers and SAT came across the Hacker News radar recently.

@tgamblin
Copy link
Copy Markdown
Member

@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).

@davydden
Copy link
Copy Markdown
Member

@adamjstewart remove the last commit and we can finish with this one?

@citibeth
Copy link
Copy Markdown
Member

citibeth commented Dec 16, 2016 via email

@davydden
Copy link
Copy Markdown
Member

Git has a revert command that will apply a new commit reversing an existing
commit.

IMHO it is easier by doing git rebase -i HEAD~3 and then removing the last one, and git push. My perception is that @adamjstewart separated commits intentionally, so I think one should not squash them during the merge and thereby the history should be clean.

@adamjstewart
Copy link
Copy Markdown
Member Author

Ok, last commit removed. Should be good to go now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants