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

pnfft: new package #2646

Merged
merged 11 commits into from
Mar 25, 2017
Merged

pnfft: new package #2646

merged 11 commits into from
Mar 25, 2017

Conversation

mkuron
Copy link
Contributor

@mkuron mkuron commented Dec 20, 2016

PNFFT is a library for parallel non-equispaced FFTs and kind of combines #2255 (parallel FFT) and #2612 (non-equispaced FFT).

from spack import *


class Pnfft(AutotoolsPackage):
Copy link
Member

Choose a reason for hiding this comment

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

given those extra steps you do in install, i think it should be plain Package

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Nfft and Pfft packages also derive from AutotoolsPackage and basically have package files identical to this one. Fftw derives from Package, and it's got only slightly more extra code. So it's a bit inconsistent already.

Copy link
Member

Choose a reason for hiding this comment

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

the simple answer is that, IMHO, they both should not use AutotoolsPackage because they have custom implementation of install anyway. Look at hdf5 for a good example where def configure_args(self): is implemented in derived class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, changed it on all three packages.

Copy link
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.

LGTM apart from minor issue

@@ -25,7 +25,7 @@
from spack import *


class Nfft(AutotoolsPackage):
class Nfft(Package):
Copy link
Member

Choose a reason for hiding this comment

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

Why is this being moved from AutotoolsPackage BACK to Package? Without a good reason, that would seem to be the wrong direction.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we are overriding install, see @davydden's comment, and for consistency with the fftw package.

Copy link
Member

Choose a reason for hiding this comment

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

@citibeth in other words, AutotoolsPackage package is NOT used here at all, the installation is still done via custom install() as opposed to overriding def configure_args(self): which is used in AutotoolsPackage.


configure(*options)
make()
if self.run_tests:
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be using Spack functionality for (1) AutotoolsPackage and (2) running tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, because we need to run the entire build process three times if float and long_double are enabled.

make("check")
make("install")

if '+float' in spec['fftw']:
Copy link
Member

Choose a reason for hiding this comment

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

Repetitive code her should be eliminated. Only the configure() statement needs to go inside the if block. (Although all this might go away with AutotoolsPackage).

More importantly... I see that this is taking options from the dependencies and propagating them UP the DAG. It looks like a neat idea to me. @adamjstewart is this kosher?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This all applies to the nfft, pfft and fftw packages too as they use the same code.

Copy link
Member

Choose a reason for hiding this comment

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

Repetitive code her should be eliminated

one could do that by defining a custom function and calling it with options (first parameter) and long double|float|... as a second one.

Copy link
Member

Choose a reason for hiding this comment

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

but my opinion is that this is not that important, so I vote to leave it as is.

three-dimensional nonequispaced FFTs."""

homepage = "https://www-user.tu-chemnitz.de/~potts/workgroup/pippig/software.php.en#pnfft"
url = "https://www-user.tu-chemnitz.de/~potts/workgroup/pippig/software/pnfft-1.0.7-alpha.tar.gz"
Copy link
Member

Choose a reason for hiding this comment

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

Now extra spaces after url (PEP-8 compliance)

Copy link
Member

Choose a reason for hiding this comment

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

I don't think that's a problem. Every package has spaces after url. That's how spack create initializes them.

@citibeth
Copy link
Member

No, because we need to run the entire build process three times if float and long_double are enabled.

I see... I looked back at fftw package, and it is making more sense now. Still... this rubs me the wrong way (but the root of the problem is in fftw).

@tgamblin How about the alternative of having fftw/package.py just build FFTW once, depending on the variant chosen (multi-valued variants from @alalazo would be useful here)? If you want FFTW once with double and once with single, then you have Spack install FFTW twice. We can install as many different variants as we want side-by-side, that is a strength of Spack.

http://www.fftw.org/fftw3_doc/Precision.html#Precision

I really feel that doing three separate builds in one package is against the spirit of Spack, and could cause problems down the line. Moving to one build will simplify FFTW --- and also simplify things that depend on FFTW (such as pnfft).

As for forwarding variants up the DAG in this PR... the more I think about it, the more I think we should not do it, at least not here. AFAIK, this would be the fisrt Spack package to work that way, all others forward variants top-down. Whatever the merits of this type of forwrading, it's better to just follow the way things have been done before.

Putting these two suggestions together, nfft would now look like:

class Nfft(AutotoolsPackage):
    ...
    version('3.3.2', '550737c06f4d6ea6c156800169d8f0d9')

    # Only one of these three allowed at once
    variant('double', default=True)
    variant('float', default=False)
    variant('long_double', default=False)

    depends_on('fftw+double', when='+double')
    depends_on('fftw+float', when='+float')
    depends_on('fftw+long_double', when='+long_double')

    def configure_args(self):
        if '+float' in self.spec:
            return ['--enable-float']
        elif '+long_double' in self.spec:
            return ['--enable-long-double']
        elif '+double' in self.spec:
            return []

This would be simplified even further with #2386

@davydden
Copy link
Member

davydden commented Dec 20, 2016

I suppose it all boils down to this

Only one of these three allowed at once

I don't know much about packages which use fftw, but it is possible that there are packages which need all variants at once:

some part of the code is using float to do FFTW faster, and another part is using double for more precision. As I vaguely remember FFTW allows using different number types within a single application.

p.s. the situation is opposite to petsc+complex, where only real-valued or complex-valued build of PETSc can be used in a single application because they have different header files.

Copy link
Member

@adamjstewart adamjstewart left a comment

Choose a reason for hiding this comment

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

I'm fine with the changes from AutotoolsPackage to Package. If you're not taking advantage of separate build phases, AutotoolsPackage is basically identical.

I don't mind variant forwarding up the dag. I think I've seen this once before. It's very clever, and a much better solution than trying to forward variants down the dag with our current broken logic.

I'm on the fence about whether to run configure/make/make install multiple times in the same package. It would make life easier if it only did things once and we could use AutotoolsPackage. It depends on how useful the resulting build is. I can see why someone would want to support all 3 in one library.

@davydden
Copy link
Member

davydden commented Dec 20, 2016

FFTW docs confirm that it is possible:

You can install single and long-double precision versions of FFTW, which replace double with float and long double, respectively (see Installation and Customization). To use these interfaces, you:

Link to the single/long-double libraries; on Unix, -lfftw3f or -lfftw3l instead of (or in addition to) -lfftw3. (You can link to the different-precision libraries simultaneously.)
Include the same <fftw3.h> header file.
Replace all lowercase instances of ‘fftw_’ with ‘fftwf_’ or ‘fftwl_’ for single or long-double precision, respectively. (fftw_complex becomes fftwf_complex, fftw_execute becomes fftwf_execute, etcetera.)

http://www.fftw.org/doc/Precision.html

Consequently, I am not in favour of splitting FFTW into separate packages with different number types.

@citibeth
Copy link
Member

I don't know much about packages which use fftw, but it is possible that there are packages which need all variants at once:

OK, that's a convincing argument. So we're stuck with the crazy triple-build...

I'm fine with the changes from AutotoolsPackage to Package. If you're not taking advantage of separate build phases, AutotoolsPackage is basically identical.

But it might not be in the future. My feeling is... if it uses Autotools, we should extend AutotoolsPackage, even if that's a NOP for now. This will help even with simple questions, like "How many Autotools projects are in Spack?" (answerable via grep).

I don't mind variant forwarding up the dag. I think I've seen this once before. It's very clever, and a much better solution than trying to forward variants down the dag with our current broken logic.

In that case, should we be moving our other stuff to forward up the DAG? If we're going to make a change in policy, we should do it in a public way, not buried inside an obscure PR.

However... I'm not so sure it's a good idea. There's an analog here with autotools/cmake. Suppose I have feature x. One way to enable it is to root around in the system, see if the libraries that would allow me to enable x are present, and then enable it only if I find those libraries. The other way is to require the user to ask for x at the top level --- and then give an error if the libraries needed for x are not present. Over time, people have decided that the latter approach is preferable. It is more predictable and transparent to the user. Same thing with our current Spack approach of forwarding variants down.

Another reason to not start casually forwarding variants up is that the variant is then undocumented. When you say spack info, it tells you what variants a package has. If variants are forwarded up (without any additional support from Spack), then spack info nfft will not tell users that a +float variant is available (or that it needs to be enabled on fftw).

Also... forwarding variants up only works if the forwarding comes from only one dependency. The +xwindows variant (actually +X) can not work in that way; what if some of your dependencies are built +X and some not, then what variant do you infer for yourself?

Another problem is that (as done here), this trick only works for one level. If something depends on nfft, it cannot check for 'float' in spec['nfft'].

For all those reasons... let's please not go down this path until / unless we've thought it through and developed appropriate support for it. Whatever the pros/cons of the existing approach, there is no reason (that I can see) that would prevent this package from just following the established pattern.

@mkuron
Copy link
Contributor Author

mkuron commented Dec 20, 2016

But it might not be in the future. My feeling is... if it uses Autotools, we should extend AutotoolsPackage, even if that's a NOP for now.

Ok, I have switched it back now and also made that change to the fftw package.

In that case, should we be moving our other stuff to forward up the DAG?

Let me add some background information about PFFT, NFFT and PNFFT: these are all (more or less) thin wrappers around FFTW. In an alternate universe, they might have been part of FFTW. Therefore, it makes no sense to build the [P|N|PN]FFT with flags other than those FFTW was built with. So even if forwarding the variant is not a good idea in general, it seems like a reasonable thing to do here.

Another problem is that (as done here), this trick only works for one level. If something depends on nfft, it cannot check for 'float' in spec['nfft'].

In that case, it would need to check for 'float' in spec['fftw'].

For all those reasons... let's please not go down this path until / unless we've thought it through and developed appropriate support for it.

Strictly speaking, we have already gone down that path. The nfft and pfft packages already do exactly the same.

@citibeth
Copy link
Member

citibeth commented Dec 20, 2016 via email

@adamjstewart
Copy link
Member

As far as variant forwarding up the DAG goes, @tgamblin himself recommended this approach here: #491 (comment)

@citibeth
Copy link
Member

citibeth commented Dec 21, 2016 via email

@becker33
Copy link
Member

I am not opposed for forwarding variants up the DAG for bindings and other libraries that serve as wrapper layers. The key point of distinction for me is that no one uses pnfft or another wrapper without understanding that it in turn depends on fftw. I would not want to see the same forwarding applied to dealii and one of its many dependencies, because I would be concerned about that being hidden from the user.

In general, I prefer variants to be forwarded down the DAG because that allows variants to be specified at the root level from the command line, which I think is the most intuitive interface. However, I don't think that this preference should be taken as rigid even if we agree unanimously, because for any heuristic there will invariably be cases in which the opposite is the most intuitive way to do things.

@citibeth
Copy link
Member

citibeth commented Mar 24, 2017 via email

@adamjstewart
Copy link
Member

I don't think there's an easy way to convert either of these packages to AutotoolsPackage. The problem is that AutotoolsPackage runs ./configure, make, and make install. These packages run these steps 3 separate times. spack build pnfft wouldn't even make sense in that context.

@citibeth
Copy link
Member

citibeth commented Mar 24, 2017 via email

@adamjstewart
Copy link
Member

@citibeth What would be the benefit of that...?

@citibeth
Copy link
Member

citibeth commented Mar 24, 2017 via email

@adamjstewart
Copy link
Member

shrugs

I guess I'm fine with it using AutotoolsPackage if @mkuron wants to do that, and I'm fine with the way it is as well. As long as it builds 😄

@mkuron
Copy link
Contributor Author

mkuron commented Mar 24, 2017

I see that class AutotoolsPackage contains phases = ['autoreconf', 'configure', 'build', 'install']. Would it make sense to replace that with phases = ['autoreconf', 'install'] in the FFTW-derived packages?, instead of passing on the non-implemented phases as suggested by @citibeth?

@citibeth
Copy link
Member

citibeth commented Mar 24, 2017 via email

@mkuron
Copy link
Contributor Author

mkuron commented Mar 25, 2017

Ok, done.

@alalazo
Copy link
Member

alalazo commented Mar 25, 2017

@mkuron I don't think the commands spack configure ... and spack build ... will behave as expected. Can you confirm that?

@mkuron
Copy link
Contributor Author

mkuron commented Mar 25, 2017

These commands cannot behave as expected since these packages do not allow separation of the build phases. The commands will just configure/build the double-precision version.

@alalazo
Copy link
Member

alalazo commented Mar 25, 2017

@mkuron If the packages are such that you can build them out of source, I think the cleanest solution will be reordering the operations, i.e. do all the configure in the configure(self, spec, prefix) callback etc.

@alalazo
Copy link
Member

alalazo commented Mar 25, 2017

These commands cannot behave as expected since these packages do not allow separation of the build phases

I am not sure of that. We have multiple calls to make & Co. so it may be possible that it is a problem of our implementation rather than the packages not allowing separate configurations / builds.

@mkuron
Copy link
Contributor Author

mkuron commented Mar 25, 2017

Separate out-of-source builds sound like a good idea. Will try that and update the pull request if it works.

@mkuron
Copy link
Contributor Author

mkuron commented Mar 25, 2017

Ok, seems to be working. Please have a look.

Copy link
Member

@adamjstewart adamjstewart left a comment

Choose a reason for hiding this comment

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

If this works, I like this design much better! Can you confirm that you can build all of these packages with all variants enabled?

# Base options
options = [
'--prefix={0}'.format(prefix),
'--enable-shared',
'--enable-threads'
]
] + self.configure_args()
Copy link
Member

Choose a reason for hiding this comment

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

self.configure_args() will only contain --prefix, right? That means it will be duplicated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it's empty.

Copy link
Member

Choose a reason for hiding this comment

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

Oh right, the default configure() adds --prefix to configure_args(). I still think we don't need this call if we know it's empty.

@@ -102,29 +103,56 @@ def install(self, spec, prefix):
float_options.append('--enable-sse2')
Copy link
Member

Choose a reason for hiding this comment

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

I can't comment on lines that you didn't change, but there's an autoreconf call up above. Might want to move that to the autoreconf stage.

with working_dir('quad'):
make("install")

def check(self, spec, prefix):
Copy link
Member

Choose a reason for hiding this comment

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

I would move this between build() and install() since that's when it runs.


# Build float/long double/quad variants
# Build double/float/long double/quad variants
with working_dir('double', create=True):
Copy link
Member

Choose a reason for hiding this comment

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

It seems like double is the only one that isn't optional. Maybe we should make this one a variant too just for uniformity?

@mkuron
Copy link
Contributor Author

mkuron commented Mar 25, 2017

I addressed your comments and looked over all my changes again.

I've successfully tested a representative sample of variants of FFTW along with NFFT. As PFFT and PNFFT have otherwise identical package files, those will also work.

@adamjstewart
Copy link
Member

I'm sure this could be simplified further with a list of variants and for loops that declare the variants, check to see if they're activate, create a working directory, and run make. But I'm satisfied with the way things are now. Does anyone else have any requests or is this good to merge?

@alalazo
Copy link
Member

alalazo commented Mar 25, 2017

@mkuron @adamjstewart If it is fine with you, I can take care of further simplifications in another PR.

@adamjstewart adamjstewart merged commit 55300d1 into spack:develop Mar 25, 2017
gmatteo added a commit to gmatteo/spack that referenced this pull request Mar 25, 2017
diaena pushed a commit to diaena/spack that referenced this pull request May 26, 2017
* pnfft: new package

* Convert some packages with overridden install from AutotoolsPackage to Package

* pnfft: fix URL

* Switch FFTW-derived packages back to AutotoolsPackage

* Disable unneeded build phases in FFTW and derived packages

* Separate build phases for FFTW and derived packages

* Fix broken merge

* fftw: pfft_patches for 3.3.6

* fftw: address @adamjstewart’s review comments
xavierandrade pushed a commit to xavierandrade/spack that referenced this pull request Jun 16, 2017
* pnfft: new package

* Convert some packages with overridden install from AutotoolsPackage to Package

* pnfft: fix URL

* Switch FFTW-derived packages back to AutotoolsPackage

* Disable unneeded build phases in FFTW and derived packages

* Separate build phases for FFTW and derived packages

* Fix broken merge

* fftw: pfft_patches for 3.3.6

* fftw: address @adamjstewart’s review comments
EmreAtes pushed a commit to EmreAtes/spack that referenced this pull request Jul 10, 2017
* pnfft: new package

* Convert some packages with overridden install from AutotoolsPackage to Package

* pnfft: fix URL

* Switch FFTW-derived packages back to AutotoolsPackage

* Disable unneeded build phases in FFTW and derived packages

* Separate build phases for FFTW and derived packages

* Fix broken merge

* fftw: pfft_patches for 3.3.6

* fftw: address @adamjstewart’s review comments
amklinv pushed a commit that referenced this pull request Jul 17, 2017
* pnfft: new package

* Convert some packages with overridden install from AutotoolsPackage to Package

* pnfft: fix URL

* Switch FFTW-derived packages back to AutotoolsPackage

* Disable unneeded build phases in FFTW and derived packages

* Separate build phases for FFTW and derived packages

* Fix broken merge

* fftw: pfft_patches for 3.3.6

* fftw: address @adamjstewart’s review comments
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.

None yet

6 participants