From 6d255dc17caf27d705b9901c17ec75f86308b685 Mon Sep 17 00:00:00 2001 From: crivella Date: Thu, 29 Feb 2024 17:04:06 +0100 Subject: [PATCH 01/38] Modularizing QE easyblock, and making sure every version uses correct set of flags --- easybuild/easyblocks/q/quantumespresso.py | 407 ++++++++++++++-------- 1 file changed, 265 insertions(+), 142 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index de3ba337190..3d18467e56f 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -27,22 +27,24 @@ @author: Kenneth Hoste (Ghent University) @author: Ake Sandgren (HPC2N, Umea University) +@author: Davide Grassano (CECAM, EPFL) """ import fileinput import os import re import shutil import sys -from easybuild.tools import LooseVersion import easybuild.tools.environment as env import easybuild.tools.toolchain as toolchain -from easybuild.easyblocks.generic.configuremake import ConfigureMake from easybuild.framework.easyconfig import CUSTOM +from easybuild.tools import LooseVersion from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import copy_dir, copy_file from easybuild.tools.modules import get_software_root, get_software_version +from easybuild.easyblocks.generic.configuremake import ConfigureMake + class EB_QuantumESPRESSO(ConfigureMake): """Support for building and installing Quantum ESPRESSO.""" @@ -70,123 +72,263 @@ def patch_step(self): """Patch files from build dir (not start dir).""" super(EB_QuantumESPRESSO, self).patch_step(beginpath=self.builddir) - def configure_step(self): - """Custom configuration procedure for Quantum ESPRESSO.""" - - # compose list of DFLAGS (flag, value, keep_stuff) - # for guidelines, see include/defs.h.README in sources - dflags = [] - - repls = [] - - extra_libs = [] - - comp_fam_dflags = { - toolchain.INTELCOMP: '-D__INTEL', - toolchain.GCC: '-D__GFORTRAN -D__STD_F95', - } - comp_fam = self.toolchain.comp_family() - if comp_fam in comp_fam_dflags: - dflags.append(comp_fam_dflags[comp_fam]) - else: + def _add_compiler_flags(self, comp_fam): + """Add compiler flags to the build.""" + allowed_toolchains = [toolchain.INTELCOMP, toolchain.GCC] + if comp_fam not in allowed_toolchains: raise EasyBuildError("EasyBuild does not yet have support for QuantumESPRESSO with toolchain %s" % comp_fam) - - if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: - self.cfg.update('configopts', '--enable-openmp') - dflags.append(" -D__OPENMP") - - if self.toolchain.options.get('usempi', None): - dflags.append('-D__MPI -D__PARA') - else: + + if LooseVersion(self.version) >= LooseVersion("6.1"): + if comp_fam == toolchain.INTELCOMP: + self._dflags += ["-D__INTEL_COMPILER"] + elif comp_fam == toolchain.GCC: + self._dflags += ["-D__GFORTRAN__"] + elif LooseVersion(self.version) >= LooseVersion("5.2.1"): + if comp_fam == toolchain.INTELCOMP: + self._dflags += ["-D__INTEL"] + elif comp_fam == toolchain.GCC: + self._dflags += ["-D__GFORTRAN"] + elif LooseVersion(self.version) >= LooseVersion("5.0"): + if comp_fam == toolchain.INTELCOMP: + self._dflags += ["-D__INTEL"] + elif comp_fam == toolchain.GCC: + self._dflags += ["-D__GFORTRAN", "-D__STD_F95"] + + def _add_openmp(self): + """Add OpenMP support to the build.""" + if not self.toolchain.options.get('openmp', False) and not self.cfg['hybrid']: + return + self.cfg.update('configopts', '--enable-openmp') + if LooseVersion(self.version) >= LooseVersion("6.2.1"): + self._dflags += ["-D_OPENMP"] + elif LooseVersion(self.version) >= LooseVersion("5.0"): + self._dflags += ["-D__OPENMP"] + + def _add_mpi(self): + """Add MPI support to the build.""" + if not self.toolchain.options.get('usempi', False): self.cfg.update('configopts', '--disable-parallel') - - if self.cfg['with_scalapack']: - dflags.append(" -D__SCALAPACK") - if self.toolchain.options.get('usempi', None): - if get_software_root("impi") and get_software_root("imkl"): + return + self.cfg.update('configopts', '--enable-parallel') + if LooseVersion(self.version) >= LooseVersion("6.0"): + self._dflags += ["-D__MPI"] + elif LooseVersion(self.version) >= LooseVersion("5.0"): + self._dflags += ["-D__MPI", "-D__PARA"] + + def _add_scalapack(self, comp_fam): + """Add ScaLAPACK support to the build.""" + if not self.cfg['with_scalapack']: + self.cfg.update('configopts', '--without-scalapack') + return + + if comp_fam == toolchain.INTELCOMP: + if get_software_root("impi") and get_software_root("imkl"): + if LooseVersion(self.version) >= LooseVersion("6.2"): self.cfg.update('configopts', '--with-scalapack=intel') + elif LooseVersion(self.version) >= LooseVersion("5.1.1"): + self.cfg.update('configopts', '--with-scalapack=intel') + self._repls += [ + ('SCALAPACK_LIBS', os.getenv('LIBSCALAPACK'), False) + ] + elif LooseVersion(self.version) >= LooseVersion("5.0"): + self.cfg.update('configopts', '--with-scalapack=yes') + self._dflags += ["-D__SCALAPACK"] + elif comp_fam == toolchain.GCC: + if get_software_root("OpenMPI") and get_software_root("ScaLAPACK"): + self.cfg.update('configopts', '--with-scalapack=yes') + self._dflags += ["-D__SCALAPACK"] else: self.cfg.update('configopts', '--without-scalapack') + def _add_libxc(self): + """Add libxc support to the build.""" libxc = get_software_root("libxc") - if libxc: - libxc_v = get_software_version("libxc") - if LooseVersion(libxc_v) < LooseVersion("3.0.1"): - raise EasyBuildError("Must use libxc >= 3.0.1") - dflags.append(" -D__LIBXC") - repls.append(('IFLAGS', '-I%s' % os.path.join(libxc, 'include'), True)) - if LooseVersion(self.version) < LooseVersion("6.5"): - extra_libs.append(" -lxcf90 -lxc") - else: - extra_libs.append(" -lxcf90 -lxcf03 -lxc") + if not libxc: + return + + libxc_v = get_software_version("libxc") + if LooseVersion(libxc_v) < LooseVersion("3.0.1"): + raise EasyBuildError("Must use libxc >= 3.0.1") + if LooseVersion(self.version) >= LooseVersion("7.0"): + if LooseVersion(libxc_v) < LooseVersion("6.0.0"): + raise EasyBuildError("libxc support for QuantumESPRESSO 7.0 only available for libxc >= 6.0.0") + self.cfg.update('configopts', '--with-libxc=yes') + self.cfg.update('configopts', f'--with-libxc-prefix={libxc}') + elif LooseVersion(self.version) >= LooseVersion("6.4"): + if LooseVersion(libxc_v) >= LooseVersion("5.0"): + raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc <= 4.3.4") + self.cfg.update('configopts', '--with-libxc=yes') + self.cfg.update('configopts', f'--with-libxc-prefix={libxc}') + else: + self.extra_libs.append(" -lxcf90 -lxc") + - hdf5 = get_software_root("HDF5") - if hdf5: - self.cfg.update('configopts', '--with-hdf5=%s' % hdf5) - dflags.append(" -D__HDF5") - hdf5_lib_repl = '-L%s/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' % hdf5 - repls.append(('HDF5_LIB', hdf5_lib_repl, False)) + self._dflags += ["-D__LIBXC"] + def _add_hdf5(self): + """Add HDF5 support to the build.""" + hdf5 = get_software_root("HDF5") + if not hdf5: + return + self.cfg.update('configopts', '--with-hdf5=%s' % hdf5) + self._dflags += ["-D__HDF5"] + hdf5_lib_repl = '-L%s/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' % hdf5 + self._repls += [('HDF5_LIB', hdf5_lib_repl, False)] + + def _add_elpa(self): + """Add ELPA support to the build.""" elpa = get_software_root("ELPA") - if elpa: - if not self.cfg['with_scalapack']: - raise EasyBuildError("ELPA requires ScaLAPACK but 'with_scalapack' is set to False") - - elpa_v = get_software_version("ELPA") - if LooseVersion(self.version) >= LooseVersion("7"): - # NOTE: from version 7, there are only three __ELPA flags, - # - __ELPA for ELPA releases 2018.11 and beyond; - # - __ELPA_2016 for ELPA releases 2016.11, 2017.x and 2018.05; - # - __ELPA_2015 for ELPA releases 2015.x and 2016.05; - # see https://github.com/QEF/q-e/commit/351f4871fee3c8045d75592dde606b2279b08e02 - if LooseVersion(elpa_v) >= LooseVersion("2018.11"): - dflags.append('-D__ELPA') - elif LooseVersion(elpa_v) >= LooseVersion("2016.11"): - dflags.append('-D__ELPA_2016') - else: - dflags.append('-D__ELPA_2015') - - elpa_min_ver = "2015" - elif LooseVersion(self.version) >= LooseVersion("6"): - # NOTE: Quantum Espresso 6.x should use -D__ELPA_ for corresponding ELPA version - # However for ELPA VERSION >= 2017.11 Quantum Espresso needs to use ELPA_2018 - # because of outdated bindings. See: https://xconfigure.readthedocs.io/en/latest/elpa/ - if LooseVersion("2018") > LooseVersion(elpa_v) >= LooseVersion("2017.11"): - dflags.append('-D__ELPA_2018') - else: - # get year from LooseVersion - elpa_year_v = elpa_v.split('.')[0] - dflags.append('-D__ELPA_%s' % elpa_year_v) + if not elpa: + return + + elpa_v = get_software_version("ELPA") + + if LooseVersion(elpa_v) < LooseVersion("2015"): + raise EasyBuildError("ELPA versions lower than 2015 are not supported") + + if LooseVersion(self.version) >= LooseVersion("6.8"): + if LooseVersion(elpa_v) >= LooseVersion("2018.11"): + self._dflags += ["-D__ELPA"] + elif LooseVersion(elpa_v) >= LooseVersion("2016.11"): + self._dflags += [f"-D__ELPA_2016"] + elif LooseVersion(elpa_v) >= LooseVersion("2015"): + self._dflags += [f"-D__ELPA_2015"] + elif LooseVersion(self.version) >= LooseVersion("6.6"): + if LooseVersion(elpa_v) >= LooseVersion("2020"): + raise EasyBuildError("ELPA support for QuantumESPRESSO 6.6 only available up to v2019.xx") + elif LooseVersion(elpa_v) >= LooseVersion("2018"): + self._dflags += ["-D__ELPA"] + elif LooseVersion(elpa_v) >= LooseVersion("2015"): + elpa_year_v = elpa_v.split('.')[0] + self._dflags += [f"-D__ELPA_{elpa_year_v}"] + elif LooseVersion(self.version) >= LooseVersion("6.0"): + if LooseVersion(elpa_v) >= LooseVersion("2017"): + raise EasyBuildError("ELPA support for QuantumESPRESSO 6.x only available up to v2016.xx") + elif LooseVersion(elpa_v) >= LooseVersion("2016"): + self._dflags += ["-D__ELPA_2016"] + elif LooseVersion(elpa_v) >= LooseVersion("2015"): + self._dflags += ["-D__ELPA_2015"] + elif LooseVersion(self.version) >= LooseVersion("5.4"): + self._dflags += ["-D__ELPA"] + self.cfg.update('configopts', f'--with-elpa={elpa}') + return + elif LooseVersion(self.version) >= LooseVersion("5.1.1"): + self.cfg.update('configopts', f'--with-elpa={elpa}') + return + else: + raise EasyBuildError("ELPA support is only available in QuantumESPRESSO 5.1.1 and later") + + if self.toolchain.options.get('openmp', False): + elpa_include = f'elpa_openmp-{elpa_v}' + elpa_lib = 'libelpa_openmp.a' + else: + elpa_include = f'elpa-{elpa_v}' + elpa_lib = 'libelpa.a' + elpa_include = os.path.join(elpa, 'include', elpa_include, 'modules') + elpa_lib = os.path.join(elpa, 'lib', elpa_lib) + self._repls += [ + ('IFLAGS', f'-I{elpa_include}', True) + ] + self.cfg.update('configopts', f'--with-elpa-include={elpa_include}') + self.cfg.update('configopts', f'--with-elpa-lib={elpa_lib}') + if LooseVersion(self.version) < LooseVersion("7.0"): + self._repls += [ + ('SCALAPACK_LIBS', f'{elpa_lib} {os.getenv("LIBSCALAPACK")}', False) + ] + + def _add_fftw(self, comp_fam): + """Add FFTW support to the build.""" + if self.toolchain.options.get('openmp', False): + libfft = os.getenv('LIBFFT_MT') + else: + libfft = os.getenv('LIBFFT') - elpa_min_ver = "2016.11.001.pre" - else: - elpa_min_ver = "2015" - dflags.append('-D__ELPA_2015 -D__ELPA') + if LooseVersion(self.version) >= LooseVersion("5.2.1"): + if comp_fam == toolchain.INTELCOMP and get_software_root("imkl"): + self._dflags += ["-D__DFTI"] + elif libfft: + self._dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] + env.setvar('FFTW_LIBS', libfft) + elif LooseVersion(self.version) >= LooseVersion("5.0"): + if libfft: + self._dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] + env.setvar('FFTW_LIBS', libfft) + + def _add_ace(self): + """Add ACE support to the build.""" + if not self.cfg['with_ace']: + return + + if LooseVersion(self.version) >= LooseVersion("6.2"): + self.log.warning("ACE support is not available in QuantumESPRESSO >= 6.2") + elif LooseVersion(self.version) >= LooseVersion("6.0"): + self._dflags += ["-D__EXX_ACE"] + else: + self.log.warning("ACE support is not available in QuantumESPRESSO < 6.0") - if LooseVersion(elpa_v) < LooseVersion(elpa_min_ver): - raise EasyBuildError("QuantumESPRESSO %s needs ELPA to be " + - "version %s or newer", self.version, elpa_min_ver) + def _add_beef(self): + """Add BEEF support to the build.""" + if LooseVersion(self.version) == LooseVersion("6.6"): + libbeef = get_software_root("libbeef") + if libbeef: + self._dflags += ["-Duse_beef"] + libbeef_lib = os.path.join(libbeef, 'lib') + self.cfg.update('configopts', f'--with-libbeef-prefix={libbeef_lib}') + self._repls += [ + ('BEEF_LIBS_SWITCH', 'external', False), + ('BEEF_LIBS', f'{os.path.join(libbeef_lib, "libbeef.a")}', False) + ] + + def _adjust_compiler_flags(self, comp_fam): + """Adjust compiler flags based on the compiler family and code version.""" + if comp_fam == toolchain.INTELCOMP: + if LooseVersion("6.0") <= LooseVersion(self.version) <= LooseVersion("6.4"): + i_mpi_cc = os.getenv('I_MPI_CC', '') + if i_mpi_cc == 'icx': + env.setvar('I_MPI_CC', 'icc') # Needed cor clib/qmmm_aux.c using implicitly + # self._repls += [ + # ('CFLAGS', '--std=c90', True), # Needed cor clib/qmmm_aux.c using implicitly + # ] + pass + # self.cfg.update('configopts', '--with-scalapack=intel') + # self._dflags += ["-D__INTEL"] + elif comp_fam == toolchain.GCC: + # self._dflags += ["-D__GFORTRAN"] + pass - if self.toolchain.options.get('openmp', False): - elpa_include = 'elpa_openmp-%s' % elpa_v - elpa_lib = 'libelpa_openmp.a' - else: - elpa_include = 'elpa-%s' % elpa_v - elpa_lib = 'libelpa.a' - elpa_include = os.path.join(elpa, 'include', elpa_include) - repls.append(('IFLAGS', '-I%s' % os.path.join(elpa_include, 'modules'), True)) - self.cfg.update('configopts', '--with-elpa-include=%s' % elpa_include) - elpa_lib = os.path.join(elpa, 'lib', elpa_lib) - self.cfg.update('configopts', '--with-elpa-lib=%s' % elpa_lib) - if comp_fam == toolchain.INTELCOMP: - # set preprocessor command (-E to stop after preprocessing, -C to preserve comments) - cpp = "%s -E -C" % os.getenv('CC') - repls.append(('CPP', cpp, False)) - env.setvar('CPP', cpp) + + + def configure_step(self): + """Custom configuration procedure for Quantum ESPRESSO.""" + + # compose list of DFLAGS (flag, value, keep_stuff) + # for guidelines, see include/defs.h.README in sources + self._dflags = dflags = [] + self._repls = repls = [] + self.extra_libs = extra_libs = [] + + comp_fam = self.toolchain.comp_family() - # also define $FCCPP, but do *not* include -C (comments should not be preserved when preprocessing Fortran) - env.setvar('FCCPP', "%s -E" % os.getenv('CC')) + self._add_compiler_flags(comp_fam) + self._add_openmp() + self._add_mpi() + self._add_scalapack(comp_fam) + self._add_libxc() + self._add_hdf5() + self._add_elpa() + self._add_fftw(comp_fam) + self._add_ace() + self._add_beef() + + # if comp_fam == toolchain.INTELCOMP: + # # set preprocessor command (-E to stop after preprocessing, -C to preserve comments) + # cpp = "%s -E -C" % os.getenv('CC') + # repls.append(('CPP', cpp, False)) + # env.setvar('CPP', cpp) + + # # also define $FCCPP, but do *not* include -C (comments should not be preserved when preprocessing Fortran) + # env.setvar('FCCPP', "%s -E" % os.getenv('CC')) if comp_fam == toolchain.INTELCOMP: # Intel compiler must have -assume byterecl (see install/configure) @@ -198,35 +340,13 @@ def configure_step(self): f90_flags.append('-fallow-argument-mismatch') repls.append(('F90FLAGS', ' '.join(f90_flags), True)) - super(EB_QuantumESPRESSO, self).configure_step() + self._adjust_compiler_flags(comp_fam) - if self.toolchain.options.get('openmp', False): - libfft = os.getenv('LIBFFT_MT') - else: - libfft = os.getenv('LIBFFT') - if libfft: - if "fftw3" in libfft: - dflags.append('-D__FFTW3') - else: - dflags.append('-D__FFTW') - env.setvar('FFTW_LIBS', libfft) - - if get_software_root('ACML'): - dflags.append('-D__ACML') - - if self.cfg['with_ace']: - dflags.append(" -D__EXX_ACE") + super(EB_QuantumESPRESSO, self).configure_step() # always include -w to supress warnings dflags.append('-w') - if LooseVersion(self.version) >= LooseVersion("6.6"): - dflags.append(" -Duse_beef") - libbeef = get_software_root("libbeef") - if libbeef: - repls.append(('BEEF_LIBS_SWITCH', 'external', False)) - repls.append(('BEEF_LIBS', '%s/lib/libbeef.a' % libbeef, False)) - repls.append(('DFLAGS', ' '.join(dflags), False)) # complete C/Fortran compiler and LD flags @@ -236,19 +356,22 @@ def configure_step(self): # obtain library settings libs = [] - num_libs = ['BLAS', 'LAPACK', 'FFT'] - if self.cfg['with_scalapack']: - num_libs.extend(['SCALAPACK']) - for lib in num_libs: - if self.toolchain.options.get('openmp', False): - val = os.getenv('LIB%s_MT' % lib) - else: - val = os.getenv('LIB%s' % lib) - if lib == 'SCALAPACK' and elpa: - val = ' '.join([elpa_lib, val]) - repls.append(('%s_LIBS' % lib, val, False)) - libs.append(val) - libs = ' '.join(libs) + if comp_fam == toolchain.GCC: + num_libs = ['BLAS', 'LAPACK', 'FFT'] + if self.cfg['with_scalapack']: + num_libs.extend(['SCALAPACK']) + elpa = get_software_root('ELPA') + elpa_lib = os.path.join(elpa or '', 'lib', 'libelpa.a' if self.toolchain.options.get('openmp', False) else 'libelpa_openmp.a') + for lib in num_libs: + if self.toolchain.options.get('openmp', False): + val = os.getenv('LIB%s_MT' % lib) + else: + val = os.getenv('LIB%s' % lib) + if lib == 'SCALAPACK' and elpa: + val = ' '.join([elpa_lib, val]) + repls.append(('%s_LIBS' % lib, val, False)) + libs.append(val) + libs = ' '.join(libs) repls.append(('BLAS_LIBS_SWITCH', 'external', False)) repls.append(('LAPACK_LIBS_SWITCH', 'external', False)) @@ -289,7 +412,7 @@ def configure_step(self): "\t$(MPIF90) $(F90FLAGS) -c $*.F90 -o $*.o", line) - if LooseVersion(self.version) >= LooseVersion("6.6"): + if LooseVersion(self.version) == LooseVersion("6.6"): # fix order of BEEF_LIBS in QE_LIBS line = re.sub(r"^(QELIBS\s*=[ \t]*)(.*) \$\(BEEF_LIBS\) (.*)$", r"QELIBS = $(BEEF_LIBS) \2 \3", line) From ea27b0c681afc65e3da900a1470c4c23c45ca565 Mon Sep 17 00:00:00 2001 From: crivella Date: Fri, 1 Mar 2024 15:49:48 +0100 Subject: [PATCH 02/38] Adjusted and tested eb with most versions of QE from 5.x to 7.x --- easybuild/easyblocks/q/quantumespresso.py | 54 +++++++++++------------ 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 3d18467e56f..b7fe3f24de0 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -63,10 +63,11 @@ def __init__(self, *args, **kwargs): """Add extra config options specific to Quantum ESPRESSO.""" super(EB_QuantumESPRESSO, self).__init__(*args, **kwargs) - if LooseVersion(self.version) >= LooseVersion("6"): - self.install_subdir = "qe-%s" % self.version - else: - self.install_subdir = "espresso-%s" % self.version + self.install_subdir = f"qe-{self.version}" + # if LooseVersion(self.version) >= LooseVersion("6"): + # self.install_subdir = f"qe-{self.version}" + # else: + # self.install_subdir = f"espresso-{self.version}" def patch_step(self): """Patch files from build dir (not start dir).""" @@ -76,7 +77,7 @@ def _add_compiler_flags(self, comp_fam): """Add compiler flags to the build.""" allowed_toolchains = [toolchain.INTELCOMP, toolchain.GCC] if comp_fam not in allowed_toolchains: - raise EasyBuildError("EasyBuild does not yet have support for QuantumESPRESSO with toolchain %s" % comp_fam) + raise EasyBuildError(f"EasyBuild does not yet have support for QuantumESPRESSO with toolchain {comp_fam}") if LooseVersion(self.version) >= LooseVersion("6.1"): if comp_fam == toolchain.INTELCOMP: @@ -170,11 +171,17 @@ def _add_hdf5(self): hdf5 = get_software_root("HDF5") if not hdf5: return - self.cfg.update('configopts', '--with-hdf5=%s' % hdf5) + self.cfg.update('configopts', f'--with-hdf5={hdf5}') self._dflags += ["-D__HDF5"] - hdf5_lib_repl = '-L%s/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' % hdf5 + hdf5_lib_repl = f'-L{hdf5}/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' self._repls += [('HDF5_LIB', hdf5_lib_repl, False)] + if LooseVersion(self.version) >= LooseVersion("6.2.1"): + pass + else: + # Should be experimental in 6.0 but gives segfaults when used + raise EasyBuildError("HDF5 support is only available in QuantumESPRESSO 6.2.1 and later") + def _add_elpa(self): """Add ELPA support to the build.""" elpa = get_software_root("ELPA") @@ -321,15 +328,6 @@ def configure_step(self): self._add_ace() self._add_beef() - # if comp_fam == toolchain.INTELCOMP: - # # set preprocessor command (-E to stop after preprocessing, -C to preserve comments) - # cpp = "%s -E -C" % os.getenv('CC') - # repls.append(('CPP', cpp, False)) - # env.setvar('CPP', cpp) - - # # also define $FCCPP, but do *not* include -C (comments should not be preserved when preprocessing Fortran) - # env.setvar('FCCPP', "%s -E" % os.getenv('CC')) - if comp_fam == toolchain.INTELCOMP: # Intel compiler must have -assume byterecl (see install/configure) repls.append(('F90FLAGS', '-fpp -assume byterecl', True)) @@ -364,12 +362,12 @@ def configure_step(self): elpa_lib = os.path.join(elpa or '', 'lib', 'libelpa.a' if self.toolchain.options.get('openmp', False) else 'libelpa_openmp.a') for lib in num_libs: if self.toolchain.options.get('openmp', False): - val = os.getenv('LIB%s_MT' % lib) + val = os.getenv(f'LIB{lib}_MT') else: - val = os.getenv('LIB%s' % lib) + val = os.getenv(f'LIB{lib}') if lib == 'SCALAPACK' and elpa: val = ' '.join([elpa_lib, val]) - repls.append(('%s_LIBS' % lib, val, False)) + repls.append((f'{lib}_LIBS', val, False)) libs.append(val) libs = ' '.join(libs) @@ -385,7 +383,7 @@ def configure_step(self): raise EasyBuildError("Found FoX external module, QuantumESPRESSO" + "must use the version they include with the source.") - self.log.debug("List of replacements to perform: %s" % repls) + self.log.debug(f"List of replacements to perform: {repls}") if LooseVersion(self.version) >= LooseVersion("6"): make_ext = '.inc' @@ -400,9 +398,9 @@ def configure_step(self): # need to use [ \t]* instead of \s*, because vars may be undefined as empty, # and we don't want to include newlines if keep: - line = re.sub(r"^(%s\s*=[ \t]*)(.*)$" % k, r"\1\2 %s" % v, line) + line = re.sub(fr"^({k}\s*=[ \t]*)(.*)$", fr"\1\2 {v}", line) else: - line = re.sub(r"^(%s\s*=[ \t]*).*$" % k, r"\1%s" % v, line) + line = re.sub(fr"^({k}\s*=[ \t]*).*$", fr"\1{v}", line) # fix preprocessing directives for .f90 files in make.sys if required if LooseVersion(self.version) < LooseVersion("6.0"): @@ -425,7 +423,7 @@ def configure_step(self): except IOError as err: raise EasyBuildError("Failed to patch %s: %s", fn, err) - self.log.debug("Contents of patched %s: %s" % (fn, open(fn, "r").read())) + self.log.debug(f"Contents of patched {fn}: {open(fn, 'r').read()}") # patch default make.sys for wannier if LooseVersion(self.version) >= LooseVersion("5"): @@ -434,14 +432,14 @@ def configure_step(self): fn = os.path.join(self.cfg['start_dir'], 'plugins', 'install', 'make_wannier90.sys') try: for line in fileinput.input(fn, inplace=1, backup='.orig.eb'): - line = re.sub(r"^(LIBS\s*=\s*).*", r"\1%s" % libs, line) + line = re.sub(r"^(LIBS\s*=\s*).*", fr"\1{libs}", line) sys.stdout.write(line) except IOError as err: raise EasyBuildError("Failed to patch %s: %s", fn, err) - self.log.debug("Contents of patched %s: %s" % (fn, open(fn, "r").read())) + self.log.debug(f"Contents of patched {fn}: {open(fn, 'r').read()}") # patch Makefile of want plugin wantprefix = 'want-' @@ -482,7 +480,7 @@ def configure_step(self): targetdir = os.path.join(self.builddir, self.install_subdir) for dirname in dirnames: shutil.move(os.path.join(self.builddir, dirname), os.path.join(targetdir, dirname)) - self.log.info("Moved %s into %s" % (dirname, targetdir)) + self.log.info(f"Moved {dirname} into {targetdir}") dirname_head = dirname.split('-')[0] # Handle the case where the directory is preceded by 'qe-' @@ -514,7 +512,7 @@ def install_step(self): # Pick up files not installed in bin def copy_binaries(path): full_dir = os.path.join(self.cfg['start_dir'], path) - self.log.info("Looking for binaries in %s" % full_dir) + self.log.info(f"Looking for binaries in {full_dir}") for filename in os.listdir(full_dir): full_path = os.path.join(full_dir, filename) if os.path.isfile(full_path): @@ -595,7 +593,7 @@ def sanity_check_step(self): bins.extend(["generate_vdW_kernel_table.x"]) if LooseVersion(self.version) <= LooseVersion("5"): bins.extend(["path_int.x"]) - if LooseVersion(self.version) < LooseVersion("5.3.0"): + if LooseVersion(self.version) < LooseVersion("5.3"): bins.extend(["band_plot.x", "bands_FS.x", "kvecs_FS.x"]) if 'pwcond' in targets or 'pwall' in targets or 'all' in targets: From 0805ae4f4ee4fc4ecef21c36a8a5ed28d33ab9c3 Mon Sep 17 00:00:00 2001 From: crivella Date: Fri, 1 Mar 2024 17:20:17 +0100 Subject: [PATCH 03/38] linting --- easybuild/easyblocks/q/quantumespresso.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index b7fe3f24de0..f1112a96753 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -78,7 +78,7 @@ def _add_compiler_flags(self, comp_fam): allowed_toolchains = [toolchain.INTELCOMP, toolchain.GCC] if comp_fam not in allowed_toolchains: raise EasyBuildError(f"EasyBuild does not yet have support for QuantumESPRESSO with toolchain {comp_fam}") - + if LooseVersion(self.version) >= LooseVersion("6.1"): if comp_fam == toolchain.INTELCOMP: self._dflags += ["-D__INTEL_COMPILER"] @@ -121,7 +121,7 @@ def _add_scalapack(self, comp_fam): if not self.cfg['with_scalapack']: self.cfg.update('configopts', '--without-scalapack') return - + if comp_fam == toolchain.INTELCOMP: if get_software_root("impi") and get_software_root("imkl"): if LooseVersion(self.version) >= LooseVersion("6.2"): @@ -146,7 +146,7 @@ def _add_libxc(self): libxc = get_software_root("libxc") if not libxc: return - + libxc_v = get_software_version("libxc") if LooseVersion(libxc_v) < LooseVersion("3.0.1"): raise EasyBuildError("Must use libxc >= 3.0.1") @@ -162,7 +162,6 @@ def _add_libxc(self): self.cfg.update('configopts', f'--with-libxc-prefix={libxc}') else: self.extra_libs.append(" -lxcf90 -lxc") - self._dflags += ["-D__LIBXC"] From 888f96606250c01bc050438fa0f728c5c3ce1f78 Mon Sep 17 00:00:00 2001 From: crivella Date: Mon, 4 Mar 2024 17:32:25 +0100 Subject: [PATCH 04/38] Using only one variable for dflags/repls/external_libs and removed f-strings --- easybuild/easyblocks/q/quantumespresso.py | 146 +++++++++++----------- 1 file changed, 72 insertions(+), 74 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index f1112a96753..28a40f288e2 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -63,11 +63,7 @@ def __init__(self, *args, **kwargs): """Add extra config options specific to Quantum ESPRESSO.""" super(EB_QuantumESPRESSO, self).__init__(*args, **kwargs) - self.install_subdir = f"qe-{self.version}" - # if LooseVersion(self.version) >= LooseVersion("6"): - # self.install_subdir = f"qe-{self.version}" - # else: - # self.install_subdir = f"espresso-{self.version}" + self.install_subdir = "qe-%s" % self.version def patch_step(self): """Patch files from build dir (not start dir).""" @@ -77,23 +73,23 @@ def _add_compiler_flags(self, comp_fam): """Add compiler flags to the build.""" allowed_toolchains = [toolchain.INTELCOMP, toolchain.GCC] if comp_fam not in allowed_toolchains: - raise EasyBuildError(f"EasyBuild does not yet have support for QuantumESPRESSO with toolchain {comp_fam}") + raise EasyBuildError("EasyBuild does not yet have support for QuantumESPRESSO with toolchain %s" % comp_fam) if LooseVersion(self.version) >= LooseVersion("6.1"): if comp_fam == toolchain.INTELCOMP: - self._dflags += ["-D__INTEL_COMPILER"] + self.dflags += ["-D__INTEL_COMPILER"] elif comp_fam == toolchain.GCC: - self._dflags += ["-D__GFORTRAN__"] + self.dflags += ["-D__GFORTRAN__"] elif LooseVersion(self.version) >= LooseVersion("5.2.1"): if comp_fam == toolchain.INTELCOMP: - self._dflags += ["-D__INTEL"] + self.dflags += ["-D__INTEL"] elif comp_fam == toolchain.GCC: - self._dflags += ["-D__GFORTRAN"] + self.dflags += ["-D__GFORTRAN"] elif LooseVersion(self.version) >= LooseVersion("5.0"): if comp_fam == toolchain.INTELCOMP: - self._dflags += ["-D__INTEL"] + self.dflags += ["-D__INTEL"] elif comp_fam == toolchain.GCC: - self._dflags += ["-D__GFORTRAN", "-D__STD_F95"] + self.dflags += ["-D__GFORTRAN", "-D__STD_F95"] def _add_openmp(self): """Add OpenMP support to the build.""" @@ -101,9 +97,9 @@ def _add_openmp(self): return self.cfg.update('configopts', '--enable-openmp') if LooseVersion(self.version) >= LooseVersion("6.2.1"): - self._dflags += ["-D_OPENMP"] + self.dflags += ["-D_OPENMP"] elif LooseVersion(self.version) >= LooseVersion("5.0"): - self._dflags += ["-D__OPENMP"] + self.dflags += ["-D__OPENMP"] def _add_mpi(self): """Add MPI support to the build.""" @@ -112,9 +108,9 @@ def _add_mpi(self): return self.cfg.update('configopts', '--enable-parallel') if LooseVersion(self.version) >= LooseVersion("6.0"): - self._dflags += ["-D__MPI"] + self.dflags += ["-D__MPI"] elif LooseVersion(self.version) >= LooseVersion("5.0"): - self._dflags += ["-D__MPI", "-D__PARA"] + self.dflags += ["-D__MPI", "-D__PARA"] def _add_scalapack(self, comp_fam): """Add ScaLAPACK support to the build.""" @@ -128,16 +124,16 @@ def _add_scalapack(self, comp_fam): self.cfg.update('configopts', '--with-scalapack=intel') elif LooseVersion(self.version) >= LooseVersion("5.1.1"): self.cfg.update('configopts', '--with-scalapack=intel') - self._repls += [ + self.repls += [ ('SCALAPACK_LIBS', os.getenv('LIBSCALAPACK'), False) ] elif LooseVersion(self.version) >= LooseVersion("5.0"): self.cfg.update('configopts', '--with-scalapack=yes') - self._dflags += ["-D__SCALAPACK"] + self.dflags += ["-D__SCALAPACK"] elif comp_fam == toolchain.GCC: if get_software_root("OpenMPI") and get_software_root("ScaLAPACK"): self.cfg.update('configopts', '--with-scalapack=yes') - self._dflags += ["-D__SCALAPACK"] + self.dflags += ["-D__SCALAPACK"] else: self.cfg.update('configopts', '--without-scalapack') @@ -154,26 +150,26 @@ def _add_libxc(self): if LooseVersion(libxc_v) < LooseVersion("6.0.0"): raise EasyBuildError("libxc support for QuantumESPRESSO 7.0 only available for libxc >= 6.0.0") self.cfg.update('configopts', '--with-libxc=yes') - self.cfg.update('configopts', f'--with-libxc-prefix={libxc}') + self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) elif LooseVersion(self.version) >= LooseVersion("6.4"): if LooseVersion(libxc_v) >= LooseVersion("5.0"): raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc <= 4.3.4") self.cfg.update('configopts', '--with-libxc=yes') - self.cfg.update('configopts', f'--with-libxc-prefix={libxc}') + self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) else: self.extra_libs.append(" -lxcf90 -lxc") - self._dflags += ["-D__LIBXC"] + self.dflags += ["-D__LIBXC"] def _add_hdf5(self): """Add HDF5 support to the build.""" hdf5 = get_software_root("HDF5") if not hdf5: return - self.cfg.update('configopts', f'--with-hdf5={hdf5}') - self._dflags += ["-D__HDF5"] - hdf5_lib_repl = f'-L{hdf5}/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' - self._repls += [('HDF5_LIB', hdf5_lib_repl, False)] + self.cfg.update('configopts', '--with-hdf5=%s' % hdf5) + self.dflags += ["-D__HDF5"] + hdf5_lib_repl = '-L%s/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' % hdf5 + self.repls += [('HDF5_LIB', hdf5_lib_repl, False)] if LooseVersion(self.version) >= LooseVersion("6.2.1"): pass @@ -194,52 +190,52 @@ def _add_elpa(self): if LooseVersion(self.version) >= LooseVersion("6.8"): if LooseVersion(elpa_v) >= LooseVersion("2018.11"): - self._dflags += ["-D__ELPA"] + self.dflags += ["-D__ELPA"] elif LooseVersion(elpa_v) >= LooseVersion("2016.11"): - self._dflags += [f"-D__ELPA_2016"] + self.dflags += ["-D__ELPA_2016"] elif LooseVersion(elpa_v) >= LooseVersion("2015"): - self._dflags += [f"-D__ELPA_2015"] + self.dflags += ["-D__ELPA_2015"] elif LooseVersion(self.version) >= LooseVersion("6.6"): if LooseVersion(elpa_v) >= LooseVersion("2020"): raise EasyBuildError("ELPA support for QuantumESPRESSO 6.6 only available up to v2019.xx") elif LooseVersion(elpa_v) >= LooseVersion("2018"): - self._dflags += ["-D__ELPA"] + self.dflags += ["-D__ELPA"] elif LooseVersion(elpa_v) >= LooseVersion("2015"): elpa_year_v = elpa_v.split('.')[0] - self._dflags += [f"-D__ELPA_{elpa_year_v}"] + self.dflags += ["-D__ELPA_%s" % elpa_year_v] elif LooseVersion(self.version) >= LooseVersion("6.0"): if LooseVersion(elpa_v) >= LooseVersion("2017"): raise EasyBuildError("ELPA support for QuantumESPRESSO 6.x only available up to v2016.xx") elif LooseVersion(elpa_v) >= LooseVersion("2016"): - self._dflags += ["-D__ELPA_2016"] + self.dflags += ["-D__ELPA_2016"] elif LooseVersion(elpa_v) >= LooseVersion("2015"): - self._dflags += ["-D__ELPA_2015"] + self.dflags += ["-D__ELPA_2015"] elif LooseVersion(self.version) >= LooseVersion("5.4"): - self._dflags += ["-D__ELPA"] - self.cfg.update('configopts', f'--with-elpa={elpa}') + self.dflags += ["-D__ELPA"] + self.cfg.update('configopts', '--with-elpa=%s' % elpa) return elif LooseVersion(self.version) >= LooseVersion("5.1.1"): - self.cfg.update('configopts', f'--with-elpa={elpa}') + self.cfg.update('configopts', '--with-elpa=%s' % elpa) return else: raise EasyBuildError("ELPA support is only available in QuantumESPRESSO 5.1.1 and later") if self.toolchain.options.get('openmp', False): - elpa_include = f'elpa_openmp-{elpa_v}' + elpa_include = 'elpa_openmp-%s' % elpa_v elpa_lib = 'libelpa_openmp.a' else: - elpa_include = f'elpa-{elpa_v}' + elpa_include = 'elpa-%s' % elpa_v elpa_lib = 'libelpa.a' elpa_include = os.path.join(elpa, 'include', elpa_include, 'modules') elpa_lib = os.path.join(elpa, 'lib', elpa_lib) - self._repls += [ - ('IFLAGS', f'-I{elpa_include}', True) + self.repls += [ + ('IFLAGS', '-I%s' % elpa_include, True) ] - self.cfg.update('configopts', f'--with-elpa-include={elpa_include}') - self.cfg.update('configopts', f'--with-elpa-lib={elpa_lib}') + self.cfg.update('configopts', '--with-elpa-include=%s' % elpa_include) + self.cfg.update('configopts', '--with-elpa-lib=%s' % elpa_lib) if LooseVersion(self.version) < LooseVersion("7.0"): - self._repls += [ - ('SCALAPACK_LIBS', f'{elpa_lib} {os.getenv("LIBSCALAPACK")}', False) + self.repls += [ + ('SCALAPACK_LIBS', '%s %s' % (elpa_lib, os.getenv("LIBSCALAPACK")), False) ] def _add_fftw(self, comp_fam): @@ -251,13 +247,13 @@ def _add_fftw(self, comp_fam): if LooseVersion(self.version) >= LooseVersion("5.2.1"): if comp_fam == toolchain.INTELCOMP and get_software_root("imkl"): - self._dflags += ["-D__DFTI"] + self.dflags += ["-D__DFTI"] elif libfft: - self._dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] + self.dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] env.setvar('FFTW_LIBS', libfft) elif LooseVersion(self.version) >= LooseVersion("5.0"): if libfft: - self._dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] + self.dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] env.setvar('FFTW_LIBS', libfft) def _add_ace(self): @@ -268,7 +264,7 @@ def _add_ace(self): if LooseVersion(self.version) >= LooseVersion("6.2"): self.log.warning("ACE support is not available in QuantumESPRESSO >= 6.2") elif LooseVersion(self.version) >= LooseVersion("6.0"): - self._dflags += ["-D__EXX_ACE"] + self.dflags += ["-D__EXX_ACE"] else: self.log.warning("ACE support is not available in QuantumESPRESSO < 6.0") @@ -277,12 +273,12 @@ def _add_beef(self): if LooseVersion(self.version) == LooseVersion("6.6"): libbeef = get_software_root("libbeef") if libbeef: - self._dflags += ["-Duse_beef"] + self.dflags += ["-Duse_beef"] libbeef_lib = os.path.join(libbeef, 'lib') - self.cfg.update('configopts', f'--with-libbeef-prefix={libbeef_lib}') - self._repls += [ + self.cfg.update('configopts', '--with-libbeef-prefix=%s' % libbeef_lib) + self.repls += [ ('BEEF_LIBS_SWITCH', 'external', False), - ('BEEF_LIBS', f'{os.path.join(libbeef_lib, "libbeef.a")}', False) + ('BEEF_LIBS', str(os.path.join(libbeef_lib, "libbeef.a")), False) ] def _adjust_compiler_flags(self, comp_fam): @@ -310,9 +306,9 @@ def configure_step(self): # compose list of DFLAGS (flag, value, keep_stuff) # for guidelines, see include/defs.h.README in sources - self._dflags = dflags = [] - self._repls = repls = [] - self.extra_libs = extra_libs = [] + self.dflags = [] + self.repls = [] + self.extra_libs = self.extra_libs = [] comp_fam = self.toolchain.comp_family() @@ -329,27 +325,27 @@ def configure_step(self): if comp_fam == toolchain.INTELCOMP: # Intel compiler must have -assume byterecl (see install/configure) - repls.append(('F90FLAGS', '-fpp -assume byterecl', True)) - repls.append(('FFLAGS', '-assume byterecl', True)) + self.repls.append(('F90FLAGS', '-fpp -assume byterecl', True)) + self.repls.append(('FFLAGS', '-assume byterecl', True)) elif comp_fam == toolchain.GCC: f90_flags = ['-cpp'] if LooseVersion(get_software_version('GCC')) >= LooseVersion('10'): f90_flags.append('-fallow-argument-mismatch') - repls.append(('F90FLAGS', ' '.join(f90_flags), True)) + self.repls.append(('F90FLAGS', ' '.join(f90_flags), True)) self._adjust_compiler_flags(comp_fam) super(EB_QuantumESPRESSO, self).configure_step() # always include -w to supress warnings - dflags.append('-w') + self.dflags.append('-w') - repls.append(('DFLAGS', ' '.join(dflags), False)) + self.repls.append(('DFLAGS', ' '.join(self.dflags), False)) # complete C/Fortran compiler and LD flags if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: - repls.append(('LDFLAGS', self.toolchain.get_flag('openmp'), True)) - repls.append(('(?:C|F90|F)FLAGS', self.toolchain.get_flag('openmp'), True)) + self.repls.append(('LDFLAGS', self.toolchain.get_flag('openmp'), True)) + self.repls.append(('(?:C|F90|F)FLAGS', self.toolchain.get_flag('openmp'), True)) # obtain library settings libs = [] @@ -361,18 +357,18 @@ def configure_step(self): elpa_lib = os.path.join(elpa or '', 'lib', 'libelpa.a' if self.toolchain.options.get('openmp', False) else 'libelpa_openmp.a') for lib in num_libs: if self.toolchain.options.get('openmp', False): - val = os.getenv(f'LIB{lib}_MT') + val = os.getenv('LIB%s_MT' % lib) else: - val = os.getenv(f'LIB{lib}') + val = os.getenv('LIB%s' % lib) if lib == 'SCALAPACK' and elpa: val = ' '.join([elpa_lib, val]) - repls.append((f'{lib}_LIBS', val, False)) + self.repls.append(('%s_LIBS' % lib, val, False)) libs.append(val) libs = ' '.join(libs) - repls.append(('BLAS_LIBS_SWITCH', 'external', False)) - repls.append(('LAPACK_LIBS_SWITCH', 'external', False)) - repls.append(('LD_LIBS', ' '.join(extra_libs + [os.getenv('LIBS')]), False)) + self.repls.append(('BLAS_LIBS_SWITCH', 'external', False)) + self.repls.append(('LAPACK_LIBS_SWITCH', 'external', False)) + self.repls.append(('LD_LIBS', ' '.join(self.extra_libs + [os.getenv('LIBS')]), False)) # Do not use external FoX. # FoX starts to be used in 6.2 and they use a patched version that @@ -382,7 +378,7 @@ def configure_step(self): raise EasyBuildError("Found FoX external module, QuantumESPRESSO" + "must use the version they include with the source.") - self.log.debug(f"List of replacements to perform: {repls}") + self.log.debug("List of replacements to perform: %s" % str(self.repls)) if LooseVersion(self.version) >= LooseVersion("6"): make_ext = '.inc' @@ -393,7 +389,7 @@ def configure_step(self): fn = os.path.join(self.cfg['start_dir'], 'make' + make_ext) try: for line in fileinput.input(fn, inplace=1, backup='.orig.eb'): - for (k, v, keep) in repls: + for (k, v, keep) in self.repls: # need to use [ \t]* instead of \s*, because vars may be undefined as empty, # and we don't want to include newlines if keep: @@ -422,7 +418,8 @@ def configure_step(self): except IOError as err: raise EasyBuildError("Failed to patch %s: %s", fn, err) - self.log.debug(f"Contents of patched {fn}: {open(fn, 'r').read()}") + with open(fn, "r") as f: + self.log.debug("Contents of patched %s: %s" % (fn, f.read())) # patch default make.sys for wannier if LooseVersion(self.version) >= LooseVersion("5"): @@ -438,7 +435,8 @@ def configure_step(self): except IOError as err: raise EasyBuildError("Failed to patch %s: %s", fn, err) - self.log.debug(f"Contents of patched {fn}: {open(fn, 'r').read()}") + with open(fn, "r") as f: + self.log.debug("Contents of patched %s: %s" % (fn, f.read())) # patch Makefile of want plugin wantprefix = 'want-' @@ -479,7 +477,7 @@ def configure_step(self): targetdir = os.path.join(self.builddir, self.install_subdir) for dirname in dirnames: shutil.move(os.path.join(self.builddir, dirname), os.path.join(targetdir, dirname)) - self.log.info(f"Moved {dirname} into {targetdir}") + self.log.info("Moved %s into %s" % (dirname, targetdir)) dirname_head = dirname.split('-')[0] # Handle the case where the directory is preceded by 'qe-' @@ -511,7 +509,7 @@ def install_step(self): # Pick up files not installed in bin def copy_binaries(path): full_dir = os.path.join(self.cfg['start_dir'], path) - self.log.info(f"Looking for binaries in {full_dir}") + self.log.info("Looking for binaries in %s" % full_dir) for filename in os.listdir(full_dir): full_path = os.path.join(full_dir, filename) if os.path.isfile(full_path): From 2115fef51a9e08ea7e2a15b8d0a087371c8a6803 Mon Sep 17 00:00:00 2001 From: crivella Date: Mon, 4 Mar 2024 18:35:58 +0100 Subject: [PATCH 05/38] Removed inline returns --- easybuild/easyblocks/q/quantumespresso.py | 62 +++++++++++------------ 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 28a40f288e2..db4dd1f3acf 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -93,49 +93,47 @@ def _add_compiler_flags(self, comp_fam): def _add_openmp(self): """Add OpenMP support to the build.""" - if not self.toolchain.options.get('openmp', False) and not self.cfg['hybrid']: - return - self.cfg.update('configopts', '--enable-openmp') - if LooseVersion(self.version) >= LooseVersion("6.2.1"): - self.dflags += ["-D_OPENMP"] - elif LooseVersion(self.version) >= LooseVersion("5.0"): - self.dflags += ["-D__OPENMP"] + if self.toolchain.options.get('openmp', False) or self.cfg['hybrid']: + self.cfg.update('configopts', '--enable-openmp') + if LooseVersion(self.version) >= LooseVersion("6.2.1"): + self.dflags += ["-D_OPENMP"] + elif LooseVersion(self.version) >= LooseVersion("5.0"): + self.dflags += ["-D__OPENMP"] def _add_mpi(self): """Add MPI support to the build.""" if not self.toolchain.options.get('usempi', False): self.cfg.update('configopts', '--disable-parallel') - return - self.cfg.update('configopts', '--enable-parallel') - if LooseVersion(self.version) >= LooseVersion("6.0"): - self.dflags += ["-D__MPI"] - elif LooseVersion(self.version) >= LooseVersion("5.0"): - self.dflags += ["-D__MPI", "-D__PARA"] + else: + self.cfg.update('configopts', '--enable-parallel') + if LooseVersion(self.version) >= LooseVersion("6.0"): + self.dflags += ["-D__MPI"] + elif LooseVersion(self.version) >= LooseVersion("5.0"): + self.dflags += ["-D__MPI", "-D__PARA"] def _add_scalapack(self, comp_fam): """Add ScaLAPACK support to the build.""" if not self.cfg['with_scalapack']: self.cfg.update('configopts', '--without-scalapack') - return - - if comp_fam == toolchain.INTELCOMP: - if get_software_root("impi") and get_software_root("imkl"): - if LooseVersion(self.version) >= LooseVersion("6.2"): - self.cfg.update('configopts', '--with-scalapack=intel') - elif LooseVersion(self.version) >= LooseVersion("5.1.1"): - self.cfg.update('configopts', '--with-scalapack=intel') - self.repls += [ - ('SCALAPACK_LIBS', os.getenv('LIBSCALAPACK'), False) - ] - elif LooseVersion(self.version) >= LooseVersion("5.0"): - self.cfg.update('configopts', '--with-scalapack=yes') - self.dflags += ["-D__SCALAPACK"] - elif comp_fam == toolchain.GCC: - if get_software_root("OpenMPI") and get_software_root("ScaLAPACK"): - self.cfg.update('configopts', '--with-scalapack=yes') - self.dflags += ["-D__SCALAPACK"] else: - self.cfg.update('configopts', '--without-scalapack') + if comp_fam == toolchain.INTELCOMP: + if get_software_root("impi") and get_software_root("imkl"): + if LooseVersion(self.version) >= LooseVersion("6.2"): + self.cfg.update('configopts', '--with-scalapack=intel') + elif LooseVersion(self.version) >= LooseVersion("5.1.1"): + self.cfg.update('configopts', '--with-scalapack=intel') + self.repls += [ + ('SCALAPACK_LIBS', os.getenv('LIBSCALAPACK'), False) + ] + elif LooseVersion(self.version) >= LooseVersion("5.0"): + self.cfg.update('configopts', '--with-scalapack=yes') + self.dflags += ["-D__SCALAPACK"] + elif comp_fam == toolchain.GCC: + if get_software_root("OpenMPI") and get_software_root("ScaLAPACK"): + self.cfg.update('configopts', '--with-scalapack=yes') + self.dflags += ["-D__SCALAPACK"] + else: + self.cfg.update('configopts', '--without-scalapack') def _add_libxc(self): """Add libxc support to the build.""" From 4727bef652e25a7175716902cbb658ae4cfc977e Mon Sep 17 00:00:00 2001 From: crivella Date: Mon, 4 Mar 2024 18:48:32 +0100 Subject: [PATCH 06/38] Removed superfluos comments --- easybuild/easyblocks/q/quantumespresso.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index db4dd1f3acf..e0cc0e5eadd 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -180,12 +180,12 @@ def _add_elpa(self): elpa = get_software_root("ELPA") if not elpa: return - + elpa_v = get_software_version("ELPA") if LooseVersion(elpa_v) < LooseVersion("2015"): raise EasyBuildError("ELPA versions lower than 2015 are not supported") - + if LooseVersion(self.version) >= LooseVersion("6.8"): if LooseVersion(elpa_v) >= LooseVersion("2018.11"): self.dflags += ["-D__ELPA"] @@ -217,7 +217,7 @@ def _add_elpa(self): return else: raise EasyBuildError("ELPA support is only available in QuantumESPRESSO 5.1.1 and later") - + if self.toolchain.options.get('openmp', False): elpa_include = 'elpa_openmp-%s' % elpa_v elpa_lib = 'libelpa_openmp.a' @@ -258,7 +258,7 @@ def _add_ace(self): """Add ACE support to the build.""" if not self.cfg['with_ace']: return - + if LooseVersion(self.version) >= LooseVersion("6.2"): self.log.warning("ACE support is not available in QuantumESPRESSO >= 6.2") elif LooseVersion(self.version) >= LooseVersion("6.0"): @@ -286,19 +286,9 @@ def _adjust_compiler_flags(self, comp_fam): i_mpi_cc = os.getenv('I_MPI_CC', '') if i_mpi_cc == 'icx': env.setvar('I_MPI_CC', 'icc') # Needed cor clib/qmmm_aux.c using implicitly - # self._repls += [ - # ('CFLAGS', '--std=c90', True), # Needed cor clib/qmmm_aux.c using implicitly - # ] - pass - # self.cfg.update('configopts', '--with-scalapack=intel') - # self._dflags += ["-D__INTEL"] elif comp_fam == toolchain.GCC: - # self._dflags += ["-D__GFORTRAN"] pass - - - def configure_step(self): """Custom configuration procedure for Quantum ESPRESSO.""" From d64c5208f5e8b9ddd6e07cda9912182c4eea02b7 Mon Sep 17 00:00:00 2001 From: crivella Date: Mon, 4 Mar 2024 19:00:58 +0100 Subject: [PATCH 07/38] Removed redundant `extra_libs` --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index e0cc0e5eadd..d39f6c3b22e 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -296,7 +296,7 @@ def configure_step(self): # for guidelines, see include/defs.h.README in sources self.dflags = [] self.repls = [] - self.extra_libs = self.extra_libs = [] + self.extra_libs = [] comp_fam = self.toolchain.comp_family() From 25eea48607408e5f00baf8dc6f1642a02352e8c5 Mon Sep 17 00:00:00 2001 From: Davide Grassano <34096612+Crivella@users.noreply.github.com> Date: Tue, 5 Mar 2024 09:25:55 +0100 Subject: [PATCH 08/38] Update easybuild/easyblocks/q/quantumespresso.py Co-authored-by: ocaisa --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index d39f6c3b22e..ae54688f5f9 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -285,7 +285,7 @@ def _adjust_compiler_flags(self, comp_fam): if LooseVersion("6.0") <= LooseVersion(self.version) <= LooseVersion("6.4"): i_mpi_cc = os.getenv('I_MPI_CC', '') if i_mpi_cc == 'icx': - env.setvar('I_MPI_CC', 'icc') # Needed cor clib/qmmm_aux.c using implicitly + env.setvar('I_MPI_CC', 'icc') # Needed as clib/qmmm_aux.c using implicitly elif comp_fam == toolchain.GCC: pass From 96ededcf4827b441c4421ce2454228b208298a18 Mon Sep 17 00:00:00 2001 From: crivella Date: Tue, 5 Mar 2024 09:50:35 +0100 Subject: [PATCH 09/38] More fixes --- easybuild/easyblocks/q/quantumespresso.py | 195 +++++++++++----------- 1 file changed, 96 insertions(+), 99 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index d39f6c3b22e..9a37cfc89cd 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -138,103 +138,100 @@ def _add_scalapack(self, comp_fam): def _add_libxc(self): """Add libxc support to the build.""" libxc = get_software_root("libxc") - if not libxc: - return - - libxc_v = get_software_version("libxc") - if LooseVersion(libxc_v) < LooseVersion("3.0.1"): - raise EasyBuildError("Must use libxc >= 3.0.1") - if LooseVersion(self.version) >= LooseVersion("7.0"): - if LooseVersion(libxc_v) < LooseVersion("6.0.0"): - raise EasyBuildError("libxc support for QuantumESPRESSO 7.0 only available for libxc >= 6.0.0") - self.cfg.update('configopts', '--with-libxc=yes') - self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) - elif LooseVersion(self.version) >= LooseVersion("6.4"): - if LooseVersion(libxc_v) >= LooseVersion("5.0"): - raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc <= 4.3.4") - self.cfg.update('configopts', '--with-libxc=yes') - self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) - else: - self.extra_libs.append(" -lxcf90 -lxc") + if libxc: + libxc_v = get_software_version("libxc") + if LooseVersion(libxc_v) < LooseVersion("3.0.1"): + raise EasyBuildError("Must use libxc >= 3.0.1") + if LooseVersion(self.version) >= LooseVersion("7.0"): + if LooseVersion(libxc_v) < LooseVersion("6.0.0"): + raise EasyBuildError("libxc support for QuantumESPRESSO 7.0 only available for libxc >= 6.0.0") + self.cfg.update('configopts', '--with-libxc=yes') + self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) + elif LooseVersion(self.version) >= LooseVersion("6.4"): + if LooseVersion(libxc_v) >= LooseVersion("5.0"): + raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc <= 4.3.4") + self.cfg.update('configopts', '--with-libxc=yes') + self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) + else: + self.extra_libs += ['-lxcf90', '-lxc'] - self.dflags += ["-D__LIBXC"] + self.dflags += ["-D__LIBXC"] def _add_hdf5(self): """Add HDF5 support to the build.""" hdf5 = get_software_root("HDF5") - if not hdf5: - return - self.cfg.update('configopts', '--with-hdf5=%s' % hdf5) - self.dflags += ["-D__HDF5"] - hdf5_lib_repl = '-L%s/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' % hdf5 - self.repls += [('HDF5_LIB', hdf5_lib_repl, False)] - - if LooseVersion(self.version) >= LooseVersion("6.2.1"): - pass - else: - # Should be experimental in 6.0 but gives segfaults when used - raise EasyBuildError("HDF5 support is only available in QuantumESPRESSO 6.2.1 and later") + if hdf5: + self.cfg.update('configopts', '--with-hdf5=%s' % hdf5) + self.dflags += ["-D__HDF5"] + hdf5_lib_repl = '-L%s/lib -lhdf5hl_fortran -lhdf5_hl -lhdf5_fortran -lhdf5 -lsz -lz -ldl -lm' % hdf5 + self.repls += [('HDF5_LIB', hdf5_lib_repl, False)] + + if LooseVersion(self.version) >= LooseVersion("6.2.1"): + pass + else: + # Should be experimental in 6.0 but gives segfaults when used + raise EasyBuildError("HDF5 support is only available in QuantumESPRESSO 6.2.1 and later") def _add_elpa(self): """Add ELPA support to the build.""" elpa = get_software_root("ELPA") - if not elpa: - return - - elpa_v = get_software_version("ELPA") - - if LooseVersion(elpa_v) < LooseVersion("2015"): - raise EasyBuildError("ELPA versions lower than 2015 are not supported") - - if LooseVersion(self.version) >= LooseVersion("6.8"): - if LooseVersion(elpa_v) >= LooseVersion("2018.11"): + if elpa: + elpa_v = get_software_version("ELPA") + + if LooseVersion(elpa_v) < LooseVersion("2015"): + raise EasyBuildError("ELPA versions lower than 2015 are not supported") + + flag = True + if LooseVersion(self.version) >= LooseVersion("6.8"): + if LooseVersion(elpa_v) >= LooseVersion("2018.11"): + self.dflags += ["-D__ELPA"] + elif LooseVersion(elpa_v) >= LooseVersion("2016.11"): + self.dflags += ["-D__ELPA_2016"] + elif LooseVersion(elpa_v) >= LooseVersion("2015"): + self.dflags += ["-D__ELPA_2015"] + elif LooseVersion(self.version) >= LooseVersion("6.6"): + if LooseVersion(elpa_v) >= LooseVersion("2020"): + raise EasyBuildError("ELPA support for QuantumESPRESSO 6.6 only available up to v2019.xx") + elif LooseVersion(elpa_v) >= LooseVersion("2018"): + self.dflags += ["-D__ELPA"] + elif LooseVersion(elpa_v) >= LooseVersion("2015"): + elpa_year_v = elpa_v.split('.')[0] + self.dflags += ["-D__ELPA_%s" % elpa_year_v] + elif LooseVersion(self.version) >= LooseVersion("6.0"): + if LooseVersion(elpa_v) >= LooseVersion("2017"): + raise EasyBuildError("ELPA support for QuantumESPRESSO 6.x only available up to v2016.xx") + elif LooseVersion(elpa_v) >= LooseVersion("2016"): + self.dflags += ["-D__ELPA_2016"] + elif LooseVersion(elpa_v) >= LooseVersion("2015"): + self.dflags += ["-D__ELPA_2015"] + elif LooseVersion(self.version) >= LooseVersion("5.4"): self.dflags += ["-D__ELPA"] - elif LooseVersion(elpa_v) >= LooseVersion("2016.11"): - self.dflags += ["-D__ELPA_2016"] - elif LooseVersion(elpa_v) >= LooseVersion("2015"): - self.dflags += ["-D__ELPA_2015"] - elif LooseVersion(self.version) >= LooseVersion("6.6"): - if LooseVersion(elpa_v) >= LooseVersion("2020"): - raise EasyBuildError("ELPA support for QuantumESPRESSO 6.6 only available up to v2019.xx") - elif LooseVersion(elpa_v) >= LooseVersion("2018"): - self.dflags += ["-D__ELPA"] - elif LooseVersion(elpa_v) >= LooseVersion("2015"): - elpa_year_v = elpa_v.split('.')[0] - self.dflags += ["-D__ELPA_%s" % elpa_year_v] - elif LooseVersion(self.version) >= LooseVersion("6.0"): - if LooseVersion(elpa_v) >= LooseVersion("2017"): - raise EasyBuildError("ELPA support for QuantumESPRESSO 6.x only available up to v2016.xx") - elif LooseVersion(elpa_v) >= LooseVersion("2016"): - self.dflags += ["-D__ELPA_2016"] - elif LooseVersion(elpa_v) >= LooseVersion("2015"): - self.dflags += ["-D__ELPA_2015"] - elif LooseVersion(self.version) >= LooseVersion("5.4"): - self.dflags += ["-D__ELPA"] - self.cfg.update('configopts', '--with-elpa=%s' % elpa) - return - elif LooseVersion(self.version) >= LooseVersion("5.1.1"): - self.cfg.update('configopts', '--with-elpa=%s' % elpa) - return - else: - raise EasyBuildError("ELPA support is only available in QuantumESPRESSO 5.1.1 and later") + self.cfg.update('configopts', '--with-elpa=%s' % elpa) + flag = False + elif LooseVersion(self.version) >= LooseVersion("5.1.1"): + self.cfg.update('configopts', '--with-elpa=%s' % elpa) + flag = False + else: + raise EasyBuildError("ELPA support is only available in QuantumESPRESSO 5.1.1 and later") - if self.toolchain.options.get('openmp', False): - elpa_include = 'elpa_openmp-%s' % elpa_v - elpa_lib = 'libelpa_openmp.a' - else: - elpa_include = 'elpa-%s' % elpa_v - elpa_lib = 'libelpa.a' - elpa_include = os.path.join(elpa, 'include', elpa_include, 'modules') - elpa_lib = os.path.join(elpa, 'lib', elpa_lib) - self.repls += [ - ('IFLAGS', '-I%s' % elpa_include, True) - ] - self.cfg.update('configopts', '--with-elpa-include=%s' % elpa_include) - self.cfg.update('configopts', '--with-elpa-lib=%s' % elpa_lib) - if LooseVersion(self.version) < LooseVersion("7.0"): - self.repls += [ - ('SCALAPACK_LIBS', '%s %s' % (elpa_lib, os.getenv("LIBSCALAPACK")), False) - ] + if flag: + if self.toolchain.options.get('openmp', False): + elpa_include = 'elpa_openmp-%s' % elpa_v + elpa_lib = 'libelpa_openmp.a' + else: + elpa_include = 'elpa-%s' % elpa_v + elpa_lib = 'libelpa.a' + elpa_include = os.path.join(elpa, 'include', elpa_include, 'modules') + elpa_lib = os.path.join(elpa, 'lib', elpa_lib) + self.repls += [ + ('IFLAGS', '-I%s' % elpa_include, True) + ] + self.cfg.update('configopts', '--with-elpa-include=%s' % elpa_include) + self.cfg.update('configopts', '--with-elpa-lib=%s' % elpa_lib) + if LooseVersion(self.version) < LooseVersion("7.0"): + self.repls += [ + ('SCALAPACK_LIBS', '%s %s' % (elpa_lib, os.getenv("LIBSCALAPACK")), False) + ] def _add_fftw(self, comp_fam): """Add FFTW support to the build.""" @@ -248,23 +245,25 @@ def _add_fftw(self, comp_fam): self.dflags += ["-D__DFTI"] elif libfft: self.dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] - env.setvar('FFTW_LIBS', libfft) + self.repls += [ + ('FFT_LIBS', libfft, False), + ] elif LooseVersion(self.version) >= LooseVersion("5.0"): if libfft: self.dflags += ["-D__FFTW"] if "fftw3" not in libfft else ["-D__FFTW3"] - env.setvar('FFTW_LIBS', libfft) + self.repls += [ + ('FFT_LIBS', libfft, False), + ] def _add_ace(self): """Add ACE support to the build.""" - if not self.cfg['with_ace']: - return - - if LooseVersion(self.version) >= LooseVersion("6.2"): - self.log.warning("ACE support is not available in QuantumESPRESSO >= 6.2") - elif LooseVersion(self.version) >= LooseVersion("6.0"): - self.dflags += ["-D__EXX_ACE"] - else: - self.log.warning("ACE support is not available in QuantumESPRESSO < 6.0") + if self.cfg['with_ace']: + if LooseVersion(self.version) >= LooseVersion("6.2"): + self.log.warning("ACE support is not available in QuantumESPRESSO >= 6.2") + elif LooseVersion(self.version) >= LooseVersion("6.0"): + self.dflags += ["-D__EXX_ACE"] + else: + self.log.warning("ACE support is not available in QuantumESPRESSO < 6.0") def _add_beef(self): """Add BEEF support to the build.""" @@ -286,8 +285,6 @@ def _adjust_compiler_flags(self, comp_fam): i_mpi_cc = os.getenv('I_MPI_CC', '') if i_mpi_cc == 'icx': env.setvar('I_MPI_CC', 'icc') # Needed cor clib/qmmm_aux.c using implicitly - elif comp_fam == toolchain.GCC: - pass def configure_step(self): """Custom configuration procedure for Quantum ESPRESSO.""" From 8c4bd0d21e72bcc6d5ca1867317fdeb2aaacd552 Mon Sep 17 00:00:00 2001 From: crivella Date: Tue, 5 Mar 2024 09:59:44 +0100 Subject: [PATCH 10/38] Fixed line length --- easybuild/easyblocks/q/quantumespresso.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index ba537c8a769..9fa5cf07baf 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -341,7 +341,8 @@ def configure_step(self): if self.cfg['with_scalapack']: num_libs.extend(['SCALAPACK']) elpa = get_software_root('ELPA') - elpa_lib = os.path.join(elpa or '', 'lib', 'libelpa.a' if self.toolchain.options.get('openmp', False) else 'libelpa_openmp.a') + elpa_lib = 'libelpa.a' if self.toolchain.options.get('openmp', False) else 'libelpa_openmp.a' + elpa_lib = os.path.join(elpa or '', 'lib', elpa_lib) for lib in num_libs: if self.toolchain.options.get('openmp', False): val = os.getenv('LIB%s_MT' % lib) From 03693db9d9e58797873e9c658ad7bd7fc6d9943a Mon Sep 17 00:00:00 2001 From: crivella Date: Tue, 5 Mar 2024 15:34:22 +0100 Subject: [PATCH 11/38] Missed f-strings --- easybuild/easyblocks/q/quantumespresso.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 9fa5cf07baf..789b7eb1a29 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -381,9 +381,9 @@ def configure_step(self): # need to use [ \t]* instead of \s*, because vars may be undefined as empty, # and we don't want to include newlines if keep: - line = re.sub(fr"^({k}\s*=[ \t]*)(.*)$", fr"\1\2 {v}", line) + line = re.sub(r"^(%s\s*=[ \t]*)(.*)$" % k, r"\1\2 %s" % v, line) else: - line = re.sub(fr"^({k}\s*=[ \t]*).*$", fr"\1{v}", line) + line = re.sub(r"^(%s\s*=[ \t]*).*$" % k, r"\1%s" % v, line) # fix preprocessing directives for .f90 files in make.sys if required if LooseVersion(self.version) < LooseVersion("6.0"): @@ -416,7 +416,7 @@ def configure_step(self): fn = os.path.join(self.cfg['start_dir'], 'plugins', 'install', 'make_wannier90.sys') try: for line in fileinput.input(fn, inplace=1, backup='.orig.eb'): - line = re.sub(r"^(LIBS\s*=\s*).*", fr"\1{libs}", line) + line = re.sub(r"^(LIBS\s*=\s*).*", r"\1%s" % libs, line) sys.stdout.write(line) From a4c79f37b66b9ee2b684d9933e9cfd959d9a5017 Mon Sep 17 00:00:00 2001 From: crivella Date: Wed, 6 Mar 2024 14:35:15 +0100 Subject: [PATCH 12/38] Added running QE test-suite in `test_step` --- easybuild/easyblocks/q/quantumespresso.py | 86 ++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 789b7eb1a29..ed943756f86 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -42,12 +42,27 @@ from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import copy_dir, copy_file from easybuild.tools.modules import get_software_root, get_software_version +from easybuild.tools.run import run_cmd from easybuild.easyblocks.generic.configuremake import ConfigureMake class EB_QuantumESPRESSO(ConfigureMake): """Support for building and installing Quantum ESPRESSO.""" + + TEST_SUITE_DIR = "test-suite" + TEST_SUITE_TARGETS = [ + "run-tests-pw", + "run-tests-pp", + "run-tests-ph", + "run-tests-cp", + "run-tests-hp", + "run-tests-tddfpt", + "run-tests-epw", + "run-tests-kcw", + "run-tests-xsd", + "run-tests-zg", + ] @staticmethod def extra_options(): @@ -56,6 +71,7 @@ def extra_options(): 'hybrid': [False, "Enable hybrid build (with OpenMP)", CUSTOM], 'with_scalapack': [True, "Enable ScaLAPACK support", CUSTOM], 'with_ace': [False, "Enable Adaptively Compressed Exchange support", CUSTOM], + 'test_threshold': [0.9, "Threshold for test suite success rate", CUSTOM], } return ConfigureMake.extra_options(extra_vars) @@ -334,8 +350,10 @@ def configure_step(self): self.repls.append(('LDFLAGS', self.toolchain.get_flag('openmp'), True)) self.repls.append(('(?:C|F90|F)FLAGS', self.toolchain.get_flag('openmp'), True)) - # obtain library settings + # libs is being used for the replacement in the wannier90 files libs = [] + # Only overriding for fcc as the intel flags are already ebing properly + # set. if comp_fam == toolchain.GCC: num_libs = ['BLAS', 'LAPACK', 'FFT'] if self.cfg['with_scalapack']: @@ -484,6 +502,72 @@ def configure_step(self): except OSError as err: raise EasyBuildError("Failed to move non-espresso directories: %s", err) + def test_step(self): + """ + Test the compilation using Quantum ESPRESSO's test suite. + cd test-suite && make run-tests NPROCS=XXX (XXX <= 4) + """ + + thr = self.cfg.get('test_threshold', 0.9) + stot = 0 + spass = 0 + parallel = min(4, self.cfg.get('parallel', 1)) + + full_out = '' + for target in self.TEST_SUITE_TARGETS: + cmd = ( + 'cd %s && ' % os.path.join(self.start_dir, self.TEST_SUITE_DIR) + + 'NPROCS=%d make %s' % (parallel, target) + ) + (out, _) = run_cmd(cmd, log_all=False, log_ok=False, simple=False, regexp=False) + + # Example output: + # All done. 2 out of 2 tests passed. + # All done. ERROR: only 6 out of 9 tests passed + _tot = 0 + _pass = 0 + rgx = r'All done. (ERROR: only )?(?P\d+) out of (?P\d+) tests passed.' + for mch in re.finditer(rgx, out): + succeded = int(mch.group('succeded')) + total = int(mch.group('total')) + _tot += total + _pass += succeded + + perc = _pass / max(_tot, 1) + self.log.info("%s: Passed %d out of %d (%.2f%%)" % (target, _pass, _tot, perc * 100)) + + # Log test-suite errors if present + if _pass < _tot: + # Example output for reported faliures: + # pw_plugins - plugin-pw2casino_1.in (arg(s): 1): **FAILED**. + # Different sets of data extracted from benchmark and test. + # Data only in benchmark: p1. + # (empty line) + flag = False + for line in out.splitlines(): + if '**FAILED**' in line: + flag = True + self.log.warning(line) + continue + elif line.strip() == '': + flag = False + if flag: + self.log.warning('| ' + line) + + stot += _tot + spass += _pass + full_out += out + + # Allow for flaky tests (eg too strict thresholds on results for structure relaxation) + perc = spass / max(stot, 1) + self.log.info("Total tests passed %d out of %d (%.2f%%)" % (spass, stot, perc * 100)) + if perc < thr: + raise EasyBuildError( + "Test suite failed with less than %.2f %% (%.2f) success rate" % (thr * 100, perc * 100) + ) + + return full_out + def install_step(self): """Custom install step for Quantum ESPRESSO.""" From b67a3c7ac7c51980549c6e73d3d7d6c1e2a6b845 Mon Sep 17 00:00:00 2001 From: crivella Date: Wed, 6 Mar 2024 14:36:50 +0100 Subject: [PATCH 13/38] linting --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index ed943756f86..a6d377665d4 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -49,7 +49,7 @@ class EB_QuantumESPRESSO(ConfigureMake): """Support for building and installing Quantum ESPRESSO.""" - + TEST_SUITE_DIR = "test-suite" TEST_SUITE_TARGETS = [ "run-tests-pw", From 730592b0192202e948aa74153cb3cc2825786c3f Mon Sep 17 00:00:00 2001 From: Davide Grassano <34096612+Crivella@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:45:27 +0100 Subject: [PATCH 14/38] Update easybuild/easyblocks/q/quantumespresso.py Co-authored-by: ocaisa --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index a6d377665d4..65bb63dcc9d 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -425,7 +425,7 @@ def configure_step(self): raise EasyBuildError("Failed to patch %s: %s", fn, err) with open(fn, "r") as f: - self.log.debug("Contents of patched %s: %s" % (fn, f.read())) + self.log.info("Contents of patched %s: %s" % (fn, f.read())) # patch default make.sys for wannier if LooseVersion(self.version) >= LooseVersion("5"): From d09af582756445a32962c40bf3b8803419be2ad1 Mon Sep 17 00:00:00 2001 From: Davide Grassano <34096612+Crivella@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:45:38 +0100 Subject: [PATCH 15/38] Update easybuild/easyblocks/q/quantumespresso.py Co-authored-by: ocaisa --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 65bb63dcc9d..ed94f7c7987 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -384,7 +384,7 @@ def configure_step(self): raise EasyBuildError("Found FoX external module, QuantumESPRESSO" + "must use the version they include with the source.") - self.log.debug("List of replacements to perform: %s" % str(self.repls)) + self.log.info("List of replacements to perform: %s" % str(self.repls)) if LooseVersion(self.version) >= LooseVersion("6"): make_ext = '.inc' From 2344c128430d0fd3dc61d693dbce5174f1a12ce1 Mon Sep 17 00:00:00 2001 From: Davide Grassano <34096612+Crivella@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:45:46 +0100 Subject: [PATCH 16/38] Update easybuild/easyblocks/q/quantumespresso.py Co-authored-by: ocaisa --- easybuild/easyblocks/q/quantumespresso.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index ed94f7c7987..c9d38dd3bb7 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -526,12 +526,12 @@ def test_step(self): # All done. ERROR: only 6 out of 9 tests passed _tot = 0 _pass = 0 - rgx = r'All done. (ERROR: only )?(?P\d+) out of (?P\d+) tests passed.' + rgx = r'All done. (ERROR: only )?(?P\d+) out of (?P\d+) tests passed.' for mch in re.finditer(rgx, out): - succeded = int(mch.group('succeded')) + succeeded = int(mch.group('succeeded')) total = int(mch.group('total')) _tot += total - _pass += succeded + _pass += succeeded perc = _pass / max(_tot, 1) self.log.info("%s: Passed %d out of %d (%.2f%%)" % (target, _pass, _tot, perc * 100)) From 59ce6d2446be808534d58251d64e18fba586dd0d Mon Sep 17 00:00:00 2001 From: Davide Grassano <34096612+Crivella@users.noreply.github.com> Date: Wed, 6 Mar 2024 16:47:52 +0100 Subject: [PATCH 17/38] Update easybuild/easyblocks/q/quantumespresso.py Co-authored-by: ocaisa --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index c9d38dd3bb7..b6752e1de79 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -207,7 +207,7 @@ def _add_elpa(self): self.dflags += ["-D__ELPA_2015"] elif LooseVersion(self.version) >= LooseVersion("6.6"): if LooseVersion(elpa_v) >= LooseVersion("2020"): - raise EasyBuildError("ELPA support for QuantumESPRESSO 6.6 only available up to v2019.xx") + raise EasyBuildError("ELPA support for QuantumESPRESSO 6.6/6.7 only available up to v2019.xx") elif LooseVersion(elpa_v) >= LooseVersion("2018"): self.dflags += ["-D__ELPA"] elif LooseVersion(elpa_v) >= LooseVersion("2015"): From 10fab211928b4baafa1617a60499d3c0dc030a36 Mon Sep 17 00:00:00 2001 From: crivella Date: Wed, 6 Mar 2024 18:00:57 +0100 Subject: [PATCH 18/38] Fixed compatibility with libxc --- easybuild/easyblocks/q/quantumespresso.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index b6752e1de79..53f7cad8282 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -159,17 +159,26 @@ def _add_libxc(self): if LooseVersion(libxc_v) < LooseVersion("3.0.1"): raise EasyBuildError("Must use libxc >= 3.0.1") if LooseVersion(self.version) >= LooseVersion("7.0"): - if LooseVersion(libxc_v) < LooseVersion("6.0.0"): - raise EasyBuildError("libxc support for QuantumESPRESSO 7.0 only available for libxc >= 6.0.0") + if LooseVersion(libxc_v) < LooseVersion("4"): + raise EasyBuildError("libxc support for QuantumESPRESSO 7.x only available for libxc >= 4") self.cfg.update('configopts', '--with-libxc=yes') self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) - elif LooseVersion(self.version) >= LooseVersion("6.4"): + elif LooseVersion(self.version) >= LooseVersion("6.6"): + if LooseVersion(libxc_v) >= LooseVersion("6.0"): + raise EasyBuildError("libxc support for QuantumESPRESSO 6.6 to 6.8 only available for libxc < 6.0") + if LooseVersion(libxc_v) < LooseVersion("4"): + raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc >= 4") + self.cfg.update('configopts', '--with-libxc=yes') + self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) + elif LooseVersion(self.version) >= LooseVersion("6.0"): if LooseVersion(libxc_v) >= LooseVersion("5.0"): - raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc <= 4.3.4") + raise EasyBuildError("libxc support for QuantumESPRESSO 6.0 to 6.5 only available for libxc <= 4.3.4") + if LooseVersion(libxc_v) < LooseVersion("4"): + raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc >= 4") self.cfg.update('configopts', '--with-libxc=yes') self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) else: - self.extra_libs += ['-lxcf90', '-lxc'] + self.extra_libs += ['-L%s/lib' % libxc, '-lxcf90', '-lxc'] self.dflags += ["-D__LIBXC"] From a3a7a4a97fac019c97d65435778d5419359e247e Mon Sep 17 00:00:00 2001 From: crivella Date: Wed, 6 Mar 2024 19:01:27 +0100 Subject: [PATCH 19/38] Linting + fix for intel compilation with wannier 90 --- easybuild/easyblocks/q/quantumespresso.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 53f7cad8282..ed0fec74e92 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -172,7 +172,9 @@ def _add_libxc(self): self.cfg.update('configopts', '--with-libxc-prefix=%s' % libxc) elif LooseVersion(self.version) >= LooseVersion("6.0"): if LooseVersion(libxc_v) >= LooseVersion("5.0"): - raise EasyBuildError("libxc support for QuantumESPRESSO 6.0 to 6.5 only available for libxc <= 4.3.4") + raise EasyBuildError( + "libxc support for QuantumESPRESSO 6.0 to 6.5 only available for libxc <= 4.3.4" + ) if LooseVersion(libxc_v) < LooseVersion("4"): raise EasyBuildError("libxc support for QuantumESPRESSO 6.x only available for libxc >= 4") self.cfg.update('configopts', '--with-libxc=yes') @@ -379,7 +381,7 @@ def configure_step(self): val = ' '.join([elpa_lib, val]) self.repls.append(('%s_LIBS' % lib, val, False)) libs.append(val) - libs = ' '.join(libs) + libs = ' '.join(libs) self.repls.append(('BLAS_LIBS_SWITCH', 'external', False)) self.repls.append(('LAPACK_LIBS_SWITCH', 'external', False)) @@ -443,7 +445,8 @@ def configure_step(self): fn = os.path.join(self.cfg['start_dir'], 'plugins', 'install', 'make_wannier90.sys') try: for line in fileinput.input(fn, inplace=1, backup='.orig.eb'): - line = re.sub(r"^(LIBS\s*=\s*).*", r"\1%s" % libs, line) + if libs: + line = re.sub(r"^(LIBS\s*=\s*).*", r"\1%s" % libs, line) sys.stdout.write(line) @@ -451,7 +454,7 @@ def configure_step(self): raise EasyBuildError("Failed to patch %s: %s", fn, err) with open(fn, "r") as f: - self.log.debug("Contents of patched %s: %s" % (fn, f.read())) + self.log.info("Contents of patched %s: %s" % (fn, f.read())) # patch Makefile of want plugin wantprefix = 'want-' From 2edc824f46c9c7c8ec6e5ff2f8cf9ec8f1eccfc1 Mon Sep 17 00:00:00 2001 From: crivella Date: Wed, 6 Mar 2024 23:05:59 +0100 Subject: [PATCH 20/38] Fixed needed for running test-suite on qe<7.0 --- easybuild/easyblocks/q/quantumespresso.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index ed0fec74e92..573a2a10a65 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -524,13 +524,28 @@ def test_step(self): stot = 0 spass = 0 parallel = min(4, self.cfg.get('parallel', 1)) + test_dir = os.path.join(self.start_dir, self.TEST_SUITE_DIR) + + pseudo_loc = "https://pseudopotentials.quantum-espresso.org/upf_files/" + if LooseVersion(self.version) < LooseVersion("7.0"): + cmd = ' && '.join([ + "cd %s" % test_dir, + "sed -i 's|export NETWORK_PSEUDO=.*|export NETWORK_PSEUDO=%s|g' ENVIRONMENT" % pseudo_loc + ]) + run_cmd(cmd, log_all=False, log_ok=False, simple=False, regexp=False) full_out = '' for target in self.TEST_SUITE_TARGETS: - cmd = ( - 'cd %s && ' % os.path.join(self.start_dir, self.TEST_SUITE_DIR) + - 'NPROCS=%d make %s' % (parallel, target) - ) + pcmd = '' + if LooseVersion(self.version) < LooseVersion("7.0"): + if parallel > 1: + target = target + "-parallel" + else: + target = target + "-serial" + else: + pcmd = 'NPROCS=%d' % parallel + + cmd = 'cd %s && %s make %s' % (test_dir, pcmd, target) (out, _) = run_cmd(cmd, log_all=False, log_ok=False, simple=False, regexp=False) # Example output: From 3b4bc09e2b46e80eafc550605e4b04f700c55c20 Mon Sep 17 00:00:00 2001 From: crivella Date: Thu, 7 Mar 2024 12:00:59 +0100 Subject: [PATCH 21/38] Made installation of FoX gipaw and wannier90 customizable --- easybuild/easyblocks/q/quantumespresso.py | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 573a2a10a65..0940ba08eb2 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -71,6 +71,9 @@ def extra_options(): 'hybrid': [False, "Enable hybrid build (with OpenMP)", CUSTOM], 'with_scalapack': [True, "Enable ScaLAPACK support", CUSTOM], 'with_ace': [False, "Enable Adaptively Compressed Exchange support", CUSTOM], + 'with_fox': [False, "Enable FoX support", CUSTOM], + 'with_gipaw': [True, "Enable GIPAW support", CUSTOM], + 'with_wannier90': [False, "Enable Wannier90 support", CUSTOM], 'test_threshold': [0.9, "Threshold for test suite success rate", CUSTOM], } return ConfigureMake.extra_options(extra_vars) @@ -305,6 +308,32 @@ def _add_beef(self): ('BEEF_LIBS', str(os.path.join(libbeef_lib, "libbeef.a")), False) ] + def _add_fox(self): + """Add FoX support to the build.""" + if self.cfg['with_fox']: + # Needed for using gipaw with QuantumESPRESSO 7.2 and later + if LooseVersion(self.version) >= LooseVersion("7.2"): + self.cfg.update('configopts', '--with-fox=yes') + + def _add_gipaw(self): + """Add GIPAW support to the build.""" + if self.cfg['with_gipaw']: + if LooseVersion(self.version) >= LooseVersion("7.2"): + if not self.cfg['with_fox']: + raise EasyBuildError("GIPAW requires FoX enabled in QuantumESPRESSO 7.2 and later") + self.cfg.update('buildopts', 'gipaw', allow_duplicate=False) + else: + if 'gipaw' in self.cfg['buildopts']: + self.cfg['buildopts'].replace('gipaw', '') + + def _add_wannier90(self): + """Add Wannier90 support to the build.""" + if self.cfg['with_wannier90']: + self.cfg.update('buildopts', 'w90', allow_duplicate=False) + else: + if 'w90' in self.cfg['buildopts']: + self.cfg['buildopts'].replace('w90', '') + def _adjust_compiler_flags(self, comp_fam): """Adjust compiler flags based on the compiler family and code version.""" if comp_fam == toolchain.INTELCOMP: @@ -336,6 +365,9 @@ def configure_step(self): self._add_fftw(comp_fam) self._add_ace() self._add_beef() + self._add_fox() + self._add_gipaw() + self._add_wannier90() if comp_fam == toolchain.INTELCOMP: # Intel compiler must have -assume byterecl (see install/configure) From 4ebbf52428d60d50b388453b64283268ddf61996 Mon Sep 17 00:00:00 2001 From: crivella Date: Thu, 7 Mar 2024 12:09:15 +0100 Subject: [PATCH 22/38] Made installation of EPW customizable + check on QE version >= 6.0 --- easybuild/easyblocks/q/quantumespresso.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 0940ba08eb2..6faec9b6877 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -72,6 +72,7 @@ def extra_options(): 'with_scalapack': [True, "Enable ScaLAPACK support", CUSTOM], 'with_ace': [False, "Enable Adaptively Compressed Exchange support", CUSTOM], 'with_fox': [False, "Enable FoX support", CUSTOM], + 'with_epw': [True, "Enable EPW support", CUSTOM], 'with_gipaw': [True, "Enable GIPAW support", CUSTOM], 'with_wannier90': [False, "Enable Wannier90 support", CUSTOM], 'test_threshold': [0.9, "Threshold for test suite success rate", CUSTOM], @@ -315,6 +316,17 @@ def _add_fox(self): if LooseVersion(self.version) >= LooseVersion("7.2"): self.cfg.update('configopts', '--with-fox=yes') + def _add_epw(self): + """Add EPW support to the build.""" + if self.cfg['with_epw']: + if LooseVersion(self.version) >= LooseVersion("6.0"): + self.cfg.update('buildopts', 'epw', allow_duplicate=False) + else: + self.log.warning("EPW support is not available in QuantumESPRESSO < 6.0") + else: + if 'epw' in self.cfg['buildopts']: + self.cfg['buildopts'].replace('epw', '') + def _add_gipaw(self): """Add GIPAW support to the build.""" if self.cfg['with_gipaw']: @@ -366,6 +378,7 @@ def configure_step(self): self._add_ace() self._add_beef() self._add_fox() + self._add_epw() self._add_gipaw() self._add_wannier90() From f7858a9f47297fe78bac923443e5e9b64f1d18d2 Mon Sep 17 00:00:00 2001 From: crivella Date: Thu, 7 Mar 2024 17:33:55 +0100 Subject: [PATCH 23/38] Made test_suite targets and allowed failures customizable. Moved threshold to 97% --- easybuild/easyblocks/q/quantumespresso.py | 49 +++++++++++++++-------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 6faec9b6877..406dffca69b 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -51,18 +51,6 @@ class EB_QuantumESPRESSO(ConfigureMake): """Support for building and installing Quantum ESPRESSO.""" TEST_SUITE_DIR = "test-suite" - TEST_SUITE_TARGETS = [ - "run-tests-pw", - "run-tests-pp", - "run-tests-ph", - "run-tests-cp", - "run-tests-hp", - "run-tests-tddfpt", - "run-tests-epw", - "run-tests-kcw", - "run-tests-xsd", - "run-tests-zg", - ] @staticmethod def extra_options(): @@ -74,8 +62,19 @@ def extra_options(): 'with_fox': [False, "Enable FoX support", CUSTOM], 'with_epw': [True, "Enable EPW support", CUSTOM], 'with_gipaw': [True, "Enable GIPAW support", CUSTOM], - 'with_wannier90': [False, "Enable Wannier90 support", CUSTOM], - 'test_threshold': [0.9, "Threshold for test suite success rate", CUSTOM], + 'with_wannier90': [False, "Enable Wannier90 support", CUSTOM], + 'test_suite_targets': [[ + "pw", "pp", "ph", "cp", "hp", "tddfpt", "epw", + ], "List of test suite targets to run", CUSTOM], + 'test_suite_allow_failures': [[ + 'relax', + 'epw_polar', + 'cp_h2o_scan_libxc', + 'hp_metal_us_magn', + 'ph_ahc_diam', + 'tddfpt_magnons_fe', + ], "List of test suite targets that are allowed to fail (name can partially match)", CUSTOM], + 'test_suite_threshold': [0.97, "Threshold for test suite success rate", CUSTOM], } return ConfigureMake.extra_options(extra_vars) @@ -321,11 +320,14 @@ def _add_epw(self): if self.cfg['with_epw']: if LooseVersion(self.version) >= LooseVersion("6.0"): self.cfg.update('buildopts', 'epw', allow_duplicate=False) + self.cfg.update('test_suite_targets', ['epw'], allow_duplicate=False) else: self.log.warning("EPW support is not available in QuantumESPRESSO < 6.0") else: if 'epw' in self.cfg['buildopts']: self.cfg['buildopts'].replace('epw', '') + if 'epw' in self.cfg['test_suite_targets']: + self.cfg['test_suite_targets'].remove('epw') def _add_gipaw(self): """Add GIPAW support to the build.""" @@ -565,7 +567,7 @@ def test_step(self): cd test-suite && make run-tests NPROCS=XXX (XXX <= 4) """ - thr = self.cfg.get('test_threshold', 0.9) + thr = self.cfg.get('test_suite_threshold', 0.9) stot = 0 spass = 0 parallel = min(4, self.cfg.get('parallel', 1)) @@ -579,8 +581,12 @@ def test_step(self): ]) run_cmd(cmd, log_all=False, log_ok=False, simple=False, regexp=False) + targets = self.cfg.get('test_suite_targets', []) + allow_fail = self.cfg.get('test_suite_allow_failures', []) + full_out = '' - for target in self.TEST_SUITE_TARGETS: + failures = [] + for target in targets: pcmd = '' if LooseVersion(self.version) < LooseVersion("7.0"): if parallel > 1: @@ -590,7 +596,7 @@ def test_step(self): else: pcmd = 'NPROCS=%d' % parallel - cmd = 'cd %s && %s make %s' % (test_dir, pcmd, target) + cmd = 'cd %s && %s make run-tests-%s' % (test_dir, pcmd, target) (out, _) = run_cmd(cmd, log_all=False, log_ok=False, simple=False, regexp=False) # Example output: @@ -618,6 +624,11 @@ def test_step(self): flag = False for line in out.splitlines(): if '**FAILED**' in line: + for allowed in allow_fail: + if allowed in line: + break + else: + failures.append(line.split('-')[0].strip()) flag = True self.log.warning(line) continue @@ -633,6 +644,10 @@ def test_step(self): # Allow for flaky tests (eg too strict thresholds on results for structure relaxation) perc = spass / max(stot, 1) self.log.info("Total tests passed %d out of %d (%.2f%%)" % (spass, stot, perc * 100)) + if failures: + failed_msg = ', '.join(failures) + self.log.error("The following tests failed: %s" % failed_msg) + raise EasyBuildError("Test suite failed") if perc < thr: raise EasyBuildError( "Test suite failed with less than %.2f %% (%.2f) success rate" % (thr * 100, perc * 100) From 0c7aff82dc84b4291d8148e551e98e3f8758e6e7 Mon Sep 17 00:00:00 2001 From: crivella Date: Thu, 7 Mar 2024 17:57:52 +0100 Subject: [PATCH 24/38] Fixed cfg assignment and improved logging --- easybuild/easyblocks/q/quantumespresso.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 406dffca69b..25fe17ced1c 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -325,7 +325,7 @@ def _add_epw(self): self.log.warning("EPW support is not available in QuantumESPRESSO < 6.0") else: if 'epw' in self.cfg['buildopts']: - self.cfg['buildopts'].replace('epw', '') + self.cfg['buildopts'] = self.cfg['buildopts'].replace('epw', '') if 'epw' in self.cfg['test_suite_targets']: self.cfg['test_suite_targets'].remove('epw') @@ -338,7 +338,7 @@ def _add_gipaw(self): self.cfg.update('buildopts', 'gipaw', allow_duplicate=False) else: if 'gipaw' in self.cfg['buildopts']: - self.cfg['buildopts'].replace('gipaw', '') + self.cfg['buildopts'] = self.cfg['buildopts'].replace('gipaw', '') def _add_wannier90(self): """Add Wannier90 support to the build.""" @@ -346,7 +346,7 @@ def _add_wannier90(self): self.cfg.update('buildopts', 'w90', allow_duplicate=False) else: if 'w90' in self.cfg['buildopts']: - self.cfg['buildopts'].replace('w90', '') + self.cfg['buildopts'] = self.cfg['buildopts'].replace('w90', '') def _adjust_compiler_flags(self, comp_fam): """Adjust compiler flags based on the compiler family and code version.""" @@ -626,9 +626,10 @@ def test_step(self): if '**FAILED**' in line: for allowed in allow_fail: if allowed in line: + self.log.info('Ignoring failure: %s' % line) break else: - failures.append(line.split('-')[0].strip()) + failures.append(line) flag = True self.log.warning(line) continue @@ -645,8 +646,9 @@ def test_step(self): perc = spass / max(stot, 1) self.log.info("Total tests passed %d out of %d (%.2f%%)" % (spass, stot, perc * 100)) if failures: - failed_msg = ', '.join(failures) - self.log.error("The following tests failed: %s" % failed_msg) + self.log.error("The following tests failed:") + for failure in failures: + self.log.error('| ' + failure) raise EasyBuildError("Test suite failed") if perc < thr: raise EasyBuildError( From 4d77c5be17c9b922fc043c8675020006611d780d Mon Sep 17 00:00:00 2001 From: crivella Date: Thu, 7 Mar 2024 23:56:14 +0100 Subject: [PATCH 25/38] Added test to allowed failures and reasons in comments --- easybuild/easyblocks/q/quantumespresso.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 25fe17ced1c..89b7fa33a87 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -67,12 +67,13 @@ def extra_options(): "pw", "pp", "ph", "cp", "hp", "tddfpt", "epw", ], "List of test suite targets to run", CUSTOM], 'test_suite_allow_failures': [[ - 'relax', - 'epw_polar', - 'cp_h2o_scan_libxc', - 'hp_metal_us_magn', - 'ph_ahc_diam', - 'tddfpt_magnons_fe', + 'relax', # Too strict thresholds + 'epw_polar', # Too strict thresholds + 'cp_h2o_scan_libxc', # Too strict thresholds + 'hp_metal_us_magn', # Too strict thresholds + 'hp_soc_UV_paw_magn', # In 7.3 test has more params than the baseline + 'ph_ahc_diam', # Test detects a ! as an energy in baseline + 'tddfpt_magnons_fe', # Too strict thresholds ], "List of test suite targets that are allowed to fail (name can partially match)", CUSTOM], 'test_suite_threshold': [0.97, "Threshold for test suite success rate", CUSTOM], } @@ -383,6 +384,8 @@ def configure_step(self): self._add_epw() self._add_gipaw() self._add_wannier90() + + run_cmd("module list", log_all=True, log_ok=True, simple=False, regexp=False) if comp_fam == toolchain.INTELCOMP: # Intel compiler must have -assume byterecl (see install/configure) From 13770aff7214a9cf78630fa37e1372b300c7eb7c Mon Sep 17 00:00:00 2001 From: crivella Date: Fri, 8 Mar 2024 10:08:34 +0100 Subject: [PATCH 26/38] Added fix foe wannier90.x being a broken symlink in QE==7.3.0 --- easybuild/easyblocks/q/quantumespresso.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 89b7fa33a87..8b404e942d3 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -663,6 +663,13 @@ def test_step(self): def install_step(self): """Custom install step for Quantum ESPRESSO.""" + # In QE 7.3 the w90 target is always invoked (even if only used as a library), and the symlink to the + # `wannier90.x` executable is generated, but the actual binary is not built. We need to remove the symlink + if LooseVersion(self.version) == LooseVersion("7.3.0"): + w90_path = os.path.join(self.start_dir, 'bin', 'wannier90.x') + if not os.path.exists(os.readlink(w90_path)): + os.unlink(w90_path) + # extract build targets as list targets = self.cfg['buildopts'].split() From fa11d73d803e3f90867a5830b8a6fd0df4ee4cc0 Mon Sep 17 00:00:00 2001 From: crivella Date: Fri, 8 Mar 2024 10:51:18 +0100 Subject: [PATCH 27/38] Fixed version for equality --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 8b404e942d3..09cb2f20c9e 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -665,7 +665,7 @@ def install_step(self): # In QE 7.3 the w90 target is always invoked (even if only used as a library), and the symlink to the # `wannier90.x` executable is generated, but the actual binary is not built. We need to remove the symlink - if LooseVersion(self.version) == LooseVersion("7.3.0"): + if LooseVersion(self.version) == LooseVersion("7.3"): w90_path = os.path.join(self.start_dir, 'bin', 'wannier90.x') if not os.path.exists(os.readlink(w90_path)): os.unlink(w90_path) From 9441a29af400667fea45b54854e0fbf013223ffb Mon Sep 17 00:00:00 2001 From: crivella Date: Fri, 8 Mar 2024 11:36:26 +0100 Subject: [PATCH 28/38] Check for link existing + linting --- easybuild/easyblocks/q/quantumespresso.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 09cb2f20c9e..51ce6890a7a 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -340,7 +340,7 @@ def _add_gipaw(self): else: if 'gipaw' in self.cfg['buildopts']: self.cfg['buildopts'] = self.cfg['buildopts'].replace('gipaw', '') - + def _add_wannier90(self): """Add Wannier90 support to the build.""" if self.cfg['with_wannier90']: @@ -384,7 +384,7 @@ def configure_step(self): self._add_epw() self._add_gipaw() self._add_wannier90() - + run_cmd("module list", log_all=True, log_ok=True, simple=False, regexp=False) if comp_fam == toolchain.INTELCOMP: @@ -667,7 +667,7 @@ def install_step(self): # `wannier90.x` executable is generated, but the actual binary is not built. We need to remove the symlink if LooseVersion(self.version) == LooseVersion("7.3"): w90_path = os.path.join(self.start_dir, 'bin', 'wannier90.x') - if not os.path.exists(os.readlink(w90_path)): + if os.path.islink(w90_path) and not os.path.exists(os.readlink(w90_path)): os.unlink(w90_path) # extract build targets as list From 28e3e238e19f1cd4d030a2d1f517fcbdfae42924 Mon Sep 17 00:00:00 2001 From: crivella Date: Fri, 8 Mar 2024 11:43:39 +0100 Subject: [PATCH 29/38] Change log.error to warning --- easybuild/easyblocks/q/quantumespresso.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 51ce6890a7a..665ce4da9fd 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -649,9 +649,9 @@ def test_step(self): perc = spass / max(stot, 1) self.log.info("Total tests passed %d out of %d (%.2f%%)" % (spass, stot, perc * 100)) if failures: - self.log.error("The following tests failed:") + self.log.warning("The following tests failed:") for failure in failures: - self.log.error('| ' + failure) + self.log.warning('| ' + failure) raise EasyBuildError("Test suite failed") if perc < thr: raise EasyBuildError( From a5647f3218a2fc4017eca3b9c4390ab8159eb9f3 Mon Sep 17 00:00:00 2001 From: ocaisa Date: Fri, 8 Mar 2024 12:02:51 +0100 Subject: [PATCH 30/38] Update easybuild/easyblocks/q/quantumespresso.py --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 665ce4da9fd..926e3aa2593 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -413,7 +413,7 @@ def configure_step(self): # libs is being used for the replacement in the wannier90 files libs = [] - # Only overriding for fcc as the intel flags are already ebing properly + # Only overriding for gcc as the intel flags are already being properly # set. if comp_fam == toolchain.GCC: num_libs = ['BLAS', 'LAPACK', 'FFT'] From ad3508bd90682bef9eddd756aaae07ce5de74d45 Mon Sep 17 00:00:00 2001 From: ocaisa Date: Fri, 8 Mar 2024 12:02:58 +0100 Subject: [PATCH 31/38] Update easybuild/easyblocks/q/quantumespresso.py --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 926e3aa2593..7152151110d 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -619,7 +619,7 @@ def test_step(self): # Log test-suite errors if present if _pass < _tot: - # Example output for reported faliures: + # Example output for reported failures: # pw_plugins - plugin-pw2casino_1.in (arg(s): 1): **FAILED**. # Different sets of data extracted from benchmark and test. # Data only in benchmark: p1. From f182aea69378c31e8e9b5099b54142ae827b3709 Mon Sep 17 00:00:00 2001 From: ocaisa Date: Fri, 8 Mar 2024 23:46:09 +0100 Subject: [PATCH 32/38] Don't raise an error just because there are some test failures --- easybuild/easyblocks/q/quantumespresso.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 7152151110d..d0272e7fa0e 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -652,7 +652,6 @@ def test_step(self): self.log.warning("The following tests failed:") for failure in failures: self.log.warning('| ' + failure) - raise EasyBuildError("Test suite failed") if perc < thr: raise EasyBuildError( "Test suite failed with less than %.2f %% (%.2f) success rate" % (thr * 100, perc * 100) From 72256de465ea892e869e41b3eed25b518f24f6cd Mon Sep 17 00:00:00 2001 From: crivella Date: Sat, 9 Mar 2024 13:50:28 +0100 Subject: [PATCH 33/38] FIX - test_suite started using NPROCS only after 7.2 --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index d0272e7fa0e..c674c01001b 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -591,7 +591,7 @@ def test_step(self): failures = [] for target in targets: pcmd = '' - if LooseVersion(self.version) < LooseVersion("7.0"): + if LooseVersion(self.version) < LooseVersion("7.2"): if parallel > 1: target = target + "-parallel" else: From 7074b6ddcb7a41a0630da270774aff64929c2339 Mon Sep 17 00:00:00 2001 From: crivella Date: Sat, 9 Mar 2024 13:51:43 +0100 Subject: [PATCH 34/38] FIX NETWORK_PSEUDO need patching also in QE 7.0 --- easybuild/easyblocks/q/quantumespresso.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index c674c01001b..7e598e7f34d 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -577,7 +577,8 @@ def test_step(self): test_dir = os.path.join(self.start_dir, self.TEST_SUITE_DIR) pseudo_loc = "https://pseudopotentials.quantum-espresso.org/upf_files/" - if LooseVersion(self.version) < LooseVersion("7.0"): + # NETWORK_PSEUDO in test_suite/ENVIRONMENT is set to old url for qe 7.0 and older + if LooseVersion(self.version) < LooseVersion("7.1"): cmd = ' && '.join([ "cd %s" % test_dir, "sed -i 's|export NETWORK_PSEUDO=.*|export NETWORK_PSEUDO=%s|g' ENVIRONMENT" % pseudo_loc From d349900c07907e9dea367fd19433d493fa0ef1bb Mon Sep 17 00:00:00 2001 From: crivella Date: Tue, 12 Mar 2024 10:14:07 +0100 Subject: [PATCH 35/38] Fixed wrong if logic --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 7e598e7f34d..c2d2bbf5adf 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -420,7 +420,7 @@ def configure_step(self): if self.cfg['with_scalapack']: num_libs.extend(['SCALAPACK']) elpa = get_software_root('ELPA') - elpa_lib = 'libelpa.a' if self.toolchain.options.get('openmp', False) else 'libelpa_openmp.a' + elpa_lib = 'libelpa_openmp.a' if self.toolchain.options.get('openmp', False) else 'libelpa.a' elpa_lib = os.path.join(elpa or '', 'lib', elpa_lib) for lib in num_libs: if self.toolchain.options.get('openmp', False): From 42b83109ecfeefba79c2774eeec8254ddcd4cb00 Mon Sep 17 00:00:00 2001 From: crivella Date: Tue, 12 Mar 2024 10:21:12 +0100 Subject: [PATCH 36/38] Added maximum number of failures on non ignored tests --- easybuild/easyblocks/q/quantumespresso.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index c2d2bbf5adf..1234f9e9cbb 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -75,7 +75,12 @@ def extra_options(): 'ph_ahc_diam', # Test detects a ! as an energy in baseline 'tddfpt_magnons_fe', # Too strict thresholds ], "List of test suite targets that are allowed to fail (name can partially match)", CUSTOM], - 'test_suite_threshold': [0.97, "Threshold for test suite success rate", CUSTOM], + 'test_suite_threshold': [ + 0.97, + "Threshold for test suite success rate (does count also allowed failures)", + CUSTOM + ], + 'test_suite_max_failed': [0, "Maximum number of failing tests (does not count allowed failures)", CUSTOM], } return ConfigureMake.extra_options(extra_vars) @@ -647,6 +652,8 @@ def test_step(self): full_out += out # Allow for flaky tests (eg too strict thresholds on results for structure relaxation) + num_fail = len(failures) + num_fail_thr = self.cfg.get('test_suite_max_failures', 0) perc = spass / max(stot, 1) self.log.info("Total tests passed %d out of %d (%.2f%%)" % (spass, stot, perc * 100)) if failures: @@ -657,6 +664,10 @@ def test_step(self): raise EasyBuildError( "Test suite failed with less than %.2f %% (%.2f) success rate" % (thr * 100, perc * 100) ) + if num_fail > num_fail_thr: + raise EasyBuildError( + "Test suite failed with more than %d failures %d" % (num_fail_thr, num_fail) + ) return full_out From abc63b67a3a6501cc150f4d666c9f9f982aa5624 Mon Sep 17 00:00:00 2001 From: crivella Date: Thu, 14 Mar 2024 10:14:28 +0100 Subject: [PATCH 37/38] Fixed wrong name --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 1234f9e9cbb..0b7258d0383 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -653,7 +653,7 @@ def test_step(self): # Allow for flaky tests (eg too strict thresholds on results for structure relaxation) num_fail = len(failures) - num_fail_thr = self.cfg.get('test_suite_max_failures', 0) + num_fail_thr = self.cfg.get('test_suite_max_failed', 0) perc = spass / max(stot, 1) self.log.info("Total tests passed %d out of %d (%.2f%%)" % (spass, stot, perc * 100)) if failures: From 7ad0303c490de8cbdad908bdb61f4d2b1d760c95 Mon Sep 17 00:00:00 2001 From: ocaisa Date: Fri, 15 Mar 2024 14:08:54 +0100 Subject: [PATCH 38/38] Update easybuild/easyblocks/q/quantumespresso.py --- easybuild/easyblocks/q/quantumespresso.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 0b7258d0383..563890072a6 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -666,7 +666,7 @@ def test_step(self): ) if num_fail > num_fail_thr: raise EasyBuildError( - "Test suite failed with more than %d failures %d" % (num_fail_thr, num_fail) + "Test suite failed with %d failures (%d failures permitted)" % (num_fail, num_fail_thr) ) return full_out