Skip to content

qmcpack: new package#4907

Merged
tgamblin merged 70 commits intospack:developfrom
wscullin:develop
Oct 6, 2017
Merged

qmcpack: new package#4907
tgamblin merged 70 commits intospack:developfrom
wscullin:develop

Conversation

@wscullin
Copy link
Copy Markdown
Contributor

This adds QMCPACK along with patches to Quantum Espresso for using Quantum Espresso in QMCPACK workflows.

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

Mostly looks good, although I'm not sure how I feel about a 41,000 line patch file...

version('3.1.0', 'bdf3acd090557acdb6cab5ddbf7c7960')
version('3.0.0', '75f9cf70e6cc6d8b7ff11a86340da43d')

# This download method is untrusted, and is not recommend by th Spack manual.
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.

typo: th -> the

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch

'CMake/FindLibxml2QMC.cmake')

print dir(self.spec['hdf5'].prefix)
print self.spec['boost'].prefix
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.

You should remove these debug statements.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

D'oh.


if 'cflags' in self.compiler.flags:
c_flags = ' '.join(self.compiler.flags['cflags'])
args.append('-DCMAKE_C_FLAGS={0}'.format(c_flags))
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 think these are handled automatically by the compiler wrappers?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As of the time of the pull request, CMakePackage wasn't passing the flags forward. I wasn't entirely sure if that was a bug or not.

FWIW, the developers of qmcpack provide their own logic for deciding on processor flags that includes the equivalent of -march=native in CMake/${Compiler}.cmake that are possibly bad ideas in multi-architecture environments, but the Intel version at least is smart enough to not override Spack if CMAKE_C_FLAGS includes -x or -ax and is cumulative for GNU.

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.

Are you sure they aren't being passed forward? They won't appear in the logs, but they should be added through the compiler wrappers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Pretty sure. I'll give things another go in a bit - I was getting architectural mismatches until that was added.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

FYI. I think that I saw other Spack packages that use CMake doing similar things.

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.

@becker33 Can you take a look at this? If every package has to manually access the flags added in compilers.yaml, then they aren't very helpful.

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.

@naromero77 There are currently no packages in Spack that access self.compiler.flags.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@adamjstewart You are right, my own poor recollection.

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.

The package should be getting its flags through CFLAGS, CXXFLAGS, etc environment variables. If you want them to be injected through the compiler wrapper instead, overwrite the default_flag_handler method or the specific cflags_handler method or equivalent for another flag. The documentation of flag handlers should give you the idiom for passing them to the compiler directly, it is

def default_flag_handler(self, env, flag_val):
    return flag_val[1]

If you want to send them to a different environment variable (if your cmake is reading different variables than expected) then you can override the flag handlers for that as well.

@adamjstewart @naromero77 does this answer your questions?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@wscullin just making sure william is still following.

args.append('-DMPI_BASE_DIR:PATH={0}'.format(self.spec['mpi'].prefix))
else:
args.append('-DCMAKE_C_COMPILER={0}'.format(self.compiler.cc))
args.append('-DCMAKE_CXX_COMPILER={0}'.format(self.compiler.cxx))
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.

Definitely don't want these in here. self.compiler.cc is the actual compiler, so you would be bypassing Spack's compiler wrappers. These should already be set, so you can remove the else clause.

# This install method creates the top level directory
# and copies the bin subdirectory into the appropriate
# location. We do not copy include or lib at this time due
# to technical difficulties.
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.

Can you elaborate on "technical difficulties"? Just curious.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will clarify the text. This is on the qmcpack end. The libraries qmcpack generates lack headers, but an include directory is created... with a header for fftw.


# install nexus
install_tree(join_path(self.stage.source_path, 'nexus'),
join_path(prefix,'nexus'))
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.

Relative paths are fine. prefix now supports arbitrary sub-directories. prefix should already exist. What about:

def install(self, spec, prefix):
    install_tree('manual', prefix.manual
    install_tree('nexus', prefix.nexus)
    
    with working_dir(self.build_directory):
        install_tree('bin', prefix.bin)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixing this.

"""Run ctest after building binary. Use 'spack install --run-tests qmcpack'.
It can take 24 hours to run all the regression tests and unit tests. """
self.ctest
pass
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've never seen this before in a package. What is self.ctest? By default, Spack runs make test. Is this different than ctest?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll have to ask @naromero77 for details.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes, self.ctest runs ctest at the command line. It is different from make test, but in the same spirit. It is a builtin function/method in the Spack CMake Python module. Actually, its not robust enough for what I want to do. As ctest should be able to take command line arguments which the Python module does not support.

Regarding the large patch file for QE. Didn't realize it was that big. The patch file is also part of the QMCPACK distribution -- instead of committing the patch into Spack can we have Spack patch QE using the patch file from the downloaded QMCPACK distribution. I think William and I were just trying to follow the convention of other Spack packages.

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.

It is a builtin function/method in the Spack CMake Python module.

You mean in CMakePackage? I don't see it anywhere.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

Ah, I see.

As ctest should be able to take command line arguments which the Python module does not support.

Actually, it can take command-line arguments, and you don't need self:

ctest('VERBOSE=ON')

'double precision) version for gpu and cpu '
'(experimental)')
variant('gui', default=False,
description='Install with Matplotlib (long installation time)')
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.

We don't actually do line-length checks on variants (or any other directive).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

sorry, not following, what is the requested action here?

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.

Not necessarily requesting a change, but I noticed that you changed all the variants from being on a single line to multiple lines (presumably to make sure that it is under 80 characters). I'm just saying that you don't need to do this as we ignore variants.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, travis seemed upset about PEP8 compliance via Flake.


# To build with QMCPACK's hdf5 interface we version 5.3.0
# and hdf5
conflicts('+qmcpackconv', when='@5.4:')
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.

Is the patch compatible with 5.3.1? What about 5.2.0?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As far as I know, it is only compatible with 5.3.0.

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.

Then you either want:

conflicts('+qmcpackconv', when='@5.3.1:')
conflicts('+qmcpackconv', when='@:5.2.999')

or no conflicts() at all. Unfortunately there is currently no not in the spec syntax.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok, simple to fix. Yes, there did not seem to be a syntax for only use this version.

# and hdf5
conflicts('+qmcpackconv', when='@5.4:')
depends_on('hdf5+mpi', when='+qmcpackconv+mpi')
depends_on('hdf5~mpi', when='+qmcpackconv~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.

You should also add depends_on('hdf5', when='+qmcpackconv'). Otherwise you can't do spack install espresso +qmcpackconv ^[email protected].

depends_on('hdf5+mpi', when='+qmcpackconv+mpi')
depends_on('hdf5~mpi', when='+qmcpackconv~mpi')
patch('add_pw2qmcpack_to_espresso-5.3.0.diff',
when='@5.3.0+qmcpackconv')
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 can be on a single line. We don't do line-length checks on patches.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok

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

You should also add depends_on('hdf5') here. Otherwise, you can't do spack install qmcpack ^[email protected]. Concretizer bug.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok

depends_on('blas')
depends_on('lapack')
depends_on('fftw+mpi', when='+mpi')
depends_on('fftw~mpi', when='~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.

Same here, add depends_on('fftw').

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok


filter_file(r'$ENV{LIBXML2_HOME}/lib',
'${LIBXML2_HOME}/lib $ENV{LIBXML2_HOME}/lib',
'CMake/FindLibxml2QMC.cmake')
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 should go in a patch() function.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@wscullin William, can you take care of this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@naromero77 certainly.

# This install method creates the top level directory
# and copies the bin subdirectory into the appropriate
# location. We do not copy include or lib at this time due
# to technical difficulties in qmcpack itself.
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 text is duplicated below. Let's just put it in the install() docstring.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ok

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Oct 1, 2017

@wscullin @naromero77: I think all the PRs needed to merge this are merged now, specifically #5132 and #5476. If you update the patching to use #5476 and the test dependencies to use #5132 we should be good to go.

@naromero77
Copy link
Copy Markdown
Contributor

@tgamblin Thanks again. I think it should be straightforward, only thing that might slow us down is that @wscullin and I are trying to get MKL detection to work robustly. We have made some progress, but we are still hitting some problems. I will have @wscullin work on those conflicts. I think he may merged the test stuff early before the final changes. In any case, hopefully by early next week.

@davydden
Copy link
Copy Markdown
Member

davydden commented Oct 1, 2017

trying to get MKL detection to work robustly

i would rather be explicit and make sure you use exactly those libs provided by libs() function, see http://spack.readthedocs.io/en/latest/packaging_guide.html#blas-lapack-and-scalapack-libraries


# Include MKL flags
if 'intel-mkl' in self.spec:
args.append('-DBLA_VENDOR=Intel10_64lp_seq')
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.

looks like here you ingnore altogether any options used in intel-mkl:

    ilp64 [off]       True, False       64 bit integers
    threads [none]    openmp, none      Multithreading support

that's why packages should really use libs() interface.

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 you use CMake, can you not explicitly set Blas/Lapack libraries, like for example here. Of course, it depends on how CMake is being used inside...

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.

the same is with other Blas/Lapack, say the build system will be free to pick up single threaded or multithreaded Atlas libs, regardless of package settings:

threads [none]    pthreads, none    Multithreading support

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think QMCPACK is not compatible with threaded BLAS. This may be for legacy reason related to the OpenMP runtime which may no longer be true. We only support sequential without 64-bit integers.

Copy link
Copy Markdown
Member

@davydden davydden Oct 2, 2017

Choose a reason for hiding this comment

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

We only support sequential without 64-bit integers.

you need to add conflicts, something like:

conflicts('^intel-mkl threads=openmp')

to make sure users don't use qmcpack in a stack of software with multithreaded blas.


# Include MKL flags
if 'intel-mkl' in self.spec:
args.append('-DBLA_VENDOR=Intel10_64lp_seq')
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 you use CMake, can you not explicitly set Blas/Lapack libraries, like for example here. Of course, it depends on how CMake is being used inside...

def setup_environment(self, spack_env, run_env):
# Add MKLROOT/lib to the CMAKE_PREFIX_PATH to enable CMake to find MKL libraries.
# MKLROOT environment variable must be defined for this to work properly.
if 'intel-mkl' in self.spec:
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 you set Blas/Lapack explicitly, you won'd need to bother with this part at all.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The way CMAKE in QMCPACK is designed we use the built-in support for finding MKL. I believe this works with the Intel compiler without any extra effort. The complication comes when using non-Intel compilers with MKL. I will take a closer look at those references, thanks.

Copy link
Copy Markdown
Member

@davydden davydden Oct 2, 2017

Choose a reason for hiding this comment

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

The way CMAKE in QMCPACK is designed we use the built-in support for finding MKL

by built-in, you probably refer to find_package, then it should possible to disable the whole search and explicitly specify blas/lapack.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@davydden Here is the issue which I am not sure how to fix. My understanding is that with a non-Intel compiler, the MKL library directory must be included in the CMAKE_PREFIX_PATH -- otherwise, the built-in CMake (part of CMake, not part of QMCPACK) won't properly detect MKL.

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.

the MKL library directory must be included in the CMAKE_PREFIX_PATH

it's up to how CMake is being used. But certainly not a requirement! I regularly compile with GCC+Intel-MKL at least these two package: trilinos and dealii and everything works as expected.

Copy link
Copy Markdown
Member

@davydden davydden Oct 2, 2017

Choose a reason for hiding this comment

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

@naromero77 if you directly call FIND_PACKAGE(LAPACK), then try following the way we configure dealii in spack: <package>_FOUND=TRUE should disable any search and just provide the libs using Spack's interfaces to blas/lapack.

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Oct 1, 2017

@naromero77: if you want, we could merge a version that does not (yet) work with MKL, and you could leave that part for a new PR. It looks like @davydden has also provided some advice, though, so perhaps that will help.

@naromero77
Copy link
Copy Markdown
Contributor

@tgamblin Yes, @wscullin and I may leave the MKL support for a new PR if we can't quickly fix it.

@prckent
Copy link
Copy Markdown
Contributor

prckent commented Oct 2, 2017

@naromero77 Leave for a later PR unless the MKL fix is trivial.

[ We are looking for a person skilled with Kitware tools to thoroughly update QMCPACK's entire CMake/CTest configuration. This will also require checking and possibly updating the known optimum build recipe for every single platform and verifying we have no regressions, so not a quick job. ]

@naromero77
Copy link
Copy Markdown
Contributor

@tgamblin I am having some trouble with the patch function. I am using it as follows.

patch_url = '<some url>'
patch_checksum = '<some checksum>'
depends_on('[email protected]~elpa~scalapack~mpi',
                     patches=patch(patch_url, sha256=patch_checksum, expand=False),
                     when='~mpi')

However, this is the error that I am getting:

==> Created stage in /Users/naromero/spack/var/spack/stage/espresso-5.3.0-d2o2gdnsemhg2ia75w4ira4qnqi74ynd
==> Error: AttributeError: 'str' object has no attribute 'parent'
AttributeError: AttributeError: 'str' object has no attribute 'parent'

/Users/naromero/spack/lib/spack/spack/package.py:1042, in do_patch:
     9             has_patch_fun = hasattr(self, 'patch') and callable(self.patch)
     10    
     11            # Get the patches from the spec (this is a shortcut for the MV-variant)
  >> 12            patches = self.spec.patches
     13    
     14            # If there are no patches, note it.
     15            if not patches and not has_patch_fun:


@naromero77
Copy link
Copy Markdown
Contributor

The problem occurs whether you have a patch file or patch url. The patch checksum seems to make it into the spec.
[email protected]%[email protected]~elpa~hdf5~mpi~openmp patches=0d8d7ba805313ddd4c02ee32c96d2f12e7091e9e82e22671d3ad5a24247860c4 ~scalapack arch=darwin-sierra-x86_64 ^[email protected]%[email protected]~doc+ncurses+openssl+ownlibs~qt arch=darwin-sierra-x86_64 ^[email protected]%[email protected]+double+float+long_double~mpi~openmp~pfft_patches~quad arch=darwin-sierra-x86_64 ^[email protected]%[email protected]~debug~external-blas+lapacke+shared arch=darwin-sierra-x86_64

If I print the values of mvar and patches from spec.py, I get:
patches from spec.py ['49ffcd644e190dc5efcb2fab491177811ea746c1a526f75d77118c2706574358']
mvar from spec.py patches=

@naromero77
Copy link
Copy Markdown
Contributor

@tgamblin I am done with changes to this PR. @davydden I commented out the MKL detection code until @wscullin and I have time to study QMCPACK's CMake and your package more carefully.

@tgamblin
Copy link
Copy Markdown
Member

tgamblin commented Oct 6, 2017

@naromero77: great! Thanks for all the effort on this!

@tgamblin tgamblin merged commit 3d8d3e8 into spack:develop Oct 6, 2017
@wscullin wscullin deleted the develop branch October 31, 2018 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants