From 9defe2c1c24ffb655346a94307fd4b0409beeff6 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Tue, 13 Jun 2017 17:22:12 +0200 Subject: espresso: fixed compilation for 6.1 (elpa) and added support for hdf5 (#4483) * espresso: fixed compilation for 6.1 (elpa) and added support for hdf5 * espresso: addressed items in @davydden review * espresso: fixed behavior for espresso@:5.4.0 --- var/spack/repos/builtin/packages/elpa/package.py | 5 +- .../builtin/packages/espresso/dspev_drv_elpa.patch | 42 ++++++++ .../repos/builtin/packages/espresso/package.py | 109 +++++++++++++-------- 3 files changed, 113 insertions(+), 43 deletions(-) create mode 100644 var/spack/repos/builtin/packages/espresso/dspev_drv_elpa.patch (limited to 'var') diff --git a/var/spack/repos/builtin/packages/elpa/package.py b/var/spack/repos/builtin/packages/elpa/package.py index 5f9a86956b..403e48f2cb 100644 --- a/var/spack/repos/builtin/packages/elpa/package.py +++ b/var/spack/repos/builtin/packages/elpa/package.py @@ -53,8 +53,11 @@ class Elpa(AutotoolsPackage): # override default implementation which returns static lib @property def libs(self): + + libname = 'libelpa_openmp' if '+openmp' in self.spec else 'libelpa' + return find_libraries( - ['libelpa'], root=self.prefix, shared=True, recurse=True + libname, root=self.prefix, shared=True, recurse=True ) build_directory = 'spack-build' diff --git a/var/spack/repos/builtin/packages/espresso/dspev_drv_elpa.patch b/var/spack/repos/builtin/packages/espresso/dspev_drv_elpa.patch new file mode 100644 index 0000000000..153bcf2ef5 --- /dev/null +++ b/var/spack/repos/builtin/packages/espresso/dspev_drv_elpa.patch @@ -0,0 +1,42 @@ +diff -ruN LAXlib-orig/dspev_drv.f90 LAXlib/dspev_drv.f90 +--- a/LAXlib/dspev_drv.f90 2017-06-12 15:00:46.157372185 +0200 ++++ b/LAXlib/dspev_drv.f90 2017-06-12 15:01:19.937371580 +0200 +@@ -708,11 +708,11 @@ + + #if defined(__ELPA_2016) + ! -> ELPA 2016.11.001_pre +- ierr = elpa_get_communicators(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) +- success = solve_evp_real_1stage(n, n, s, lds, w, vv, lds,SIZE(s,2),nb ,mpi_comm_rows, mpi_comm_cols, ortho_comm) ++ !ierr = elpa_get_communicators(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) ++ !success = solve_evp_real_1stage(n, n, s, lds, w, vv, lds,SIZE(s,2),nb ,mpi_comm_rows, mpi_comm_cols, ortho_comm) + ! -> ELPA 2016.05.003 +- !ierr = get_elpa_row_col_comms(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) +- !success = solve_evp_real_1stage(n, n, s, lds, w, vv, lds,SIZE(s,2),nb ,mpi_comm_rows, mpi_comm_cols) ++ ierr = get_elpa_row_col_comms(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) ++ success = solve_evp_real_1stage(n, n, s, lds, w, vv, lds,SIZE(s,2),nb ,mpi_comm_rows, mpi_comm_cols) + #elif defined(__ELPA_2015) + ierr = get_elpa_row_col_comms(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) + ierr = solve_evp_real(n, n, s, lds, w, vv, lds,SIZE(s,2),nb ,mpi_comm_rows, mpi_comm_cols) +diff -ruN LAXlib-orig/zhpev_drv.f90 LAXlib/zhpev_drv.f90 +--- a/LAXlib/zhpev_drv.f90 2017-06-12 15:00:46.157372185 +0200 ++++ b/LAXlib/zhpev_drv.f90 2017-06-12 15:02:09.309370696 +0200 +@@ -1519,13 +1519,13 @@ + + #if defined(__ELPA_2016) + ! -> ELPA 2016.11.001_pre +- ierr = elpa_get_communicators(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) +- success = solve_evp_complex_1stage_double(n, n, h, size(h,1), w, v, size(h,1), size(h,2), nb, & +- mpi_comm_rows, mpi_comm_cols, ortho_comm) ++ !ierr = elpa_get_communicators(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) ++ !success = solve_evp_complex_1stage_double(n, n, h, size(h,1), w, v, size(h,1), size(h,2), nb, & ++ ! mpi_comm_rows, mpi_comm_cols, ortho_comm) + ! -> ELPA 2016.05.003 +- !ierr = get_elpa_row_col_comms(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) +- !success = solve_evp_complex(n, n, h, size(h,1), w, v, size(h,1), size(h,2), nb, & +- ! mpi_comm_rows, mpi_comm_cols) ++ ierr = get_elpa_row_col_comms(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) ++ success = solve_evp_complex(n, n, h, size(h,1), w, v, size(h,1), size(h,2), nb, & ++ mpi_comm_rows, mpi_comm_cols) + #elif defined(__ELPA_2015) + ierr = get_elpa_row_col_comms(ortho_comm, my_prow, my_pcol,mpi_comm_rows, mpi_comm_cols) + ierr = solve_evp_complex(n, n, h, size(h,1), w, v, size(h,1), size(h,2), nb, & diff --git a/var/spack/repos/builtin/packages/espresso/package.py b/var/spack/repos/builtin/packages/espresso/package.py index 097049370a..b53374fa9e 100644 --- a/var/spack/repos/builtin/packages/espresso/package.py +++ b/var/spack/repos/builtin/packages/espresso/package.py @@ -22,16 +22,17 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## +import glob +import os.path + from spack import * -import os -from glob import glob class Espresso(Package): - """QE is an integrated suite of Open-Source computer codes for - electronic-structure calculations and materials modeling at - the nanoscale. It is based on density-functional theory, plane - waves, and pseudopotentials. + """Quantum-ESPRESSO is an integrated suite of Open-Source computer codes + for electronic-structure calculations and materials modeling at the + nanoscale. It is based on density-functional theory, plane waves, and + pseudopotentials. """ homepage = 'http://quantum-espresso.org' @@ -55,34 +56,43 @@ class Espresso(Package): variant('scalapack', default=True, description='Enables scalapack support') variant('elpa', default=True, description='Uses elpa as an eigenvalue solver') + # Support for HDF5 has been added starting in version 6.1.0 and is + # still experimental, therefore we default to False for the variant + variant('hdf5', default=False, description='Builds with HDF5 support') + depends_on('blas') depends_on('lapack') - depends_on('mpi', when='+mpi') - depends_on('fftw~mpi', when='~mpi') - depends_on('fftw+mpi', when='+mpi') - # TODO : + mpi needed to avoid false dependencies installation depends_on('scalapack', when='+scalapack+mpi') - depends_on('elpa@2016.11.001.pre', when='@6.1.0+elpa') + + depends_on('fftw+mpi', when='+mpi') + depends_on('fftw~mpi', when='~mpi') + depends_on('elpa+openmp', when='+elpa+openmp') + depends_on('elpa~openmp', when='+elpa~openmp') + depends_on('hdf5', when='+hdf5') + + patch('dspev_drv_elpa.patch', when='@6.1 ^elpa@2016.05.004') + patch('dspev_drv_elpa.patch', when='@6.1 ^elpa@2016.05.003') + + # We can't ask for scalapack or elpa if we don't want MPI + conflicts('+scalapack', when='~mpi') + conflicts('+elpa', when='~mpi') + + # Elpa is formally supported by @:5.4.0, but QE configure searches + # for it in the wrong folders (or tries to download it within + # the build directory). Instead of patching Elpa to provide the + # folder QE expects as a link, we issue a conflict here. + conflicts('+elpa', when='@:5.4.0') + conflicts('+hdf5', when='@:5.4.0') # Spurious problems running in parallel the Makefile # generated by the configure parallel = False - def check_variants(self, spec): - error = 'you cannot ask for \'+{variant}\' when \'+mpi\' is not active' - if '+scalapack' in spec and '~mpi' in spec: - raise RuntimeError(error.format(variant='scalapack')) - if '+elpa' in spec and ('~mpi' in spec or '~scalapack' in spec): - raise RuntimeError(error.format(variant='elpa')) - def install(self, spec, prefix): - self.check_variants(spec) - options = [ - '-prefix=%s' % (prefix.bin if spec.satisfies('@:5.4.0') else - prefix) - ] + prefix_path = prefix.bin if '@:5.4.0' in spec else prefix + options = ['-prefix={0}'.format(prefix_path)] if '+mpi' in spec: options.append('--enable-parallel') @@ -91,38 +101,53 @@ class Espresso(Package): options.append('--enable-openmp') if '+scalapack' in spec: - options.append('--with-scalapack=yes') + scalapack_option = 'intel' if '^intel-mkl' in spec else 'yes' + options.append('--with-scalapack={0}'.format(scalapack_option)) if '+elpa' in spec: - if spec.satisfies('@:5.4.0'): - options.append('--with-elpa=yes') - else: - options.extend([ - '--with-elpa-include={0}'.format( - join_path(spec['elpa'].prefix, - 'include', - 'elpa-{0}'.format(str(spec['elpa'].version)), - 'modules') - ), - '--with-elpa-lib={0}'.format(spec['elpa'].libs.joined()) - ]) + + # Spec for elpa + elpa = spec['elpa'] + + # Find where the Fortran module resides + elpa_module = find(elpa.prefix, 'elpa.mod') + + # Compute the include directory from there: versions + # of espresso prior to 6.1 requires -I in front of the directory + elpa_include = '' if '@6.1:' in spec else '-I' + elpa_include += os.path.dirname(elpa_module[0]) + + options.extend([ + '--with-elpa-include={0}'.format(elpa_include), + '--with-elpa-lib={0}'.format(elpa.libs[0]) + ]) + + if '+hdf5' in spec: + options.append('--with-hdf5={0}'.format(spec['hdf5'].prefix)) # Add a list of directories to search search_list = [] for dependency_spec in spec.dependencies(): - search_list.extend([dependency_spec.prefix.lib, - dependency_spec.prefix.lib64]) + search_list.extend([ + dependency_spec.prefix.lib, + dependency_spec.prefix.lib64 + ]) search_list = " ".join(search_list) - options.append('LIBDIRS=%s' % search_list) - options.append('F90=%s' % os.environ['FC']) + + options.extend([ + 'LIBDIRS={0}'.format(search_list), + 'F90={0}'.format(env['SPACK_FC']), + 'CC={0}'.format(env['SPACK_CC']) + ]) configure(*options) + make('all') - if spec.satisfies('platform=darwin'): + if 'platform=darwin' in spec: mkdirp(prefix.bin) - for filename in glob("bin/*.x"): + for filename in glob.glob("bin/*.x"): install(filename, prefix.bin) else: make('install') -- cgit v1.2.3-60-g2f50