From 0f71a06bc2c4dfd61832a6be9793460346556463 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 14 Sep 2021 11:30:19 +0200 Subject: [PATCH 001/325] TensorFlow: Handle OpenSSL usage --- easybuild/easyblocks/t/tensorflow.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 8e40621918..f667716384 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -398,6 +398,18 @@ def get_system_libs(self): else: ignored_system_deps.append('%s (Python package %s)' % (tf_name, pkg_name)) + # If we use OpenSSL (potentially as a wrapper) somewhere in the chain we must tell TF to use it too + openssl_root = get_software_root('OpenSSL') + if openssl_root: + if 'boringssl' not in system_libs: + system_libs.append('boringssl') + incpath = os.path.join(sw_root, 'include') + if os.path.exists(incpath): + cpaths.append(incpath) + libpath = get_software_libdir(dep_name) + if libpath: + libpaths.append(os.path.join(sw_root, libpath)) + if ignored_system_deps: print_warning('%d TensorFlow dependencies have not been resolved by EasyBuild. Check the log for details.', len(ignored_system_deps)) From 27d6f00e1a4989ac11f43acc394e2c35e4a63c46 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 14 Sep 2021 12:13:16 +0200 Subject: [PATCH 002/325] Fix used variable --- easybuild/easyblocks/t/tensorflow.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index f667716384..a55d3524a1 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -400,15 +400,18 @@ def get_system_libs(self): # If we use OpenSSL (potentially as a wrapper) somewhere in the chain we must tell TF to use it too openssl_root = get_software_root('OpenSSL') + print("OSSL:", openssl_root) if openssl_root: if 'boringssl' not in system_libs: system_libs.append('boringssl') - incpath = os.path.join(sw_root, 'include') + incpath = os.path.join(openssl_root, 'include') + print(incpath) if os.path.exists(incpath): cpaths.append(incpath) libpath = get_software_libdir(dep_name) + print(libpath) if libpath: - libpaths.append(os.path.join(sw_root, libpath)) + libpaths.append(os.path.join(openssl_root, libpath)) if ignored_system_deps: print_warning('%d TensorFlow dependencies have not been resolved by EasyBuild. Check the log for details.', From 223101c898ecf8f113fb97e3b3e67c2fb1c049d0 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 14 Sep 2021 15:29:15 +0200 Subject: [PATCH 003/325] Remove debug prints --- easybuild/easyblocks/t/tensorflow.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index a55d3524a1..d37aea99a4 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -400,16 +400,13 @@ def get_system_libs(self): # If we use OpenSSL (potentially as a wrapper) somewhere in the chain we must tell TF to use it too openssl_root = get_software_root('OpenSSL') - print("OSSL:", openssl_root) if openssl_root: if 'boringssl' not in system_libs: system_libs.append('boringssl') incpath = os.path.join(openssl_root, 'include') - print(incpath) if os.path.exists(incpath): cpaths.append(incpath) libpath = get_software_libdir(dep_name) - print(libpath) if libpath: libpaths.append(os.path.join(openssl_root, libpath)) From 0855a2edd12b206a0a6620c8a481f6530deb0385 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 14 Feb 2022 18:55:32 +0000 Subject: [PATCH 004/325] adding fix_shebang to install_step so that we can fix shebangs when installing extensions --- easybuild/easyblocks/generic/pythonpackage.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index 6211e038dd..46d9b2e0c5 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -704,6 +704,9 @@ def install_step(self): # (for iterated installations over multiply Python versions) self.install_cmd_output += out + # fix shebangs if specified + self.fix_shebang() + # restore env vars if it they were set for name in ('PYTHONPATH', 'PATH'): value = old_values[name] From 45e6bbdf385bbef0ac2076326c239b2e1412aa38 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 22 Jul 2022 13:06:07 +0200 Subject: [PATCH 005/325] adding easyblocks: cudacompat.py --- easybuild/easyblocks/c/cudacompat.py | 133 +++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 easybuild/easyblocks/c/cudacompat.py diff --git a/easybuild/easyblocks/c/cudacompat.py b/easybuild/easyblocks/c/cudacompat.py new file mode 100644 index 0000000000..4b1d14d951 --- /dev/null +++ b/easybuild/easyblocks/c/cudacompat.py @@ -0,0 +1,133 @@ +## +# Copyright 2012-2022 Ghent University +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for CUDA compat libraries, implemented as an easyblock + +Ref: https://docs.nvidia.com/deploy/cuda-compatibility/index.html#manually-installing-from-runfile + +@author: Alexander Grund (TU Dresden) +""" + +import os +from distutils.version import LooseVersion + +from easybuild.easyblocks.generic.binary import Binary +from easybuild.framework.easyconfig import MANDATORY +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.filetools import copy_file, find_glob_pattern, mkdir, symlink +from easybuild.tools.run import run_cmd + + +class EB_CUDAcompat(Binary): + """ + Support for installing CUDA compat libraries. + """ + + @staticmethod + def extra_options(): + """Add variable for driver version""" + extra_vars = Binary.extra_options() + extra_vars.update({ + 'nv_version': [None, "Version of the driver package", MANDATORY], + }) + # We don't need the extract and install step from the Binary EasyBlock + del extra_vars['extract_sources'] + del extra_vars['install_cmd'] + # And also no need to modify the PATH + del extra_vars['prepend_to_path'] + return extra_vars + + def __init__(self, *args, **kwargs): + """Initialize custom class variables for Clang.""" + super(EB_CUDAcompat, self).__init__(*args, **kwargs) + + def extract_step(self): + """Extract the files without running the installer.""" + execpath = self.src[0]['path'] + tmpdir = os.path.join(self.builddir, 'tmp') + targetdir = os.path.join(self.builddir, 'extracted') + run_cmd("/bin/sh " + execpath + " --extract-only --tmpdir='%s' --target '%s'" % (tmpdir, targetdir)) + self.src[0]['finalpath'] = targetdir + + def install_step(self): + """Install CUDA compat libraries by copying library files and creating the symlinks.""" + libdir = os.path.join(self.installdir, 'lib') + mkdir(libdir) + + # From https://docs.nvidia.com/deploy/cuda-compatibility/index.html#installing-from-network-repo: + # The cuda-compat package consists of the following files: + # - libcuda.so.* - the CUDA Driver + # - libnvidia-nvvm.so.* - JIT LTO ( CUDA 11.5 and later only) + # - libnvidia-ptxjitcompiler.so.* - the JIT (just-in-time) compiler for PTX files + + library_globs = [ + 'libcuda.so.*', + 'libnvidia-ptxjitcompiler.so.*', + ] + if LooseVersion(self.version) >= '11.5': + library_globs.append('libnvidia-nvvm.so.*') + + startdir = self.cfg['start_dir'] + nv_version = self.cfg['nv_version'] + for library_glob in library_globs: + library_path = find_glob_pattern(os.path.join(startdir, library_glob)) + library = os.path.basename(library_path) + # Sanity check the version + if library_glob == 'libcuda.so.*': + library_version = library.split('.', 2)[2] + if library_version != nv_version: + raise EasyBuildError('Expected driver version %s (from nv_version) but found %s ' + '(determined from file %s)', nv_version, library_version, library_path) + + copy_file(library_path, os.path.join(libdir, library)) + if library.endswith('.' + nv_version): + # E.g. libcuda.so.510.73.08 -> libcuda.so.1 + versioned_symlink = library[:-len(nv_version)] + '1' + else: + # E.g. libnvidia-nvvm.so.4.0.0 -> libnvidia-nvvm.so.4 + versioned_symlink = library.rsplit('.', 2)[0] + symlink(library, os.path.join(libdir, versioned_symlink), use_abspath_source=False) + # E.g. libcuda.so.1 -> libcuda.so + unversioned_symlink = versioned_symlink.rsplit('.', 1)[0] + symlink(versioned_symlink, os.path.join(libdir, unversioned_symlink), use_abspath_source=False) + + def make_module_extra(self): + """Skip the changes from the Binary EasyBlock.""" + + return super(Binary, self).make_module_extra() + + def sanity_check_step(self): + """Check for core files (unversioned libs, symlinks)""" + libraries = [ + 'libcuda.so', + 'libnvidia-ptxjitcompiler.so', + ] + if LooseVersion(self.version) >= '11.5': + libraries.append('libnvidia-nvvm.so') + custom_paths = { + 'files': [os.path.join(self.installdir, 'lib', x) for x in libraries], + 'dirs': ['lib', 'lib64'], + } + super(EB_CUDAcompat, self).sanity_check_step(custom_paths=custom_paths) From e5a65b9a160e089ac633899b99b9d002f0d66f7d Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 25 Jul 2022 15:06:00 +0200 Subject: [PATCH 006/325] Check for EULA acceptance before downloading sources --- easybuild/easyblocks/c/cudacompat.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/easybuild/easyblocks/c/cudacompat.py b/easybuild/easyblocks/c/cudacompat.py index 4b1d14d951..4969357b9a 100644 --- a/easybuild/easyblocks/c/cudacompat.py +++ b/easybuild/easyblocks/c/cudacompat.py @@ -63,6 +63,16 @@ def __init__(self, *args, **kwargs): """Initialize custom class variables for Clang.""" super(EB_CUDAcompat, self).__init__(*args, **kwargs) + def fetch_step(self, *args, **kwargs): + """Check for EULA acceptance prior to getting sources.""" + # EULA for NVIDIA driver must be accepted via --accept-eula-for EasyBuild configuration option, + # or via 'accept_eula = True' in easyconfig file + self.check_accepted_eula( + name='NVIDIA-driver', + more_info='https://www.nvidia.com/content/DriverDownload-March2009/licence.php?lang=us' + ) + super(EB_CUDAcompat, self).fetch_step(*args, **kwargs) + def extract_step(self): """Extract the files without running the installer.""" execpath = self.src[0]['path'] From 3d11d24ae40d180ac54498e21e565675d3f56329 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 25 Jul 2022 14:09:05 +0000 Subject: [PATCH 007/325] introduce is_extend, is_dot_org, is_dot_com and simplify logic --- easybuild/easyblocks/o/openfoam.py | 68 +++++++++++++++--------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/easybuild/easyblocks/o/openfoam.py b/easybuild/easyblocks/o/openfoam.py index bbdfc4e29e..a112f8f063 100644 --- a/easybuild/easyblocks/o/openfoam.py +++ b/easybuild/easyblocks/o/openfoam.py @@ -78,7 +78,11 @@ def __init__(self, *args, **kwargs): self.looseversion = LooseVersion(clean_version) - if 'extend' in self.name.lower(): + self.is_extend = 'extend' in self.name.lower() + self.is_dot_com = self.looseversion >= LooseVersion('1606') + self.is_dot_org = self.looseversion <= LooseVersion('100') + + if self.is_extend: if self.looseversion >= LooseVersion('3.0'): self.openfoamdir = 'foam-extend-%s' % self.version else: @@ -153,7 +157,7 @@ def configure_step(self): extra_flags = '-fuse-ld=bfd' # older versions of OpenFOAM-Extend require -fpermissive - if 'extend' in self.name.lower() and self.looseversion < LooseVersion('2.0'): + if self.is_extend and self.looseversion < LooseVersion('2.0'): extra_flags += ' -fpermissive' if self.looseversion < LooseVersion('3.0'): @@ -174,13 +178,13 @@ def configure_step(self): regex_subs = [(r"^(setenv|export) WM_THIRD_PARTY_USE_.*[ =].*$", r"# \g<0>")] # this does not work for OpenFOAM Extend lower than 2.0 - if 'extend' not in self.name.lower() or self.looseversion >= LooseVersion('2.0'): + if not self.is_extend or self.looseversion >= LooseVersion('2.0'): key = "WM_PROJECT_VERSION" regex_subs += [(r"^(setenv|export) %s=.*$" % key, r"export %s=%s #\g<0>" % (key, self.version))] WM_env_var = ['WM_COMPILER', 'WM_COMPILE_OPTION', 'WM_MPLIB', 'WM_THIRD_PARTY_DIR'] # OpenFOAM >= 3.0.0 can use 64 bit integers - if 'extend' not in self.name.lower() and self.looseversion >= LooseVersion('3.0'): + if not self.is_extend and self.looseversion >= LooseVersion('3.0'): WM_env_var.append('WM_LABEL_SIZE') for env_var in WM_env_var: regex_subs.append((r"^(setenv|export) (?P%s)[ =](?P.*)$" % env_var, @@ -257,14 +261,14 @@ def configure_step(self): env.setvar("WM_NCOMPPROCS", str(self.cfg['parallel'])) # OpenFOAM >= 3.0.0 can use 64 bit integers - if 'extend' not in self.name.lower() and self.looseversion >= LooseVersion('3.0'): + if not self.is_extend and self.looseversion >= LooseVersion('3.0'): if self.toolchain.options['i8']: env.setvar("WM_LABEL_SIZE", '64') else: env.setvar("WM_LABEL_SIZE", '32') # make sure lib/include dirs for dependencies are found - openfoam_extend_v3 = 'extend' in self.name.lower() and self.looseversion >= LooseVersion('3.0') + openfoam_extend_v3 = self.is_extend and self.looseversion >= LooseVersion('3.0') if self.looseversion < LooseVersion("2") or openfoam_extend_v3: self.log.debug("List of deps: %s" % self.cfg.dependencies()) for dep in self.cfg.dependencies(): @@ -297,7 +301,7 @@ def build_step(self): setup_cmake_env(self.toolchain) precmd = "source %s" % os.path.join(self.builddir, self.openfoamdir, "etc", "bashrc") - if 'extend' not in self.name.lower() and self.looseversion >= LooseVersion('4.0'): + if not self.is_extend and self.looseversion >= LooseVersion('4.0'): if self.looseversion >= LooseVersion('2006'): cleancmd = "cd $WM_PROJECT_DIR && wclean -platform -all && cd -" else: @@ -312,7 +316,7 @@ def build_step(self): 'prebuildopts': self.cfg['prebuildopts'], 'makecmd': os.path.join(self.builddir, self.openfoamdir, '%s'), } - if 'extend' in self.name.lower() and self.looseversion >= LooseVersion('3.0'): + if self.is_extend and self.looseversion >= LooseVersion('3.0'): qa = { "Proceed without compiling ParaView [Y/n]": 'Y', "Proceed without compiling cudaSolvers? [Y/n]": 'Y', @@ -340,7 +344,7 @@ def det_psubdir(self): """Determine the platform-specific installation directory for OpenFOAM.""" # OpenFOAM >= 3.0.0 can use 64 bit integers # same goes for OpenFOAM-Extend >= 4.1 - if 'extend' in self.name.lower(): + if self.is_extend: set_int_size = self.looseversion >= LooseVersion('4.1') else: set_int_size = self.looseversion >= LooseVersion('3.0') @@ -357,7 +361,7 @@ def det_psubdir(self): arch = get_cpu_architecture() if arch == AARCH64: # Variants have different abbreviations for ARM64... - if self.looseversion < LooseVersion("100"): + if self.is_dot_org: archpart = 'Arm64' else: archpart = 'ARM64' @@ -386,7 +390,7 @@ def install_step(self): # to make sure they take precedence over the libraries in the dummy subdirectory shlib_ext = get_shared_lib_ext() psubdir = self.det_psubdir() - openfoam_extend_v3 = 'extend' in self.name.lower() and self.looseversion >= LooseVersion('3.0') + openfoam_extend_v3 = self.is_extend and self.looseversion >= LooseVersion('3.0') if openfoam_extend_v3 or self.looseversion < LooseVersion("2"): libdir = os.path.join(self.installdir, self.openfoamdir, "lib", psubdir) else: @@ -410,7 +414,7 @@ def sanity_check_step(self): shlib_ext = get_shared_lib_ext() psubdir = self.det_psubdir() - openfoam_extend_v3 = 'extend' in self.name.lower() and self.looseversion >= LooseVersion('3.0') + openfoam_extend_v3 = self.is_extend and self.looseversion >= LooseVersion('3.0') if openfoam_extend_v3 or self.looseversion < LooseVersion("2"): toolsdir = os.path.join(self.openfoamdir, "applications", "bin", psubdir) libsdir = os.path.join(self.openfoamdir, "lib", psubdir) @@ -422,26 +426,28 @@ def sanity_check_step(self): # some randomly selected binaries # if one of these is missing, it's very likely something went wrong + tools = ["boundaryFoam", "engineFoam", "buoyantSimpleFoam", "buoyantBoussinesqSimpleFoam", "sonicFoam"] + tools += ["surfaceAdd", "surfaceFind", "surfaceSmooth"] + tools += ["blockMesh", "checkMesh", "deformedGeom", "engineSwirl", "modifyMesh", "refineMesh"] + + # surfaceSmooth is replaced by surfaceLambdaMuSmooth is OpenFOAM v2.3.0 + if not self.is_extend and self.looseversion >= LooseVersion("2.3.0"): + tools.remove("surfaceSmooth") + tools.append("surfaceLambdaMuSmooth") + # sonicFoam and buoyantBoussineqSimpleFoam deprecated in version 7+ + if self.is_dot_org and self.looseversion >= LooseVersion('7'): + tools.remove("buoyantBoussinesqSimpleFoam") + tools.remove("sonicFoam") + bins = [os.path.join(self.openfoamdir, "bin", x) for x in ["paraFoam"]] + \ - [os.path.join(toolsdir, "buoyantSimpleFoam")] + \ - [os.path.join(toolsdir, "%sFoam" % x) for x in ["boundary", "engine"]] + \ - [os.path.join(toolsdir, "surface%s" % x) for x in ["Add", "Find", "Smooth"]] + \ - [os.path.join(toolsdir, x) for x in ['blockMesh', 'checkMesh', 'deformedGeom', 'engineSwirl', - 'modifyMesh', 'refineMesh']] + [os.path.join(toolsdir, x) for x in tools] # test setting up the OpenFOAM environment in bash shell load_openfoam_env = "source $FOAM_BASH" custom_commands = [load_openfoam_env] - # only include Boussinesq and sonic since for OpenFOAM < 7, since those solvers have been deprecated - if self.looseversion < LooseVersion('7'): - bins.extend([ - os.path.join(toolsdir, "buoyantBoussinesqSimpleFoam"), - os.path.join(toolsdir, "sonicFoam") - ]) - # check for the Pstream and scotchDecomp libraries, there must be a dummy one and an mpi one - if 'extend' in self.name.lower(): + if self.is_extend: libs = [os.path.join(libsdir, "libscotchDecomp.%s" % shlib_ext), os.path.join(libsdir, "libmetisDecomp.%s" % shlib_ext)] if self.looseversion < LooseVersion('3.2'): @@ -452,7 +458,7 @@ def sanity_check_step(self): libs.extend([os.path.join(libsdir, "libparMetisDecomp.%s" % shlib_ext)]) else: # OpenFOAM v2012 puts mpi into eb-mpi - if self.looseversion >= LooseVersion("2012"): + if self.is_dot_com and self.looseversion >= LooseVersion("2012"): mpilibssubdir = "eb-mpi" else: mpilibssubdir = "mpi" @@ -463,12 +469,8 @@ def sanity_check_step(self): [os.path.join(libsdir, "libscotchDecomp.%s" % shlib_ext)] + \ [os.path.join(libsdir, "dummy", "libscotchDecomp.%s" % shlib_ext)] - if 'extend' not in self.name.lower() and self.looseversion >= LooseVersion("2.3.0"): - # surfaceSmooth is replaced by surfaceLambdaMuSmooth is OpenFOAM v2.3.0 - bins.remove(os.path.join(toolsdir, "surfaceSmooth")) - bins.append(os.path.join(toolsdir, "surfaceLambdaMuSmooth")) - if 'extend' not in self.name.lower() and self.looseversion >= LooseVersion("2.4.0"): + if not self.is_extend and self.looseversion >= LooseVersion("2.4.0"): # also check for foamMonitor for OpenFOAM versions other than OpenFOAM-Extend bins.append(os.path.join(self.openfoamdir, 'bin', 'foamMonitor')) @@ -484,7 +486,7 @@ def sanity_check_step(self): # run motorBike tutorial case to ensure the installation is functional (if it's available); # only for recent (>= v6.0) versions of openfoam.org variant - if self.looseversion >= LooseVersion('6') and self.looseversion < LooseVersion('100'): + if self.is_dot_org and self.looseversion >= LooseVersion('6'): openfoamdir_path = os.path.join(self.installdir, self.openfoamdir) motorbike_path = os.path.join(openfoamdir_path, 'tutorials', 'incompressible', 'simpleFoam', 'motorBike') if os.path.exists(motorbike_path): @@ -537,7 +539,7 @@ def make_module_extra(self, altroot=None, altversion=None): ] # OpenFOAM >= 3.0.0 can use 64 bit integers - if 'extend' not in self.name.lower() and self.looseversion >= LooseVersion('3.0'): + if not self.is_extend and self.looseversion >= LooseVersion('3.0'): if self.toolchain.options['i8']: env_vars += [('WM_LABEL_SIZE', '64')] else: From 3a5e8ccb17bf544a645c7b9ccc33c69bdc4700da Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 25 Jul 2022 14:11:15 +0000 Subject: [PATCH 008/325] update tools for OpenFOAM 10 --- easybuild/easyblocks/o/openfoam.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/easybuild/easyblocks/o/openfoam.py b/easybuild/easyblocks/o/openfoam.py index a112f8f063..67f651f9e3 100644 --- a/easybuild/easyblocks/o/openfoam.py +++ b/easybuild/easyblocks/o/openfoam.py @@ -438,6 +438,14 @@ def sanity_check_step(self): if self.is_dot_org and self.looseversion >= LooseVersion('7'): tools.remove("buoyantBoussinesqSimpleFoam") tools.remove("sonicFoam") + # buoyantSimpleFoam replaced by buoyantFoam in versions 10+ + if self.is_dot_org and self.looseversion >= LooseVersion("10"): + tools.remove("buoyantSimpleFoam") + tools.append("buoyantFoam") + # engineFoam replaced by reactingFoam in versions 10+ + if self.is_dot_org and self.looseversion >= LooseVersion("10"): + tools.remove("engineFoam") + tools.append("reactingFoam") bins = [os.path.join(self.openfoamdir, "bin", x) for x in ["paraFoam"]] + \ [os.path.join(toolsdir, x) for x in tools] From 400235564ccd4f517e706c9bf446481fcfb12964 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 25 Jul 2022 14:14:59 +0000 Subject: [PATCH 009/325] appeasing hound --- easybuild/easyblocks/o/openfoam.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/o/openfoam.py b/easybuild/easyblocks/o/openfoam.py index 67f651f9e3..82327581b0 100644 --- a/easybuild/easyblocks/o/openfoam.py +++ b/easybuild/easyblocks/o/openfoam.py @@ -477,7 +477,6 @@ def sanity_check_step(self): [os.path.join(libsdir, "libscotchDecomp.%s" % shlib_ext)] + \ [os.path.join(libsdir, "dummy", "libscotchDecomp.%s" % shlib_ext)] - if not self.is_extend and self.looseversion >= LooseVersion("2.4.0"): # also check for foamMonitor for OpenFOAM versions other than OpenFOAM-Extend bins.append(os.path.join(self.openfoamdir, 'bin', 'foamMonitor')) From 49d2db06819d45ddb11542c9a8e84077c7529436 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 29 Jul 2022 16:40:36 +0200 Subject: [PATCH 010/325] Add nvidia-smi checks to validate driver requirements and installed module --- easybuild/easyblocks/c/cudacompat.py | 130 +++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 7 deletions(-) diff --git a/easybuild/easyblocks/c/cudacompat.py b/easybuild/easyblocks/c/cudacompat.py index 4969357b9a..8aea98f23b 100644 --- a/easybuild/easyblocks/c/cudacompat.py +++ b/easybuild/easyblocks/c/cudacompat.py @@ -34,9 +34,10 @@ from distutils.version import LooseVersion from easybuild.easyblocks.generic.binary import Binary -from easybuild.framework.easyconfig import MANDATORY -from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import copy_file, find_glob_pattern, mkdir, symlink +from easybuild.framework.easyconfig import CUSTOM, MANDATORY +from easybuild.tools.build_log import EasyBuildError, print_warning +from easybuild.tools.config import build_option, IGNORE +from easybuild.tools.filetools import copy_file, find_glob_pattern, mkdir, symlink, which from easybuild.tools.run import run_cmd @@ -50,6 +51,7 @@ def extra_options(): """Add variable for driver version""" extra_vars = Binary.extra_options() extra_vars.update({ + 'compatible_driver_versions': [None, "Minimum (system) CUDA driver versions which are compatible", CUSTOM], 'nv_version': [None, "Version of the driver package", MANDATORY], }) # We don't need the extract and install step from the Binary EasyBlock @@ -60,8 +62,52 @@ def extra_options(): return extra_vars def __init__(self, *args, **kwargs): - """Initialize custom class variables for Clang.""" + """Initialize custom class variables for CUDACompat.""" super(EB_CUDAcompat, self).__init__(*args, **kwargs) + self._has_nvidia_smi = None + + @property + def has_nvidia_smi(self): + """Return whether the system has nvidia-smi and print a warning once if not""" + if self._has_nvidia_smi is None: + self._has_nvidia_smi = which('nvidia-smi', on_error=IGNORE) is not None + if not self._has_nvidia_smi: + print_warning('Could not find nvidia-smi. Assuming a system without GPUs and skipping checks!') + return self._has_nvidia_smi + + def _run_nvidia_smi(self, args): + """ + Run nvidia-smi with the given argument(s) and return the output. + + Also does sensible logging. + Raises RuntimeError on failure. + """ + if not self.has_nvidia_smi: + raise RuntimeError('Could not find nvidia-smi.') + cmd = 'nvidia-smi ' + args + out, ec = run_cmd(cmd, log_ok=False, log_all=False, regexp=False) + if ec != 0: + raise RuntimeError("`%s` returned exit code %s with output:\n%s" % (cmd, ec, out)) + else: + self.log.info('`%s` succeeded with output:\n%s' % (cmd, out)) + return out.strip().split('\n') + + def prepare_step(self, *args, **kwargs): + """Parse and check the compatible_driver_versions value of the EasyConfig""" + compatible_driver_versions = self.cfg.get('compatible_driver_versions') + if compatible_driver_versions: + try: + # Create a dictionary with the major version as the keys + self.compatible_driver_version_map = { + int(v.split('.', 1)[0]): v + for v in compatible_driver_versions + } + except ValueError: + raise EasyBuildError("Invalid format of compatible_driver_versions. " + "Expected numeric major versions, got '%s'", compatible_driver_versions) + else: + self.compatible_driver_version_map = None + super(EB_CUDAcompat, self).prepare_step(*args, **kwargs) def fetch_step(self, *args, **kwargs): """Check for EULA acceptance prior to getting sources.""" @@ -71,7 +117,7 @@ def fetch_step(self, *args, **kwargs): name='NVIDIA-driver', more_info='https://www.nvidia.com/content/DriverDownload-March2009/licence.php?lang=us' ) - super(EB_CUDAcompat, self).fetch_step(*args, **kwargs) + return super(EB_CUDAcompat, self).fetch_step(*args, **kwargs) def extract_step(self): """Extract the files without running the installer.""" @@ -81,6 +127,44 @@ def extract_step(self): run_cmd("/bin/sh " + execpath + " --extract-only --tmpdir='%s' --target '%s'" % (tmpdir, targetdir)) self.src[0]['finalpath'] = targetdir + def test_step(self): + """ + Check for a compatible driver version if the EC has that information. + + This can be skipped with `--skip-test-step`. + """ + + if self.compatible_driver_version_map and self.has_nvidia_smi: + try: + out_lines = self._run_nvidia_smi('--query-gpu=driver_version --format=csv,noheader') + if not out_lines or not out_lines[0]: + raise RuntimeError('nvidia-smi did not find any GPUs on the system') + driver_version = out_lines[0] + version_parts = driver_version.split('.') + if len(version_parts) < 3 or any(not v.isdigit() for v in version_parts): + raise RuntimeError("Expected the version to be in format x.y.z (all numeric) " + "but got '%s'" % driver_version) + except RuntimeError as err: + self.log.warning("Failed to get the CUDA driver version: %s", err) + driver_version = None + + if not driver_version: + print_warning('Failed to determine the CUDA driver version, so skipping the compatibility check!') + else: + driver_version_major = int(driver_version.split('.', 1)[0]) + compatible_driver_versions = ', '.join(self.compatible_driver_version_map.values()) + if driver_version_major not in self.compatible_driver_version_map: + raise EasyBuildError('The installed CUDA driver %s is not a supported branch/major version for ' + '%s %s. Supported drivers: %s', + driver_version, self.name, self.version, compatible_driver_versions) + elif LooseVersion(driver_version) < self.compatible_driver_version_map[driver_version_major]: + raise EasyBuildError('The installed CUDA driver %s is to old for %s %s. Supported drivers: %s', + driver_version, self.name, self.version, compatible_driver_versions) + else: + self.log.info('The installed CUDA driver %s appears to be supported.', driver_version) + + return super(EB_CUDAcompat, self).test_step() + def install_step(self): """Install CUDA compat libraries by copying library files and creating the symlinks.""" libdir = os.path.join(self.installdir, 'lib') @@ -123,10 +207,16 @@ def install_step(self): unversioned_symlink = versioned_symlink.rsplit('.', 1)[0] symlink(versioned_symlink, os.path.join(libdir, unversioned_symlink), use_abspath_source=False) + def make_module_req_guess(self): + """Don't try to guess anything.""" + return dict() + def make_module_extra(self): - """Skip the changes from the Binary EasyBlock.""" + """Skip the changes from the Binary EasyBlock and (only) set LD_LIBRARY_PATH.""" - return super(Binary, self).make_module_extra() + txt = super(Binary, self).make_module_extra() + txt += self.module_generator.prepend_paths('LD_LIBRARY_PATH', 'lib') + return txt def sanity_check_step(self): """Check for core files (unversioned libs, symlinks)""" @@ -141,3 +231,29 @@ def sanity_check_step(self): 'dirs': ['lib', 'lib64'], } super(EB_CUDAcompat, self).sanity_check_step(custom_paths=custom_paths) + + if self.has_nvidia_smi: + fake_mod_data = None + + # skip loading of fake module when using --sanity-check-only, load real module instead + if build_option('sanity_check_only'): + self.load_module() + elif not self.dry_run: + fake_mod_data = self.load_fake_module(purge=True, verbose=True) + + try: + out_lines = self._run_nvidia_smi('--query --display=COMPUTE') + + if fake_mod_data: + self.clean_up_fake_module(fake_mod_data) + + cuda_version = next((line.rsplit(' ', 1)[1] for line in out_lines if line.startswith('CUDA')), None) + if not cuda_version: + raise RuntimeError('Failed to find CUDA version!') + self.log.info('CUDA version (as per nvidia-smi) after loading the module: ' + cuda_version) + if LooseVersion(cuda_version) != self.version: + raise RuntimeError('Reported CUDA version %s is not %s' % (cuda_version, self.version)) + except RuntimeError as err: + if fake_mod_data: + self.clean_up_fake_module(fake_mod_data) + raise EasyBuildError('Version check via nvidia-smi after loading the module failed: %s', err) From aa8f91e5185ea83a1bef0b44fa7a153dcdc070f4 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 23 Sep 2022 18:42:46 +0200 Subject: [PATCH 011/325] Improve the way test failures are counted, and the summary report that is printed in the warning. It now shows the amount of failures per test suite, as well as the total number of tests in those failing test suite. This should help interpret if 'a lot' of tests are failing, or if it is a neglible amount --- easybuild/easyblocks/p/pytorch.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 6ba20f42ea..60b542fc07 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -267,16 +267,34 @@ def test_step(self): test_cnt = 0 for hit in ran_tests_hits: test_cnt += int(hit) - - failed_tests = nub(re.findall(r"^(?P.*) failed!\s*$", tests_out, re.M)) - failed_test_cnt = len(failed_tests) - - if failed_test_cnt: +# This counts failed test suites, not failed tests +# failed_tests = nub(re.findall(r"^(?P.*) failed!\s*$", tests_out, re.M)) +# failed_test_cnt = len(failed_tests) + + # Get matches to create clear summary report + summary_matches=re.findall(r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?P.*) failed!$", tests_out, re.M) + + # Count test failures and errors + # TODO: these regexps don't properly grab the output from distributions/test_constraints and test_torch. We'll need to make additional regexps for those to guarantee that they are not missed... + test_failures=re.findall(r"^FAILED \((?[0-9]+).*\)$", tests_out, re.M) + test_fail_cnt=0 + for failures in test_failures: + test_fail_cnt += int(failures) + + test_errors=re.findall(f"^FAILED \(*.errors=(?P[0-9]+).*\)$", tests_out, re.M) + test_error_cnt=0 + for errors in test_errors: + test_error_cnt += int(errors) + + failed_test_cnt = test_fail_cnt + test_error_cnt + + if failed_test_cnt > 0: max_failed_tests = self.cfg['max_failed_tests'] test_or_tests = 'tests' if failed_test_cnt > 1 else 'test' msg = "%d %s (out of %d) failed:\n" % (failed_test_cnt, test_or_tests, test_cnt) - msg += '\n'.join('* %s' % t for t in sorted(failed_tests)) + for summary in summary_matches: + msg += "{test_suite} ({total} total tests, {failure_summary})\n".format(test_suite=summary[2], total=summary[0], failure_summary=summary[1]) if max_failed_tests == 0: raise EasyBuildError(msg) From 6ff70d1a7f511e6d7db1fa8393e7f4cc8117c865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 26 Sep 2022 16:38:42 +0200 Subject: [PATCH 012/325] Remove docs and java and add Rocky support for ABAQUS --- easybuild/easyblocks/a/abaqus.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/easybuild/easyblocks/a/abaqus.py b/easybuild/easyblocks/a/abaqus.py index 91ba89d56d..fe8ed67a5a 100644 --- a/easybuild/easyblocks/a/abaqus.py +++ b/easybuild/easyblocks/a/abaqus.py @@ -44,6 +44,7 @@ from easybuild.tools.filetools import change_dir, symlink, write_file from easybuild.tools.modules import get_software_root from easybuild.tools.run import run_cmd_qa +from easybuild.tools.systemtools import get_os_name from easybuild.tools.py2vs3 import OrderedDict @@ -78,6 +79,9 @@ def extract_step(self): def configure_step(self): """Configure ABAQUS installation.""" if LooseVersion(self.version) >= LooseVersion('2016'): + # Rocky Linux isn't recognized; faking it as RHEL + if get_os_name() == 'Rocky Linux': + setvar('DISTRIB_ID', 'RedHatEnterpriseServer') # skip checking of Linux version setvar('DSY_Force_OS', 'linux_a64') # skip checking of license server @@ -126,10 +130,9 @@ def install_step(self): # rather than a regular dictionary (where there's no guarantee on key order in general) std_qa = OrderedDict() - # Enable Extended Product Documentation - std_qa[selectionstr % (r"\[ \]", "Extended Product Documentation")] = "%(nr)s" - # Enable Abaqus CAE (docs) - std_qa[selectionstr % (r"\[ \]", "Abaqus CAE")] = "%(nr)s" + # Disable Extended Product Documentation (because it has a troublesome Java dependency) + std_qa[selectionstr % (r"\[*\]", "Extended Product Documentation")] = "%(nr)s" + installed_docs = False # enable all ABAQUS components std_qa[selectionstr % (r"\[ \]", "Abaqus.*")] = "%(nr)s" @@ -146,9 +149,9 @@ def install_step(self): # Disable/enable Tosca if self.cfg['with_tosca']: - std_qa[selectionstr % (r"\[\ \]", "Tosca")] = "%(nr)s" + std_qa[selectionstr % (r"\[\ \]", "Tosca.*")] = "%(nr)s" else: - std_qa[selectionstr % (r"\[\*\]", "Tosca")] = "%(nr)s" + std_qa[selectionstr % (r"\[\*\]", "Tosca.*")] = "%(nr)s" # disable CloudView std_qa[r"(?P[0-9]+) \[X\] Search using CloudView\nEnter selection:"] = '%(cloudview)s\n\n' @@ -170,7 +173,7 @@ def install_step(self): cae_subdir = os.path.join(self.installdir, 'cae') sim_subdir = os.path.join(self.installdir, 'sim') std_qa[r"Default.*SIMULIA/EstProducts.*:"] = cae_subdir - std_qa[r"SIMULIA[0-9]*doc.*:"] = os.path.join(self.installdir, 'doc') + std_qa[r"SIMULIA[0-9]*doc.*:"] = os.path.join(self.installdir, 'doc') # if docs are installed std_qa[r"SimulationServices.*:"] = sim_subdir std_qa[r"Choose the CODE installation directory.*:\n.*\n\n.*:"] = sim_subdir std_qa[r"SIMULIA/CAE.*:"] = cae_subdir @@ -197,13 +200,13 @@ def install_step(self): std_qa[r"Please choose an action:"] = '1' - if LooseVersion(self.version) >= LooseVersion('2022'): + if LooseVersion(self.version) >= LooseVersion('2022') and installed_docs: java_root = get_software_root('Java') if java_root: std_qa[r"Please enter .*Java Runtime Environment.* path.(\n.*)+Default \[\]:"] = java_root std_qa[r"Please enter .*Java Runtime Environment.* path.(\n.*)+Default \[.+\]:"] = '' else: - raise EasyBuildError("Java is a required dependency for ABAQUS versions >= 2022, but it is missing") + raise EasyBuildError("Java is a required dependency for ABAQUS docs versions >= 2022, but it is missing") # Continue std_qa[nextstr] = '' From 0df3f3acecca82bf4ae855d55b1428d5d6e80e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 26 Sep 2022 16:41:03 +0200 Subject: [PATCH 013/325] Fix long line --- easybuild/easyblocks/a/abaqus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/a/abaqus.py b/easybuild/easyblocks/a/abaqus.py index fe8ed67a5a..eff6c668c3 100644 --- a/easybuild/easyblocks/a/abaqus.py +++ b/easybuild/easyblocks/a/abaqus.py @@ -206,7 +206,7 @@ def install_step(self): std_qa[r"Please enter .*Java Runtime Environment.* path.(\n.*)+Default \[\]:"] = java_root std_qa[r"Please enter .*Java Runtime Environment.* path.(\n.*)+Default \[.+\]:"] = '' else: - raise EasyBuildError("Java is a required dependency for ABAQUS docs versions >= 2022, but it is missing") + raise EasyBuildError("Java is required for ABAQUS docs versions >= 2022, but it is missing") # Continue std_qa[nextstr] = '' From 5e9c2538a18b9a760274a2bac21f4508b903cbcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 26 Sep 2022 17:06:13 +0200 Subject: [PATCH 014/325] Remove doc sanity check --- easybuild/easyblocks/a/abaqus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/a/abaqus.py b/easybuild/easyblocks/a/abaqus.py index eff6c668c3..c8bc797e0b 100644 --- a/easybuild/easyblocks/a/abaqus.py +++ b/easybuild/easyblocks/a/abaqus.py @@ -333,7 +333,7 @@ def sanity_check_step(self): custom_commands = [] if LooseVersion(self.version) >= LooseVersion('2016'): - custom_paths['dirs'].extend(['cae', 'Commands', 'doc']) + custom_paths['dirs'].extend(['cae', 'Commands']) if LooseVersion(self.version) < LooseVersion('2020'): custom_paths['dirs'].extend(['sim']) # 'all' also check license server, but lmstat is usually not available From cf0eeaf99d8fd045d23e07876103f6788d544e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 28 Sep 2022 14:07:49 +0200 Subject: [PATCH 015/325] Include AlmaLinux in abaqus block as well Co-authored-by: Sam Moors --- easybuild/easyblocks/a/abaqus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/a/abaqus.py b/easybuild/easyblocks/a/abaqus.py index c8bc797e0b..be0013795b 100644 --- a/easybuild/easyblocks/a/abaqus.py +++ b/easybuild/easyblocks/a/abaqus.py @@ -80,7 +80,7 @@ def configure_step(self): """Configure ABAQUS installation.""" if LooseVersion(self.version) >= LooseVersion('2016'): # Rocky Linux isn't recognized; faking it as RHEL - if get_os_name() == 'Rocky Linux': + if get_os_name() in ['Rocky Linux', 'AlmaLinux']: setvar('DISTRIB_ID', 'RedHatEnterpriseServer') # skip checking of Linux version setvar('DSY_Force_OS', 'linux_a64') From db706d7039b8c7c3cff9959886e3e6a087ca2b7f Mon Sep 17 00:00:00 2001 From: casparl Date: Thu, 29 Sep 2022 16:54:06 +0200 Subject: [PATCH 016/325] Correctly count the number of failing tests, not failing test suites. Improve error reporting to provide more insight into which test suites fail --- easybuild/easyblocks/p/pytorch.py | 73 ++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 36aa710cb2..f200234209 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -264,17 +264,68 @@ def test_step(self): (tests_out, tests_ec) = super(EB_PyTorch, self).test_step(return_output_ec=True) ran_tests_hits = re.findall(r"^Ran (?P[0-9]+) tests in", tests_out, re.M) - test_cnt = sum(int(hit) for hit in ran_tests_hits) - - failed_tests = nub(re.findall(r"^(?P.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M)) - failed_test_cnt = len(failed_tests) - - if failed_test_cnt: - max_failed_tests = self.cfg['max_failed_tests'] - - test_or_tests = 'tests' if failed_test_cnt > 1 else 'test' - msg = "%d %s (out of %d) failed:\n" % (failed_test_cnt, test_or_tests, test_cnt) - msg += '\n'.join('* %s' % t for t in sorted(failed_tests)) + test_cnt = 0 + for hit in ran_tests_hits: + test_cnt += int(hit) + + # Get matches to create clear summary report, greps for patterns like: + # FAILED (errors=10, skipped=190, expected failures=6) + # test_fx failed! + summary_matches=re.findall(r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$", tests_out, re.M) + + # Get matches to create clear summary report, greps for patterns like: + # ===================== 2 failed, 128 passed, 2 skipped, 2 warnings in 3.43s ===================== + summary_matches_pattern2=re.findall(r"^=+ (?P.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$", tests_out, re.M) + + # Count failures and errors + def get_count_for_pattern(regex, text): + match = re.findall(regex, text, re.M) + if len(match) == 0: + return 0 + elif len(match) == 1: + return int(match[0]) + elif len(match) > 1: + # Shouldn't happen, throw warning (we don't need to error on a failed grep, the build could very well be fine) + # TODO: THROW WARNING + print("WARNING") + + failure_cnt=0 + error_cnt=0 + # Loop over first pattern to count failures/errors: + for summary in summary_matches: + print("Summary: %s" % summary[1]) + failures = get_count_for_pattern(r"^.*(?[0-9]+).*$", summary[1]) + print("Failures: %s" % failures) + failure_cnt += failures + errs = get_count_for_pattern(r"^.*errors=(?P[0-9]+).*$", summary[1]) + print("Errors: %s" % errs) + error_cnt += errs + + # Loop over the second pattern to count failures/errors + for summary in summary_matches_pattern2: + print("Summary: %s" % summary[0]) + failures = get_count_for_pattern(r"^.*(?P[0-9]+) failed.*$", summary[0]) + print("Failures: %s" % failures) + failure_cnt += failures + errs = get_count_for_pattern(r"^.*(?P[0-9]+) error.*$", summary[0]) + print("Errors: %s" % errs) + error_cnt += errs + + print("Total failures: %s" % failure_cnt) + print("Total errors: %s" % error_cnt) + + # Calculate total number of unsuccesful tests + failed_test_cnt = failure_cnt + error_cnt + + if failed_test_cnt > 0: + + failure_or_failures = 'failures' if failure_cnt > 1 else 'failure' + error_or_errors = 'errors' if error_cnt > 1 else 'error' + msg = "%d test %s, %d test %s (out of %d):\n" % (failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt) + for summary in summary_matches_pattern2: + msg += "{test_suite} ({failure_summary})\n".format(test_suite=summary[1], failure_summary=summary[0]) + for summary in summary_matches: + msg += "{test_suite} ({total} total tests, {failure_summary})\n".format(test_suite=summary[2], total=summary[0], failure_summary=summary[1]) if max_failed_tests == 0: raise EasyBuildError(msg) From 7c94d972d33eaf530ab8a8735bc31da0b0c84fe9 Mon Sep 17 00:00:00 2001 From: casparl Date: Thu, 29 Sep 2022 17:07:22 +0200 Subject: [PATCH 017/325] Fix formatting issues --- easybuild/easyblocks/p/pytorch.py | 49 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index f200234209..64bd3e88cb 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -271,12 +271,14 @@ def test_step(self): # Get matches to create clear summary report, greps for patterns like: # FAILED (errors=10, skipped=190, expected failures=6) # test_fx failed! - summary_matches=re.findall(r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$", tests_out, re.M) - + regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" + summary_matches = re.findall(regex, tests_out, re.M) + # Get matches to create clear summary report, greps for patterns like: # ===================== 2 failed, 128 passed, 2 skipped, 2 warnings in 3.43s ===================== - summary_matches_pattern2=re.findall(r"^=+ (?P.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$", tests_out, re.M) - + regex = r"^=+ (?P.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" + summary_matches_pattern2 = re.findall(regex, tests_out, re.M) + # Count failures and errors def get_count_for_pattern(regex, text): match = re.findall(regex, text, re.M) @@ -285,47 +287,44 @@ def get_count_for_pattern(regex, text): elif len(match) == 1: return int(match[0]) elif len(match) > 1: - # Shouldn't happen, throw warning (we don't need to error on a failed grep, the build could very well be fine) - # TODO: THROW WARNING - print("WARNING") - - failure_cnt=0 - error_cnt=0 + # Shouldn't happen, but means something went wrong with the regular expressions. + # Throw warning, as the build might be fine, no need to error on this. + warn_msg = "Error in counting the number of test failures in the output of the PyTorch test suite.\n" + warn_msg += "Please check the EasyBuild log to verify the number of failures (if any) was acceptable." + print_warning(warning_msg) + + failure_cnt = 0 + error_cnt = 0 # Loop over first pattern to count failures/errors: for summary in summary_matches: - print("Summary: %s" % summary[1]) failures = get_count_for_pattern(r"^.*(?[0-9]+).*$", summary[1]) - print("Failures: %s" % failures) failure_cnt += failures errs = get_count_for_pattern(r"^.*errors=(?P[0-9]+).*$", summary[1]) - print("Errors: %s" % errs) error_cnt += errs - + # Loop over the second pattern to count failures/errors for summary in summary_matches_pattern2: - print("Summary: %s" % summary[0]) failures = get_count_for_pattern(r"^.*(?P[0-9]+) failed.*$", summary[0]) - print("Failures: %s" % failures) failure_cnt += failures errs = get_count_for_pattern(r"^.*(?P[0-9]+) error.*$", summary[0]) - print("Errors: %s" % errs) error_cnt += errs - - print("Total failures: %s" % failure_cnt) - print("Total errors: %s" % error_cnt) - + # Calculate total number of unsuccesful tests failed_test_cnt = failure_cnt + error_cnt - + if failed_test_cnt > 0: - + failure_or_failures = 'failures' if failure_cnt > 1 else 'failure' error_or_errors = 'errors' if error_cnt > 1 else 'error' - msg = "%d test %s, %d test %s (out of %d):\n" % (failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt) + msg = "%d test %s, %d test %s (out of %d):\n" % ( + failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt + ) for summary in summary_matches_pattern2: msg += "{test_suite} ({failure_summary})\n".format(test_suite=summary[1], failure_summary=summary[0]) for summary in summary_matches: - msg += "{test_suite} ({total} total tests, {failure_summary})\n".format(test_suite=summary[2], total=summary[0], failure_summary=summary[1]) + msg += "{test_suite} ({total} total tests, {failure_summary})\n".format( + test_suite=summary[2], total=summary[0], failure_summary=summary[1] + ) if max_failed_tests == 0: raise EasyBuildError(msg) From 9ea72be727282ee509a1c007ba3252319a19b68a Mon Sep 17 00:00:00 2001 From: casparl Date: Thu, 29 Sep 2022 17:08:05 +0200 Subject: [PATCH 018/325] Fix typo --- easybuild/easyblocks/p/pytorch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 64bd3e88cb..6384bdda07 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -291,7 +291,7 @@ def get_count_for_pattern(regex, text): # Throw warning, as the build might be fine, no need to error on this. warn_msg = "Error in counting the number of test failures in the output of the PyTorch test suite.\n" warn_msg += "Please check the EasyBuild log to verify the number of failures (if any) was acceptable." - print_warning(warning_msg) + print_warning(warn_msg) failure_cnt = 0 error_cnt = 0 From 8b96b6978ad59e4d7ca43482b57644f2f24ef99f Mon Sep 17 00:00:00 2001 From: casparl Date: Thu, 29 Sep 2022 17:09:53 +0200 Subject: [PATCH 019/325] Further formatting fixes --- easybuild/easyblocks/p/pytorch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 6384bdda07..0b407190fc 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -271,9 +271,9 @@ def test_step(self): # Get matches to create clear summary report, greps for patterns like: # FAILED (errors=10, skipped=190, expected failures=6) # test_fx failed! - regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" + regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: W503 summary_matches = re.findall(regex, tests_out, re.M) - + # Get matches to create clear summary report, greps for patterns like: # ===================== 2 failed, 128 passed, 2 skipped, 2 warnings in 3.43s ===================== regex = r"^=+ (?P.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" From 9be147e2527f631e00c8166c71fd0d71f75e58e6 Mon Sep 17 00:00:00 2001 From: casparl Date: Thu, 29 Sep 2022 17:11:31 +0200 Subject: [PATCH 020/325] Further formatting fixes --- easybuild/easyblocks/p/pytorch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 0b407190fc..0045910cd5 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -271,7 +271,7 @@ def test_step(self): # Get matches to create clear summary report, greps for patterns like: # FAILED (errors=10, skipped=190, expected failures=6) # test_fx failed! - regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: W503 + regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: W501 summary_matches = re.findall(regex, tests_out, re.M) # Get matches to create clear summary report, greps for patterns like: From 6bab8b77c598e5409c39f45e368213579def2860 Mon Sep 17 00:00:00 2001 From: casparl Date: Fri, 30 Sep 2022 10:32:14 +0200 Subject: [PATCH 021/325] Forgot to assign max_failed_tests variable --- easybuild/easyblocks/p/pytorch.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 0045910cd5..df29fbfd02 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -313,6 +313,7 @@ def get_count_for_pattern(regex, text): failed_test_cnt = failure_cnt + error_cnt if failed_test_cnt > 0: + max_failed_tests = self.cfg['max_failed_tests'] failure_or_failures = 'failures' if failure_cnt > 1 else 'failure' error_or_errors = 'errors' if error_cnt > 1 else 'error' From adbd9115be9b7bed8bd36d7ec252c4ddcba6f1cc Mon Sep 17 00:00:00 2001 From: casparl Date: Fri, 30 Sep 2022 10:36:27 +0200 Subject: [PATCH 022/325] Removed include that is no longer needed --- easybuild/easyblocks/p/pytorch.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index df29fbfd02..4b2a993ec5 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -40,7 +40,6 @@ from easybuild.tools.filetools import symlink, apply_regex_substitutions from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.systemtools import POWER, get_cpu_architecture -from easybuild.tools.utilities import nub class EB_PyTorch(PythonPackage): From 1e6b4a7975f29ee46e47accfeb4c24b9f76caac9 Mon Sep 17 00:00:00 2001 From: casparl Date: Fri, 30 Sep 2022 10:41:13 +0200 Subject: [PATCH 023/325] Accept longer line, don't want to break a single regex in the middle --- easybuild/easyblocks/p/pytorch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 4b2a993ec5..57a9ea65c0 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -270,7 +270,7 @@ def test_step(self): # Get matches to create clear summary report, greps for patterns like: # FAILED (errors=10, skipped=190, expected failures=6) # test_fx failed! - regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: W501 + regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: E501 summary_matches = re.findall(regex, tests_out, re.M) # Get matches to create clear summary report, greps for patterns like: From dab687999313a8e448e4735458e211bbb44d45f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Fri, 30 Sep 2022 15:49:29 +0200 Subject: [PATCH 024/325] Update easybuild/easyblocks/a/abaqus.py Co-authored-by: ocaisa --- easybuild/easyblocks/a/abaqus.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/a/abaqus.py b/easybuild/easyblocks/a/abaqus.py index be0013795b..56d15b93be 100644 --- a/easybuild/easyblocks/a/abaqus.py +++ b/easybuild/easyblocks/a/abaqus.py @@ -130,9 +130,9 @@ def install_step(self): # rather than a regular dictionary (where there's no guarantee on key order in general) std_qa = OrderedDict() - # Disable Extended Product Documentation (because it has a troublesome Java dependency) + # Disable Extended Product Documentation because it has a troublesome Java dependency std_qa[selectionstr % (r"\[*\]", "Extended Product Documentation")] = "%(nr)s" - installed_docs = False + installed_docs = False # hard disabled, previous support was actually incomplete # enable all ABAQUS components std_qa[selectionstr % (r"\[ \]", "Abaqus.*")] = "%(nr)s" From ec7912624400649bfdcc491fed23d105eafcf58c Mon Sep 17 00:00:00 2001 From: Viktor Rehnberg <35767167+VRehnberg@users.noreply.github.com> Date: Fri, 30 Sep 2022 16:39:03 +0200 Subject: [PATCH 025/325] Fix typo TensorFlow -> PyTorch --- easybuild/easyblocks/p/pytorch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 36aa710cb2..fcf264095d 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -44,7 +44,7 @@ class EB_PyTorch(PythonPackage): - """Support for building/installing TensorFlow.""" + """Support for building/installing PyTorch.""" @staticmethod def extra_options(): From 3ac00ffb34ad1c47153ce494ab6f8bf1a4536036 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 30 Sep 2022 18:00:02 +0200 Subject: [PATCH 026/325] Fix typo Co-authored-by: ocaisa --- easybuild/easyblocks/c/cudacompat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/cudacompat.py b/easybuild/easyblocks/c/cudacompat.py index 8aea98f23b..5feaf25964 100644 --- a/easybuild/easyblocks/c/cudacompat.py +++ b/easybuild/easyblocks/c/cudacompat.py @@ -158,7 +158,7 @@ def test_step(self): '%s %s. Supported drivers: %s', driver_version, self.name, self.version, compatible_driver_versions) elif LooseVersion(driver_version) < self.compatible_driver_version_map[driver_version_major]: - raise EasyBuildError('The installed CUDA driver %s is to old for %s %s. Supported drivers: %s', + raise EasyBuildError('The installed CUDA driver %s is too old for %s %s. Supported drivers: %s', driver_version, self.name, self.version, compatible_driver_versions) else: self.log.info('The installed CUDA driver %s appears to be supported.', driver_version) From dea75454d2a14bd6749d225e30eb24c241c6ffdd Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 3 Oct 2022 13:33:52 +0200 Subject: [PATCH 027/325] Updated Clang EasyBlock to solve https://github.com/easybuilders/easybuild-easyconfigs/issues/15106 . Testing is ongoing. --- easybuild/easyblocks/c/clang.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 0479ebd1c9..b72f783b01 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -49,7 +49,7 @@ from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import AARCH32, AARCH64, POWER, X86_64 from easybuild.tools.systemtools import get_cpu_architecture, get_os_name, get_os_version, get_shared_lib_ext -from easybuild.tools.environment import setvar +from easybuild.tools.environment import setvar, restore_env, read_environment # List of all possible build targets for Clang CLANG_TARGETS = ["all", "AArch64", "AMDGPU", "ARM", "CppBackend", "Hexagon", "Mips", @@ -407,13 +407,16 @@ def build_with_prev_stage(self, prev_obj, next_obj): mkdir(next_obj) change_dir(next_obj) - # Configure. - CC = os.path.join(prev_obj, 'bin', 'clang') - CXX = os.path.join(prev_obj, 'bin', 'clang++') + # Make sure the clang and clang++ compilers from previous stages are (temporarily) in PATH + orig_env = copy.deepcopy(os.environ) + prev_obj_path = os.path.join(prev_obj, 'bin') + current_path = read_environment({'path': 'PATH'}) + setvar('PATH', current_path['path'] + prev_obj_path) + # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir - options += "-DCMAKE_C_COMPILER='%s' " % CC - options += "-DCMAKE_CXX_COMPILER='%s' " % CXX + options += "-DCMAKE_C_COMPILER='clang' " + options += "-DCMAKE_CXX_COMPILER='clang++' " options += self.cfg['configopts'] options += "-DCMAKE_BUILD_TYPE=%s" % self.build_type @@ -423,6 +426,9 @@ def build_with_prev_stage(self, prev_obj, next_obj): self.log.info("Building") run_cmd("make %s" % self.make_parallel_opts, log_all=True) + # Restore environment (specifically: PATH) + restore_env(orig_env) + def run_clang_tests(self, obj_dir): """Run Clang tests in specified directory (unless disabled).""" if not self.cfg['skip_all_tests']: From 9b7064ce32eee25dd65c29a0f6e7b84d95e3d524 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 3 Oct 2022 14:00:49 +0200 Subject: [PATCH 028/325] Forgot to import 'copy' --- easybuild/easyblocks/c/clang.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index b72f783b01..3f0ab07ca8 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -37,6 +37,7 @@ import glob import os import shutil +import copy from distutils.version import LooseVersion from easybuild.easyblocks.generic.cmakemake import CMakeMake From c034687cd8a2f2fca18dc6cb8a7d999077633a04 Mon Sep 17 00:00:00 2001 From: satishk Date: Tue, 4 Oct 2022 12:18:18 +0200 Subject: [PATCH 029/325] Modifications for PETSc 2022a. Now the SCOTCH libraries need to be specified due to library name changes. Several additional libraries added to the SuiteSparse which are required by PETSc as well. --- easybuild/easyblocks/p/petsc.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py index 0e42a3b60f..e147b5640b 100644 --- a/easybuild/easyblocks/p/petsc.py +++ b/easybuild/easyblocks/p/petsc.py @@ -210,6 +210,10 @@ def configure_step(self): # filter out deps handled seperately sep_deps = ['BLACS', 'BLAS', 'CMake', 'FFTW', 'LAPACK', 'numpy', 'mpi4py', 'papi', 'ScaLAPACK', 'SciPy-bundle', 'SuiteSparse'] + # SCOTCH has to be treated separately since they add weird postfixes + # to library names from SCOTCH 7.0.1 or PETSc version 3.17. + if (LooseVersion(self.version) >= LooseVersion("3.17")): + sep_deps += ['SCOTCH'] depfilter = [d['name'] for d in self.cfg.builddependencies()] + sep_deps deps = [dep['name'] for dep in self.cfg.dependencies() if not dep['name'] in depfilter] @@ -224,6 +228,21 @@ def configure_step(self): withdep = "--with-%s" % dep[1].lower() self.cfg.update('configopts', '%s=1 %s-dir=%s' % (withdep, withdep, deproot)) + # SCOTCH has to be treated separately since they add weird postfixes + # to library names from SCOTCH 7.0.1 or PETSc version 3.17. + if (LooseVersion(self.version) >= LooseVersion("3.17")): + scotch = get_software_root('SCOTCH') + if scotch: + withdep = "--with-ptscotch" + scotch_inc = [os.path.join(scotch, "include")] + inc_spec = "-include=[%s]" % ','.join(scotch_inc) + + # For some reason there is a v3 suffix added to libptscotchparmetis + # which is the reason for this new code. + req_scotch_libs = ['libptesmumps.a', 'libptscotchparmetisv3.a', 'libptscotch.a', 'libptscotcherr.a', 'libesmumps.a', 'libscotch.a', 'libscotcherr.a'] + scotch_libs = [os.path.join(scotch, "lib", x) for x in req_scotch_libs] + lib_spec = "-lib=[%s]" % ','.join(scotch_libs) + self.cfg.update('configopts', ' '.join([withdep + spec for spec in ['=1', inc_spec, lib_spec]])) # SuiteSparse options changed in PETSc 3.5, suitesparse = get_software_root('SuiteSparse') if suitesparse: @@ -231,13 +250,18 @@ def configure_step(self): withdep = "--with-suitesparse" # specified order of libs matters! ss_libs = ["UMFPACK", "KLU", "CHOLMOD", "BTF", "CCOLAMD", "COLAMD", "CAMD", "AMD"] + ss_libs_remove_spl_char = ss_libs + # More libraries added after version 3.17 + if LooseVersion(self.version) >= LooseVersion("3.17"): + # specified order of libs matters! + ss_libs = ["UMFPACK", "KLU", "SPQR", "CHOLMOD", "BTF", "CCOLAMD", "COLAMD", "CSparse", "CXSparse", "LDL", "RBio", "SLIP_LU", "CAMD", "AMD"] suitesparse_inc = [os.path.join(suitesparse, x, "Include") for x in ss_libs] suitesparse_inc.append(os.path.join(suitesparse, "SuiteSparse_config")) inc_spec = "-include=[%s]" % ','.join(suitesparse_inc) - suitesparse_libs = [os.path.join(suitesparse, x, "Lib", "lib%s.a" % x.lower()) + suitesparse_libs = [os.path.join(suitesparse, x, "Lib", "lib%s.a" % x.replace("_","").lower()) for x in ss_libs] suitesparse_libs.append(os.path.join(suitesparse, "SuiteSparse_config", "libsuitesparseconfig.a")) lib_spec = "-lib=[%s]" % ','.join(suitesparse_libs) From 5cf5588a317f91f2434487265a391dd553f874c6 Mon Sep 17 00:00:00 2001 From: satishk Date: Tue, 4 Oct 2022 12:31:49 +0200 Subject: [PATCH 030/325] Trying to satisfy the hound. --- easybuild/easyblocks/p/petsc.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py index e147b5640b..90c84cdf4c 100644 --- a/easybuild/easyblocks/p/petsc.py +++ b/easybuild/easyblocks/p/petsc.py @@ -239,7 +239,9 @@ def configure_step(self): # For some reason there is a v3 suffix added to libptscotchparmetis # which is the reason for this new code. - req_scotch_libs = ['libptesmumps.a', 'libptscotchparmetisv3.a', 'libptscotch.a', 'libptscotcherr.a', 'libesmumps.a', 'libscotch.a', 'libscotcherr.a'] + req_scotch_libs = ['libptesmumps.a', 'libptscotchparmetisv3.a', \ + 'libptscotch.a', 'libptscotcherr.a', 'libesmumps.a', \ + 'libscotch.a', 'libscotcherr.a'] scotch_libs = [os.path.join(scotch, "lib", x) for x in req_scotch_libs] lib_spec = "-lib=[%s]" % ','.join(scotch_libs) self.cfg.update('configopts', ' '.join([withdep + spec for spec in ['=1', inc_spec, lib_spec]])) @@ -250,18 +252,19 @@ def configure_step(self): withdep = "--with-suitesparse" # specified order of libs matters! ss_libs = ["UMFPACK", "KLU", "CHOLMOD", "BTF", "CCOLAMD", "COLAMD", "CAMD", "AMD"] - ss_libs_remove_spl_char = ss_libs # More libraries added after version 3.17 if LooseVersion(self.version) >= LooseVersion("3.17"): # specified order of libs matters! - ss_libs = ["UMFPACK", "KLU", "SPQR", "CHOLMOD", "BTF", "CCOLAMD", "COLAMD", "CSparse", "CXSparse", "LDL", "RBio", "SLIP_LU", "CAMD", "AMD"] + ss_libs = ["UMFPACK", "KLU", "SPQR", "CHOLMOD", "BTF", "CCOLAMD",\ + "COLAMD", "CSparse", "CXSparse", "LDL", "RBio",\ + "SLIP_LU", "CAMD", "AMD"] suitesparse_inc = [os.path.join(suitesparse, x, "Include") for x in ss_libs] suitesparse_inc.append(os.path.join(suitesparse, "SuiteSparse_config")) inc_spec = "-include=[%s]" % ','.join(suitesparse_inc) - suitesparse_libs = [os.path.join(suitesparse, x, "Lib", "lib%s.a" % x.replace("_","").lower()) + suitesparse_libs = [os.path.join(suitesparse, x, "Lib", "lib%s.a" % x.replace("_", "").lower()) for x in ss_libs] suitesparse_libs.append(os.path.join(suitesparse, "SuiteSparse_config", "libsuitesparseconfig.a")) lib_spec = "-lib=[%s]" % ','.join(suitesparse_libs) From 7126deb3c0433d17baafde3fdf6416fb123d796b Mon Sep 17 00:00:00 2001 From: satishk Date: Tue, 4 Oct 2022 12:34:22 +0200 Subject: [PATCH 031/325] Trying to satisfy the hound. --- easybuild/easyblocks/p/petsc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py index 90c84cdf4c..dfb97b1cf2 100644 --- a/easybuild/easyblocks/p/petsc.py +++ b/easybuild/easyblocks/p/petsc.py @@ -239,8 +239,8 @@ def configure_step(self): # For some reason there is a v3 suffix added to libptscotchparmetis # which is the reason for this new code. - req_scotch_libs = ['libptesmumps.a', 'libptscotchparmetisv3.a', \ - 'libptscotch.a', 'libptscotcherr.a', 'libesmumps.a', \ + req_scotch_libs = ['libptesmumps.a', 'libptscotchparmetisv3.a', + 'libptscotch.a', 'libptscotcherr.a', 'libesmumps.a', 'libscotch.a', 'libscotcherr.a'] scotch_libs = [os.path.join(scotch, "lib", x) for x in req_scotch_libs] lib_spec = "-lib=[%s]" % ','.join(scotch_libs) @@ -255,8 +255,8 @@ def configure_step(self): # More libraries added after version 3.17 if LooseVersion(self.version) >= LooseVersion("3.17"): # specified order of libs matters! - ss_libs = ["UMFPACK", "KLU", "SPQR", "CHOLMOD", "BTF", "CCOLAMD",\ - "COLAMD", "CSparse", "CXSparse", "LDL", "RBio",\ + ss_libs = ["UMFPACK", "KLU", "SPQR", "CHOLMOD", "BTF", "CCOLAMD", + "COLAMD", "CSparse", "CXSparse", "LDL", "RBio", "SLIP_LU", "CAMD", "AMD"] suitesparse_inc = [os.path.join(suitesparse, x, "Include") From fd6c5e79d1d4408e0b118bdfc0519b84a50d9c6f Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Tue, 4 Oct 2022 16:07:03 +0200 Subject: [PATCH 032/325] Added path seperator --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 3f0ab07ca8..8974b56456 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -412,7 +412,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): orig_env = copy.deepcopy(os.environ) prev_obj_path = os.path.join(prev_obj, 'bin') current_path = read_environment({'path': 'PATH'}) - setvar('PATH', current_path['path'] + prev_obj_path) + setvar('PATH', current_path['path'] + ":" + prev_obj_path) # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir From e1c4517fa1f543d974e8e3620537ee4bc392ba1b Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Tue, 4 Oct 2022 16:15:34 +0200 Subject: [PATCH 033/325] Also log to easybuild log file. The message contains a much easier to read overview of failing tests etc than what is logged in the logfile by default. --- easybuild/easyblocks/p/pytorch.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 57a9ea65c0..6dc8492b9a 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -337,8 +337,12 @@ def get_count_for_pattern(regex, text): "are known to be flaky, or do not affect your intended usage of PyTorch.", "In case of doubt, reach out to the EasyBuild community (via GitHub, Slack, or mailing list).", ]) + # Print to console, the user should really be aware that we are accepting failing tests here... print_warning(msg) + # Also log this warning in the file log + self.log.warning(msg) + if failed_test_cnt > max_failed_tests: raise EasyBuildError("Too many failed tests (%d), maximum allowed is %d", failed_test_cnt, max_failed_tests) From 05b215d12f01deeeb5c8affe510cfa2b6d960e75 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Wed, 5 Oct 2022 17:19:00 +0200 Subject: [PATCH 034/325] Improve error (sorted versions, show min. compatible version) --- easybuild/easyblocks/c/cudacompat.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/c/cudacompat.py b/easybuild/easyblocks/c/cudacompat.py index 5feaf25964..6d8563b795 100644 --- a/easybuild/easyblocks/c/cudacompat.py +++ b/easybuild/easyblocks/c/cudacompat.py @@ -152,14 +152,18 @@ def test_step(self): print_warning('Failed to determine the CUDA driver version, so skipping the compatibility check!') else: driver_version_major = int(driver_version.split('.', 1)[0]) - compatible_driver_versions = ', '.join(self.compatible_driver_version_map.values()) - if driver_version_major not in self.compatible_driver_version_map: + compatible_driver_versions = ', '.join(sorted(self.compatible_driver_version_map.values())) + try: + min_required_version = self.compatible_driver_version_map[driver_version_major] + except KeyError: raise EasyBuildError('The installed CUDA driver %s is not a supported branch/major version for ' '%s %s. Supported drivers: %s', driver_version, self.name, self.version, compatible_driver_versions) - elif LooseVersion(driver_version) < self.compatible_driver_version_map[driver_version_major]: - raise EasyBuildError('The installed CUDA driver %s is too old for %s %s. Supported drivers: %s', - driver_version, self.name, self.version, compatible_driver_versions) + if LooseVersion(driver_version) < min_required_version: + raise EasyBuildError('The installed CUDA driver %s is to old for %s %s, ' + 'need at least %s. Supported drivers: %s', + driver_version, self.name, self.version, + min_required_version, compatible_driver_versions) else: self.log.info('The installed CUDA driver %s appears to be supported.', driver_version) From fd0caab5f58401fae490555390a0a67d800621dc Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 6 Oct 2022 09:39:32 +0200 Subject: [PATCH 035/325] Make the test output from PythonPackage less verbose When the EasyBlock wants to handle the test output itself it doesn't make sense to search it for potential errors using the generic RegExp. This applies e.g. to PyTorch and TensorFlow which search for test failures themselves. So set `regexp=False` to avoid making the log much harder to read due to duplicated and, more annoyingly, partial test (fail) output. --- easybuild/easyblocks/generic/pythonpackage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index f84b601ef0..77c493b56e 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -684,8 +684,8 @@ def test_step(self, return_output_ec=False): ]) if return_output_ec: - (out, ec) = run_cmd(cmd, log_all=False, log_ok=False, simple=False) - # need to log seperately, since log_all and log_ok need to be false to retreive out and ec + (out, ec) = run_cmd(cmd, log_all=False, log_ok=False, simple=False, regexp=False) + # need to log seperately, since log_all and log_ok need to be false to retrieve out and ec self.log.info("cmd '%s' exited with exit code %s and output:\n%s", cmd, ec, out) else: run_cmd(cmd, log_all=True, simple=True) From 502f3085f0e86d27e8a03f1e276df0e187c84ace Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 6 Oct 2022 15:05:20 +0000 Subject: [PATCH 036/325] handle iterative builds with MakeCP EasyBlock --- easybuild/easyblocks/generic/makecp.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/makecp.py b/easybuild/easyblocks/generic/makecp.py index f8603445b7..55a223e755 100644 --- a/easybuild/easyblocks/generic/makecp.py +++ b/easybuild/easyblocks/generic/makecp.py @@ -26,6 +26,7 @@ @author: George Tsouloupas (The Cyprus Institute) @author: Fotis Georgatos (Uni.Lu, NTUA) @author: Kenneth Hoste (Ghent University) +@author: Maxime Boissonneault (Digital Research Alliance of Canada, Universite Laval) """ import os import glob @@ -70,6 +71,10 @@ def install_step(self): files_to_copy = self.cfg.get('files_to_copy') or [] self.log.debug("Starting install_step with files_to_copy: %s", files_to_copy) + + # if buildopts is a list, this is an iterative build, and directories will be copied multiple times + dirs_exist_ok = isinstance(self.cfg.get('buildopts'), list) + for fil in files_to_copy: if isinstance(fil, tuple): # ([src1, src2], targetdir) @@ -128,6 +133,6 @@ def install_step(self): elif os.path.isdir(filepath): self.log.debug("Copying directory %s to %s", filepath, target) fulltarget = os.path.join(target, os.path.basename(filepath)) - copy_dir(filepath, fulltarget, symlinks=self.cfg['keepsymlinks']) + copy_dir(filepath, fulltarget, symlinks=self.cfg['keepsymlinks'], dirs_exist_ok=dirs_exist_ok) else: raise EasyBuildError("Can't copy non-existing path %s to %s", filepath, target) From c8344f9040146b962371754506c92cdb03a3ac9c Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 6 Oct 2022 15:30:33 +0000 Subject: [PATCH 037/325] properly check if iterative build --- easybuild/easyblocks/generic/makecp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/generic/makecp.py b/easybuild/easyblocks/generic/makecp.py index 55a223e755..02b2ad12d0 100644 --- a/easybuild/easyblocks/generic/makecp.py +++ b/easybuild/easyblocks/generic/makecp.py @@ -72,8 +72,8 @@ def install_step(self): files_to_copy = self.cfg.get('files_to_copy') or [] self.log.debug("Starting install_step with files_to_copy: %s", files_to_copy) - # if buildopts is a list, this is an iterative build, and directories will be copied multiple times - dirs_exist_ok = isinstance(self.cfg.get('buildopts'), list) + # if this is an iterative build directories will be copied multiple times + dirs_exist_ok = True if self.iter_opts else False for fil in files_to_copy: if isinstance(fil, tuple): From d5d503ddd70f15f39b91463a1ada79340336dc8f Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Thu, 6 Oct 2022 21:24:25 +0200 Subject: [PATCH 038/325] First attempt at fixing https://github.com/easybuilders/easybuild-easyconfigs/issues/15106 --- easybuild/easyblocks/c/clang.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 8974b56456..8ca9263bc7 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -414,18 +414,24 @@ def build_with_prev_stage(self, prev_obj, next_obj): current_path = read_environment({'path': 'PATH'}) setvar('PATH', current_path['path'] + ":" + prev_obj_path) + # Hacky test fix by Caspar to create RPATH wrappers for the Clang compilers + from easybuild.toolchains.compiler.clang import Clang + my_clang_toolchain = Clang(name='Clang', version='1') + my_clang_toolchain.prepare_rpath_wrappers() + self.log.info("Prepared clang rpath wrappers") + # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir options += "-DCMAKE_C_COMPILER='clang' " options += "-DCMAKE_CXX_COMPILER='clang++' " options += self.cfg['configopts'] - options += "-DCMAKE_BUILD_TYPE=%s" % self.build_type + options += "-DCMAKE_BUILD_TYPE=%s " % self.build_type self.log.info("Configuring") run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) self.log.info("Building") - run_cmd("make %s" % self.make_parallel_opts, log_all=True) + run_cmd("make %s VERBOSE=1" % self.make_parallel_opts, log_all=True) # Restore environment (specifically: PATH) restore_env(orig_env) From 26ea18428719114eefbd1dfa8fbe18f932f22a58 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 7 Oct 2022 01:16:13 +0200 Subject: [PATCH 039/325] Combination of -Werror and Wunused-command-line-argument causes various cmake configure tests to fail. The unused command line arguments are the -Wl,-rpath commands added by the RPATH wrapper. We suppress those by adding -Wnounused-command-line-argument --- easybuild/easyblocks/c/clang.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 06d09df8f6..2a34a79649 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -420,6 +420,14 @@ def build_with_prev_stage(self, prev_obj, next_obj): my_clang_toolchain.prepare_rpath_wrappers() self.log.info("Prepared clang rpath wrappers") + # CvL: Add to CXXFLAGS to avoid unused command line argument warnings + # Since these result into some errors during configure (due to -Werror) + import easybuild.tools.environment as env + cflags = os.getenv('CFLAGS') + cxxflags = os.getenv('CXXFLAGS') + env.setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) + env.setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) + # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir options += "-DCMAKE_C_COMPILER='clang' " From 36794873ca20f6c760a99a033a1ddbab9e0d0bed Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 12 Oct 2022 14:15:50 +0000 Subject: [PATCH 040/325] Added support for cmake files in external dir for clang 15.x --- easybuild/easyblocks/c/clang.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 0479ebd1c9..4bb4b32be7 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -269,6 +269,13 @@ def configure_step(self): self.log.debug("Disabling the sanitizer tests") self.disable_sanitizer_tests() + # Since version 15.x, clang includes common CMake files in a separate source which must be + # added to the CMAKE_MODULE_PATH + # https://github.com/llvm/llvm-project/tree/main/cmake + if LooseVersion(self.version) >= LooseVersion('15.0'): + cmake_module_path = os.path.join(self.builddir, "cmake-%s.src" % self.version, "Modules") + self.cfg.update('configopts', '-DCMAKE_MODULE_PATH=%s' % cmake_module_path) + # Create and enter build directory. mkdir(self.llvm_obj_dir_stage1) change_dir(self.llvm_obj_dir_stage1) From 8345425ac66eae311370bdeddff2c17c05480f83 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 12 Oct 2022 14:18:37 +0000 Subject: [PATCH 041/325] add authorship --- easybuild/easyblocks/c/clang.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 4bb4b32be7..19ae71d760 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -32,6 +32,7 @@ @author: Dmitri Gribenko (National Technical University of Ukraine "KPI") @author: Ward Poelmans (Ghent University) @author: Alan O'Cais (Juelich Supercomputing Centre) +@author: Maxime Boissonneault (Digital Research Alliance of Canada, Universite Laval) """ import glob From 37cff29696d39c31030b8d93eba70088650b0232 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 12 Oct 2022 17:54:34 +0000 Subject: [PATCH 042/325] update clang.py EasyBlock for CLang 14+ --- easybuild/easyblocks/c/clang.py | 115 +++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 39 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 19ae71d760..79aea703e8 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -124,20 +124,7 @@ def check_readiness_step(self): def extract_step(self): """ - Prepare a combined LLVM source tree. The layout is: - llvm/ Unpack llvm-*.tar.gz here - projects/ - compiler-rt/ Unpack compiler-rt-*.tar.gz here - openmp/ Unpack openmp-*.tar.xz here - tools/ - clang/ Unpack clang-*.tar.gz here - tools/ - extra/ Unpack clang-tools-extra-*.tar.gz here - polly/ Unpack polly-*.tar.gz here - libcxx/ Unpack libcxx-*.tar.gz here - libcxxabi/ Unpack libcxxabi-*.tar.gz here - lld/ Unpack lld-*.tar.gz here - libunwind/ Unpack libunwind-*.tar.gz here + Prepare a combined LLVM source tree. The layout is different for versions earlier and later than 14. """ # Extract everything into separate directories. @@ -165,27 +152,71 @@ def find_source_dir(globpatterns, targetdir): glob_src_dirs) src_dirs[glob_src_dirs[0]] = targetdir - find_source_dir('compiler-rt-*', os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt')) + # the expected directory structure has completely changed in version 14.x of the project + if LooseVersion(self.version) >= LooseVersion('14'): + # For versions 14 and later, all tarballs get extracted at the directory level + # in a directory named after the component name - if self.cfg["usepolly"]: - find_source_dir('polly-*', os.path.join(self.llvm_src_dir, 'tools', 'polly')) - - if self.cfg["build_lld"]: - find_source_dir('lld-*', os.path.join(self.llvm_src_dir, 'tools', 'lld')) - if LooseVersion(self.version) >= LooseVersion('12.0.1'): - find_source_dir('libunwind-*', os.path.normpath(os.path.join(self.llvm_src_dir, '..', 'libunwind'))) + # the first extracted tarball behaves differently, we must change its finalpath + for tmp in self.src: + if tmp['name'].startswith("llvm-"): + tmp['finalpath'] = os.path.join(tmp['finalpath'], "..") + break - if self.cfg["libcxx"]: - find_source_dir('libcxx-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxx')) - find_source_dir('libcxxabi-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxxabi')) + # make the directory which will contain all extracted tarballs + self.llvm_src_dir = os.path.join(self.builddir, "llvm-project-%s" % self.version) + mkdir(self.llvm_src_dir) - find_source_dir(['clang-[1-9]*', 'cfe-*'], os.path.join(self.llvm_src_dir, 'tools', 'clang')) + components = ['llvm', 'cmake', 'compiler-rt', 'clang', 'openmp'] + if self.cfg["usepolly"]: components += ['polly'] + if self.cfg["build_lld"]: components += ['lld', 'libunwind'] + if self.cfg["build_lldb"]: components += ['lldb'] + if self.cfg["libcxx"]: components += ['libcxx', 'libcxxabi'] + if self.cfg["build_extra_clang_tools"]: components += ['clang-tools-extra'] - if self.cfg["build_extra_clang_tools"]: - find_source_dir('clang-tools-extra-*', os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra')) + for component in components: + find_source_dir("%s-[0-9]*" % component, os.path.join(self.llvm_src_dir, component)) - if LooseVersion(self.version) >= LooseVersion('3.8'): - find_source_dir('openmp-*', os.path.join(self.llvm_src_dir, 'projects', 'openmp')) + else: + # Layout for previous versions + # llvm/ Unpack llvm-*.tar.gz here + # projects/ + # compiler-rt/ Unpack compiler-rt-*.tar.gz here + # openmp/ Unpack openmp-*.tar.xz here + # tools/ + # clang/ Unpack clang-*.tar.gz here + # tools/ + # extra/ Unpack clang-tools-extra-*.tar.gz here + # polly/ Unpack polly-*.tar.gz here + # libcxx/ Unpack libcxx-*.tar.gz here + # libcxxabi/ Unpack libcxxabi-*.tar.gz here + # lld/ Unpack lld-*.tar.gz here + # lldb/ Unpack lldb-*.tar.gz here + # libunwind/ Unpack libunwind-*.tar.gz here + find_source_dir('compiler-rt-*', os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt')) + + if self.cfg["usepolly"]: + find_source_dir('polly-*', os.path.join(self.llvm_src_dir, 'tools', 'polly')) + + if self.cfg["build_lld"]: + find_source_dir('lld-*', os.path.join(self.llvm_src_dir, 'tools', 'lld')) + if LooseVersion(self.version) >= LooseVersion('12.0.1'): + find_source_dir('libunwind-*', os.path.normpath(os.path.join(self.llvm_src_dir, '..', 'libunwind'))) + + if self.cfg["build_lldb"]: + find_source_dir('lldb-*', os.path.join(self.llvm_src_dir, 'tools', 'lldb')) + + if self.cfg["libcxx"]: + find_source_dir('libcxx-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxx')) + find_source_dir('libcxxabi-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxxabi')) + + find_source_dir(['clang-[1-9]*', 'cfe-*'], os.path.join(self.llvm_src_dir, 'tools', 'clang')) + + if self.cfg["build_extra_clang_tools"]: + find_source_dir('clang-tools-extra-*', os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra')) + + if LooseVersion(self.version) >= LooseVersion('3.8'): + find_source_dir('openmp-*', os.path.join(self.llvm_src_dir, 'projects', 'openmp')) for src in self.src: for (dirname, new_path) in src_dirs.items(): @@ -270,13 +301,6 @@ def configure_step(self): self.log.debug("Disabling the sanitizer tests") self.disable_sanitizer_tests() - # Since version 15.x, clang includes common CMake files in a separate source which must be - # added to the CMAKE_MODULE_PATH - # https://github.com/llvm/llvm-project/tree/main/cmake - if LooseVersion(self.version) >= LooseVersion('15.0'): - cmake_module_path = os.path.join(self.builddir, "cmake-%s.src" % self.version, "Modules") - self.cfg.update('configopts', '-DCMAKE_MODULE_PATH=%s' % cmake_module_path) - # Create and enter build directory. mkdir(self.llvm_obj_dir_stage1) change_dir(self.llvm_obj_dir_stage1) @@ -375,8 +399,18 @@ def configure_step(self): "without specifying 'amd_gfx_list'") self.cfg.update('configopts', '-DLIBOMPTARGET_AMDGCN_GFXLIST=%s' % ' '.join(ec_amdgfx)) + # benchmarks are now in a third-party directory which is not found in any tarball component + # see https://github.com/llvm/llvm-project/issues/58320 + if LooseVersion(self.version) >= LooseVersion("14"): + self.cfg.update('configopts', '-DLLVM_INCLUDE_BENCHMARKS=OFF') + self.log.info("Configuring") - super(EB_Clang, self).configure_step(srcdir=self.llvm_src_dir) + + # directory structure has changed in version 14.x, cmake must start in llvm sub directory + if LooseVersion(self.version) >= LooseVersion("14"): + super(EB_Clang, self).configure_step(srcdir=os.path.join(self.llvm_src_dir, "llvm")) + else: + super(EB_Clang, self).configure_step(srcdir=self.llvm_src_dir) def disable_sanitizer_tests(self): """Disable the tests of all the sanitizers by removing the test directories from the build system""" @@ -399,7 +433,10 @@ def disable_sanitizer_tests(self): else: # In Clang 3.6, the sanitizer tests are grouped together in one CMakeLists # We patch out adding the subdirectories with the sanitizer tests - cmakelists_tests = os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt', 'test', 'CMakeLists.txt') + if LooseVersion(self.version) >= LooseVersion("14"): + cmakelists_tests = os.path.join(self.llvm_src_dir, 'compiler-rt', 'test', 'CMakeLists.txt') + else: + cmakelists_tests = os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt', 'test', 'CMakeLists.txt') regex_subs = [] if LooseVersion(self.version) >= LooseVersion('5.0'): regex_subs.append((r'compiler_rt_test_runtime.*san.*', '')) From b11228a7002bf51e060b624420ff4bf20d20689b Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 12 Oct 2022 18:06:29 +0000 Subject: [PATCH 043/325] appeasing hound --- easybuild/easyblocks/c/clang.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 79aea703e8..72cc9201cb 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -168,11 +168,16 @@ def find_source_dir(globpatterns, targetdir): mkdir(self.llvm_src_dir) components = ['llvm', 'cmake', 'compiler-rt', 'clang', 'openmp'] - if self.cfg["usepolly"]: components += ['polly'] - if self.cfg["build_lld"]: components += ['lld', 'libunwind'] - if self.cfg["build_lldb"]: components += ['lldb'] - if self.cfg["libcxx"]: components += ['libcxx', 'libcxxabi'] - if self.cfg["build_extra_clang_tools"]: components += ['clang-tools-extra'] + if self.cfg["usepolly"]: + components += ['polly'] + if self.cfg["build_lld"]: + components += ['lld', 'libunwind'] + if self.cfg["build_lldb"]: + components += ['lldb'] + if self.cfg["libcxx"]: + components += ['libcxx', 'libcxxabi'] + if self.cfg["build_extra_clang_tools"]: + components += ['clang-tools-extra'] for component in components: find_source_dir("%s-[0-9]*" % component, os.path.join(self.llvm_src_dir, component)) @@ -213,7 +218,8 @@ def find_source_dir(globpatterns, targetdir): find_source_dir(['clang-[1-9]*', 'cfe-*'], os.path.join(self.llvm_src_dir, 'tools', 'clang')) if self.cfg["build_extra_clang_tools"]: - find_source_dir('clang-tools-extra-*', os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra')) + find_source_dir('clang-tools-extra-*', + os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra')) if LooseVersion(self.version) >= LooseVersion('3.8'): find_source_dir('openmp-*', os.path.join(self.llvm_src_dir, 'projects', 'openmp')) From df19190a07392fade55f3ffc48af507f14df8056 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 12 Oct 2022 18:15:06 +0000 Subject: [PATCH 044/325] fix later stages to use the new directory structure in llvm 14 --- easybuild/easyblocks/c/clang.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 72cc9201cb..d2fe22d9dc 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -469,7 +469,10 @@ def build_with_prev_stage(self, prev_obj, next_obj): options += "-DCMAKE_BUILD_TYPE=%s" % self.build_type self.log.info("Configuring") - run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) + if LooseVersion(self.version) >= LooseVersion("14"): + run_cmd("cmake %s %s" % (options, os.path.join(self.llvm_src_dir, "llvm")), log_all=True) + else: + run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) self.log.info("Building") run_cmd("make %s" % self.make_parallel_opts, log_all=True) From b436f55669e5e09fe49555c7ce6a3c456dbacc4a Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Thu, 13 Oct 2022 14:43:23 +0200 Subject: [PATCH 045/325] Wrap in if-statements so that RPATH-specific logic is only executed when --rpath is used. Also, put more clear comments --- easybuild/easyblocks/c/clang.py | 41 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 2a34a79649..66409dce8e 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -45,7 +45,7 @@ from easybuild.tools import run from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import build_option -from easybuild.tools.filetools import apply_regex_substitutions, change_dir, mkdir +from easybuild.tools.filetools import apply_regex_substitutions, change_dir, mkdir, which from easybuild.tools.modules import get_software_root from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import AARCH32, AARCH64, POWER, X86_64 @@ -414,19 +414,24 @@ def build_with_prev_stage(self, prev_obj, next_obj): current_path = read_environment({'path': 'PATH'}) setvar('PATH', current_path['path'] + ":" + prev_obj_path) - # Hacky test fix by Caspar to create RPATH wrappers for the Clang compilers - from easybuild.toolchains.compiler.clang import Clang - my_clang_toolchain = Clang(name='Clang', version='1') - my_clang_toolchain.prepare_rpath_wrappers() - self.log.info("Prepared clang rpath wrappers") - - # CvL: Add to CXXFLAGS to avoid unused command line argument warnings - # Since these result into some errors during configure (due to -Werror) - import easybuild.tools.environment as env - cflags = os.getenv('CFLAGS') - cxxflags = os.getenv('CXXFLAGS') - env.setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) - env.setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) + # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 + if build_option('rpath'): + from easybuild.toolchains.compiler.clang import Clang + my_clang_toolchain = Clang(name='Clang', version='1') + my_clang_toolchain.prepare_rpath_wrappers() + self.log.info("Prepared clang rpath wrappers") + + # RPATH wrappers add -Wl,rpath arguments to all command lines, including when it is just compiling + # Clang by default warns about that, and then some configure tests use -Werror which turns those warnings + # into errors. As a result, those configure tests fail, even though the compiler supports the requested + # functionality (e.g. the test that checks if -fPIC is supported would fail, and it compiles without + # resulting in relocation errors). + # See https://github.com/easybuilders/easybuild-easyblocks/pull/2799#issuecomment-1270621100 + # Here, we add -Wno-unused-command-line-argument to CXXFLAGS to avoid these warnings alltogether + cflags = os.getenv('CFLAGS') + cxxflags = os.getenv('CXXFLAGS') + setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) + setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir @@ -435,6 +440,14 @@ def build_with_prev_stage(self, prev_obj, next_obj): options += self.cfg['configopts'] options += "-DCMAKE_BUILD_TYPE=%s " % self.build_type + # Cmake looks for llvm-link by default in the same directory as the compiler + # However, when compiling with rpath, the clang 'compiler' is not actually the compiler, but the wrapper + # Clearly, the wrapper directory won't llvm-link. Thus, we pass the linker to be used by full path. + # See https://github.com/easybuilders/easybuild-easyblocks/pull/2799#issuecomment-1275916186 + if build_option('rpath'): + llvm_link = which('llvm-link') + options += "-DLIBOMPTARGET_NVPTX_BC_LINKER=%s" % llvm_link + self.log.info("Configuring") run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) From 00bc1767af1fa3054e9be799d2ecbd2afa7a9218 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 13 Oct 2022 14:43:35 +0000 Subject: [PATCH 046/325] introduce llvm_projects variable and use the combined tarball instead of components --- easybuild/easyblocks/c/clang.py | 74 ++++++++++++++++----------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index d2fe22d9dc..082d0d7cef 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -99,6 +99,7 @@ def extra_options(): # The sanitizer tests often fail on HPC systems due to the 'weird' environment. 'skip_sanitizer_tests': [True, "Do not run the sanitizer tests", CUSTOM], 'usepolly': [False, "Build Clang with polly", CUSTOM], + 'llvm_projects': [[], "LLVM projects to install", CUSTOM], }) # disable regular out-of-source build, too simplistic for Clang to work extra_vars['separate_build_dir'][0] = False @@ -114,6 +115,30 @@ def __init__(self, *args, **kwargs): self.llvm_obj_dir_stage3 = None self.make_parallel_opts = "" + if not self.cfg['llvm_projects']: + self.cfg['llvm_projects'] = [] + + # keep compatibility between using llvm_projects vs using flags + if LooseVersion(self.version) >= LooseVersion('14'): + self.cfg.update('llvm_projects', ['llvm', 'compiler-rt', 'clang', 'openmp'], allow_duplicate=False) + if self.cfg['usepolly']: + self.cfg.update('llvm_projects', 'polly', allow_duplicate=False) + if self.cfg['build_lld']: + self.cfg.update('llvm_projects', ['lld', 'libunwind'], allow_duplicate=False) + if self.cfg['build_lldb']: + self.cfg.update('llvm_projects', 'lldb', allow_duplicate=False) + if self.cfg['libcxx']: + self.cfg.update('llvm_projects', ['libcxx', 'libcxxabi'], allow_duplicate=False) + if self.cfg['build_extra_clang_tools']: + self.cfg.update('llvm_projects', 'clang-tools-extra', allow_duplicate=False) + else: + self.cfg['usepolly'] = 'polly' in self.cfg['llvm_projects'] + self.cfg['build_lld'] = all([x in self.cfg['llvm_projects'] for x in ['lld', 'libunwind']]) + self.cfg['build_lldb'] = 'lldb' in self.cfg['llvm_projects'] + self.cfg['libcxx'] = all([x in self.cfg['llvm_projects'] for x in ['libcxx', 'libcxxabi']]) + self.cfg['build_extra_clang_tools'] = 'clang-tools-extra' in self.cfg['llvm_projects'] + + def check_readiness_step(self): """Fail early on RHEL 5.x and derivatives because of known bug in libc.""" super(EB_Clang, self).check_readiness_step() @@ -152,36 +177,11 @@ def find_source_dir(globpatterns, targetdir): glob_src_dirs) src_dirs[glob_src_dirs[0]] = targetdir - # the expected directory structure has completely changed in version 14.x of the project if LooseVersion(self.version) >= LooseVersion('14'): - # For versions 14 and later, all tarballs get extracted at the directory level - # in a directory named after the component name - - # the first extracted tarball behaves differently, we must change its finalpath - for tmp in self.src: - if tmp['name'].startswith("llvm-"): - tmp['finalpath'] = os.path.join(tmp['finalpath'], "..") - break - - # make the directory which will contain all extracted tarballs - self.llvm_src_dir = os.path.join(self.builddir, "llvm-project-%s" % self.version) - mkdir(self.llvm_src_dir) - - components = ['llvm', 'cmake', 'compiler-rt', 'clang', 'openmp'] - if self.cfg["usepolly"]: - components += ['polly'] - if self.cfg["build_lld"]: - components += ['lld', 'libunwind'] - if self.cfg["build_lldb"]: - components += ['lldb'] - if self.cfg["libcxx"]: - components += ['libcxx', 'libcxxabi'] - if self.cfg["build_extra_clang_tools"]: - components += ['clang-tools-extra'] - - for component in components: - find_source_dir("%s-[0-9]*" % component, os.path.join(self.llvm_src_dir, component)) - + # the expected directory structure has completely changed in version 14.x of the project, we use the + # complete tarball + find_source_dir("../llvm-project-*", os.path.join(self.llvm_src_dir, "llvm-project-%s" % self.version)) + self.cfg.update('configopts', '-DLLVM_ENABLE_PROJECTS="%s"' % ';'.join(self.cfg['llvm_projects'])) else: # Layout for previous versions # llvm/ Unpack llvm-*.tar.gz here @@ -405,15 +405,10 @@ def configure_step(self): "without specifying 'amd_gfx_list'") self.cfg.update('configopts', '-DLIBOMPTARGET_AMDGCN_GFXLIST=%s' % ' '.join(ec_amdgfx)) - # benchmarks are now in a third-party directory which is not found in any tarball component - # see https://github.com/llvm/llvm-project/issues/58320 - if LooseVersion(self.version) >= LooseVersion("14"): - self.cfg.update('configopts', '-DLLVM_INCLUDE_BENCHMARKS=OFF') - self.log.info("Configuring") # directory structure has changed in version 14.x, cmake must start in llvm sub directory - if LooseVersion(self.version) >= LooseVersion("14"): + if LooseVersion(self.version) >= LooseVersion('14'): super(EB_Clang, self).configure_step(srcdir=os.path.join(self.llvm_src_dir, "llvm")) else: super(EB_Clang, self).configure_step(srcdir=self.llvm_src_dir) @@ -439,7 +434,7 @@ def disable_sanitizer_tests(self): else: # In Clang 3.6, the sanitizer tests are grouped together in one CMakeLists # We patch out adding the subdirectories with the sanitizer tests - if LooseVersion(self.version) >= LooseVersion("14"): + if LooseVersion(self.version) >= LooseVersion('14'): cmakelists_tests = os.path.join(self.llvm_src_dir, 'compiler-rt', 'test', 'CMakeLists.txt') else: cmakelists_tests = os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt', 'test', 'CMakeLists.txt') @@ -469,7 +464,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): options += "-DCMAKE_BUILD_TYPE=%s" % self.build_type self.log.info("Configuring") - if LooseVersion(self.version) >= LooseVersion("14"): + if LooseVersion(self.version) >= LooseVersion('14'): run_cmd("cmake %s %s" % (options, os.path.join(self.llvm_src_dir, "llvm")), log_all=True) else: run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) @@ -547,7 +542,10 @@ def post_install_step(self): # copy Python bindings here in post-install step so that it is not done more than once in multi_deps context if self.cfg['python_bindings']: - python_bindings_source_dir = os.path.join(self.llvm_src_dir, "tools", "clang", "bindings", "python") + if LooseVersion(self.version) >= LooseVersion('14'): + python_bindings_source_dir = os.path.join(self.llvm_src_dir, "clang", "bindings", "python") + else: + python_bindings_source_dir = os.path.join(self.llvm_src_dir, "tools", "clang", "bindings", "python") python_bindins_target_dir = os.path.join(self.installdir, 'lib', 'python') shutil.copytree(python_bindings_source_dir, python_bindins_target_dir) From f578c775239c4e6c1f1c858636986dc0a47afb30 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 13 Oct 2022 14:45:58 +0000 Subject: [PATCH 047/325] add support for lldb --- easybuild/easyblocks/c/clang.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 082d0d7cef..3e0ffe5476 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -87,6 +87,7 @@ def extra_options(): 'bootstrap': [True, "Bootstrap Clang using GCC", CUSTOM], 'build_extra_clang_tools': [False, "Build extra Clang tools", CUSTOM], 'build_lld': [False, "Build the LLVM lld linker", CUSTOM], + 'build_lldb': [False, "Build the LLVM lldb debugger", CUSTOM], 'build_targets': [None, "Build targets for LLVM (host architecture if None). Possible values: " + ', '.join(CLANG_TARGETS), CUSTOM], 'default_cuda_capability': [None, "Default CUDA capability specified for clang, e.g. '7.5'", CUSTOM], @@ -574,6 +575,9 @@ def sanity_check_step(self): if self.cfg["build_lld"]: custom_paths['files'].extend(["bin/lld"]) + if self.cfg["build_lldb"]: + custom_paths['files'].extend(["bin/lldb"]) + if self.cfg["libcxx"]: custom_paths['files'].extend(["lib/libc++.%s" % shlib_ext]) custom_paths['files'].extend(["lib/libc++abi.%s" % shlib_ext]) From 1e403987a6bcfd482677f886e90d120b59f6a4a5 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 13 Oct 2022 14:46:37 +0000 Subject: [PATCH 048/325] appeasing lint --- easybuild/easyblocks/c/clang.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 3e0ffe5476..a3e06b1690 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -139,7 +139,6 @@ def __init__(self, *args, **kwargs): self.cfg['libcxx'] = all([x in self.cfg['llvm_projects'] for x in ['libcxx', 'libcxxabi']]) self.cfg['build_extra_clang_tools'] = 'clang-tools-extra' in self.cfg['llvm_projects'] - def check_readiness_step(self): """Fail early on RHEL 5.x and derivatives because of known bug in libc.""" super(EB_Clang, self).check_readiness_step() From c693551347b4972cff0343be1340675d31f8c513 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Fri, 14 Oct 2022 11:26:13 +0200 Subject: [PATCH 049/325] enhance OpenBLAS easyblock to support running LAPACK test suite + checking how many tests fail --- easybuild/easyblocks/o/openblas.py | 63 +++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/o/openblas.py b/easybuild/easyblocks/o/openblas.py index 4973fa0df1..be12dbd08a 100644 --- a/easybuild/easyblocks/o/openblas.py +++ b/easybuild/easyblocks/o/openblas.py @@ -3,21 +3,40 @@ @author: Andrew Edmondson (University of Birmingham) @author: Alex Domingo (Vrije Universiteit Brussel) +@author: Kenneth Hoste (Ghent University) """ import os +import re from distutils.version import LooseVersion from easybuild.easyblocks.generic.configuremake import ConfigureMake +from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.systemtools import POWER, get_cpu_architecture, get_shared_lib_ext -from easybuild.tools.build_log import print_warning +from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import ERROR from easybuild.tools.run import run_cmd, check_log_for_errors +LAPACK_TEST_TARGET = 'lapack-test' TARGET = 'TARGET' class EB_OpenBLAS(ConfigureMake): """Support for building/installing OpenBLAS.""" + @staticmethod + def extra_options(): + """Custom easyconfig parameters for OpenBLAS easyblock.""" + extra_vars = { + 'max_failing_lapack_tests_num_errors': [0, "Maximum number of LAPACK tests failing " + "due to numerical errors", CUSTOM], + 'max_failing_lapack_tests_other_errors': [0, "Maximum number of LAPACK tests failing " + "due to non-numerical errors", CUSTOM], + 'run_lapack_tests': [False, "Run LAPACK tests during test step, " + "and check whether failing tests exceeds threshold", CUSTOM], + } + + return ConfigureMake.extra_options(extra_vars) + + def configure_step(self): """ set up some options - but no configure command to run""" @@ -72,10 +91,47 @@ def build_step(self): cmd = ' '.join([self.cfg['prebuildopts'], makecmd, ' '.join(build_parts), self.cfg['buildopts']]) run_cmd(cmd, log_all=True, simple=True) + def check_lapack_test_results(self, test_output): + """Check output of OpenBLAS' LAPACK test suite ('make lapack-test').""" + + # example: + # --> LAPACK TESTING SUMMARY <-- + # SUMMARY nb test run numerical error other error + # ================ =========== ================= ================ + # ... + # --> ALL PRECISIONS 4116982 4172 (0.101%) 0 (0.000%) + test_summary_pattern = r'\s+'.join([ + r"^--> ALL PRECISIONS", + r"(?P[0-9]+)", + r"(?P[0-9]+)\s+\([0-9.]+\%\)", + r"(?P[0-9]+)\s+\([0-9.]+\%\)", + ]) + regex = re.compile(test_summary_pattern, re.M) + res = regex.search(test_output) + if res: + (tot_cnt, fail_cnt_num_errors, fail_cnt_other_errors) = [int(x) for x in res.groups()] + msg = "%d LAPACK tests run - %d failed due to numerical errors - %d failed due to other errors" + self.log.info(msg, tot_cnt, fail_cnt_num_errors, fail_cnt_other_errors) + + if fail_cnt_other_errors > self.cfg['max_failing_lapack_tests_other_errors']: + raise EasyBuildError("Too many LAPACK tests failed due to non-numerical errors: %d (> %d)", + fail_cnt_other_errors, self.cfg['max_failing_lapack_tests_other_errors']) + + if fail_cnt_num_errors > self.cfg['max_failing_lapack_tests_num_errors']: + raise EasyBuildError("Too many LAPACK tests failed due to numerical errors: %d (> %d)", + fail_cnt_num_errors, self.cfg['max_failing_lapack_tests_num_errors']) + else: + raise EasyBuildError("Failed to find test summary using pattern '%s' in test output: %s", + test_summary_pattern, test_output) + def test_step(self): """ Mandatory test step plus optional runtest""" run_tests = ['tests'] + + if self.cfg['run_lapack_tests']: + run_tests += [LAPACK_TEST_TARGET] + if self.cfg['runtest']: run_tests += [self.cfg['runtest']] @@ -86,6 +142,11 @@ def test_step(self): # Raise an error if any test failed check_log_for_errors(out, [('FATAL ERROR', ERROR)]) + # check number of failing LAPACK tests more closely + if runtest == LAPACK_TEST_TARGET: + self.check_lapack_test_results(out) + + def sanity_check_step(self): """ Custom sanity check for OpenBLAS """ custom_paths = { From 25d2e06f2b8aa6be633a73a92cd2a0ca16fafff2 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Fri, 14 Oct 2022 12:30:45 +0200 Subject: [PATCH 050/325] trivial style fixes for OpenBLAS easyblock --- easybuild/easyblocks/o/openblas.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/o/openblas.py b/easybuild/easyblocks/o/openblas.py index be12dbd08a..9ce5034ba0 100644 --- a/easybuild/easyblocks/o/openblas.py +++ b/easybuild/easyblocks/o/openblas.py @@ -27,16 +27,15 @@ def extra_options(): """Custom easyconfig parameters for OpenBLAS easyblock.""" extra_vars = { 'max_failing_lapack_tests_num_errors': [0, "Maximum number of LAPACK tests failing " - "due to numerical errors", CUSTOM], + "due to numerical errors", CUSTOM], 'max_failing_lapack_tests_other_errors': [0, "Maximum number of LAPACK tests failing " - "due to non-numerical errors", CUSTOM], + "due to non-numerical errors", CUSTOM], 'run_lapack_tests': [False, "Run LAPACK tests during test step, " "and check whether failing tests exceeds threshold", CUSTOM], } return ConfigureMake.extra_options(extra_vars) - def configure_step(self): """ set up some options - but no configure command to run""" @@ -146,7 +145,6 @@ def test_step(self): if runtest == LAPACK_TEST_TARGET: self.check_lapack_test_results(out) - def sanity_check_step(self): """ Custom sanity check for OpenBLAS """ custom_paths = { From a1426529608c7ca3d8fed4fb971d1dc9db121c0d Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 14 Oct 2022 17:40:31 +0200 Subject: [PATCH 051/325] Fix https://github.com/easybuilders/easybuild-easyblocks/issues/2802 using improved regex --- easybuild/easyblocks/p/pytorch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index ec4ee9ad97..42ed999e85 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -303,9 +303,9 @@ def get_count_for_pattern(regex, text): # Loop over the second pattern to count failures/errors for summary in summary_matches_pattern2: - failures = get_count_for_pattern(r"^.*(?P[0-9]+) failed.*$", summary[0]) + failures = get_count_for_pattern(r"^.*[^0-9](?P[0-9]+) failed.*$", summary[0]) failure_cnt += failures - errs = get_count_for_pattern(r"^.*(?P[0-9]+) error.*$", summary[0]) + errs = get_count_for_pattern(r"^.*[^0-9](?P[0-9]+) error.*$", summary[0]) error_cnt += errs # Calculate total number of unsuccesful tests From ae86d8876b2ab79319ce2a2cc1587f3116603a27 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Fri, 14 Oct 2022 19:19:35 +0000 Subject: [PATCH 052/325] update logic to be coherent before and after llvm 14 --- easybuild/easyblocks/c/clang.py | 43 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index a3e06b1690..91ab0b7661 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -132,12 +132,14 @@ def __init__(self, *args, **kwargs): self.cfg.update('llvm_projects', ['libcxx', 'libcxxabi'], allow_duplicate=False) if self.cfg['build_extra_clang_tools']: self.cfg.update('llvm_projects', 'clang-tools-extra', allow_duplicate=False) - else: - self.cfg['usepolly'] = 'polly' in self.cfg['llvm_projects'] - self.cfg['build_lld'] = all([x in self.cfg['llvm_projects'] for x in ['lld', 'libunwind']]) - self.cfg['build_lldb'] = 'lldb' in self.cfg['llvm_projects'] - self.cfg['libcxx'] = all([x in self.cfg['llvm_projects'] for x in ['libcxx', 'libcxxabi']]) - self.cfg['build_extra_clang_tools'] = 'clang-tools-extra' in self.cfg['llvm_projects'] + + # ensure libunwind is there if lld is there + if 'lld' in self.cfg['llvm_projects']: + self.cfg.update('llvm_projects', 'libunwind', allow_duplicate=False) + + # ensure libcxxabi is there if libcxx is there + if 'libcxx' in self.cfg['llvm_projects']: + self.cfg.update('llvm_projects', 'libcxxabi', allow_duplicate=False) def check_readiness_step(self): """Fail early on RHEL 5.x and derivatives because of known bug in libc.""" @@ -177,9 +179,8 @@ def find_source_dir(globpatterns, targetdir): glob_src_dirs) src_dirs[glob_src_dirs[0]] = targetdir - if LooseVersion(self.version) >= LooseVersion('14'): - # the expected directory structure has completely changed in version 14.x of the project, we use the - # complete tarball + if any([x['name'].startswith('llvm-project') for x in self.src]): + # if sources contain 'llvm-project*', we use the full tarball find_source_dir("../llvm-project-*", os.path.join(self.llvm_src_dir, "llvm-project-%s" % self.version)) self.cfg.update('configopts', '-DLLVM_ENABLE_PROJECTS="%s"' % ';'.join(self.cfg['llvm_projects'])) else: @@ -200,24 +201,24 @@ def find_source_dir(globpatterns, targetdir): # libunwind/ Unpack libunwind-*.tar.gz here find_source_dir('compiler-rt-*', os.path.join(self.llvm_src_dir, 'projects', 'compiler-rt')) - if self.cfg["usepolly"]: + if 'polly' in self.cfg['llvm_projects']: find_source_dir('polly-*', os.path.join(self.llvm_src_dir, 'tools', 'polly')) - if self.cfg["build_lld"]: + if 'lld' in self.cfg['llvm_projects']: find_source_dir('lld-*', os.path.join(self.llvm_src_dir, 'tools', 'lld')) if LooseVersion(self.version) >= LooseVersion('12.0.1'): find_source_dir('libunwind-*', os.path.normpath(os.path.join(self.llvm_src_dir, '..', 'libunwind'))) - if self.cfg["build_lldb"]: + if 'lldb' in self.cfg['llvm_projects']: find_source_dir('lldb-*', os.path.join(self.llvm_src_dir, 'tools', 'lldb')) - if self.cfg["libcxx"]: + if 'libcxx' in self.cfg['llvm_projects']: find_source_dir('libcxx-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxx')) find_source_dir('libcxxabi-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxxabi')) find_source_dir(['clang-[1-9]*', 'cfe-*'], os.path.join(self.llvm_src_dir, 'tools', 'clang')) - if self.cfg["build_extra_clang_tools"]: + if 'clang-tools-extra' in self.cfg['llvm_projects']: find_source_dir('clang-tools-extra-*', os.path.join(self.llvm_src_dir, 'tools', 'clang', 'tools', 'extra')) @@ -344,7 +345,7 @@ def configure_step(self): else: self.cfg.update('configopts', "-DLLVM_ENABLE_ASSERTIONS=OFF") - if self.cfg["usepolly"]: + if 'polly' in self.cfg['llvm_projects']: self.cfg.update('configopts', "-DLINK_POLLY_INTO_TOOLS=ON") # If Z3 is included as a dep, enable support in static analyzer (if enabled) @@ -356,7 +357,7 @@ def configure_step(self): build_targets = self.cfg['build_targets'] - if self.cfg["usepolly"] and "NVPTX" in build_targets: + if 'polly' in self.cfg['llvm_projects'] and "NVPTX" in build_targets: self.cfg.update('configopts', "-DPOLLY_ENABLE_GPGPU_CODEGEN=ON") self.cfg.update('configopts', '-DLLVM_TARGETS_TO_BUILD="%s"' % ';'.join(build_targets)) @@ -564,20 +565,20 @@ def sanity_check_step(self): if self.cfg['static_analyzer']: custom_paths['files'].extend(["bin/scan-build", "bin/scan-view"]) - if self.cfg['build_extra_clang_tools'] and LooseVersion(self.version) >= LooseVersion('3.4'): + if 'clang-tools-extra' in self.cfg['llvm_projects'] and LooseVersion(self.version) >= LooseVersion('3.4'): custom_paths['files'].extend(["bin/clang-tidy"]) - if self.cfg["usepolly"]: + if 'polly' in self.cfg['llvm_projects']: custom_paths['files'].extend(["lib/LLVMPolly.%s" % shlib_ext]) custom_paths['dirs'].extend(["include/polly"]) - if self.cfg["build_lld"]: + if 'lld' in self.cfg['llvm_projects']: custom_paths['files'].extend(["bin/lld"]) - if self.cfg["build_lldb"]: + if 'lldb' in self.cfg['llvm_projects']: custom_paths['files'].extend(["bin/lldb"]) - if self.cfg["libcxx"]: + if 'libcxx' in self.cfg['llvm_projects']: custom_paths['files'].extend(["lib/libc++.%s" % shlib_ext]) custom_paths['files'].extend(["lib/libc++abi.%s" % shlib_ext]) From b8cdfdb6545b88641ff703dcd2e4fc7aed62a319 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 17 Oct 2022 13:39:49 +0200 Subject: [PATCH 053/325] Check `filter_env_vars` for $LD_LIBRARY_PATH --- easybuild/easyblocks/c/cudacompat.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easybuild/easyblocks/c/cudacompat.py b/easybuild/easyblocks/c/cudacompat.py index 6d8563b795..07e7bdb175 100644 --- a/easybuild/easyblocks/c/cudacompat.py +++ b/easybuild/easyblocks/c/cudacompat.py @@ -107,6 +107,9 @@ def prepare_step(self, *args, **kwargs): "Expected numeric major versions, got '%s'", compatible_driver_versions) else: self.compatible_driver_version_map = None + if 'LD_LIBRARY_PATH' in (build_option('filter_env_vars') or []): + raise EasyBuildError("This module relies on setting $LD_LIBRARY_PATH, " + "so you need to remove this variable from --filter-env-vars") super(EB_CUDAcompat, self).prepare_step(*args, **kwargs) def fetch_step(self, *args, **kwargs): From 018d685dc0849ba1de6b4fed873f9c11aa4a58de Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Mon, 17 Oct 2022 14:03:00 +0200 Subject: [PATCH 054/325] allow empty optarch string for opencv --- easybuild/easyblocks/o/opencv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/o/opencv.py b/easybuild/easyblocks/o/opencv.py index 7d18d0906e..035fd751a3 100644 --- a/easybuild/easyblocks/o/opencv.py +++ b/easybuild/easyblocks/o/opencv.py @@ -165,7 +165,7 @@ def configure_step(self): # see https://github.com/opencv/opencv/wiki/CPU-optimizations-build-options if self.toolchain.options.get('optarch') and 'CPU_BASELINE' not in self.cfg['configopts']: optarch = build_option('optarch') - if optarch is None: + if not optarch: # optimize for host arch (let OpenCV detect it) self.cfg.update('configopts', '-DCPU_BASELINE=DETECT') elif optarch == OPTARCH_GENERIC: From 7e08937d22adb49a0c37d4b41ede1f62e3c3f8f2 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Mon, 17 Oct 2022 22:21:04 +0200 Subject: [PATCH 055/325] enhance EasyBuildMeta easyblock to auto-enable installing with pip rather than 'setup.py install' when using Python >= 3.6 and if pip >= 21.0 is available --- easybuild/easyblocks/e/easybuildmeta.py | 26 +++++++++++++++++-- easybuild/easyblocks/generic/pythonpackage.py | 8 +++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/e/easybuildmeta.py b/easybuild/easyblocks/e/easybuildmeta.py index 5949a181f8..86ceb75d73 100644 --- a/easybuild/easyblocks/e/easybuildmeta.py +++ b/easybuild/easyblocks/e/easybuildmeta.py @@ -33,9 +33,9 @@ import sys from distutils.version import LooseVersion -from easybuild.easyblocks.generic.pythonpackage import PythonPackage +from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pip_version from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import read_file +from easybuild.tools.filetools import read_file, which from easybuild.tools.modules import get_software_root_env_var_name from easybuild.tools.py2vs3 import OrderedDict from easybuild.tools.utilities import flatten @@ -66,6 +66,28 @@ def __init__(self, *args, **kwargs): # consider setuptools first, in case it is listed as a sources self.easybuild_pkgs.insert(0, 'setuptools') + # opt-in to using pip for recent version of EasyBuild, if: + # - EasyBuild is being installed for Python >= 3.6; + # - pip is available, and recent enough (>= 21.0); + # - use_pip is not specified; + pyver = sys.version.split(' ')[0] + pip = which('pip') + self.log.info("Python version: %s - pip: %s", pyver, pip) + if sys.version_info >= (3, 6) and pip and self.cfg['use_pip'] is None: + # try to determine pip version, ignore any failures that occur while doing so; + # problems may occur due changes in environment ($PYTHONPATH, etc.) + pip_version = None + try: + pip_version = det_pip_version() + self.log.info("Found Python v%s + pip: %s", pyver, pip_version) + except Exception as err: + self.log.warning("Failed to determine pip version: %s", err) + + if pip_version and LooseVersion(pip_version) >= LooseVersion('21.0'): + self.log.info("Auto-enabling use of pip to install EasyBuild!") + self.cfg['use_pip'] = True + self.determine_install_command() + # Override this function since we want to respect the user choice for the python installation to use # (which can be influenced by EB_PYTHON and EB_INSTALLPYTHON) def prepare_python(self): diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index 77c493b56e..5788c05bed 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -318,6 +318,12 @@ def __init__(self, *args, **kwargs): # determine install command self.use_setup_py = False + self.determine_install_command() + + def determine_install_command(self): + """ + Determine install command to use. + """ if self.cfg.get('use_pip', False) or self.cfg.get('use_pip_editable', False): self.install_cmd = PIP_INSTALL_CMD @@ -361,7 +367,7 @@ def __init__(self, *args, **kwargs): else: raise EasyBuildError("Installing zipped eggs requires using easy_install or pip") - self.log.debug("Using '%s' as install command", self.install_cmd) + self.log.info("Using '%s' as install command", self.install_cmd) def set_pylibdirs(self): """Set Python lib directory-related class variables.""" From fd77f29c259109fef9c794275e2bf24e93cee4b3 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Mon, 17 Oct 2022 22:22:14 +0200 Subject: [PATCH 056/325] enhance EasyBuildMeta easyblock to fix easybuild-easyconfigs's setup.py so installation with setuptools >= 61.0 works --- easybuild/easyblocks/e/easybuildmeta.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/e/easybuildmeta.py b/easybuild/easyblocks/e/easybuildmeta.py index 86ceb75d73..abb7b89837 100644 --- a/easybuild/easyblocks/e/easybuildmeta.py +++ b/easybuild/easyblocks/e/easybuildmeta.py @@ -35,7 +35,7 @@ from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pip_version from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import read_file, which +from easybuild.tools.filetools import apply_regex_substitutions, change_dir, read_file, which from easybuild.tools.modules import get_software_root_env_var_name from easybuild.tools.py2vs3 import OrderedDict from easybuild.tools.utilities import flatten @@ -114,6 +114,21 @@ def build_step(self): """No building for EasyBuild packages.""" pass + def fix_easyconfigs_setup_py_setuptools61(self): + """ + Patch setup.py of easybuild-easyconfigs package if needed to make sure that installation works + for recent setuptools versions (>= 61.0). + """ + # cfr. https://github.com/easybuilders/easybuild-easyconfigs/pull/15206 + cwd = os.getcwd() + regex = re.compile(r'packages=\[\]') + setup_py_txt = read_file('setup.py') + if regex.search(setup_py_txt) is None: + self.log.info("setup.py at %s needs to be fixed to install with setuptools >= 61.0", cwd) + apply_regex_substitutions('setup.py', [(r'^setup\(', 'setup(packages=[],')]) + else: + self.log.info("setup.py at %s does not need to be fixed to install with setuptools >= 61.0", cwd) + def install_step(self): """Install EasyBuild packages one by one.""" try: @@ -130,7 +145,11 @@ def install_step(self): else: self.log.info("Installing package %s", pkg) - os.chdir(os.path.join(self.builddir, seldirs[0])) + change_dir(os.path.join(self.builddir, seldirs[0])) + + if pkg == 'easybuild-easyconfigs': + self.fix_easyconfigs_setup_py_setuptools61() + super(EB_EasyBuildMeta, self).install_step() except OSError as err: From 6a866b70bb34608239fa09ab49aabe802443db29 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 18 Oct 2022 11:10:45 +0200 Subject: [PATCH 057/325] create $XDG_CACHE_HOME for PyTorch tests The path must exist or PyTorch will show errors/warnings like: > UserWarning: Specified kernel cache directory could not be created! This disables kernel caching. --- easybuild/easyblocks/p/pytorch.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index ec4ee9ad97..32ef1e3231 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -37,7 +37,7 @@ from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import build_option -from easybuild.tools.filetools import symlink, apply_regex_substitutions +from easybuild.tools.filetools import symlink, apply_regex_substitutions, mkdir from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.systemtools import POWER, get_cpu_architecture @@ -239,10 +239,16 @@ def configure_step(self): self.cfg.update('prebuildopts', ' '.join(unique_options) + ' ') self.cfg.update('preinstallopts', ' '.join(unique_options) + ' ') + def _set_cache_dir(self): + """Set $XDG_CACHE_HOME to avoid PyTorch defaulting to $HOME""" + cache_dir = os.path.join(self.tmpdir, '.cache') + # The path must exist! + mkdir(cache_dir, parents=True) + env.setvar('XDG_CACHE_HOME', cache_dir) + def test_step(self): """Run unit tests""" - # Make PyTorch tests not use the user home - env.setvar('XDG_CACHE_HOME', os.path.join(self.tmpdir, '.cache')) + self._set_cache_dir() # Pretend to be on FB CI which disables some tests, especially those which download stuff env.setvar('SANDCASTLE', '1') # Skip this test(s) which is very flaky @@ -350,8 +356,7 @@ def get_count_for_pattern(regex, text): raise EasyBuildError("Test command had non-zero exit code (%s), but no failed tests found?!", tests_ec) def test_cases_step(self): - # Make PyTorch tests not use the user home - env.setvar('XDG_CACHE_HOME', os.path.join(self.tmpdir, '.cache')) + self._set_cache_dir() super(EB_PyTorch, self).test_cases_step() def sanity_check_step(self, *args, **kwargs): From db889b62385bf991eaab45b8cb88d445c79782a1 Mon Sep 17 00:00:00 2001 From: Alan O'Cais Date: Tue, 18 Oct 2022 15:20:24 +0200 Subject: [PATCH 058/325] Prefer `python -m pip` over `pip` for Python packages --- easybuild/easyblocks/d/dm_reverb.py | 1 + easybuild/easyblocks/generic/pythonpackage.py | 36 ++++++++++--------- easybuild/easyblocks/t/tensorrt.py | 1 + 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/easybuild/easyblocks/d/dm_reverb.py b/easybuild/easyblocks/d/dm_reverb.py index 18012d98bb..60b012f7a2 100644 --- a/easybuild/easyblocks/d/dm_reverb.py +++ b/easybuild/easyblocks/d/dm_reverb.py @@ -121,6 +121,7 @@ def install_step(self, *args, **kwargs): 'installopts': self.cfg['installopts'], 'loc': whl_path, 'prefix': self.installdir, + 'python': self.python_cmd, } return super(EB_dm_minus_reverb, self).install_step(*args, **kwargs) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index 77c493b56e..b95c043393 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -60,7 +60,7 @@ # not 'easy_install' deliberately, to avoid that pkg installations listed in easy-install.pth get preference # '.' is required at the end when using easy_install/pip in unpacked source dir EASY_INSTALL_TARGET = "easy_install" -PIP_INSTALL_CMD = "pip install --prefix=%(prefix)s %(installopts)s %(loc)s" +PIP_INSTALL_CMD = "%(python)s -m pip install --prefix=%(prefix)s %(installopts)s %(loc)s" SETUP_PY_INSTALL_CMD = "%(python)s setup.py %(install_target)s --prefix=%(prefix)s %(installopts)s" UNKNOWN = 'UNKNOWN' @@ -204,14 +204,14 @@ def get_pylibdirs(python_cmd): return all_pylibdirs -def det_pip_version(): - """Determine version of currently active 'pip' command.""" +def det_pip_version(python_cmd='python'): + """Determine version of currently active 'pip' module.""" pip_version = None log = fancylogger.getLogger('det_pip_version', fname=False) log.info("Determining pip version...") - out, _ = run_cmd("pip --version", verbose=False, simple=False, trace=False) + out, _ = run_cmd("%s -m pip --version" % python_cmd, verbose=False, simple=False, trace=False) pip_version_regex = re.compile('^pip ([0-9.]+)') res = pip_version_regex.search(out) @@ -247,8 +247,8 @@ def extra_options(extra_vars=None): "the pip version check. Enabled by default when pip_ignore_installed=True", CUSTOM], 'req_py_majver': [None, "Required major Python version (only relevant when using system Python)", CUSTOM], 'req_py_minver': [None, "Required minor Python version (only relevant when using system Python)", CUSTOM], - 'sanity_pip_check': [False, "Run 'pip check' to ensure all required Python packages are installed " - "and check for any package with an invalid (0.0.0) version.", CUSTOM], + 'sanity_pip_check': [False, "Run 'python -m pip check' to ensure all required Python packages are " + "installed and check for any package with an invalid (0.0.0) version.", CUSTOM], 'runtest': [True, "Run unit tests.", CUSTOM], # overrides default 'unpack_sources': [None, "Unpack sources prior to build/install. Defaults to 'True' except for whl files", CUSTOM], @@ -261,8 +261,8 @@ def extra_options(extra_vars=None): # see https://packaging.python.org/tutorials/installing-packages/#installing-setuptools-extras 'use_pip_extras': [None, "String with comma-separated list of 'extras' to install via pip", CUSTOM], 'use_pip_for_deps': [False, "Install dependencies using '%s'" % PIP_INSTALL_CMD, CUSTOM], - 'use_pip_requirement': [False, "Install using 'pip install --requirement'. The sources is expected " + - "to be the requirements file.", CUSTOM], + 'use_pip_requirement': [False, "Install using 'python -m pip install --requirement'. The sources is " + + "expected to be the requirements file.", CUSTOM], 'zipped_egg': [False, "Install as a zipped eggs", CUSTOM], }) # Use PYPI_SOURCE as the default for source_urls. @@ -468,7 +468,7 @@ def compose_install_command(self, prefix, extrapath=None, installopts=None): using_pip = self.install_cmd.startswith(PIP_INSTALL_CMD) if using_pip: - pip_version = det_pip_version() + pip_version = det_pip_version(python_cmd=self.python_cmd) if pip_version: # pip 8.x or newer required, because of --prefix option being used if LooseVersion(pip_version) >= LooseVersion('8.0'): @@ -834,8 +834,11 @@ def sanity_check_step(self, *args, **kwargs): kwargs.update({'exts_filter': exts_filter}) if self.cfg.get('sanity_pip_check', False): - pip_version = det_pip_version() + pip_version = det_pip_version(python_cmd=python_cmd) + if pip_version: + pip_check_command = "%s -m pip check" % python_cmd + if LooseVersion(pip_version) >= LooseVersion('9.0.0'): if not self.is_extension: @@ -846,11 +849,11 @@ def sanity_check_step(self, *args, **kwargs): pip_check_errors = [] - pip_check_msg, ec = run_cmd("pip check", log_ok=False) + pip_check_msg, ec = run_cmd(pip_check_command, log_ok=False) if ec: - pip_check_errors.append('`pip check` failed:\n%s' % pip_check_msg) + pip_check_errors.append('`%s` failed:\n%s' % (pip_check_command, pip_check_msg)) else: - self.log.info('`pip check` completed successfully') + self.log.info('`%s` completed successfully' % pip_check_command) # Also check for a common issue where the package version shows up as 0.0.0 often caused # by using setup.py as the installation method for a package which is released as a generic wheel @@ -869,8 +872,8 @@ def sanity_check_step(self, *args, **kwargs): version = next(pkg['version'] for pkg in pkgs if pkg['name'] == unversioned_package) except StopIteration: msg = ('Package %s in unversioned_packages was not found in the installed packages. ' - 'Check that the name from `pip list` is used which may be different than the ' - 'module name.' % unversioned_package) + 'Check that the name from `python -m pip list` is used which may be different ' + 'than the module name.' % unversioned_package) else: msg = ('Package %s in unversioned_packages has a version of %s which is valid. ' 'Please remove it from unversioned_packages.' % (unversioned_package, version)) @@ -894,7 +897,8 @@ def sanity_check_step(self, *args, **kwargs): if pip_check_errors: raise EasyBuildError('\n'.join(pip_check_errors)) else: - raise EasyBuildError("pip >= 9.0.0 is required for running 'pip check', found %s", pip_version) + raise EasyBuildError("pip >= 9.0.0 is required for running '%s', found %s", (pip_check_command, + pip_version)) else: raise EasyBuildError("Failed to determine pip version!") diff --git a/easybuild/easyblocks/t/tensorrt.py b/easybuild/easyblocks/t/tensorrt.py index 3d5489b13c..e438658803 100644 --- a/easybuild/easyblocks/t/tensorrt.py +++ b/easybuild/easyblocks/t/tensorrt.py @@ -108,6 +108,7 @@ def extensions_step(self): 'installopts': self.cfg['installopts'], 'loc': whl_paths[0], 'prefix': self.installdir, + 'python': self.python_cmd, } # Use --no-deps to prevent pip from downloading & installing From 9fd3361a10f45d4bbb5fa417d5cb73326e8ebe63 Mon Sep 17 00:00:00 2001 From: casparl Date: Tue, 18 Oct 2022 15:32:41 +0200 Subject: [PATCH 059/325] Add mamba EasyBlock --- easybuild/easyblocks/m/mamba.py | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 easybuild/easyblocks/m/mamba.py diff --git a/easybuild/easyblocks/m/mamba.py b/easybuild/easyblocks/m/mamba.py new file mode 100644 index 0000000000..cf65e3e62a --- /dev/null +++ b/easybuild/easyblocks/m/mamba.py @@ -0,0 +1,52 @@ +## +# Copyright 2009-2022 Ghent University +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for building and installing Mamba, implemented as an easyblock + +@author: Caspar van Leeuwen (SURF) +@author: Kenneth Hoste (HPC-UGent) +""" + +import os +import stat + +from easybuild.easyblocks.a.anaconda import EB_Anaconda +from easybuild.tools.filetools import adjust_permissions, remove_dir +from easybuild.tools.run import run_cmd + + +class EB_Mamba(EB_Anaconda): + """Support for building/installing Mamba.""" + + def sanity_check_step(self): + """ + Custom sanity check for Anaconda and Miniconda + """ + custom_paths = { + 'files': [os.path.join('bin', x) for x in ['2to3', 'conda', 'pydoc', 'python', 'mamba']], + 'dirs': ['bin', 'etc', 'lib', 'pkgs'], + } + # Directly call EB_Anaconda's super, as this sanity_check_step should _overwrite_ Anaconda's (not call it) + super(EB_Anaconda, self).sanity_check_step(custom_paths=custom_paths) From 8617bd33db82f1d32d61e90728835ef45d05ab40 Mon Sep 17 00:00:00 2001 From: casparl Date: Tue, 18 Oct 2022 15:40:00 +0200 Subject: [PATCH 060/325] Removed unneeded imports --- easybuild/easyblocks/m/mamba.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/easybuild/easyblocks/m/mamba.py b/easybuild/easyblocks/m/mamba.py index cf65e3e62a..8c6c5afd3e 100644 --- a/easybuild/easyblocks/m/mamba.py +++ b/easybuild/easyblocks/m/mamba.py @@ -33,8 +33,6 @@ import stat from easybuild.easyblocks.a.anaconda import EB_Anaconda -from easybuild.tools.filetools import adjust_permissions, remove_dir -from easybuild.tools.run import run_cmd class EB_Mamba(EB_Anaconda): From 662667c28ea14e9fe82d3ab14394f531e9168a9b Mon Sep 17 00:00:00 2001 From: casparl Date: Tue, 18 Oct 2022 15:40:32 +0200 Subject: [PATCH 061/325] Removed more unneeded imports --- easybuild/easyblocks/m/mamba.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/m/mamba.py b/easybuild/easyblocks/m/mamba.py index 8c6c5afd3e..beebea0245 100644 --- a/easybuild/easyblocks/m/mamba.py +++ b/easybuild/easyblocks/m/mamba.py @@ -30,7 +30,6 @@ """ import os -import stat from easybuild.easyblocks.a.anaconda import EB_Anaconda From 595b3be62c710e14f8453b91c42037568f647f2f Mon Sep 17 00:00:00 2001 From: Alan O'Cais Date: Tue, 18 Oct 2022 16:30:58 +0200 Subject: [PATCH 062/325] Make dm_reverb aware of prebuildopts --- easybuild/easyblocks/d/dm_reverb.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/d/dm_reverb.py b/easybuild/easyblocks/d/dm_reverb.py index 60b012f7a2..c847aea331 100644 --- a/easybuild/easyblocks/d/dm_reverb.py +++ b/easybuild/easyblocks/d/dm_reverb.py @@ -94,7 +94,8 @@ def build_step(self, *args, **kwargs): # print full compilation commands bazel_build_opts += " --subcommands" - bazel_cmd = "bazel %s build %s %s" % (bazel_opts, bazel_build_opts, bazel_build_pkg) + bazel_cmd = "%s bazel %s build %s %s" % (self.cfg['prebuildopts'], bazel_opts, bazel_build_opts, + bazel_build_pkg) return run_cmd(bazel_cmd, log_all=True, simple=True, log_output=True) From 7923a47b9015f6f98d29a89aa9aa124c475e032a Mon Sep 17 00:00:00 2001 From: casparl Date: Tue, 18 Oct 2022 17:17:05 +0200 Subject: [PATCH 063/325] Changed function description for sanity check. Removed 'bin', since its presence is already indirectly checked through the files in the sanity_check --- easybuild/easyblocks/m/mamba.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/m/mamba.py b/easybuild/easyblocks/m/mamba.py index beebea0245..bba972ae1a 100644 --- a/easybuild/easyblocks/m/mamba.py +++ b/easybuild/easyblocks/m/mamba.py @@ -39,11 +39,11 @@ class EB_Mamba(EB_Anaconda): def sanity_check_step(self): """ - Custom sanity check for Anaconda and Miniconda + Custom sanity check for Mamba """ custom_paths = { 'files': [os.path.join('bin', x) for x in ['2to3', 'conda', 'pydoc', 'python', 'mamba']], - 'dirs': ['bin', 'etc', 'lib', 'pkgs'], + 'dirs': ['etc', 'lib', 'pkgs'], } # Directly call EB_Anaconda's super, as this sanity_check_step should _overwrite_ Anaconda's (not call it) super(EB_Anaconda, self).sanity_check_step(custom_paths=custom_paths) From 58a7a05622e219e69ed33794f5836cc660c12774 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 18 Oct 2022 20:07:19 +0200 Subject: [PATCH 064/325] fix alphabetical order for filetools imports in PyTorch easyblock --- easybuild/easyblocks/p/pytorch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 32ef1e3231..31c70c9a4d 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -37,7 +37,7 @@ from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import build_option -from easybuild.tools.filetools import symlink, apply_regex_substitutions, mkdir +from easybuild.tools.filetools import apply_regex_substitutions, mkdir, symlink from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.systemtools import POWER, get_cpu_architecture From 71e057678832dc91c76d4cd59d41f30a9c0f9f9d Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 19 Oct 2022 12:48:59 +0200 Subject: [PATCH 065/325] don't check for pip command in EasyBuildMeta easyblcok + pass path to python command to use to determine pip version --- easybuild/easyblocks/e/easybuildmeta.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/e/easybuildmeta.py b/easybuild/easyblocks/e/easybuildmeta.py index abb7b89837..b1e9970d00 100644 --- a/easybuild/easyblocks/e/easybuildmeta.py +++ b/easybuild/easyblocks/e/easybuildmeta.py @@ -35,7 +35,7 @@ from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pip_version from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import apply_regex_substitutions, change_dir, read_file, which +from easybuild.tools.filetools import apply_regex_substitutions, change_dir, read_file from easybuild.tools.modules import get_software_root_env_var_name from easybuild.tools.py2vs3 import OrderedDict from easybuild.tools.utilities import flatten @@ -71,14 +71,13 @@ def __init__(self, *args, **kwargs): # - pip is available, and recent enough (>= 21.0); # - use_pip is not specified; pyver = sys.version.split(' ')[0] - pip = which('pip') - self.log.info("Python version: %s - pip: %s", pyver, pip) - if sys.version_info >= (3, 6) and pip and self.cfg['use_pip'] is None: + self.log.info("Python version: %s", pyver) + if sys.version_info >= (3, 6) and self.cfg['use_pip'] is None: # try to determine pip version, ignore any failures that occur while doing so; # problems may occur due changes in environment ($PYTHONPATH, etc.) pip_version = None try: - pip_version = det_pip_version() + pip_version = det_pip_version(python_cmd=sys.executable) self.log.info("Found Python v%s + pip: %s", pyver, pip_version) except Exception as err: self.log.warning("Failed to determine pip version: %s", err) From 1f903f37990166c4e1c2814e5bfd7f76162e980a Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 20 Oct 2022 07:47:41 +0200 Subject: [PATCH 066/325] For version >= 3.20.07 use "noAsk" option to config. --- easybuild/easyblocks/x/xmipp.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/easybuild/easyblocks/x/xmipp.py b/easybuild/easyblocks/x/xmipp.py index c84a43a50f..20343ee1ce 100644 --- a/easybuild/easyblocks/x/xmipp.py +++ b/easybuild/easyblocks/x/xmipp.py @@ -101,10 +101,15 @@ def configure_step(self): # Tell xmipp config that there is no Scipion. env.setvar('XMIPP_NOSCIPION', 'True') # Initialize the config file and then patch it with the correct values + if LooserVersion(self.version) >= LooserVersion('3.20.07'): + noask = 'noAsk' + else: + noask = '' cmd = ' '.join([ self.cfg['preconfigopts'], self.xmipp_exe, 'config', + noask, self.cfg['configopts'], ]) run_cmd(cmd, log_all=True, simple=True) From 37deb6b0f150dfdd2f43a9415caa313665171bbe Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 20 Oct 2022 07:49:13 +0200 Subject: [PATCH 067/325] Fix typo --- easybuild/easyblocks/x/xmipp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/x/xmipp.py b/easybuild/easyblocks/x/xmipp.py index 20343ee1ce..122c49543b 100644 --- a/easybuild/easyblocks/x/xmipp.py +++ b/easybuild/easyblocks/x/xmipp.py @@ -101,7 +101,7 @@ def configure_step(self): # Tell xmipp config that there is no Scipion. env.setvar('XMIPP_NOSCIPION', 'True') # Initialize the config file and then patch it with the correct values - if LooserVersion(self.version) >= LooserVersion('3.20.07'): + if LooseVersion(self.version) >= LooseVersion('3.20.07'): noask = 'noAsk' else: noask = '' From 9f248200824c4750416156b4d2152d3e3790b7be Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 20 Oct 2022 10:35:17 +0200 Subject: [PATCH 068/325] make numexpr easyblock aware of toolchain with GCC + imkl --- easybuild/easyblocks/n/numexpr.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/n/numexpr.py b/easybuild/easyblocks/n/numexpr.py index 00fe5c89a7..cce57b69ea 100644 --- a/easybuild/easyblocks/n/numexpr.py +++ b/easybuild/easyblocks/n/numexpr.py @@ -28,7 +28,9 @@ import os from distutils.version import LooseVersion +import easybuild.tools.toolchain as toolchain from easybuild.easyblocks.generic.pythonpackage import PythonPackage +from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import write_file from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.systemtools import get_cpu_features @@ -78,12 +80,20 @@ def configure_step(self): mkl_ver = get_software_version('imkl') + comp_fam = self.toolchain.comp_family() + self.log.info("Using toolchain with compiler family %s", comp_fam) + if LooseVersion(mkl_ver) >= LooseVersion('2021'): mkl_lib_dirs = [ os.path.join(self.imkl_root, 'mkl', 'latest', 'lib', 'intel64'), ] mkl_include_dirs = os.path.join(self.imkl_root, 'mkl', 'latest', 'include') - mkl_libs = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5'] + if comp_fam == toolchain.INTELCOMP: + mkl_libs = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5'] + elif comp_fam == toolchain.GCC: + mkl_libs = ['mkl_intel_lp64', 'mkl_gnu_thread', 'mkl_core', 'gomp'] + else: + raise EasyBuildError("Unknown compiler family, don't know how to link MKL libraries: %s", comp_fam) else: mkl_lib_dirs = [ os.path.join(self.imkl_root, 'mkl', 'lib', 'intel64'), @@ -103,7 +113,9 @@ def configure_step(self): else: site_cfg_lines.append("mkl_libs = %s" % ', '.join(mkl_libs)) - write_file('site.cfg', '\n'.join(site_cfg_lines)) + site_cfg_txt = '\n'.join(site_cfg_lines) + write_file('site.cfg', site_cfg_txt) + self.log.info("site.cfg used for numexpr:\n" + site_cfg_txt) def sanity_check_step(self): """Custom sanity check for numexpr.""" From d8aa9420be572ab4df2c5993c5a3cdf370623404 Mon Sep 17 00:00:00 2001 From: Simon Branford Date: Thu, 20 Oct 2022 10:37:49 +0100 Subject: [PATCH 069/325] Add sanity check commands to netCDF --- easybuild/easyblocks/n/netcdf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/n/netcdf.py b/easybuild/easyblocks/n/netcdf.py index 879136495b..47f5645ea4 100644 --- a/easybuild/easyblocks/n/netcdf.py +++ b/easybuild/easyblocks/n/netcdf.py @@ -141,7 +141,9 @@ def sanity_check_step(self): 'dirs': [] } - super(EB_netCDF, self).sanity_check_step(custom_paths=custom_paths) + custom_commands = ["nc-config --help", "ncgen -h"] + + super(EB_netCDF, self).sanity_check_step(custom_commands=custom_commands, custom_paths=custom_paths) def set_netcdf_env_vars(log): From 2aecf21ebbf5737c72a2b02ae58db5cf78724d23 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 20 Oct 2022 11:40:39 +0200 Subject: [PATCH 070/325] trivial code refactoring in sanity_check_step of netCDF eaysblock --- easybuild/easyblocks/n/netcdf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/n/netcdf.py b/easybuild/easyblocks/n/netcdf.py index 47f5645ea4..83289a936e 100644 --- a/easybuild/easyblocks/n/netcdf.py +++ b/easybuild/easyblocks/n/netcdf.py @@ -141,7 +141,10 @@ def sanity_check_step(self): 'dirs': [] } - custom_commands = ["nc-config --help", "ncgen -h"] + custom_commands = [ + "nc-config --help", + "ncgen -h", + ] super(EB_netCDF, self).sanity_check_step(custom_commands=custom_commands, custom_paths=custom_paths) From 53f742829eaa56cfe1496850a3b3f66de45c2c12 Mon Sep 17 00:00:00 2001 From: Miguel Dias Costa Date: Fri, 21 Oct 2022 12:15:18 +0800 Subject: [PATCH 071/325] prepare release notes for EasyBuild v4.6.2 + bump version to 4.6.2 --- RELEASE_NOTES | 29 ++++++++++++++++++++++++++++- easybuild/easyblocks/__init__.py | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 7e9f4fd022..1941781e8d 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,7 +3,34 @@ For more detailed information, please see the git log. These release notes can also be consulted at http://easybuild.readthedocs.org/en/latest/Release_notes.html. -The latest version of easybuild-easyblocks provides 246 software-specific easyblocks and 37 generic easyblocks. +The latest version of easybuild-easyblocks provides 248 software-specific easyblocks and 37 generic easyblocks. + + +v4.6.2 (October 21st 2022) +-------------------------- + +update/bugfix release + +- 2 new software-specific easyblock: + - CUDA compatibility libraries (#2764) and mamba (#2808) +- minor enhancements and updates, including: + - update OpenFOAM easyblock to support OpenFOAM 10 + clean up variant/version checks (#2766) + - added support for ESMPy in ESMF (#2789) + - enhance OpenBLAS easyblock to support running LAPACK test suite + checking how many tests fail (#2801) + - make numexpr easyblock aware of toolchain with GCC + imkl (#2810) + - add sanity check commands for netCDF (#2811) +- various bug fixes, including: + - handle problems copying symlink that points to CUDA folder that is not created for non CUDA builds of SuiteSparse (#2790) + - don't install docs (to avoid trouble with Java) + add Rocky support for ABAQUS (#2792) + - Correctly count the number of failing tests (not failing test suites) in PyTorch builds (#2794) + - fix docstring for PyTorch easyblock (#2795) + - handle iterative builds with MakeCP EasyBlock (#2798) + - correctly count errors/failures in PyTorch test summary (#2803) + - accept both None and empty value for optarch to let OpenCV detect host CPU (#2804) + - enhance EasyBuildMeta easyblock: auto-enable installing with pip + fix setup.py of easyconfigs package so installation with setuptools >= 61.0 works (#2805) + - use `python -m pip` instead of `pip` in PythonPackage easyblock (#2807) +- other changes: + - make the test output from PythonPackage less verbose by disabling default search for error patterns done by run_cmd (2797) v4.6.1 (September 12th 2022) diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index c546b0843b..a1ef9ee8ef 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.6.2.dev0') +VERSION = LooseVersion('4.6.2') UNKNOWN = 'UNKNOWN' From ea557bd10227520885dcdd237ab3d11347637a36 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Fri, 21 Oct 2022 06:33:02 +0200 Subject: [PATCH 072/325] minor tweak release notes for EasyBuild v4.6.2 --- RELEASE_NOTES | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 1941781e8d..77347cb907 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -22,10 +22,9 @@ update/bugfix release - various bug fixes, including: - handle problems copying symlink that points to CUDA folder that is not created for non CUDA builds of SuiteSparse (#2790) - don't install docs (to avoid trouble with Java) + add Rocky support for ABAQUS (#2792) - - Correctly count the number of failing tests (not failing test suites) in PyTorch builds (#2794) + - correctly count the number of failing tests (not failing test suites) in PyTorch builds (#2794, #2803) - fix docstring for PyTorch easyblock (#2795) - - handle iterative builds with MakeCP EasyBlock (#2798) - - correctly count errors/failures in PyTorch test summary (#2803) + - handle iterative builds with MakeCp easyblock (#2798) - accept both None and empty value for optarch to let OpenCV detect host CPU (#2804) - enhance EasyBuildMeta easyblock: auto-enable installing with pip + fix setup.py of easyconfigs package so installation with setuptools >= 61.0 works (#2805) - use `python -m pip` instead of `pip` in PythonPackage easyblock (#2807) From 3cf3eb5d55cb0602dd1b72b3a861d878f7ab6835 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Fri, 21 Oct 2022 10:58:35 +0200 Subject: [PATCH 073/325] bump version to 4.6.3dev Co-authored-by: Miguel Dias Costa --- easybuild/easyblocks/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index a1ef9ee8ef..29b70f4815 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.6.2') +VERSION = LooseVersion('4.6.3.dev0') UNKNOWN = 'UNKNOWN' From 21442f8e8dcac3425bb0af18d623a49b5163df18 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 26 Oct 2022 08:41:23 +0200 Subject: [PATCH 074/325] always use full path to clang/clang++ in staged build, only restore $PATH, import Clang on top --- easybuild/easyblocks/c/clang.py | 36 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 66409dce8e..c77aa92f53 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -37,11 +37,11 @@ import glob import os import shutil -import copy from distutils.version import LooseVersion from easybuild.easyblocks.generic.cmakemake import CMakeMake from easybuild.framework.easyconfig import CUSTOM +from easybuild.toolchains.compiler.clang import Clang from easybuild.tools import run from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import build_option @@ -50,7 +50,7 @@ from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import AARCH32, AARCH64, POWER, X86_64 from easybuild.tools.systemtools import get_cpu_architecture, get_os_name, get_os_version, get_shared_lib_ext -from easybuild.tools.environment import setvar, restore_env, read_environment +from easybuild.tools.environment import setvar # List of all possible build targets for Clang CLANG_TARGETS = ["all", "AArch64", "AMDGPU", "ARM", "CppBackend", "Hexagon", "Mips", @@ -408,15 +408,11 @@ def build_with_prev_stage(self, prev_obj, next_obj): mkdir(next_obj) change_dir(next_obj) - # Make sure the clang and clang++ compilers from previous stages are (temporarily) in PATH - orig_env = copy.deepcopy(os.environ) - prev_obj_path = os.path.join(prev_obj, 'bin') - current_path = read_environment({'path': 'PATH'}) - setvar('PATH', current_path['path'] + ":" + prev_obj_path) + # keep track of original $PATH value, we need to restore it in case RPATH wrappers were put in place + orig_path = os.getenv('PATH') # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): - from easybuild.toolchains.compiler.clang import Clang my_clang_toolchain = Clang(name='Clang', version='1') my_clang_toolchain.prepare_rpath_wrappers() self.log.info("Prepared clang rpath wrappers") @@ -433,12 +429,18 @@ def build_with_prev_stage(self, prev_obj, next_obj): setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) + # determine full path to clang/clang++ (which may be wrapper scripts in case of RPATH linking) + clang = which('clang') or os.path.join(prev_obj, 'bin', 'clang') + clangxx = which('clang++') or os.path.join(prev_obj, 'bin', 'clang++') + # Configure. - options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir - options += "-DCMAKE_C_COMPILER='clang' " - options += "-DCMAKE_CXX_COMPILER='clang++' " - options += self.cfg['configopts'] - options += "-DCMAKE_BUILD_TYPE=%s " % self.build_type + options = [ + "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir, + "-DCMAKE_C_COMPILER='%s' " % clang, + "-DCMAKE_CXX_COMPILER='%s' " % clangxx, + self.cfg['configopts'], + "-DCMAKE_BUILD_TYPE=%s " % self.build_type, + ] # Cmake looks for llvm-link by default in the same directory as the compiler # However, when compiling with rpath, the clang 'compiler' is not actually the compiler, but the wrapper @@ -446,16 +448,16 @@ def build_with_prev_stage(self, prev_obj, next_obj): # See https://github.com/easybuilders/easybuild-easyblocks/pull/2799#issuecomment-1275916186 if build_option('rpath'): llvm_link = which('llvm-link') - options += "-DLIBOMPTARGET_NVPTX_BC_LINKER=%s" % llvm_link + options.append("-DLIBOMPTARGET_NVPTX_BC_LINKER=%s" % llvm_link) self.log.info("Configuring") - run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) + run_cmd("cmake %s %s" % (' '.join(options), self.llvm_src_dir), log_all=True) self.log.info("Building") run_cmd("make %s VERBOSE=1" % self.make_parallel_opts, log_all=True) - # Restore environment (specifically: PATH) - restore_env(orig_env) + # restore $PATH + setvar('PATH', orig_path) def run_clang_tests(self, obj_dir): """Run Clang tests in specified directory (unless disabled).""" From 30be41574d70f1e9201a4931d75e26043bbb2b6c Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Wed, 19 Oct 2022 02:29:25 +0200 Subject: [PATCH 075/325] add easyblock for JuliaPackage --- easybuild/easyblocks/generic/juliapackage.py | 170 +++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 easybuild/easyblocks/generic/juliapackage.py diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py new file mode 100644 index 0000000000..2ac3fb5c38 --- /dev/null +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -0,0 +1,170 @@ +## +# Copyright 2022-2022 Vrije Universiteit Brussel +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for Julia Packages, implemented as an easyblock + +@author: Alex Domingo (Vrije Universiteit Brussel) +""" +import os + +from distutils.version import LooseVersion + +import easybuild.tools.environment as env +from easybuild.framework.easyconfig import CUSTOM +from easybuild.framework.extensioneasyblock import ExtensionEasyBlock +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.modules import get_software_root, get_software_version +from easybuild.tools.filetools import copy_dir +from easybuild.tools.run import run_cmd + +EXTS_FILTER_JULIA_PACKAGES = ("julia -e 'using %(ext_name)s'", "") + + +class JuliaPackage(ExtensionEasyBlock): + """Builds and installs Julia Packages.""" + + @staticmethod + def extra_options(extra_vars=None): + """Extra easyconfig parameters specific to JuliaPackage.""" + extra_vars = ExtensionEasyBlock.extra_options(extra_vars=extra_vars) + extra_vars.update({ + 'bundle_deps': [ + False, "Let Julia download and bundle all needed dependencies for this installation", CUSTOM + ], + }) + return extra_vars + + def __init__(self, *args, **kwargs): + """JuliaPackage easyblock constructor.""" + super(JuliaPackage, self).__init__(*args, **kwargs) + + def set_pkg_offline(self): + """Enable offline mode of Julia Pkg""" + if get_software_root('Julia') is None: + raise EasyBuildError("Julia not included as dependency!") + + if not self.cfg['bundle_deps']: + julia_version = get_software_version('Julia') + if LooseVersion(julia_version) >= LooseVersion('1.5'): + # Enable offline mode of Julia Pkg + # https://pkgdocs.julialang.org/v1/api/#Pkg.offline + env.setvar('JULIA_PKG_OFFLINE', 'true') + else: + errmsg = ( + "Cannot set offline mode in Julia v%s (needs Julia >= 1.5). " + "Enable easyconfig option 'bundle_deps' to allow installation " + "with any extra downloaded dependencies." + ) + raise EasyBuildError(errmsg, julia_version) + + def prepare_step(self, *args, **kwargs): + """Prepare for installing Julia package.""" + super(JuliaPackage, self).prepare_step(*args, **kwargs) + self.set_pkg_offline() + + def configure_step(self): + """No separate configuration for JuliaPackage.""" + pass + + def build_step(self): + """No separate build procedure for JuliaPackage.""" + pass + + def test_step(self): + """No separate (standard) test procedure for JuliaPackage.""" + pass + + def install_julia_pkg(self): + """Install procedure for Julia packages with Pkg""" + + # prepend installation directory to Julia DEPOT_PATH + # see https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_DEPOT_PATH + env.setvar('JULIA_DEPOT_PATH', ':'.join([self.installdir, os.getenv('JULIA_DEPOT_PATH', '')])) + + # command sequence for Julia.Pkg + julia_pkg_cmd = ['using Pkg'] + if os.path.isdir(os.path.join(self.start_dir, '.git')): + # sources from git repos can be installed as any remote package + self.log.debug('Installing Julia package in normal mode (Pkg.add)') + + julia_pkg_cmd.extend([ + # install package from local path preserving existing dependencies + 'Pkg.add(url="%s"; preserve=Pkg.PRESERVE_ALL)' % self.start_dir, + ]) + else: + # plain sources have to be installed in develop mode + # copy sources to install directory and install + self.log.debug('Installing Julia package in develop mode (Pkg.develop)') + + install_pkg_path = os.path.join(self.installdir, 'packages', self.name) + copy_dir(self.start_dir, install_pkg_path) + + julia_pkg_cmd.extend([ + 'Pkg.develop(PackageSpec(path="%s"))' % install_pkg_path, + 'Pkg.build("%s")' % self.name, + ]) + julia_pkg_cmd = ';'.join(julia_pkg_cmd) + + install_cmd = "julia -e '%s'" % julia_pkg_cmd + + cmd = ' '.join([self.cfg['preinstallopts'], install_cmd, self.cfg['installopts']]) + + (out, _) = run_cmd(cmd, log_all=True, simple=False) + + return out + + def install_step(self): + """Install Julia package""" + self.install_julia_pkg() + + def run(self): + """Install Julia package as an extension.""" + + if not self.src: + errmsg = "No source found for Julia package %s, require d for installation. (src: %s)" + raise EasyBuildError(errmsg, self.name, self.src) + ExtensionEasyBlock.run(self, unpack_src=True) + + self.set_pkg_offline() + self.install_julia_pkg() + + def sanity_check_step(self, *args, **kwargs): + """Custom sanity check for JuliaPackage""" + + pkg_dir = os.path.join('packages', self.name) + + custom_paths = { + 'files': [], + 'dirs': [pkg_dir], + } + kwargs.update({'custom_paths': custom_paths}) + + return ExtensionEasyBlock.sanity_check_step(self, EXTS_FILTER_JULIA_PACKAGES, *args, **kwargs) + + def make_module_extra(self): + """Prepend installation directory to JULIA_DEPOT_PATH in module file.""" + txt = super(JuliaPackage, self).make_module_extra() + txt += self.module_generator.prepend_paths('JULIA_DEPOT_PATH', ['']) + return txt From be4d155b4bcfa9c89e48a31db23ccaa567305cbf Mon Sep 17 00:00:00 2001 From: satishk Date: Wed, 26 Oct 2022 15:49:20 +0200 Subject: [PATCH 076/325] Incorporating improvements suggested by @boegel --- easybuild/easyblocks/p/petsc.py | 35 +++++++++++++++++---------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py index dfb97b1cf2..5a2d97d0b1 100644 --- a/easybuild/easyblocks/p/petsc.py +++ b/easybuild/easyblocks/p/petsc.py @@ -37,7 +37,7 @@ from easybuild.framework.easyconfig import BUILD, CUSTOM from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import symlink, apply_regex_substitutions -from easybuild.tools.modules import get_software_root +from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import get_shared_lib_ext from easybuild.tools.py2vs3 import string_type @@ -213,7 +213,7 @@ def configure_step(self): # SCOTCH has to be treated separately since they add weird postfixes # to library names from SCOTCH 7.0.1 or PETSc version 3.17. if (LooseVersion(self.version) >= LooseVersion("3.17")): - sep_deps += ['SCOTCH'] + sep_deps.append('SCOTCH') depfilter = [d['name'] for d in self.cfg.builddependencies()] + sep_deps deps = [dep['name'] for dep in self.cfg.dependencies() if not dep['name'] in depfilter] @@ -230,21 +230,22 @@ def configure_step(self): # SCOTCH has to be treated separately since they add weird postfixes # to library names from SCOTCH 7.0.1 or PETSc version 3.17. - if (LooseVersion(self.version) >= LooseVersion("3.17")): - scotch = get_software_root('SCOTCH') - if scotch: - withdep = "--with-ptscotch" - scotch_inc = [os.path.join(scotch, "include")] - inc_spec = "-include=[%s]" % ','.join(scotch_inc) - - # For some reason there is a v3 suffix added to libptscotchparmetis - # which is the reason for this new code. - req_scotch_libs = ['libptesmumps.a', 'libptscotchparmetisv3.a', - 'libptscotch.a', 'libptscotcherr.a', 'libesmumps.a', - 'libscotch.a', 'libscotcherr.a'] - scotch_libs = [os.path.join(scotch, "lib", x) for x in req_scotch_libs] - lib_spec = "-lib=[%s]" % ','.join(scotch_libs) - self.cfg.update('configopts', ' '.join([withdep + spec for spec in ['=1', inc_spec, lib_spec]])) + scotch = get_software_root('SCOTCH') + scotch_ver = get_software_version('SCOTCH') + if (scotch and LooseVersion(scotch_ver) >= LooseVersion("7.0.1")): + withdep = "--with-ptscotch" + scotch_inc = [os.path.join(scotch, "include")] + inc_spec = "-include=[%s]" % ','.join(scotch_inc) + + # For some reason there is a v3 suffix added to libptscotchparmetis + # which is the reason for this new code. + req_scotch_libs = ['libesmumps.a', 'libptesmumps.a', 'libptscotch.a', + 'libptscotcherr.a', 'libptscotchparmetisv3.a', 'libscotch.a', + 'libscotcherr.a'] + scotch_libs = [os.path.join(scotch, "lib", x) for x in req_scotch_libs] + lib_spec = "-lib=[%s]" % ','.join(scotch_libs) + self.cfg.update('configopts', ' '.join([withdep + spec for spec in ['=1', inc_spec, lib_spec]])) + # SuiteSparse options changed in PETSc 3.5, suitesparse = get_software_root('SuiteSparse') if suitesparse: From 213a8bb99f84ad3c5f843a3c0e7d38c518e312f7 Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 27 Oct 2022 16:16:12 +0200 Subject: [PATCH 077/325] opencv: in v4 the opencv2 include dir is in include/opencv4, so include/opencv4 must be in CPATH --- easybuild/easyblocks/o/opencv.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easybuild/easyblocks/o/opencv.py b/easybuild/easyblocks/o/opencv.py index 035fd751a3..564b41bc35 100644 --- a/easybuild/easyblocks/o/opencv.py +++ b/easybuild/easyblocks/o/opencv.py @@ -228,6 +228,9 @@ def make_module_extra(self): """Custom extra module file entries for OpenCV.""" txt = super(EB_OpenCV, self).make_module_extra() + if LooseVersion(self.version) >= LooseVersion('4.0'): + txt += self.module_generator.prepend_paths('CPATH', os.path.join('include', 'opencv4')) + txt += self.module_generator.prepend_paths('CLASSPATH', os.path.join('share', 'OpenCV', 'java')) if os.path.exists(os.path.join(self.installdir, self.pylibdir)): From 2077aa809a815783d77afd3c2b773ff6ffe6544a Mon Sep 17 00:00:00 2001 From: Sebastian Achilles Date: Thu, 27 Oct 2022 16:26:25 +0200 Subject: [PATCH 078/325] use gfortran for -g77 in NVHPC --- easybuild/easyblocks/n/nvhpc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/n/nvhpc.py b/easybuild/easyblocks/n/nvhpc.py index eabb8f0600..b0216c5700 100644 --- a/easybuild/easyblocks/n/nvhpc.py +++ b/easybuild/easyblocks/n/nvhpc.py @@ -164,7 +164,7 @@ def install_step(self): line = re.sub(r"^PATH=/", r"#PATH=/", line) sys.stdout.write(line) - cmd = "%s -x %s -g77 /" % (makelocalrc_filename, compilers_subdir) + cmd = "%s -x %s -g77 gfortran" % (makelocalrc_filename, compilers_subdir) run_cmd(cmd, log_all=True, simple=True) # If an OS libnuma is NOT found, makelocalrc creates symbolic links to libpgnuma.so From 8209d48bb1aabf57989efba7bcdfc9d0ed6587ad Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 27 Oct 2022 16:03:14 +0200 Subject: [PATCH 079/325] load fake Julia in ModuleOnlyTest of JuliaPackage --- test/easyblocks/module.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index 034dc65961..6d8bc1c729 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -42,6 +42,7 @@ from easybuild.base import fancylogger from easybuild.base.testing import TestCase from easybuild.easyblocks.generic.gopackage import GoPackage +from easybuild.easyblocks.generic.juliapackage import JuliaPackage from easybuild.easyblocks.generic.intelbase import IntelBase from easybuild.easyblocks.generic.pythonbundle import PythonBundle from easybuild.easyblocks.gcc import EB_GCC @@ -286,6 +287,11 @@ def template_module_only_test(self, easyblock, name, version='1.3.2', extra_txt= os.environ['EBROOTGO'] = '/fake/install/prefix/Go/1.14' os.environ['EBVERSIONGO'] = '1.14' + elif app_class == JuliaPackage: + # $EBROOTJULIA must be set for JuliaPackage easyblock + os.environ['EBROOTJULIA'] = '/fake/install/prefix/Julia/1.6.7' + os.environ['EBVERSIONJULIA'] = '1.6.7' + elif app_class == EB_OpenFOAM: # proper toolchain must be used for OpenFOAM(-Extend), to determine value to set for $WM_COMPILER write_file(os.path.join(tmpdir, 'GCC', '4.9.3-2.25'), '\n'.join([ From 91246e1838d8f0f77029e8051aa4421e7a2743be Mon Sep 17 00:00:00 2001 From: Killian Murphy Date: Fri, 28 Oct 2022 11:03:52 +0100 Subject: [PATCH 080/325] Add extra option for disabling LAPACK in ESMF Add an extra option (disable_lapack) for disabling LAPACK in ESMF builds. When LAPACK is disabled, MOAB is also disabled, as it is not possible to build MOAB without LAPACK. --- easybuild/easyblocks/e/esmf.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/e/esmf.py b/easybuild/easyblocks/e/esmf.py index cc3986ca45..2656a78dce 100644 --- a/easybuild/easyblocks/e/esmf.py +++ b/easybuild/easyblocks/e/esmf.py @@ -39,11 +39,20 @@ from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import get_shared_lib_ext +from easybuild.framework.easyconfig import CUSTOM, MANDATORY class EB_ESMF(ConfigureMake): """Support for building/installing ESMF.""" + @staticmethod + def extra_options(): + """Custom easyconfig parameters for ESMF""" + extra_vars = { + 'disable_lapack': [False, 'Disable external LAPACK - True or False', MANDATORY] + } + return ConfigureMake.extra_options(extra_vars) + def configure_step(self): """Custom configuration procedure for ESMF through environment variables.""" @@ -75,13 +84,18 @@ def configure_step(self): env.setvar('ESMF_COMM', comm) # specify decent LAPACK lib - env.setvar('ESMF_LAPACK', 'user') - ldflags = os.getenv('LDFLAGS') - liblapack = os.getenv('LIBLAPACK_MT') or os.getenv('LIBLAPACK') - if liblapack is None: - raise EasyBuildError("$LIBLAPACK(_MT) not defined, no BLAS/LAPACK in %s toolchain?", self.toolchain.name) + if self.cfg['disable_lapack']: + env.setvar('ESMF_LAPACK', 'OFF') + # MOAB can't be built without LAPACK + env.setvar('ESMF_MOAB', 'OFF') else: - env.setvar('ESMF_LAPACK_LIBS', ldflags + ' ' + liblapack) + env.setvar('ESMF_LAPACK', 'user') + ldflags = os.getenv('LDFLAGS') + liblapack = os.getenv('LIBLAPACK_MT') or os.getenv('LIBLAPACK') + if liblapack is None: + raise EasyBuildError("$LIBLAPACK(_MT) not defined, no BLAS/LAPACK in %s toolchain?", self.toolchain.name) + else: + env.setvar('ESMF_LAPACK_LIBS', ldflags + ' ' + liblapack) # specify netCDF netcdf = get_software_root('netCDF') From 16e124d0ebbcb8ad54617315217fc6e1d5c4fbd2 Mon Sep 17 00:00:00 2001 From: Killian Murphy Date: Fri, 28 Oct 2022 11:13:20 +0100 Subject: [PATCH 081/325] Fix issues identified by hound --- easybuild/easyblocks/e/esmf.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/easybuild/easyblocks/e/esmf.py b/easybuild/easyblocks/e/esmf.py index 2656a78dce..1cd1f65971 100644 --- a/easybuild/easyblocks/e/esmf.py +++ b/easybuild/easyblocks/e/esmf.py @@ -39,7 +39,7 @@ from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import get_shared_lib_ext -from easybuild.framework.easyconfig import CUSTOM, MANDATORY +from easybuild.framework.easyconfig import MANDATORY class EB_ESMF(ConfigureMake): @@ -47,11 +47,11 @@ class EB_ESMF(ConfigureMake): @staticmethod def extra_options(): - """Custom easyconfig parameters for ESMF""" - extra_vars = { - 'disable_lapack': [False, 'Disable external LAPACK - True or False', MANDATORY] - } - return ConfigureMake.extra_options(extra_vars) + """Custom easyconfig parameters for ESMF""" + extra_vars = { + 'disable_lapack': [False, 'Disable external LAPACK - True or False', MANDATORY] + } + return ConfigureMake.extra_options(extra_vars) def configure_step(self): """Custom configuration procedure for ESMF through environment variables.""" @@ -89,13 +89,13 @@ def configure_step(self): # MOAB can't be built without LAPACK env.setvar('ESMF_MOAB', 'OFF') else: - env.setvar('ESMF_LAPACK', 'user') - ldflags = os.getenv('LDFLAGS') - liblapack = os.getenv('LIBLAPACK_MT') or os.getenv('LIBLAPACK') - if liblapack is None: - raise EasyBuildError("$LIBLAPACK(_MT) not defined, no BLAS/LAPACK in %s toolchain?", self.toolchain.name) - else: - env.setvar('ESMF_LAPACK_LIBS', ldflags + ' ' + liblapack) + env.setvar('ESMF_LAPACK', 'user') + ldflags = os.getenv('LDFLAGS') + liblapack = os.getenv('LIBLAPACK_MT') or os.getenv('LIBLAPACK') + if liblapack is None: + raise EasyBuildError("$LIBLAPACK(_MT) not defined, no BLAS/LAPACK in %s toolchain?", self.toolchain.name) + else: + env.setvar('ESMF_LAPACK_LIBS', ldflags + ' ' + liblapack) # specify netCDF netcdf = get_software_root('netCDF') From d5d70768ee4dc4aca85dff044ab8b24f2b696ce4 Mon Sep 17 00:00:00 2001 From: Killian Murphy Date: Fri, 28 Oct 2022 11:16:19 +0100 Subject: [PATCH 082/325] Fix line length issue identified by hound --- easybuild/easyblocks/e/esmf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/e/esmf.py b/easybuild/easyblocks/e/esmf.py index 1cd1f65971..45cd2d1b01 100644 --- a/easybuild/easyblocks/e/esmf.py +++ b/easybuild/easyblocks/e/esmf.py @@ -93,7 +93,8 @@ def configure_step(self): ldflags = os.getenv('LDFLAGS') liblapack = os.getenv('LIBLAPACK_MT') or os.getenv('LIBLAPACK') if liblapack is None: - raise EasyBuildError("$LIBLAPACK(_MT) not defined, no BLAS/LAPACK in %s toolchain?", self.toolchain.name) + msg = "$LIBLAPACK(_MT) not defined, no BLAS/LAPACK in %s toolchain?" + raise EasyBuildError(msg, self.toolchain.name) else: env.setvar('ESMF_LAPACK_LIBS', ldflags + ' ' + liblapack) From 89d026010cf7f57e871e140bdef720cd04efe40f Mon Sep 17 00:00:00 2001 From: Fokke Dijkstra Date: Mon, 31 Oct 2022 14:54:47 +0100 Subject: [PATCH 083/325] Removed openmp build flag as MRtrix itself does not contain any OpenMP code. Using the flag led to issues with unresolved omp symbols however. --- easybuild/easyblocks/m/mrtrix.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/easybuild/easyblocks/m/mrtrix.py b/easybuild/easyblocks/m/mrtrix.py index 74b866d4f7..094d368f4f 100644 --- a/easybuild/easyblocks/m/mrtrix.py +++ b/easybuild/easyblocks/m/mrtrix.py @@ -65,9 +65,6 @@ def configure_step(self): env.setvar('QMAKE_CXX', os.getenv('CXX')) cmd = "python configure -verbose" - if LooseVersion(self.version) >= LooseVersion('3.0'): - cmd += " -openmp" - run_cmd(cmd, log_all=True, simple=True, log_ok=True) def build_step(self): From 49e0c963f2ac69771008eac94670404e7ac77d3b Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 31 Oct 2022 16:01:49 +0100 Subject: [PATCH 084/325] prepare_rpath_wrappers only works if the original compilers are in the PATH, so put the lines back that add the original compilers to PATH --- easybuild/easyblocks/c/clang.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index c77aa92f53..92fec63898 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -408,8 +408,10 @@ def build_with_prev_stage(self, prev_obj, next_obj): mkdir(next_obj) change_dir(next_obj) - # keep track of original $PATH value, we need to restore it in case RPATH wrappers were put in place + # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH orig_path = os.getenv('PATH') + prev_obj_path = os.path.join(prev_obj, 'bin') + setvar('PATH', prev_obj_path + ":" + current_path['path']) # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): @@ -430,8 +432,8 @@ def build_with_prev_stage(self, prev_obj, next_obj): setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) # determine full path to clang/clang++ (which may be wrapper scripts in case of RPATH linking) - clang = which('clang') or os.path.join(prev_obj, 'bin', 'clang') - clangxx = which('clang++') or os.path.join(prev_obj, 'bin', 'clang++') + clang = which('clang') + clangxx = which('clang++') # Configure. options = [ From 7b9adc42fae7992c9854cb01b69843ae26746685 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 31 Oct 2022 16:04:33 +0100 Subject: [PATCH 085/325] Mixed up variable names... fixed that now --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 92fec63898..d0cd50ca15 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -411,7 +411,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH orig_path = os.getenv('PATH') prev_obj_path = os.path.join(prev_obj, 'bin') - setvar('PATH', prev_obj_path + ":" + current_path['path']) + setvar('PATH', prev_obj_path + ":" + orig_path['path']) # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): From c5f66a8121f8207f39e9ce8362f40429efb042d8 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 31 Oct 2022 17:08:40 +0100 Subject: [PATCH 086/325] Orig_path is not a dict, no need to index it by key... This was a copy-paste mistake from when I still used the full environment instead of just the PATH --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index d0cd50ca15..a2dce3ff48 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -411,7 +411,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH orig_path = os.getenv('PATH') prev_obj_path = os.path.join(prev_obj, 'bin') - setvar('PATH', prev_obj_path + ":" + orig_path['path']) + setvar('PATH', prev_obj_path + ":" + orig_path) # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): From a05d16885e52c6c2dd4b27c6b5a795d0fa52cf34 Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Thu, 3 Nov 2022 17:16:17 +0100 Subject: [PATCH 087/325] make C API thread safe for HDF5 --- easybuild/easyblocks/h/hdf5.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easybuild/easyblocks/h/hdf5.py b/easybuild/easyblocks/h/hdf5.py index 06b82c635b..3dd8b75294 100644 --- a/easybuild/easyblocks/h/hdf5.py +++ b/easybuild/easyblocks/h/hdf5.py @@ -77,6 +77,9 @@ def configure_step(self): self.cfg.update('configopts', "--with-pic --with-pthread --enable-shared") self.cfg.update('configopts', "--enable-cxx --enable-fortran %s" % fcomp) + # make C API thread safe (C++ / FORTRAN APIs are unaffected) + self.cfg.update('configopts', "--enable-threadsafe") + # MPI and C++ support enabled requires --enable-unsupported, because this is untested by HDF5 # also returns False if MPI is not supported by this toolchain if self.toolchain.options.get('usempi', None): From 34d098c74a5e79c0f4081e88af41c9c51140269e Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Fri, 4 Nov 2022 16:32:32 +0100 Subject: [PATCH 088/325] add --enable-unsupported unconditionally --- easybuild/easyblocks/h/hdf5.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/h/hdf5.py b/easybuild/easyblocks/h/hdf5.py index 3dd8b75294..f96942e841 100644 --- a/easybuild/easyblocks/h/hdf5.py +++ b/easybuild/easyblocks/h/hdf5.py @@ -80,10 +80,13 @@ def configure_step(self): # make C API thread safe (C++ / FORTRAN APIs are unaffected) self.cfg.update('configopts', "--enable-threadsafe") + # --enable-unsupported is needed to allow --enable-threadsafe to be used together with --enable-cxx + self.cfg.update('configopts', "--enable-unsupported") + # MPI and C++ support enabled requires --enable-unsupported, because this is untested by HDF5 # also returns False if MPI is not supported by this toolchain if self.toolchain.options.get('usempi', None): - self.cfg.update('configopts', "--enable-unsupported --enable-parallel") + self.cfg.update('configopts', "--enable-parallel") mpich_mpi_families = [toolchain.INTELMPI, toolchain.MPICH, toolchain.MPICH2, toolchain.MVAPICH2] if self.toolchain.mpi_family() in mpich_mpi_families: self.cfg.update('buildopts', 'CXXFLAGS="$CXXFLAGS -DMPICH_IGNORE_CXX_SEEK"') From 3730f080c5fe201eef8e618ae91ca92e2bbb2f26 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 7 Nov 2022 12:15:33 +0100 Subject: [PATCH 089/325] Added comments to explain why we really need to temporarily put the stage 1 and 2 compilers on the PATH --- easybuild/easyblocks/c/clang.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index a2dce3ff48..b339c33ac5 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -409,6 +409,8 @@ def build_with_prev_stage(self, prev_obj, next_obj): change_dir(next_obj) # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH + # The call to prepare_rpath_wrappers() requires the compilers-to-be-wrapped on the PATH + # Also, the call to 'which' in later in this current function also requires that orig_path = os.getenv('PATH') prev_obj_path = os.path.join(prev_obj, 'bin') setvar('PATH', prev_obj_path + ":" + orig_path) From 3fb8cde401c6e167bf7d5fe64aeb1a5533abe9d6 Mon Sep 17 00:00:00 2001 From: satishk Date: Mon, 7 Nov 2022 14:46:09 +0100 Subject: [PATCH 090/325] Incorporating improvements suggested by @boegel --- easybuild/easyblocks/p/petsc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py index 5a2d97d0b1..00af8bf532 100644 --- a/easybuild/easyblocks/p/petsc.py +++ b/easybuild/easyblocks/p/petsc.py @@ -232,7 +232,7 @@ def configure_step(self): # to library names from SCOTCH 7.0.1 or PETSc version 3.17. scotch = get_software_root('SCOTCH') scotch_ver = get_software_version('SCOTCH') - if (scotch and LooseVersion(scotch_ver) >= LooseVersion("7.0.1")): + if (scotch and LooseVersion(scotch_ver) >= LooseVersion("7.0")): withdep = "--with-ptscotch" scotch_inc = [os.path.join(scotch, "include")] inc_spec = "-include=[%s]" % ','.join(scotch_inc) From 7732cf4285eb33d420f19e9e889dd38ab3fff9a6 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 9 Nov 2022 21:18:25 +0100 Subject: [PATCH 091/325] enable building of static libraries for libxml2 >= 2.10 --- easybuild/easyblocks/l/libxml2.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/easybuild/easyblocks/l/libxml2.py b/easybuild/easyblocks/l/libxml2.py index 159f48304a..cab458fec5 100644 --- a/easybuild/easyblocks/l/libxml2.py +++ b/easybuild/easyblocks/l/libxml2.py @@ -92,6 +92,10 @@ def configure_step(self): else: self.cfg.update('configopts', '--without-python') + # building of static libraries is disabled by default for libxml >= 2.10 + if LooseVersion(self.version) >= LooseVersion('2.10'): + self.cfg.update('configopts', '--enable-static') + ConfigureMake.configure_step(self) if self.with_python_bindings: From 2843f9a298e31d6bd240a635902cc29e96767741 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 10 Nov 2022 15:04:47 +0100 Subject: [PATCH 092/325] remove custom init from JuliaPackage --- easybuild/easyblocks/generic/juliapackage.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index 2ac3fb5c38..5c7573c632 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -56,10 +56,6 @@ def extra_options(extra_vars=None): }) return extra_vars - def __init__(self, *args, **kwargs): - """JuliaPackage easyblock constructor.""" - super(JuliaPackage, self).__init__(*args, **kwargs) - def set_pkg_offline(self): """Enable offline mode of Julia Pkg""" if get_software_root('Julia') is None: From 0d4a9936d426db511e7b00db63d02d71031fdb60 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 10 Nov 2022 15:10:02 +0100 Subject: [PATCH 093/325] rename JuliaPackage option bundle-deps to download_pkg_deps --- easybuild/easyblocks/generic/juliapackage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index 5c7573c632..2189c282e5 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -50,7 +50,7 @@ def extra_options(extra_vars=None): """Extra easyconfig parameters specific to JuliaPackage.""" extra_vars = ExtensionEasyBlock.extra_options(extra_vars=extra_vars) extra_vars.update({ - 'bundle_deps': [ + 'download_pkg_deps': [ False, "Let Julia download and bundle all needed dependencies for this installation", CUSTOM ], }) @@ -61,7 +61,7 @@ def set_pkg_offline(self): if get_software_root('Julia') is None: raise EasyBuildError("Julia not included as dependency!") - if not self.cfg['bundle_deps']: + if not self.cfg['download_pkg_deps']: julia_version = get_software_version('Julia') if LooseVersion(julia_version) >= LooseVersion('1.5'): # Enable offline mode of Julia Pkg @@ -70,7 +70,7 @@ def set_pkg_offline(self): else: errmsg = ( "Cannot set offline mode in Julia v%s (needs Julia >= 1.5). " - "Enable easyconfig option 'bundle_deps' to allow installation " + "Enable easyconfig option 'download_pkg_deps' to allow installation " "with any extra downloaded dependencies." ) raise EasyBuildError(errmsg, julia_version) From a8e23e5b8a9dac5de6a603e829229e54841e1c8c Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 10 Nov 2022 15:13:13 +0100 Subject: [PATCH 094/325] merge JuliaPackage.install_julia_pkg() into the install step --- easybuild/easyblocks/generic/juliapackage.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index 2189c282e5..e0e14bc7a3 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -92,8 +92,8 @@ def test_step(self): """No separate (standard) test procedure for JuliaPackage.""" pass - def install_julia_pkg(self): - """Install procedure for Julia packages with Pkg""" + def install_step(self): + """Install Julia package with Pkg""" # prepend installation directory to Julia DEPOT_PATH # see https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_DEPOT_PATH @@ -131,20 +131,16 @@ def install_julia_pkg(self): return out - def install_step(self): - """Install Julia package""" - self.install_julia_pkg() - def run(self): """Install Julia package as an extension.""" if not self.src: - errmsg = "No source found for Julia package %s, require d for installation. (src: %s)" + errmsg = "No source found for Julia package %s, required for installation. (src: %s)" raise EasyBuildError(errmsg, self.name, self.src) ExtensionEasyBlock.run(self, unpack_src=True) self.set_pkg_offline() - self.install_julia_pkg() + self.install_step() def sanity_check_step(self, *args, **kwargs): """Custom sanity check for JuliaPackage""" From d12181b57c26deffca3385669989f496ce6227d3 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 10 Nov 2022 15:20:17 +0100 Subject: [PATCH 095/325] simplify JuliaPackage install command --- easybuild/easyblocks/generic/juliapackage.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index e0e14bc7a3..88a1ac9416 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -121,12 +121,13 @@ def install_step(self): 'Pkg.develop(PackageSpec(path="%s"))' % install_pkg_path, 'Pkg.build("%s")' % self.name, ]) - julia_pkg_cmd = ';'.join(julia_pkg_cmd) - - install_cmd = "julia -e '%s'" % julia_pkg_cmd - - cmd = ' '.join([self.cfg['preinstallopts'], install_cmd, self.cfg['installopts']]) + julia_pkg_cmd = ';'.join(julia_pkg_cmd) + cmd = ' '.join([ + self.cfg['preinstallopts'], + "julia -e '%s'" % julia_pkg_cmd, + self.cfg['installopts'], + ]) (out, _) = run_cmd(cmd, log_all=True, simple=False) return out From 744a628a8928de76ffbf4bb2e29d5aadd6c2c5e9 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 10 Nov 2022 15:26:58 +0100 Subject: [PATCH 096/325] avoid trailing : in JULIA_DEPOT_PATH --- easybuild/easyblocks/generic/juliapackage.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index 88a1ac9416..d68fb249ff 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -97,7 +97,10 @@ def install_step(self): # prepend installation directory to Julia DEPOT_PATH # see https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_DEPOT_PATH - env.setvar('JULIA_DEPOT_PATH', ':'.join([self.installdir, os.getenv('JULIA_DEPOT_PATH', '')])) + depot_path = os.getenv('JULIA_DEPOT_PATH') + if depot_path is not None: + depot_path = ':'.join([self.installdir, depot_path]) + env.setvar('JULIA_DEPOT_PATH', depot_path) # command sequence for Julia.Pkg julia_pkg_cmd = ['using Pkg'] From 260750c36821d8bdface8a82b982d470b35cfc3a Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Mon, 14 Nov 2022 20:16:31 +0100 Subject: [PATCH 097/325] use new EasyBuild logo in README --- README.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 240714ed02..b651c614a6 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,8 @@ -.. image:: https://github.com/easybuilders/easybuild-easyblocks/workflows/easyblocks%20unit%20tests/badge.svg?branch=develop - -.. image:: https://easybuilders.github.io/easybuild/images/easybuild_logo_small.png +.. image:: https://github.com/easybuilders/easybuild/raw/develop/logo/png/easybuild_logo_2022_horizontal_dark_bg_transparent.png :align: center + :height: 400px + +.. image:: https://github.com/easybuilders/easybuild-easyblocks/workflows/easyblocks%20unit%20tests/badge.svg?branch=develop `EasyBuild `_ is a software build and installation framework that allows you to manage (scientific) software From b7f8ccf94c67809d3a339109a0158d287612b383 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Mon, 26 Sep 2022 10:25:08 +0200 Subject: [PATCH 098/325] load module early during PythonPackage's sanity check step via sanity_check_load_module (fixes #2745) --- easybuild/easyblocks/generic/pythonpackage.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index e158e90444..9cdbbd9e70 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -790,6 +790,14 @@ def sanity_check_step(self, *args, **kwargs): success, fail_msg = True, '' + # load module early ourselves rather than letting parent sanity_check_step method do so, + # since custom actions taken below require that environment is set up properly already + # (especially when using --sanity-check-only) + if not self.sanity_check_module_loaded: + extension = self.is_extension or kwargs.get('extension', False) + extra_modules = kwargs.get('extra_modules', None) + self.fake_mod_data = self.sanity_check_load_module(extension=extension, extra_modules=extra_modules) + # don't add user site directory to sys.path (equivalent to python -s) # see https://www.python.org/dev/peps/pep-0370/; # must be set here to ensure that it is defined when running sanity check for extensions, From 286877c66e826bf6801ee9b14b9c140ad5ab075e Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Wed, 16 Nov 2022 16:55:01 +0100 Subject: [PATCH 099/325] add easyblock for JuliaBundle --- easybuild/easyblocks/generic/juliabundle.py | 96 +++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 easybuild/easyblocks/generic/juliabundle.py diff --git a/easybuild/easyblocks/generic/juliabundle.py b/easybuild/easyblocks/generic/juliabundle.py new file mode 100644 index 0000000000..6198344b1f --- /dev/null +++ b/easybuild/easyblocks/generic/juliabundle.py @@ -0,0 +1,96 @@ +## +# Copyright 2022-2022 Vrije Universiteit Brussel +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for bundles of Julia packages, implemented as an easyblock + +@author: Alex Domingo (Vrije Universiteit Brussel) +""" +import os + +from easybuild.easyblocks.generic.bundle import Bundle +from easybuild.easyblocks.generic.juliapackage import EXTS_FILTER_JULIA_PACKAGES, JuliaPackage +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.modules import get_software_root + + +class JuliaBundle(Bundle): + """ + Bundle of modules: only generate module files, nothing to build/install + """ + + @staticmethod + def extra_options(extra_vars=None): + """Easyconfig parameters specific to bundles of Julia packages.""" + if extra_vars is None: + extra_vars = {} + # combine custom easyconfig parameters of Bundle & JuliaPackage + extra_vars = Bundle.extra_options(extra_vars) + return JuliaPackage.extra_options(extra_vars) + + def __init__(self, *args, **kwargs): + """Initialize JuliaBundle easyblock.""" + super(JuliaBundle, self).__init__(*args, **kwargs) + + self.cfg['exts_defaultclass'] = 'JuliaPackage' + self.cfg['exts_filter'] = EXTS_FILTER_JULIA_PACKAGES + + # need to disable templating to ensure that actual value for exts_default_options is updated... + prev_enable_templating = self.cfg.enable_templating + self.cfg.enable_templating = False + + # set default options for extensions according to relevant top-level easyconfig parameters + jlpkg_keys = JuliaPackage.extra_options().keys() + for key in jlpkg_keys: + if key not in self.cfg['exts_default_options']: + self.cfg['exts_default_options'][key] = self.cfg[key] + + self.cfg.enable_templating = prev_enable_templating + + self.log.info("exts_default_options: %s", self.cfg['exts_default_options']) + + def prepare_step(self, *args, **kwargs): + """Prepare for installing bundle of Julia packages.""" + super(JuliaBundle, self).prepare_step(*args, **kwargs) + + if get_software_root('Julia') is None: + raise EasyBuildError("Julia not included as dependency!") + + def make_module_extra(self, *args, **kwargs): + """Prepend installation directory to JULIA_DEPOT_PATH in module file.""" + txt = super(JuliaBundle, self).make_module_extra() + txt += self.module_generator.prepend_paths('JULIA_DEPOT_PATH', ['']) + return txt + + def sanity_check_step(self, *args, **kwargs): + """Custom sanity check for bundle of Julia packages""" + if not self.cfg['sanity_check_paths']: + pkg_dir = os.path.join('packages', self.name) + + self.cfg['sanity_check_paths'] = { + 'files': [], + 'dirs': [pkg_dir], + } + + super(JuliaBundle, self).sanity_check_step(*args, **kwargs) From 70673fb2777575bd5b43ea1ad8c8e6af00186e64 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 16 Nov 2022 19:35:52 +0000 Subject: [PATCH 100/325] address ocaisa's comments --- easybuild/easyblocks/c/clang.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 91ab0b7661..ac0b776965 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -73,6 +73,9 @@ # List of all supported CUDA toolkit versions supported by LLVM CUDA_TOOLKIT_SUPPORT = ['80', '90', '91', '92', '100', '101', '102', '110', '111', '112'] +# List of the known LLVM projects +KNOWN_LLVM_PROJECTS = ['llvm', 'compiler-rt', 'clang', 'openmp', 'polly', 'lld', 'libunwind', 'lldb', + 'libcxx', 'libcxxabi', 'clang-tools-extra', 'flang'] class EB_Clang(CMakeMake): """Support for bootstrapping Clang.""" @@ -118,6 +121,11 @@ def __init__(self, *args, **kwargs): if not self.cfg['llvm_projects']: self.cfg['llvm_projects'] = [] + else: + for project in [p for p in self.cfg['llvm_projects'] if p not in KNOWN_LLVM_PROJECTS]: + msg = "LLVM project %s included but not recognised, this project will NOT be sanity checked!" % project + self.log.warning(msg) + print_warning(msg) # keep compatibility between using llvm_projects vs using flags if LooseVersion(self.version) >= LooseVersion('14'): @@ -582,6 +590,9 @@ def sanity_check_step(self): custom_paths['files'].extend(["lib/libc++.%s" % shlib_ext]) custom_paths['files'].extend(["lib/libc++abi.%s" % shlib_ext]) + if 'flang' in self.cfg['llvm_projects'] and LooseVersion(self.version) >= LooseVersion('15'): + custom_paths['files'].extend(["bin/flang"]) + if LooseVersion(self.version) >= LooseVersion('3.8'): custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version]) From 368de3b07708711a8ac8bffadab9e14d01ba4731 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 17 Nov 2022 02:31:08 +0100 Subject: [PATCH 101/325] rename tarballs of Julia packages in bundles to avoid filename collisions --- easybuild/easyblocks/generic/juliabundle.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/easybuild/easyblocks/generic/juliabundle.py b/easybuild/easyblocks/generic/juliabundle.py index 6198344b1f..2f144d8a7b 100644 --- a/easybuild/easyblocks/generic/juliabundle.py +++ b/easybuild/easyblocks/generic/juliabundle.py @@ -66,6 +66,17 @@ def __init__(self, *args, **kwargs): if key not in self.cfg['exts_default_options']: self.cfg['exts_default_options'][key] = self.cfg[key] + # Sources of Julia packages are commonly distributed from GitHub repos. + # By default, rename downloaded tarballs to avoid name collisions on + # packages sharing the same version string + if 'sources' not in self.cfg['exts_default_options']: + self.cfg['exts_default_options']['sources'] = [ + { + 'download_filename': 'v%(version)s.tar.gz', + 'filename': '%(name)s-%(version)s.tar.gz', + } + ] + self.cfg.enable_templating = prev_enable_templating self.log.info("exts_default_options: %s", self.cfg['exts_default_options']) From 118e33bc2971731d6948ce7d5f4ffbb25e3f1917 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 17 Nov 2022 02:38:27 +0100 Subject: [PATCH 102/325] simplify inititalization of extension default options in JuliaBundle --- easybuild/easyblocks/generic/juliabundle.py | 38 +++++++++------------ 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/easybuild/easyblocks/generic/juliabundle.py b/easybuild/easyblocks/generic/juliabundle.py index 2f144d8a7b..d6247d644a 100644 --- a/easybuild/easyblocks/generic/juliabundle.py +++ b/easybuild/easyblocks/generic/juliabundle.py @@ -57,27 +57,23 @@ def __init__(self, *args, **kwargs): self.cfg['exts_filter'] = EXTS_FILTER_JULIA_PACKAGES # need to disable templating to ensure that actual value for exts_default_options is updated... - prev_enable_templating = self.cfg.enable_templating - self.cfg.enable_templating = False - - # set default options for extensions according to relevant top-level easyconfig parameters - jlpkg_keys = JuliaPackage.extra_options().keys() - for key in jlpkg_keys: - if key not in self.cfg['exts_default_options']: - self.cfg['exts_default_options'][key] = self.cfg[key] - - # Sources of Julia packages are commonly distributed from GitHub repos. - # By default, rename downloaded tarballs to avoid name collisions on - # packages sharing the same version string - if 'sources' not in self.cfg['exts_default_options']: - self.cfg['exts_default_options']['sources'] = [ - { - 'download_filename': 'v%(version)s.tar.gz', - 'filename': '%(name)s-%(version)s.tar.gz', - } - ] - - self.cfg.enable_templating = prev_enable_templating + with self.cfg.disable_templating(): + # set default options for extensions according to relevant top-level easyconfig parameters + jlpkg_keys = JuliaPackage.extra_options().keys() + for key in jlpkg_keys: + if key not in self.cfg['exts_default_options']: + self.cfg['exts_default_options'][key] = self.cfg[key] + + # Sources of Julia packages are commonly distributed from GitHub repos. + # By default, rename downloaded tarballs to avoid name collisions on + # packages sharing the same version string + if 'sources' not in self.cfg['exts_default_options']: + self.cfg['exts_default_options']['sources'] = [ + { + 'download_filename': 'v%(version)s.tar.gz', + 'filename': '%(name)s-%(version)s.tar.gz', + } + ] self.log.info("exts_default_options: %s", self.cfg['exts_default_options']) From bde9df58e4798440f6aa96bee571a4c38357690e Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 17 Nov 2022 02:40:21 +0100 Subject: [PATCH 103/325] simplify sanity check step in JuliaBundle --- easybuild/easyblocks/generic/juliabundle.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/easybuild/easyblocks/generic/juliabundle.py b/easybuild/easyblocks/generic/juliabundle.py index d6247d644a..61f5425021 100644 --- a/easybuild/easyblocks/generic/juliabundle.py +++ b/easybuild/easyblocks/generic/juliabundle.py @@ -92,12 +92,8 @@ def make_module_extra(self, *args, **kwargs): def sanity_check_step(self, *args, **kwargs): """Custom sanity check for bundle of Julia packages""" - if not self.cfg['sanity_check_paths']: - pkg_dir = os.path.join('packages', self.name) - - self.cfg['sanity_check_paths'] = { - 'files': [], - 'dirs': [pkg_dir], - } - - super(JuliaBundle, self).sanity_check_step(*args, **kwargs) + custom_paths = { + 'files': [], + 'dirs': [os.path.join('packages', self.name)], + } + super(JuliaBundle, self).sanity_check_step(custom_paths=custom_paths) From 3cd073697bf7704f34070626461c8e0df35157fb Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 17 Nov 2022 02:44:11 +0100 Subject: [PATCH 104/325] load Julia on JuliaBundle easyblock tests --- test/easyblocks/module.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index 6d8bc1c729..2e302cd864 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -42,6 +42,7 @@ from easybuild.base import fancylogger from easybuild.base.testing import TestCase from easybuild.easyblocks.generic.gopackage import GoPackage +from easybuild.easyblocks.generic.juliabundle import JuliaBundle from easybuild.easyblocks.generic.juliapackage import JuliaPackage from easybuild.easyblocks.generic.intelbase import IntelBase from easybuild.easyblocks.generic.pythonbundle import PythonBundle @@ -287,8 +288,8 @@ def template_module_only_test(self, easyblock, name, version='1.3.2', extra_txt= os.environ['EBROOTGO'] = '/fake/install/prefix/Go/1.14' os.environ['EBVERSIONGO'] = '1.14' - elif app_class == JuliaPackage: - # $EBROOTJULIA must be set for JuliaPackage easyblock + elif app_class in (JuliaPackage, JuliaBundle): + # $EBROOTJULIA must be set for JuliaPackage/JuliaBundle easyblock os.environ['EBROOTJULIA'] = '/fake/install/prefix/Julia/1.6.7' os.environ['EBVERSIONJULIA'] = '1.6.7' From 53e6bcd96afb3f2b69e495ae82741cc0fb91662a Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 17 Nov 2022 08:23:40 +0100 Subject: [PATCH 105/325] update xmipp.py to handle effects of CUDA at SYSTEM level and newer CUDA version requirements for stdc++ --- easybuild/easyblocks/x/xmipp.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/x/xmipp.py b/easybuild/easyblocks/x/xmipp.py index 122c49543b..6d35526471 100644 --- a/easybuild/easyblocks/x/xmipp.py +++ b/easybuild/easyblocks/x/xmipp.py @@ -150,9 +150,13 @@ def configure_step(self): if cuda_root: params.update({'CUDA_BIN': os.path.join(cuda_root, 'bin')}) params.update({'CUDA_LIB': os.path.join(cuda_root, 'lib64')}) - params.update({'NVCC': os.environ['CUDA_CXX']}) + params.update({'NVCC': os.environ.get('CUDA_CXX', 'nvcc')}) # Their default for NVCC is to use g++-5, fix that - nvcc_flags = '-v --x cu -D_FORCE_INLINES -Xcompiler -fPIC -Wno-deprecated-gpu-targets -std=c++11' + nvcc_flags = '-v --x cu -D_FORCE_INLINES -Xcompiler -fPIC -Wno-deprecated-gpu-targets' + if LooseVersion(self.version) < LooseVersion('3.22'): + nvcc_flags += ' --std=c++11' + else: + nvcc_flags += ' --std=c++17' if LooseVersion(self.version) >= LooseVersion('3.20.07'): nvcc_flags += ' --extended-lambda' params.update({'NVCC_CXXFLAGS': nvcc_flags}) From e973b7fb9a2215056096198c2f7c1af980b24aae Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 10 Sep 2022 13:39:13 +0200 Subject: [PATCH 106/325] fix version check for NVPTX library in sanity check of Clang easyblock (fixes #2782) --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index ac0b776965..9e5453345d 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -621,7 +621,7 @@ def sanity_check_step(self): cuda_cc = cfg_cuda_cc or ec_cuda_cc or [] # We need the CUDA capability in the form of '75' and not '7.5' cuda_cc = [cc.replace('.', '') for cc in cuda_cc] - if LooseVersion('11.0') < LooseVersion(self.version) < LooseVersion('13.0'): + if LooseVersion('12.0') < LooseVersion(self.version) < LooseVersion('13.0'): custom_paths['files'].extend(["lib/libomptarget-nvptx-cuda_%s-sm_%s.bc" % (x, y) for x in CUDA_TOOLKIT_SUPPORT for y in cuda_cc]) else: From ea7567e5f382e10e2af93681b4d691eca712a18a Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 3 Oct 2022 13:33:52 +0200 Subject: [PATCH 107/325] Updated Clang EasyBlock to solve https://github.com/easybuilders/easybuild-easyconfigs/issues/15106 . Testing is ongoing. --- easybuild/easyblocks/c/clang.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 9e5453345d..2eebdc99f0 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -50,7 +50,7 @@ from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import AARCH32, AARCH64, POWER, X86_64 from easybuild.tools.systemtools import get_cpu_architecture, get_os_name, get_os_version, get_shared_lib_ext -from easybuild.tools.environment import setvar +from easybuild.tools.environment import setvar, restore_env, read_environment # List of all possible build targets for Clang CLANG_TARGETS = ["all", "AArch64", "AMDGPU", "ARM", "CppBackend", "Hexagon", "Mips", @@ -462,13 +462,16 @@ def build_with_prev_stage(self, prev_obj, next_obj): mkdir(next_obj) change_dir(next_obj) - # Configure. - CC = os.path.join(prev_obj, 'bin', 'clang') - CXX = os.path.join(prev_obj, 'bin', 'clang++') + # Make sure the clang and clang++ compilers from previous stages are (temporarily) in PATH + orig_env = copy.deepcopy(os.environ) + prev_obj_path = os.path.join(prev_obj, 'bin') + current_path = read_environment({'path': 'PATH'}) + setvar('PATH', current_path['path'] + prev_obj_path) + # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir - options += "-DCMAKE_C_COMPILER='%s' " % CC - options += "-DCMAKE_CXX_COMPILER='%s' " % CXX + options += "-DCMAKE_C_COMPILER='clang' " + options += "-DCMAKE_CXX_COMPILER='clang++' " options += self.cfg['configopts'] options += "-DCMAKE_BUILD_TYPE=%s" % self.build_type @@ -481,6 +484,9 @@ def build_with_prev_stage(self, prev_obj, next_obj): self.log.info("Building") run_cmd("make %s" % self.make_parallel_opts, log_all=True) + # Restore environment (specifically: PATH) + restore_env(orig_env) + def run_clang_tests(self, obj_dir): """Run Clang tests in specified directory (unless disabled).""" if not self.cfg['skip_all_tests']: From 31cc7c5f458bc193c09cb773529cedad16f0a42c Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 3 Oct 2022 14:00:49 +0200 Subject: [PATCH 108/325] Forgot to import 'copy' --- easybuild/easyblocks/c/clang.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 2eebdc99f0..cf3b0f91d9 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -38,6 +38,7 @@ import glob import os import shutil +import copy from distutils.version import LooseVersion from easybuild.easyblocks.generic.cmakemake import CMakeMake From c6375fb17538723b8d0f280001c2ee7c8676a479 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Tue, 4 Oct 2022 16:07:03 +0200 Subject: [PATCH 109/325] Added path seperator --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index cf3b0f91d9..e7186e95b3 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -467,7 +467,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): orig_env = copy.deepcopy(os.environ) prev_obj_path = os.path.join(prev_obj, 'bin') current_path = read_environment({'path': 'PATH'}) - setvar('PATH', current_path['path'] + prev_obj_path) + setvar('PATH', current_path['path'] + ":" + prev_obj_path) # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir From e4ffc7db980c4d83277b4017524645f77af9baee Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Thu, 6 Oct 2022 21:24:25 +0200 Subject: [PATCH 110/325] First attempt at fixing https://github.com/easybuilders/easybuild-easyconfigs/issues/15106 --- easybuild/easyblocks/c/clang.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index e7186e95b3..65ab27cc13 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -469,12 +469,18 @@ def build_with_prev_stage(self, prev_obj, next_obj): current_path = read_environment({'path': 'PATH'}) setvar('PATH', current_path['path'] + ":" + prev_obj_path) + # Hacky test fix by Caspar to create RPATH wrappers for the Clang compilers + from easybuild.toolchains.compiler.clang import Clang + my_clang_toolchain = Clang(name='Clang', version='1') + my_clang_toolchain.prepare_rpath_wrappers() + self.log.info("Prepared clang rpath wrappers") + # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir options += "-DCMAKE_C_COMPILER='clang' " options += "-DCMAKE_CXX_COMPILER='clang++' " options += self.cfg['configopts'] - options += "-DCMAKE_BUILD_TYPE=%s" % self.build_type + options += "-DCMAKE_BUILD_TYPE=%s " % self.build_type self.log.info("Configuring") if LooseVersion(self.version) >= LooseVersion('14'): @@ -483,7 +489,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) self.log.info("Building") - run_cmd("make %s" % self.make_parallel_opts, log_all=True) + run_cmd("make %s VERBOSE=1" % self.make_parallel_opts, log_all=True) # Restore environment (specifically: PATH) restore_env(orig_env) From e2b7b85eeb1ef5cb7ec8aac88df40fe671725ba7 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 7 Oct 2022 01:16:13 +0200 Subject: [PATCH 111/325] Combination of -Werror and Wunused-command-line-argument causes various cmake configure tests to fail. The unused command line arguments are the -Wl,-rpath commands added by the RPATH wrapper. We suppress those by adding -Wnounused-command-line-argument --- easybuild/easyblocks/c/clang.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 65ab27cc13..d49930831f 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -475,6 +475,14 @@ def build_with_prev_stage(self, prev_obj, next_obj): my_clang_toolchain.prepare_rpath_wrappers() self.log.info("Prepared clang rpath wrappers") + # CvL: Add to CXXFLAGS to avoid unused command line argument warnings + # Since these result into some errors during configure (due to -Werror) + import easybuild.tools.environment as env + cflags = os.getenv('CFLAGS') + cxxflags = os.getenv('CXXFLAGS') + env.setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) + env.setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) + # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir options += "-DCMAKE_C_COMPILER='clang' " From 70f6cf7b893be104d7329c330176540e6d92e6ce Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Thu, 13 Oct 2022 14:43:23 +0200 Subject: [PATCH 112/325] Wrap in if-statements so that RPATH-specific logic is only executed when --rpath is used. Also, put more clear comments --- easybuild/easyblocks/c/clang.py | 41 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index d49930831f..e94bd48102 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -46,7 +46,7 @@ from easybuild.tools import run from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import build_option -from easybuild.tools.filetools import apply_regex_substitutions, change_dir, mkdir +from easybuild.tools.filetools import apply_regex_substitutions, change_dir, mkdir, which from easybuild.tools.modules import get_software_root from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import AARCH32, AARCH64, POWER, X86_64 @@ -469,19 +469,24 @@ def build_with_prev_stage(self, prev_obj, next_obj): current_path = read_environment({'path': 'PATH'}) setvar('PATH', current_path['path'] + ":" + prev_obj_path) - # Hacky test fix by Caspar to create RPATH wrappers for the Clang compilers - from easybuild.toolchains.compiler.clang import Clang - my_clang_toolchain = Clang(name='Clang', version='1') - my_clang_toolchain.prepare_rpath_wrappers() - self.log.info("Prepared clang rpath wrappers") - - # CvL: Add to CXXFLAGS to avoid unused command line argument warnings - # Since these result into some errors during configure (due to -Werror) - import easybuild.tools.environment as env - cflags = os.getenv('CFLAGS') - cxxflags = os.getenv('CXXFLAGS') - env.setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) - env.setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) + # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 + if build_option('rpath'): + from easybuild.toolchains.compiler.clang import Clang + my_clang_toolchain = Clang(name='Clang', version='1') + my_clang_toolchain.prepare_rpath_wrappers() + self.log.info("Prepared clang rpath wrappers") + + # RPATH wrappers add -Wl,rpath arguments to all command lines, including when it is just compiling + # Clang by default warns about that, and then some configure tests use -Werror which turns those warnings + # into errors. As a result, those configure tests fail, even though the compiler supports the requested + # functionality (e.g. the test that checks if -fPIC is supported would fail, and it compiles without + # resulting in relocation errors). + # See https://github.com/easybuilders/easybuild-easyblocks/pull/2799#issuecomment-1270621100 + # Here, we add -Wno-unused-command-line-argument to CXXFLAGS to avoid these warnings alltogether + cflags = os.getenv('CFLAGS') + cxxflags = os.getenv('CXXFLAGS') + setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) + setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) # Configure. options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir @@ -490,6 +495,14 @@ def build_with_prev_stage(self, prev_obj, next_obj): options += self.cfg['configopts'] options += "-DCMAKE_BUILD_TYPE=%s " % self.build_type + # Cmake looks for llvm-link by default in the same directory as the compiler + # However, when compiling with rpath, the clang 'compiler' is not actually the compiler, but the wrapper + # Clearly, the wrapper directory won't llvm-link. Thus, we pass the linker to be used by full path. + # See https://github.com/easybuilders/easybuild-easyblocks/pull/2799#issuecomment-1275916186 + if build_option('rpath'): + llvm_link = which('llvm-link') + options += "-DLIBOMPTARGET_NVPTX_BC_LINKER=%s" % llvm_link + self.log.info("Configuring") if LooseVersion(self.version) >= LooseVersion('14'): run_cmd("cmake %s %s" % (options, os.path.join(self.llvm_src_dir, "llvm")), log_all=True) From f5aa9842d4bd0a3593c9689480c8d8db3562ebf3 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 26 Oct 2022 08:41:23 +0200 Subject: [PATCH 113/325] always use full path to clang/clang++ in staged build, only restore $PATH, import Clang on top --- easybuild/easyblocks/c/clang.py | 38 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index e94bd48102..4c3265e7c4 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -38,11 +38,11 @@ import glob import os import shutil -import copy from distutils.version import LooseVersion from easybuild.easyblocks.generic.cmakemake import CMakeMake from easybuild.framework.easyconfig import CUSTOM +from easybuild.toolchains.compiler.clang import Clang from easybuild.tools import run from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import build_option @@ -51,7 +51,7 @@ from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import AARCH32, AARCH64, POWER, X86_64 from easybuild.tools.systemtools import get_cpu_architecture, get_os_name, get_os_version, get_shared_lib_ext -from easybuild.tools.environment import setvar, restore_env, read_environment +from easybuild.tools.environment import setvar # List of all possible build targets for Clang CLANG_TARGETS = ["all", "AArch64", "AMDGPU", "ARM", "CppBackend", "Hexagon", "Mips", @@ -463,15 +463,11 @@ def build_with_prev_stage(self, prev_obj, next_obj): mkdir(next_obj) change_dir(next_obj) - # Make sure the clang and clang++ compilers from previous stages are (temporarily) in PATH - orig_env = copy.deepcopy(os.environ) - prev_obj_path = os.path.join(prev_obj, 'bin') - current_path = read_environment({'path': 'PATH'}) - setvar('PATH', current_path['path'] + ":" + prev_obj_path) + # keep track of original $PATH value, we need to restore it in case RPATH wrappers were put in place + orig_path = os.getenv('PATH') # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): - from easybuild.toolchains.compiler.clang import Clang my_clang_toolchain = Clang(name='Clang', version='1') my_clang_toolchain.prepare_rpath_wrappers() self.log.info("Prepared clang rpath wrappers") @@ -488,12 +484,18 @@ def build_with_prev_stage(self, prev_obj, next_obj): setvar('CFLAGS', "%s %s" % (cflags, '-Wno-unused-command-line-argument')) setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) + # determine full path to clang/clang++ (which may be wrapper scripts in case of RPATH linking) + clang = which('clang') or os.path.join(prev_obj, 'bin', 'clang') + clangxx = which('clang++') or os.path.join(prev_obj, 'bin', 'clang++') + # Configure. - options = "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir - options += "-DCMAKE_C_COMPILER='clang' " - options += "-DCMAKE_CXX_COMPILER='clang++' " - options += self.cfg['configopts'] - options += "-DCMAKE_BUILD_TYPE=%s " % self.build_type + options = [ + "-DCMAKE_INSTALL_PREFIX=%s " % self.installdir, + "-DCMAKE_C_COMPILER='%s' " % clang, + "-DCMAKE_CXX_COMPILER='%s' " % clangxx, + self.cfg['configopts'], + "-DCMAKE_BUILD_TYPE=%s " % self.build_type, + ] # Cmake looks for llvm-link by default in the same directory as the compiler # However, when compiling with rpath, the clang 'compiler' is not actually the compiler, but the wrapper @@ -501,19 +503,19 @@ def build_with_prev_stage(self, prev_obj, next_obj): # See https://github.com/easybuilders/easybuild-easyblocks/pull/2799#issuecomment-1275916186 if build_option('rpath'): llvm_link = which('llvm-link') - options += "-DLIBOMPTARGET_NVPTX_BC_LINKER=%s" % llvm_link + options.append("-DLIBOMPTARGET_NVPTX_BC_LINKER=%s" % llvm_link) self.log.info("Configuring") if LooseVersion(self.version) >= LooseVersion('14'): - run_cmd("cmake %s %s" % (options, os.path.join(self.llvm_src_dir, "llvm")), log_all=True) + run_cmd("cmake %s %s" % (' '.join(options), os.path.join(self.llvm_src_dir, "llvm")), log_all=True) else: - run_cmd("cmake %s %s" % (options, self.llvm_src_dir), log_all=True) + run_cmd("cmake %s %s" % (' '.join(options), self.llvm_src_dir), log_all=True) self.log.info("Building") run_cmd("make %s VERBOSE=1" % self.make_parallel_opts, log_all=True) - # Restore environment (specifically: PATH) - restore_env(orig_env) + # restore $PATH + setvar('PATH', orig_path) def run_clang_tests(self, obj_dir): """Run Clang tests in specified directory (unless disabled).""" From 1b4ce8189605e03b89095e512d1d366460660462 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 31 Oct 2022 16:01:49 +0100 Subject: [PATCH 114/325] prepare_rpath_wrappers only works if the original compilers are in the PATH, so put the lines back that add the original compilers to PATH --- easybuild/easyblocks/c/clang.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 4c3265e7c4..527b9df530 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -463,8 +463,10 @@ def build_with_prev_stage(self, prev_obj, next_obj): mkdir(next_obj) change_dir(next_obj) - # keep track of original $PATH value, we need to restore it in case RPATH wrappers were put in place + # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH orig_path = os.getenv('PATH') + prev_obj_path = os.path.join(prev_obj, 'bin') + setvar('PATH', prev_obj_path + ":" + current_path['path']) # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): @@ -485,8 +487,8 @@ def build_with_prev_stage(self, prev_obj, next_obj): setvar('CXXFLAGS', "%s %s" % (cxxflags, '-Wno-unused-command-line-argument')) # determine full path to clang/clang++ (which may be wrapper scripts in case of RPATH linking) - clang = which('clang') or os.path.join(prev_obj, 'bin', 'clang') - clangxx = which('clang++') or os.path.join(prev_obj, 'bin', 'clang++') + clang = which('clang') + clangxx = which('clang++') # Configure. options = [ From 980878cd9ddb2a13e192b2e74d2f12468a6e8914 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 31 Oct 2022 16:04:33 +0100 Subject: [PATCH 115/325] Mixed up variable names... fixed that now --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 527b9df530..aecda005e7 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -466,7 +466,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH orig_path = os.getenv('PATH') prev_obj_path = os.path.join(prev_obj, 'bin') - setvar('PATH', prev_obj_path + ":" + current_path['path']) + setvar('PATH', prev_obj_path + ":" + orig_path['path']) # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): From 6a3b7197ef19cd0ad0ccedc43353b794444d1735 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 31 Oct 2022 17:08:40 +0100 Subject: [PATCH 116/325] Orig_path is not a dict, no need to index it by key... This was a copy-paste mistake from when I still used the full environment instead of just the PATH --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index aecda005e7..fe232b5ab1 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -466,7 +466,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH orig_path = os.getenv('PATH') prev_obj_path = os.path.join(prev_obj, 'bin') - setvar('PATH', prev_obj_path + ":" + orig_path['path']) + setvar('PATH', prev_obj_path + ":" + orig_path) # If building with rpath, create RPATH wrappers for the Clang compilers for stage 2 and 3 if build_option('rpath'): From e728cbc7db69d1b6f1b42ed842117e66c6607001 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 7 Nov 2022 12:15:33 +0100 Subject: [PATCH 117/325] Added comments to explain why we really need to temporarily put the stage 1 and 2 compilers on the PATH --- easybuild/easyblocks/c/clang.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index fe232b5ab1..91a7ddce9d 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -464,6 +464,8 @@ def build_with_prev_stage(self, prev_obj, next_obj): change_dir(next_obj) # Make sure clang and clang++ compilers from the previous stage are (temporarily) in PATH + # The call to prepare_rpath_wrappers() requires the compilers-to-be-wrapped on the PATH + # Also, the call to 'which' in later in this current function also requires that orig_path = os.getenv('PATH') prev_obj_path = os.path.join(prev_obj, 'bin') setvar('PATH', prev_obj_path + ":" + orig_path) From 6514a0f745a22f3b0539629fab06cb7f47195ccb Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 17 Nov 2022 16:05:02 +0000 Subject: [PATCH 118/325] appeasing lint --- easybuild/easyblocks/c/clang.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 91a7ddce9d..709f897e85 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -78,6 +78,7 @@ KNOWN_LLVM_PROJECTS = ['llvm', 'compiler-rt', 'clang', 'openmp', 'polly', 'lld', 'libunwind', 'lldb', 'libcxx', 'libcxxabi', 'clang-tools-extra', 'flang'] + class EB_Clang(CMakeMake): """Support for bootstrapping Clang.""" From 308b24305e83ee05d40bbaa2d6cb60c49c939b01 Mon Sep 17 00:00:00 2001 From: Killian Murphy Date: Thu, 17 Nov 2022 16:21:46 +0000 Subject: [PATCH 119/325] Address review comments - make new extra_var CUSTOM instead of MANDATORY --- easybuild/easyblocks/e/esmf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/e/esmf.py b/easybuild/easyblocks/e/esmf.py index 45cd2d1b01..0a2f2fa6c5 100644 --- a/easybuild/easyblocks/e/esmf.py +++ b/easybuild/easyblocks/e/esmf.py @@ -39,7 +39,7 @@ from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import get_shared_lib_ext -from easybuild.framework.easyconfig import MANDATORY +from easybuild.framework.easyconfig import CUSTOM class EB_ESMF(ConfigureMake): @@ -49,7 +49,7 @@ class EB_ESMF(ConfigureMake): def extra_options(): """Custom easyconfig parameters for ESMF""" extra_vars = { - 'disable_lapack': [False, 'Disable external LAPACK - True or False', MANDATORY] + 'disable_lapack': [False, 'Disable external LAPACK - True or False', CUSTOM] } return ConfigureMake.extra_options(extra_vars) From 9e077fb3ad401378d48bd36228c453346b1e50fa Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Fri, 18 Nov 2022 08:48:03 -0500 Subject: [PATCH 120/325] Update easybuild/easyblocks/c/clang.py Co-authored-by: ocaisa --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 709f897e85..2368cad552 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -632,7 +632,7 @@ def sanity_check_step(self): custom_paths['files'].extend(["lib/libc++abi.%s" % shlib_ext]) if 'flang' in self.cfg['llvm_projects'] and LooseVersion(self.version) >= LooseVersion('15'): - custom_paths['files'].extend(["bin/flang"]) + custom_paths['files'].extend(["bin/flang-new"]) if LooseVersion(self.version) >= LooseVersion('3.8'): custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version]) From 461b84d549312791b4f22e906226a825ac13aab4 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Fri, 18 Nov 2022 16:54:23 +0000 Subject: [PATCH 121/325] extend flang compiler tests and allow for expected future change in flang name --- easybuild/easyblocks/c/clang.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 2368cad552..1f9aebe8ee 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -602,6 +602,7 @@ def post_install_step(self): def sanity_check_step(self): """Custom sanity check for Clang.""" + custom_commands = ['clang --help', 'clang++ --help', 'llvm-config --cxxflags'] shlib_ext = get_shared_lib_ext() custom_paths = { 'files': [ @@ -632,7 +633,9 @@ def sanity_check_step(self): custom_paths['files'].extend(["lib/libc++abi.%s" % shlib_ext]) if 'flang' in self.cfg['llvm_projects'] and LooseVersion(self.version) >= LooseVersion('15'): - custom_paths['files'].extend(["bin/flang-new"]) + flang_compiler = 'flang-new' + custom_paths['files'].extend(["bin/%s" % flang_compiler]) + custom_commands.extend(["%s --help" % flang_compiler]) if LooseVersion(self.version) >= LooseVersion('3.8'): custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version]) @@ -690,7 +693,6 @@ def sanity_check_step(self): custom_paths['files'].extend(["lib/libomptarget-new-amdgpu-%s.bc" % gfx for gfx in self.cfg['amd_gfx_list']]) - custom_commands = ['clang --help', 'clang++ --help', 'llvm-config --cxxflags'] if self.cfg['python_bindings']: custom_paths['files'].extend([os.path.join("lib", "python", "clang", "cindex.py")]) custom_commands.extend(["python -c 'import clang'"]) From 3c5f6e2ea19f2181e8c00e077533c9a717f27f40 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 21 Nov 2022 17:15:02 +0000 Subject: [PATCH 122/325] split projects into projects + runtime and adjust library path accordingly --- easybuild/easyblocks/c/clang.py | 93 ++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 1f9aebe8ee..2caeeece2c 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -75,8 +75,11 @@ CUDA_TOOLKIT_SUPPORT = ['80', '90', '91', '92', '100', '101', '102', '110', '111', '112'] # List of the known LLVM projects -KNOWN_LLVM_PROJECTS = ['llvm', 'compiler-rt', 'clang', 'openmp', 'polly', 'lld', 'libunwind', 'lldb', - 'libcxx', 'libcxxabi', 'clang-tools-extra', 'flang'] +KNOWN_LLVM_PROJECTS = ['llvm', 'compiler-rt', 'clang', 'openmp', 'polly', 'lld', 'lldb', + 'clang-tools-extra', 'flang'] + +# List of the known LLVM runtimes +KNOWN_LLVM_RUNTIMES = ['libunwind', 'libcxx', 'libcxxabi'] class EB_Clang(CMakeMake): @@ -106,6 +109,7 @@ def extra_options(): 'skip_sanitizer_tests': [True, "Do not run the sanitizer tests", CUSTOM], 'usepolly': [False, "Build Clang with polly", CUSTOM], 'llvm_projects': [[], "LLVM projects to install", CUSTOM], + 'llvm_runtimes': [[], "LLVM runtimes to install", CUSTOM], }) # disable regular out-of-source build, too simplistic for Clang to work extra_vars['separate_build_dir'][0] = False @@ -129,27 +133,36 @@ def __init__(self, *args, **kwargs): self.log.warning(msg) print_warning(msg) - # keep compatibility between using llvm_projects vs using flags + if not self.cfg['llvm_runtimes']: + self.cfg['llvm_runtimes'] = [] + else: + for runtime in [r for r in self.cfg['llvm_runtimes'] if r not in KNOWN_LLVM_RUNTIMES]: + msg = "LLVM runtime %s included but not recognised, this runtime will NOT be sanity checked!" % runtime + self.log.warning(msg) + print_warning(msg) + + # keep compatibility between using llvm_projects/llvm_runtimes vs using flags if LooseVersion(self.version) >= LooseVersion('14'): self.cfg.update('llvm_projects', ['llvm', 'compiler-rt', 'clang', 'openmp'], allow_duplicate=False) if self.cfg['usepolly']: self.cfg.update('llvm_projects', 'polly', allow_duplicate=False) if self.cfg['build_lld']: - self.cfg.update('llvm_projects', ['lld', 'libunwind'], allow_duplicate=False) + self.cfg.update('llvm_projects', ['lld'], allow_duplicate=False) + self.cfg.update('llvm_runtimes', ['libunwind'], allow_duplicate=False) if self.cfg['build_lldb']: self.cfg.update('llvm_projects', 'lldb', allow_duplicate=False) if self.cfg['libcxx']: - self.cfg.update('llvm_projects', ['libcxx', 'libcxxabi'], allow_duplicate=False) + self.cfg.update('llvm_runtimes', ['libcxx', 'libcxxabi'], allow_duplicate=False) if self.cfg['build_extra_clang_tools']: self.cfg.update('llvm_projects', 'clang-tools-extra', allow_duplicate=False) # ensure libunwind is there if lld is there if 'lld' in self.cfg['llvm_projects']: - self.cfg.update('llvm_projects', 'libunwind', allow_duplicate=False) + self.cfg.update('llvm_runtimes', 'libunwind', allow_duplicate=False) # ensure libcxxabi is there if libcxx is there - if 'libcxx' in self.cfg['llvm_projects']: - self.cfg.update('llvm_projects', 'libcxxabi', allow_duplicate=False) + if 'libcxx' in self.cfg['llvm_runtimes']: + self.cfg.update('llvm_runtimes', 'libcxxabi', allow_duplicate=False) def check_readiness_step(self): """Fail early on RHEL 5.x and derivatives because of known bug in libc.""" @@ -193,6 +206,7 @@ def find_source_dir(globpatterns, targetdir): # if sources contain 'llvm-project*', we use the full tarball find_source_dir("../llvm-project-*", os.path.join(self.llvm_src_dir, "llvm-project-%s" % self.version)) self.cfg.update('configopts', '-DLLVM_ENABLE_PROJECTS="%s"' % ';'.join(self.cfg['llvm_projects'])) + self.cfg.update('configopts', '-DLLVM_ENABLE_RUNTIMES="%s"' % ';'.join(self.cfg['llvm_runtimes'])) else: # Layout for previous versions # llvm/ Unpack llvm-*.tar.gz here @@ -222,7 +236,7 @@ def find_source_dir(globpatterns, targetdir): if 'lldb' in self.cfg['llvm_projects']: find_source_dir('lldb-*', os.path.join(self.llvm_src_dir, 'tools', 'lldb')) - if 'libcxx' in self.cfg['llvm_projects']: + if 'libcxx' in self.cfg['llvm_runtimes']: find_source_dir('libcxx-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxx')) find_source_dir('libcxxabi-*', os.path.join(self.llvm_src_dir, 'projects', 'libcxxabi')) @@ -604,6 +618,32 @@ def sanity_check_step(self): """Custom sanity check for Clang.""" custom_commands = ['clang --help', 'clang++ --help', 'llvm-config --cxxflags'] shlib_ext = get_shared_lib_ext() + + # Detect OpenMP support for CPU architecture + arch = get_cpu_architecture() + # Check architecture explicitly since Clang uses potentially + # different names + if arch == X86_64: + arch = 'x86_64' + elif arch == POWER: + arch = 'ppc64' + elif arch == AARCH64: + arch = 'aarch64' + else: + print_warning("Unknown CPU architecture (%s) for OpenMP and runtime libraries check!" % arch) + + if LooseVersion(self.version) >= LooseVersion('14'): + glob_pattern = os.path.join(self.installdir, 'lib', '%s-*' % arch) + matches = glob.glob(glob_pattern) + if matches: + directory = os.path.basename(match[0]) + self.runtime_lib_path = os.path.join("lib", directory) + else: + print_warning("Could not find runtime library directory") + self.runtime_lib_path = "lib" + else: + self.runtime_lib_path = "lib" + custom_paths = { 'files': [ "bin/clang", "bin/clang++", "bin/llvm-ar", "bin/llvm-nm", "bin/llvm-as", "bin/opt", "bin/llvm-link", @@ -628,9 +668,14 @@ def sanity_check_step(self): if 'lldb' in self.cfg['llvm_projects']: custom_paths['files'].extend(["bin/lldb"]) - if 'libcxx' in self.cfg['llvm_projects']: - custom_paths['files'].extend(["lib/libc++.%s" % shlib_ext]) - custom_paths['files'].extend(["lib/libc++abi.%s" % shlib_ext]) + if 'libunwind' in self.cfg['llvm_runtimes']: + custom_paths['files'].extend([os.path.join(self.runtime_lib_path, "libunwind.%s" % shlib_ext)]) + + if 'libcxx' in self.cfg['llvm_runtimes']: + custom_paths['files'].extend([os.path.join(self.runtime_lib_path, "libc++.%s" % shlib_ext)]) + + if 'libcxxabi' in self.cfg['llvm_runtimes']: + custom_paths['files'].extend([os.path.join(self.runtime_lib_path, "libc++abi.%s" % shlib_ext)]) if 'flang' in self.cfg['llvm_projects'] and LooseVersion(self.version) >= LooseVersion('15'): flang_compiler = 'flang-new' @@ -640,18 +685,6 @@ def sanity_check_step(self): if LooseVersion(self.version) >= LooseVersion('3.8'): custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version]) - # Detect OpenMP support for CPU architecture - arch = get_cpu_architecture() - # Check architecture explicitly since Clang uses potentially - # different names - if arch == X86_64: - arch = 'x86_64' - elif arch == POWER: - arch = 'ppc64' - elif arch == AARCH64: - arch = 'aarch64' - else: - print_warning("Unknown CPU architecture (%s) for OpenMP library check!" % arch) custom_paths['files'].extend(["lib/libomptarget.%s" % shlib_ext, "lib/libomptarget.rtl.%s.%s" % (arch, shlib_ext)]) # If building for CUDA check that OpenMP target library was created @@ -708,3 +741,15 @@ def make_module_extra(self): if self.cfg['python_bindings']: txt += self.module_generator.prepend_paths('PYTHONPATH', os.path.join("lib", "python")) return txt + + def make_module_req_guess(self): + """ + Clang can find its own headers and libraries but the .so's need to be in LD_LIBRARY_PATH + """ + guesses = super(EB_Clang, self).make_module_req_guess() + guesses.update({ + 'CPATH': [], + 'LIBRARY_PATH': [], + 'LD_LIBRARY_PATH': ['lib', 'lib64', self.runtime_lib_path], + }) + return guesses From 0adb274a1f212acf2edf6bf926409d0923bcfa4c Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 21 Nov 2022 17:19:24 +0000 Subject: [PATCH 123/325] fix typo --- easybuild/easyblocks/c/clang.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 2caeeece2c..83133ad1f9 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -636,7 +636,7 @@ def sanity_check_step(self): glob_pattern = os.path.join(self.installdir, 'lib', '%s-*' % arch) matches = glob.glob(glob_pattern) if matches: - directory = os.path.basename(match[0]) + directory = os.path.basename(matches[0]) self.runtime_lib_path = os.path.join("lib", directory) else: print_warning("Could not find runtime library directory") From f5b77d384809faabf3ee27246383b343ae02edf1 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 21 Nov 2022 18:52:06 +0000 Subject: [PATCH 124/325] specify runtime_lib_path as class variable --- easybuild/easyblocks/c/clang.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 83133ad1f9..e0c1138269 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -124,6 +124,7 @@ def __init__(self, *args, **kwargs): self.llvm_obj_dir_stage2 = None self.llvm_obj_dir_stage3 = None self.make_parallel_opts = "" + self.runtime_lib_path = "lib" if not self.cfg['llvm_projects']: self.cfg['llvm_projects'] = [] From f58041ab637d4e2be7a42aec0ecb48411ecf19c0 Mon Sep 17 00:00:00 2001 From: ocaisa Date: Tue, 22 Nov 2022 11:26:27 +0100 Subject: [PATCH 125/325] Update list of available runtimes ...and some other tweaks --- easybuild/easyblocks/c/clang.py | 49 +++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index e0c1138269..f44bc681ec 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -74,12 +74,12 @@ # List of all supported CUDA toolkit versions supported by LLVM CUDA_TOOLKIT_SUPPORT = ['80', '90', '91', '92', '100', '101', '102', '110', '111', '112'] -# List of the known LLVM projects -KNOWN_LLVM_PROJECTS = ['llvm', 'compiler-rt', 'clang', 'openmp', 'polly', 'lld', 'lldb', - 'clang-tools-extra', 'flang'] +## When extending the lists below, make sure to add additional sanity checks +# List of the known LLVM projects +KNOWN_LLVM_PROJECTS = ['llvm', 'clang', 'polly', 'lld', 'lldb', 'clang-tools-extra', 'flang'] # List of the known LLVM runtimes -KNOWN_LLVM_RUNTIMES = ['libunwind', 'libcxx', 'libcxxabi'] +KNOWN_LLVM_RUNTIMES = ['compiler-rt', 'libunwind', 'libcxx', 'libcxxabi', 'openmp'] class EB_Clang(CMakeMake): @@ -128,23 +128,32 @@ def __init__(self, *args, **kwargs): if not self.cfg['llvm_projects']: self.cfg['llvm_projects'] = [] - else: - for project in [p for p in self.cfg['llvm_projects'] if p not in KNOWN_LLVM_PROJECTS]: - msg = "LLVM project %s included but not recognised, this project will NOT be sanity checked!" % project - self.log.warning(msg) - print_warning(msg) - if not self.cfg['llvm_runtimes']: self.cfg['llvm_runtimes'] = [] - else: - for runtime in [r for r in self.cfg['llvm_runtimes'] if r not in KNOWN_LLVM_RUNTIMES]: - msg = "LLVM runtime %s included but not recognised, this runtime will NOT be sanity checked!" % runtime - self.log.warning(msg) - print_warning(msg) + + # Be forgiving if someone places a runtime under projects since it is pretty new + for project in [p for p in self.cfg['llvm_projects'] if p in KNOWN_LLVM_RUNTIMES]: + msg = "LLVM project %s included but this should be a runtime, moving to runtime list!" % project + self.log.warning(msg) + self.cfg.update('llvm_runtimes', [project], allow_duplicate=False) + # No cleaner way to remove an element from the list + self.cfg['llvm_projects'] = [p for p in self.cfg['llvm_projects'] if p != project] + print_warning(msg) + + for project in [p for p in self.cfg['llvm_projects'] if p not in KNOWN_LLVM_PROJECTS]: + msg = "LLVM project %s included but not recognised, this project will NOT be sanity checked!" % project + self.log.warning(msg) + print_warning(msg) + + for runtime in [r for r in self.cfg['llvm_runtimes'] if r not in KNOWN_LLVM_RUNTIMES]: + msg = "LLVM runtime %s included but not recognised, this runtime will NOT be sanity checked!" % runtime + self.log.warning(msg) + print_warning(msg) # keep compatibility between using llvm_projects/llvm_runtimes vs using flags if LooseVersion(self.version) >= LooseVersion('14'): - self.cfg.update('llvm_projects', ['llvm', 'compiler-rt', 'clang', 'openmp'], allow_duplicate=False) + self.cfg.update('llvm_projects', ['llvm', 'clang'], allow_duplicate=False) + self.cfg.update('llvm_runtimes', ['compiler-rt', 'openmp'], allow_duplicate=False) if self.cfg['usepolly']: self.cfg.update('llvm_projects', 'polly', allow_duplicate=False) if self.cfg['build_lld']: @@ -371,7 +380,11 @@ def configure_step(self): self.cfg.update('configopts', "-DLLVM_ENABLE_ASSERTIONS=OFF") if 'polly' in self.cfg['llvm_projects']: - self.cfg.update('configopts', "-DLINK_POLLY_INTO_TOOLS=ON") + # Not exactly sure when this change took place, educated guess + if LooseVersion(self.version) >= LooseVersion('14'): + self.cfg.update('configopts', "-DLLVM_POLLY_LINK_INTO_TOOLS=ON") + else: + self.cfg.update('configopts', "-DLINK_POLLY_INTO_TOOLS=ON") # If Z3 is included as a dep, enable support in static analyzer (if enabled) if self.cfg["static_analyzer"] and LooseVersion(self.version) >= LooseVersion('9.0.0'): @@ -452,7 +465,7 @@ def disable_sanitizer_tests(self): regex_subs = [(r'.*add_subdirectory\(lit_tests\).*', '')] apply_regex_substitutions(cmakelists, regex_subs) - # There is a common part seperate for the specific saniters, we disable all the common tests + # There is a common part seperate for the specific sanitizers, we disable all the common tests cmakelists = os.path.join('projects', 'compiler-rt', 'lib', 'sanitizer_common', 'CMakeLists.txt') regex_subs = [(r'.*add_subdirectory\(tests\).*', '')] apply_regex_substitutions(cmakelists, regex_subs) From 31a7631ace4ecca11083f44c013986e386bb7605 Mon Sep 17 00:00:00 2001 From: ocaisa Date: Tue, 22 Nov 2022 11:37:30 +0100 Subject: [PATCH 126/325] Fix linting issues --- easybuild/easyblocks/c/clang.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index f44bc681ec..fe1f255c06 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -75,7 +75,7 @@ CUDA_TOOLKIT_SUPPORT = ['80', '90', '91', '92', '100', '101', '102', '110', '111', '112'] -## When extending the lists below, make sure to add additional sanity checks +# When extending the lists below, make sure to add additional sanity checks! # List of the known LLVM projects KNOWN_LLVM_PROJECTS = ['llvm', 'clang', 'polly', 'lld', 'lldb', 'clang-tools-extra', 'flang'] # List of the known LLVM runtimes @@ -135,7 +135,7 @@ def __init__(self, *args, **kwargs): for project in [p for p in self.cfg['llvm_projects'] if p in KNOWN_LLVM_RUNTIMES]: msg = "LLVM project %s included but this should be a runtime, moving to runtime list!" % project self.log.warning(msg) - self.cfg.update('llvm_runtimes', [project], allow_duplicate=False) + self.cfg.update('llvm_runtimes', [project], allow_duplicate=False) # No cleaner way to remove an element from the list self.cfg['llvm_projects'] = [p for p in self.cfg['llvm_projects'] if p != project] print_warning(msg) From 7488928ccce6a0d5c3d6b6483e2a420687eb1b2e Mon Sep 17 00:00:00 2001 From: ocaisa Date: Tue, 22 Nov 2022 16:50:51 +0100 Subject: [PATCH 127/325] Allow Clang easyblock to work with `--module-only` and Clang < v12 --- easybuild/easyblocks/c/clang.py | 83 +++++++++++++++++---------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index fe1f255c06..2feb653032 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -173,6 +173,42 @@ def __init__(self, *args, **kwargs): # ensure libcxxabi is there if libcxx is there if 'libcxx' in self.cfg['llvm_runtimes']: self.cfg.update('llvm_runtimes', 'libcxxabi', allow_duplicate=False) + + build_targets = self.cfg['build_targets'] + # define build_targets if not set + if build_targets is None: + arch = get_cpu_architecture() + try: + default_targets = DEFAULT_TARGETS_MAP[arch][:] + # If CUDA is included as a dep, add NVPTX as a target + if get_software_root("CUDA"): + default_targets += ["NVPTX"] + # For AMDGPU support we need ROCR-Runtime and + # ROCT-Thunk-Interface, however, since ROCT is a dependency of + # ROCR we only check for the ROCR-Runtime here + # https://openmp.llvm.org/SupportAndFAQ.html#q-how-to-build-an-openmp-amdgpu-offload-capable-compiler + if get_software_root("ROCR-Runtime"): + default_targets += ["AMDGPU"] + self.cfg['build_targets'] = build_targets = default_targets + self.log.debug("Using %s as default build targets for CPU/GPU architecture %s.", default_targets, arch) + except KeyError: + raise EasyBuildError("No default build targets defined for CPU architecture %s.", arch) + + # carry on with empty list from this point forward if no build targets are specified + if build_targets is None: + self.cfg['build_targets'] = build_targets = [] + + unknown_targets = [target for target in build_targets if target not in CLANG_TARGETS] + + if unknown_targets: + raise EasyBuildError("Some of the chosen build targets (%s) are not in %s.", + ', '.join(unknown_targets), ', '.join(CLANG_TARGETS)) + + if LooseVersion(self.version) < LooseVersion('3.4') and "R600" in build_targets: + raise EasyBuildError("Build target R600 not supported in < Clang-3.4") + + if LooseVersion(self.version) > LooseVersion('3.3') and "MBlaze" in build_targets: + raise EasyBuildError("Build target MBlaze is not supported anymore in > Clang-3.3") def check_readiness_step(self): """Fail early on RHEL 5.x and derivatives because of known bug in libc.""" @@ -270,45 +306,6 @@ def find_source_dir(globpatterns, targetdir): src['finalpath'] = new_path break - def prepare_step(self, *args, **kwargs): - """Prepare build environment.""" - super(EB_Clang, self).prepare_step(*args, **kwargs) - - build_targets = self.cfg['build_targets'] - if build_targets is None: - arch = get_cpu_architecture() - try: - default_targets = DEFAULT_TARGETS_MAP[arch][:] - # If CUDA is included as a dep, add NVPTX as a target - if get_software_root("CUDA"): - default_targets += ["NVPTX"] - # For AMDGPU support we need ROCR-Runtime and - # ROCT-Thunk-Interface, however, since ROCT is a dependency of - # ROCR we only check for the ROCR-Runtime here - # https://openmp.llvm.org/SupportAndFAQ.html#q-how-to-build-an-openmp-amdgpu-offload-capable-compiler - if get_software_root("ROCR-Runtime"): - default_targets += ["AMDGPU"] - self.cfg['build_targets'] = build_targets = default_targets - self.log.debug("Using %s as default build targets for CPU/GPU architecture %s.", default_targets, arch) - except KeyError: - raise EasyBuildError("No default build targets defined for CPU architecture %s.", arch) - - # carry on with empty list from this point forward if no build targets are specified - if build_targets is None: - self.cfg['build_targets'] = build_targets = [] - - unknown_targets = [target for target in build_targets if target not in CLANG_TARGETS] - - if unknown_targets: - raise EasyBuildError("Some of the chosen build targets (%s) are not in %s.", - ', '.join(unknown_targets), ', '.join(CLANG_TARGETS)) - - if LooseVersion(self.version) < LooseVersion('3.4') and "R600" in build_targets: - raise EasyBuildError("Build target R600 not supported in < Clang-3.4") - - if LooseVersion(self.version) > LooseVersion('3.3') and "MBlaze" in build_targets: - raise EasyBuildError("Build target MBlaze is not supported anymore in > Clang-3.3") - def configure_step(self): """Run CMake for stage 1 Clang.""" @@ -699,8 +696,12 @@ def sanity_check_step(self): if LooseVersion(self.version) >= LooseVersion('3.8'): custom_paths['files'].extend(["lib/libomp.%s" % shlib_ext, "lib/clang/%s/include/omp.h" % self.version]) - custom_paths['files'].extend(["lib/libomptarget.%s" % shlib_ext, - "lib/libomptarget.rtl.%s.%s" % (arch, shlib_ext)]) + if LooseVersion(self.version) >= LooseVersion('12'): + omp_target_libs = ["lib/libomptarget.%s" % shlib_ext, "lib/libomptarget.rtl.%s.%s" % (arch, shlib_ext)] + else: + omp_target_libs = ["lib/libomptarget.%s" % shlib_ext] + custom_paths['files'].extend(omp_target_libs) + # If building for CUDA check that OpenMP target library was created if 'NVPTX' in self.cfg['build_targets']: custom_paths['files'].append("lib/libomptarget.rtl.cuda.%s" % shlib_ext) From 23ca7c9ec5581a75d4e685b99cea9a6159b0b98f Mon Sep 17 00:00:00 2001 From: ocaisa Date: Tue, 22 Nov 2022 16:55:22 +0100 Subject: [PATCH 128/325] Fix lint --- easybuild/easyblocks/c/clang.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 2feb653032..0267bdfa19 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -173,7 +173,7 @@ def __init__(self, *args, **kwargs): # ensure libcxxabi is there if libcxx is there if 'libcxx' in self.cfg['llvm_runtimes']: self.cfg.update('llvm_runtimes', 'libcxxabi', allow_duplicate=False) - + build_targets = self.cfg['build_targets'] # define build_targets if not set if build_targets is None: @@ -701,7 +701,7 @@ def sanity_check_step(self): else: omp_target_libs = ["lib/libomptarget.%s" % shlib_ext] custom_paths['files'].extend(omp_target_libs) - + # If building for CUDA check that OpenMP target library was created if 'NVPTX' in self.cfg['build_targets']: custom_paths['files'].append("lib/libomptarget.rtl.cuda.%s" % shlib_ext) From 3b90adaa6b4313cbd06b503f0a250c3956790032 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 23 Nov 2022 15:30:19 +0100 Subject: [PATCH 129/325] update LLVM easyblock to put 'cmake' symlink in place so separate CMake modules requires for LLVM 15+ can be found --- easybuild/easyblocks/l/llvm.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/easybuild/easyblocks/l/llvm.py b/easybuild/easyblocks/l/llvm.py index 73703b99d3..36c376b4fd 100644 --- a/easybuild/easyblocks/l/llvm.py +++ b/easybuild/easyblocks/l/llvm.py @@ -26,11 +26,15 @@ EasyBuild support for building and installing LLVM, implemented as an easyblock @author: Simon Branford (University of Birmingham) +@author: Kenneth Hoste (Ghent University) """ +import os + from easybuild.easyblocks.clang import CLANG_TARGETS, DEFAULT_TARGETS_MAP from easybuild.easyblocks.generic.cmakemake import CMakeMake from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.filetools import change_dir, symlink from easybuild.tools.modules import get_software_root from easybuild.tools.systemtools import get_cpu_architecture from distutils.version import LooseVersion @@ -98,4 +102,15 @@ def configure_step(self): self.cfg.update('configopts', '-DLLVM_TARGETS_TO_BUILD="%s"' % ';'.join(build_targets)) + if LooseVersion(self.version) >= LooseVersion('15.0'): + # make sure that CMake modules are available in build directory, + # and if so make a 'cmake' symlink so LLVM can find them + cmake_modules_path = os.path.join(self.builddir, 'cmake-%s.src' % self.version) + if os.path.exists(cmake_modules_path): + cwd = change_dir(self.builddir) + symlink('cmake-%s.src' % self.version, 'cmake') + change_dir(cwd) + else: + raise EasyBuildError("Failed to find unpacked CMake modules directory at %s", cmake_modules_path) + super(EB_LLVM, self).configure_step() From 47314783a57dd0168f901688b2ca066bb2bc6968 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 24 Nov 2022 13:58:55 +0100 Subject: [PATCH 130/325] update docstring of JuliaBundle --- easybuild/easyblocks/generic/juliabundle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/juliabundle.py b/easybuild/easyblocks/generic/juliabundle.py index 61f5425021..9aa033420b 100644 --- a/easybuild/easyblocks/generic/juliabundle.py +++ b/easybuild/easyblocks/generic/juliabundle.py @@ -37,7 +37,8 @@ class JuliaBundle(Bundle): """ - Bundle of modules: only generate module files, nothing to build/install + Bundle of JuliaPackages: install Julia packages as extensions in a bundle + Defines custom sanity checks and module environment """ @staticmethod From ccadb144f5871e6fb4bad012f64f291b1695a052 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 24 Nov 2022 14:06:34 +0100 Subject: [PATCH 131/325] update doctring of PythonBundle --- easybuild/easyblocks/generic/pythonbundle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/pythonbundle.py b/easybuild/easyblocks/generic/pythonbundle.py index ba5a317473..732f44eb79 100644 --- a/easybuild/easyblocks/generic/pythonbundle.py +++ b/easybuild/easyblocks/generic/pythonbundle.py @@ -41,7 +41,8 @@ class PythonBundle(Bundle): """ - Bundle of modules: only generate module files, nothing to build/install + Bundle of PythonPackages: install Python packages as extensions in a bundle + Defines custom sanity checks and module environment """ @staticmethod From 57288b65bd474e7013737aa32d0ad6f6b924d925 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 24 Nov 2022 22:30:40 +0100 Subject: [PATCH 132/325] don't load fake module to run 'pip check', just check it is loaded, since module is already loaded at start of PythonPackage.sanity_check_step --- easybuild/easyblocks/generic/pythonpackage.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index 9cdbbd9e70..b73eede999 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -860,9 +860,14 @@ def sanity_check_step(self, *args, **kwargs): if not self.is_extension: # for stand-alone Python package installations (not part of a bundle of extensions), - # we need to load the fake module file, otherwise the Python package being installed - # is not "in view", and we will overlook missing dependencies... - fake_mod_data = self.load_fake_module(purge=True) + # the (fake or real) module file must be loaded at this point, + # otherwise the Python package being installed is not "in view", + # and we will overlook missing dependencies... + loaded_modules = [x['mod_name'] for x in self.modules_tool.list()] + if self.short_mod_name not in loaded_modules: + self.log.debug("Currently loaded modules: %s", loaded_modules) + raise EasyBuildError("%s module is not loaded, this should never happen...", + self.short_mod_name) pip_check_errors = [] @@ -908,9 +913,6 @@ def sanity_check_step(self, *args, **kwargs): ) % (faulty_version, '\n'.join(faulty_pkg_names)) pip_check_errors.append(msg) - if not self.is_extension: - self.clean_up_fake_module(fake_mod_data) - if pip_check_errors: raise EasyBuildError('\n'.join(pip_check_errors)) else: From bec22a6c404fb791230f2338d47dc42091d4fa1f Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 25 Nov 2022 13:24:26 +0100 Subject: [PATCH 133/325] Fix counting of failures in PyTorch tests --- easybuild/easyblocks/p/pytorch.py | 73 ++++++++++++++++--------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index e72a701351..32a295c02c 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -273,23 +273,12 @@ def test_step(self): for hit in ran_tests_hits: test_cnt += int(hit) - # Get matches to create clear summary report, greps for patterns like: - # FAILED (errors=10, skipped=190, expected failures=6) - # test_fx failed! - regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: E501 - summary_matches = re.findall(regex, tests_out, re.M) - - # Get matches to create clear summary report, greps for patterns like: - # ===================== 2 failed, 128 passed, 2 skipped, 2 warnings in 3.43s ===================== - regex = r"^=+ (?P.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" - summary_matches_pattern2 = re.findall(regex, tests_out, re.M) - - # Count failures and errors def get_count_for_pattern(regex, text): - match = re.findall(regex, text, re.M) - if len(match) == 0: - return 0 - elif len(match) == 1: + """Match the regexp containing a single group and return the integer value of the matched group. + Return zero if no or more than 1 match was found and warn for the latter case + """ + match = re.findall(regex, text) + if len(match) == 1: return int(match[0]) elif len(match) > 1: # Shouldn't happen, but means something went wrong with the regular expressions. @@ -297,22 +286,41 @@ def get_count_for_pattern(regex, text): warn_msg = "Error in counting the number of test failures in the output of the PyTorch test suite.\n" warn_msg += "Please check the EasyBuild log to verify the number of failures (if any) was acceptable." print_warning(warn_msg) + return 0 + # Create clear summary report + failure_report = "" failure_cnt = 0 error_cnt = 0 - # Loop over first pattern to count failures/errors: - for summary in summary_matches: - failures = get_count_for_pattern(r"^.*(?[0-9]+).*$", summary[1]) - failure_cnt += failures - errs = get_count_for_pattern(r"^.*errors=(?P[0-9]+).*$", summary[1]) - error_cnt += errs - - # Loop over the second pattern to count failures/errors - for summary in summary_matches_pattern2: - failures = get_count_for_pattern(r"^.*[^0-9](?P[0-9]+) failed.*$", summary[0]) - failure_cnt += failures - errs = get_count_for_pattern(r"^.*[^0-9](?P[0-9]+) error.*$", summary[0]) - error_cnt += errs + + # Grep for patterns like: + # Ran 219 tests in 67.325s + # + # FAILED (errors=10, skipped=190, expected failures=6) + # test_fx failed! + regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: E501 + + for summary in re.findall(regex, tests_out, re.M): + # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' + failure_summary = summary[1] + failure_report += "{test_suite} ({total} total tests, {failure_summary})\n".format( + test_suite=summary[2], total=summary[0], failure_summary=failure_summary + ) + failure_cnt += get_count_for_pattern(r"(?.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" + + for summary in re.findall(regex, tests_out, re.M): + # E.g. '2 failed, 128 passed, 2 skipped, 2 warnings' + failure_summary = summary[0] + failure_report += "{test_suite} ({failure_summary})\n".format( + test_suite=summary[1], failure_summary=failure_summary + ) + failure_cnt = get_count_for_pattern(r"([0-9]+) failed", failure_summary) + error_cnt = get_count_for_pattern(r"([0-9]+) error", failure_summary) # Calculate total number of unsuccesful tests failed_test_cnt = failure_cnt + error_cnt @@ -325,12 +333,7 @@ def get_count_for_pattern(regex, text): msg = "%d test %s, %d test %s (out of %d):\n" % ( failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt ) - for summary in summary_matches_pattern2: - msg += "{test_suite} ({failure_summary})\n".format(test_suite=summary[1], failure_summary=summary[0]) - for summary in summary_matches: - msg += "{test_suite} ({total} total tests, {failure_summary})\n".format( - test_suite=summary[2], total=summary[0], failure_summary=summary[1] - ) + msg += failure_summary if max_failed_tests == 0: raise EasyBuildError(msg) From 4e8a97e62ea0be231665df76454a256c61d50534 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 25 Nov 2022 13:32:51 +0100 Subject: [PATCH 134/325] Also handle tests terminating by a signal --- easybuild/easyblocks/p/pytorch.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 32a295c02c..b1c4577404 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -298,7 +298,10 @@ def get_count_for_pattern(regex, text): # # FAILED (errors=10, skipped=190, expected failures=6) # test_fx failed! - regex = r"^Ran (?P[0-9]+) tests.*$\n\nFAILED \((?P.*)\)$\n(?:^(?:(?!failed!).)*$\n)*(?P.*) failed!$" # noqa: E501 + regex = (r"^Ran (?P[0-9]+) tests.*$\n\n" + r"FAILED \((?P.*)\)$\n" + r"(?:^(?:(?!failed!).)*$\n)*" + r"(?P.*) failed!(?: Received signal: \w+)?\s*$") for summary in re.findall(regex, tests_out, re.M): # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' From b0e63fea20468befdbfac146cf07d3b1993def36 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Sat, 26 Nov 2022 11:19:48 +0100 Subject: [PATCH 135/325] Add (not overwrite) failure/error counts Co-authored-by: Simon Branford <4967+branfosj@users.noreply.github.com> --- easybuild/easyblocks/p/pytorch.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index b1c4577404..fa28329351 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -322,8 +322,8 @@ def get_count_for_pattern(regex, text): failure_report += "{test_suite} ({failure_summary})\n".format( test_suite=summary[1], failure_summary=failure_summary ) - failure_cnt = get_count_for_pattern(r"([0-9]+) failed", failure_summary) - error_cnt = get_count_for_pattern(r"([0-9]+) error", failure_summary) + failure_cnt += get_count_for_pattern(r"([0-9]+) failed", failure_summary) + error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) # Calculate total number of unsuccesful tests failed_test_cnt = failure_cnt + error_cnt From 3398051e0022851231c1fcd675ade7a694b1beca Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 28 Nov 2022 10:52:43 +0100 Subject: [PATCH 136/325] Fix failure_report and use finditer --- easybuild/easyblocks/p/pytorch.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index fa28329351..f991d36aa8 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -303,11 +303,12 @@ def get_count_for_pattern(regex, text): r"(?:^(?:(?!failed!).)*$\n)*" r"(?P.*) failed!(?: Received signal: \w+)?\s*$") - for summary in re.findall(regex, tests_out, re.M): + for m in re.finditer(regex, tests_out, re.M): # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' - failure_summary = summary[1] + failure_summary = m['failure_summary'] + total, test_suite = m.group('test_cnt', 'failed_test_suite_name') failure_report += "{test_suite} ({total} total tests, {failure_summary})\n".format( - test_suite=summary[2], total=summary[0], failure_summary=failure_summary + test_suite=test_suite, total=total, failure_summary=failure_summary ) failure_cnt += get_count_for_pattern(r"(?.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" - for summary in re.findall(regex, tests_out, re.M): + for m in re.finditer(regex, tests_out, re.M): # E.g. '2 failed, 128 passed, 2 skipped, 2 warnings' - failure_summary = summary[0] + failure_summary = m['failure_summary'] + test_suite = m['failed_test_suite_name'] failure_report += "{test_suite} ({failure_summary})\n".format( - test_suite=summary[1], failure_summary=failure_summary + test_suite=test_suite, failure_summary=failure_summary ) failure_cnt += get_count_for_pattern(r"([0-9]+) failed", failure_summary) error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) @@ -336,7 +338,7 @@ def get_count_for_pattern(regex, text): msg = "%d test %s, %d test %s (out of %d):\n" % ( failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt ) - msg += failure_summary + msg += failure_report if max_failed_tests == 0: raise EasyBuildError(msg) From 55bdf743cd811330ff68c626737a675473581fe3 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 28 Nov 2022 12:08:28 +0100 Subject: [PATCH 137/325] Include also failed tests due to syntax errors etc. --- easybuild/easyblocks/p/pytorch.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index f991d36aa8..40f4164b46 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -40,6 +40,7 @@ from easybuild.tools.filetools import apply_regex_substitutions, mkdir, symlink from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.systemtools import POWER, get_cpu_architecture +from easybuild.tools.utilities import nub class EB_PyTorch(PythonPackage): @@ -292,6 +293,7 @@ def get_count_for_pattern(regex, text): failure_report = "" failure_cnt = 0 error_cnt = 0 + failed_test_suites = [] # Grep for patterns like: # Ran 219 tests in 67.325s @@ -312,6 +314,7 @@ def get_count_for_pattern(regex, text): ) failure_cnt += get_count_for_pattern(r"(?.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M) + ) + if failed_test_suites_2 != failed_test_suites: + failure_report = '\n'.join('* %s' % t for t in sorted(failed_test_suites_2)) + failure_report if failed_test_cnt > 0: max_failed_tests = self.cfg['max_failed_tests'] @@ -340,7 +352,8 @@ def get_count_for_pattern(regex, text): ) msg += failure_report - if max_failed_tests == 0: + # If no tests are supposed to fail or some failed for which we were not able to count errors fail now + if max_failed_tests == 0 or failed_test_suites_2 != failed_test_suites: raise EasyBuildError(msg) else: msg += '\n\n' + ' '.join([ @@ -360,6 +373,8 @@ def get_count_for_pattern(regex, text): if failed_test_cnt > max_failed_tests: raise EasyBuildError("Too many failed tests (%d), maximum allowed is %d", failed_test_cnt, max_failed_tests) + elif failure_report: + raise EasyBuildError("Test command had non-zero exit code (%s)!\n%s", tests_ec, failure_report) elif tests_ec: raise EasyBuildError("Test command had non-zero exit code (%s), but no failed tests found?!", tests_ec) From 59bce86c80992a695ae786500df612cfb3b6085f Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 28 Nov 2022 14:24:11 +0100 Subject: [PATCH 138/325] Cancel old GithubAction runs --- .github/workflows/linting.yml | 5 +++++ .github/workflows/unit_tests.yml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 6346d95977..d7482ec3f7 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,5 +1,10 @@ name: Static Analysis on: [push, pull_request] + +concurrency: + group: ${{format('{0}:{1}:{2}', github.repository, github.ref, github.workflow)}} + cancel-in-progress: true + jobs: python-linting: runs-on: ubuntu-20.04 diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 551c78bafb..6a28ae97e6 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -1,5 +1,10 @@ name: easyblocks unit tests on: [push, pull_request] + +concurrency: + group: ${{format('{0}:{1}:{2}', github.repository, github.ref, github.workflow)}} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-20.04 From c6daaef924bcbe87d42d033f8babf35ffade9f21 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 28 Nov 2022 15:48:52 +0100 Subject: [PATCH 139/325] Improve error message --- easybuild/easyblocks/p/pytorch.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 40f4164b46..52e1b52e98 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -267,12 +267,7 @@ def test_step(self): 'excluded_tests': ' '.join(excluded_tests) }) - (tests_out, tests_ec) = super(EB_PyTorch, self).test_step(return_output_ec=True) - - ran_tests_hits = re.findall(r"^Ran (?P[0-9]+) tests in", tests_out, re.M) - test_cnt = 0 - for hit in ran_tests_hits: - test_cnt += int(hit) + tests_out, tests_ec = super(EB_PyTorch, self).test_step(return_output_ec=True) def get_count_for_pattern(regex, text): """Match the regexp containing a single group and return the integer value of the matched group. @@ -331,29 +326,36 @@ def get_count_for_pattern(regex, text): error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) failed_test_suites.append(test_suite) - # Calculate total number of unsuccesful tests - failed_test_cnt = failure_cnt + error_cnt # Make the names unique failed_test_suites = nub(failed_test_suites) # Gather all failed tests suites in case we missed any (e.g. when it exited due to syntax errors) - failed_test_suites_2 = nub( + all_failed_test_suites = nub( re.findall(r"^(?P.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M) ) - if failed_test_suites_2 != failed_test_suites: - failure_report = '\n'.join('* %s' % t for t in sorted(failed_test_suites_2)) + failure_report + # If we missed any test suites prepend a list of all failed test suites + if failed_test_suites != all_failed_test_suites: + failure_report_save = failure_report + failure_report = 'Failed tests (suites/files):\n' + failure_report += '\n'.join('* %s' % t for t in sorted(all_failed_test_suites)) + if failure_report_save: + failure_report += '\n' + failure_report_save + + # Calculate total number of unsuccesful and total tests + failed_test_cnt = failure_cnt + error_cnt + test_cnt = sum(int(hit) for hit in re.findall(r"^Ran (?P[0-9]+) tests in", tests_out, re.M)) if failed_test_cnt > 0: max_failed_tests = self.cfg['max_failed_tests'] - failure_or_failures = 'failures' if failure_cnt > 1 else 'failure' - error_or_errors = 'errors' if error_cnt > 1 else 'error' + failure_or_failures = 'failure' if failure_cnt == 1 else 'failures' + error_or_errors = 'error' if error_cnt == 1 else 'errors' msg = "%d test %s, %d test %s (out of %d):\n" % ( failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt ) msg += failure_report # If no tests are supposed to fail or some failed for which we were not able to count errors fail now - if max_failed_tests == 0 or failed_test_suites_2 != failed_test_suites: + if max_failed_tests == 0 or failed_test_suites != all_failed_test_suites: raise EasyBuildError(msg) else: msg += '\n\n' + ' '.join([ From 8287ad75eed960ccb978d94a3e053c6a4a3318af Mon Sep 17 00:00:00 2001 From: Miguel Dias Costa Date: Tue, 29 Nov 2022 08:07:18 +0800 Subject: [PATCH 140/325] set TEMPDIRPATH for testsuite in the BerkeleyGW easyblock, to avoid polluting /tmp --- easybuild/easyblocks/b/berkeleygw.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/b/berkeleygw.py b/easybuild/easyblocks/b/berkeleygw.py index 2a2fbfaf59..386d9f83f3 100644 --- a/easybuild/easyblocks/b/berkeleygw.py +++ b/easybuild/easyblocks/b/berkeleygw.py @@ -178,6 +178,7 @@ def test_step(self): if self.cfg['runtest'] is not False: self.cfg['runtest'] = 'check' setvar('OMP_NUM_THREADS', '4') + setvar('TEMPDIRPATH', os.path.join(self.builddir, 'tmp')) super(EB_BerkeleyGW, self).test_step() def sanity_check_step(self): From fa23f2af374a1891b1d9cd610e1d89e57c8a56ec Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Tue, 29 Nov 2022 10:14:09 +0100 Subject: [PATCH 141/325] Compare sorted list of test suites --- easybuild/easyblocks/p/pytorch.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 52e1b52e98..ecdbee711e 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -40,7 +40,6 @@ from easybuild.tools.filetools import apply_regex_substitutions, mkdir, symlink from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.systemtools import POWER, get_cpu_architecture -from easybuild.tools.utilities import nub class EB_PyTorch(PythonPackage): @@ -326,17 +325,18 @@ def get_count_for_pattern(regex, text): error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) failed_test_suites.append(test_suite) - # Make the names unique - failed_test_suites = nub(failed_test_suites) + # Make the names unique and sorted + failed_test_suites = sorted(set(failed_test_suites)) # Gather all failed tests suites in case we missed any (e.g. when it exited due to syntax errors) - all_failed_test_suites = nub( + # Also unique and sorted to be able to compare the lists below + all_failed_test_suites = sorted(set( re.findall(r"^(?P.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M) - ) + )) # If we missed any test suites prepend a list of all failed test suites if failed_test_suites != all_failed_test_suites: failure_report_save = failure_report failure_report = 'Failed tests (suites/files):\n' - failure_report += '\n'.join('* %s' % t for t in sorted(all_failed_test_suites)) + failure_report += '\n'.join('* %s' % t for t in all_failed_test_suites) if failure_report_save: failure_report += '\n' + failure_report_save From e7839eac201934ea0947c602c1dfd20427977655 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Wed, 30 Nov 2022 09:54:35 +0100 Subject: [PATCH 142/325] Fix Python 2.7 compatibility of PyTorch easyblock --- easybuild/easyblocks/p/pytorch.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index ecdbee711e..bc1cf90e12 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -301,7 +301,7 @@ def get_count_for_pattern(regex, text): for m in re.finditer(regex, tests_out, re.M): # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' - failure_summary = m['failure_summary'] + failure_summary = m.group('failure_summary') total, test_suite = m.group('test_cnt', 'failed_test_suite_name') failure_report += "{test_suite} ({total} total tests, {failure_summary})\n".format( test_suite=test_suite, total=total, failure_summary=failure_summary @@ -316,8 +316,8 @@ def get_count_for_pattern(regex, text): for m in re.finditer(regex, tests_out, re.M): # E.g. '2 failed, 128 passed, 2 skipped, 2 warnings' - failure_summary = m['failure_summary'] - test_suite = m['failed_test_suite_name'] + failure_summary = m.group('failure_summary') + test_suite = m.group('failed_test_suite_name') failure_report += "{test_suite} ({failure_summary})\n".format( test_suite=test_suite, failure_summary=failure_summary ) From 0d7b2322f333cd59759d7a68db70eb7be8b29e9b Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 2 Dec 2022 12:42:24 +0100 Subject: [PATCH 143/325] Make TensorFlow builds easier to debug --- easybuild/easyblocks/t/tensorflow.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 99fa5e6783..8580cda991 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -430,10 +430,14 @@ def get_system_libs(self): def setup_build_dirs(self): """Setup temporary build directories""" + # This is either the builddir (for standalone builds) or the extension sub folder when TF is an extension + # Either way this folder only contains the folder with the sources and hence we can use fixed names + # for the subfolders + parent_dir = os.path.dirname(self.start_dir) # Path where Bazel will store its output, build artefacts etc. - self.output_user_root_dir = tempfile.mkdtemp(suffix='-bazel-tf', dir=self.builddir) + self.output_user_root_dir = os.path.join(parent_dir, 'bazel-root') # Folder where wrapper binaries can be placed, where required. TODO: Replace by --action_env cmds - self.wrapper_dir = tempfile.mkdtemp(suffix='-wrapper_bin', dir=self.builddir) + self.wrapper_dir = os.path.join(parent_dir, 'wrapper_bin') def configure_step(self): """Custom configuration procedure for TensorFlow.""" From a49dc7d3a0cecef689485c78dfe670909b08aaaf Mon Sep 17 00:00:00 2001 From: jfgrimm Date: Thu, 8 Dec 2022 17:14:20 +0000 Subject: [PATCH 144/325] add option to skip addition of prefix to configure command in configuremake --- easybuild/easyblocks/generic/configuremake.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/configuremake.py b/easybuild/easyblocks/generic/configuremake.py index 3771f61b64..2039a0b011 100644 --- a/easybuild/easyblocks/generic/configuremake.py +++ b/easybuild/easyblocks/generic/configuremake.py @@ -184,6 +184,7 @@ def extra_options(extra_vars=None): " False implies to leave it up to the configure script)", CUSTOM], 'configure_cmd': [DEFAULT_CONFIGURE_CMD, "Configure command to use", CUSTOM], 'configure_cmd_prefix': ['', "Prefix to be glued before ./configure", CUSTOM], + 'configure_no_prefix': [False, "Avoid adding a prefix to the configure command", CUSTOM], 'host_type': [None, "Value to provide to --host option of configure script, e.g., x86_64-pc-linux-gnu " "(determined by config.guess shipped with EasyBuild if None," " False implies to leave it up to the configure script)", CUSTOM], @@ -303,11 +304,16 @@ def configure_step(self, cmd_prefix=''): if host_type: build_and_host_options.append(' --host=' + host_type) + if self.cfg.get('configure_no_prefix'): + configure_prefix = '' + else: + configure_prefix = prefix_opt + self.installdir + cmd = ' '.join( [ self.cfg['preconfigopts'], configure_command, - prefix_opt + self.installdir, + configure_prefix, ] + build_and_host_options + [self.cfg['configopts']] ) From 6005d37a1ed2b130a18b5bd525df810f19ba3bbd Mon Sep 17 00:00:00 2001 From: jfgrimm Date: Thu, 8 Dec 2022 19:18:29 +0000 Subject: [PATCH 145/325] rename configure_no_prefix to configure_without_installdir clarify configure_without_installdir description print warning if prefix_opt is specified with configure_without_installdir --- easybuild/easyblocks/generic/configuremake.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/generic/configuremake.py b/easybuild/easyblocks/generic/configuremake.py index 2039a0b011..548332190d 100644 --- a/easybuild/easyblocks/generic/configuremake.py +++ b/easybuild/easyblocks/generic/configuremake.py @@ -184,7 +184,8 @@ def extra_options(extra_vars=None): " False implies to leave it up to the configure script)", CUSTOM], 'configure_cmd': [DEFAULT_CONFIGURE_CMD, "Configure command to use", CUSTOM], 'configure_cmd_prefix': ['', "Prefix to be glued before ./configure", CUSTOM], - 'configure_no_prefix': [False, "Avoid adding a prefix to the configure command", CUSTOM], + 'configure_without_installdir': [False, "Avoid passing an install directory to the configure command " + "(such as via --prefix)", CUSTOM], 'host_type': [None, "Value to provide to --host option of configure script, e.g., x86_64-pc-linux-gnu " "(determined by config.guess shipped with EasyBuild if None," " False implies to leave it up to the configure script)", CUSTOM], @@ -304,8 +305,11 @@ def configure_step(self, cmd_prefix=''): if host_type: build_and_host_options.append(' --host=' + host_type) - if self.cfg.get('configure_no_prefix'): + if self.cfg.get('configure_without_installdir'): configure_prefix = '' + if self.cfg.get('prefix_opt'): + print_warning("Specified prefix_opt '%s' is ignored due to use of configure_without_installdir", + prefix_opt) else: configure_prefix = prefix_opt + self.installdir From 35828dab808ec022b83702ea61ae10239de45d6e Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sun, 11 Dec 2022 11:16:58 +0100 Subject: [PATCH 146/325] also run unit tests with Python 3.11 --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 6a28ae97e6..c6b163cac3 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10'] + python: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11'] modules_tool: [Lmod-6.6.3, Lmod-7.8.22, Lmod-8.1.14, modules-tcl-1.147, modules-3.2.10, modules-4.1.4] module_syntax: [Lua, Tcl] # exclude some configuration for non-Lmod modules tool: From 353cb0c756e6e1e9fd1ac92a0158899883cc348e Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sun, 11 Dec 2022 11:17:37 +0100 Subject: [PATCH 147/325] add Python 3.10 + 3.11 to classifiers in setup.py --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 768d47e80f..e3c9030cc8 100644 --- a/setup.py +++ b/setup.py @@ -79,6 +79,8 @@ def read(fname): "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Software Development :: Build Tools", ], platforms="Linux", From 01d314bb860079465a8db6b4ecea83b50f49051c Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Tue, 13 Dec 2022 15:02:52 +0100 Subject: [PATCH 148/325] update qscintilla.py to be compatible with EB install of PyQt5 >= 5.15 --- easybuild/easyblocks/q/qscintilla.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/qscintilla.py b/easybuild/easyblocks/q/qscintilla.py index 3701fee992..c7b993d840 100644 --- a/easybuild/easyblocks/q/qscintilla.py +++ b/easybuild/easyblocks/q/qscintilla.py @@ -124,7 +124,10 @@ def install_step(self): 'site-packages', 'sip', self.pyqt_pkg_name), False) # fall back to a single sipdir if not pyqt_sipdir: - pyqt_sipdir = os.path.join(self.pyqt_root, 'share', 'sip', self.pyqt_pkg_name) + if LooseVersion(get_software_version(self.pyqt_pkg_name)) >= LooseVersion('5.15'): + pyqt_sipdir = os.path.join(self.pyqt_root, 'share', 'sip') + else: + pyqt_sipdir = os.path.join(self.pyqt_root, 'share', 'sip', self.pyqt_pkg_name) cfgopts = [ '--destdir %s' % os.path.join(self.installdir, pylibdir), From 94e770f44b6df3c386493674316f8b3d34168447 Mon Sep 17 00:00:00 2001 From: Sebastian Achilles Date: Tue, 20 Dec 2022 13:06:26 +0100 Subject: [PATCH 149/325] add UCC to known_dependencies in OpenMPI EasyBlock --- easybuild/easyblocks/o/openmpi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/o/openmpi.py b/easybuild/easyblocks/o/openmpi.py index c756d16819..a017cc3171 100644 --- a/easybuild/easyblocks/o/openmpi.py +++ b/easybuild/easyblocks/o/openmpi.py @@ -69,7 +69,7 @@ def config_opt_used(key, enable_opt=False): self.cfg.update('configopts', '--enable-%s' % key) # List of EasyBuild dependencies for which OMPI has known options - known_dependencies = ('CUDA', 'hwloc', 'libevent', 'libfabric', 'PMIx', 'UCX') + known_dependencies = ('CUDA', 'hwloc', 'libevent', 'libfabric', 'PMIx', 'UCX', 'UCC') # Value to use for `--with-=` if the dependency is not specified in the easyconfig # No entry is interpreted as no option added at all # This is to make builds reproducible even when the system libraries are changed and avoids failures From eee02d2c69967ba119e6c2ced8e9cfc0671d9849 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 3 Jan 2023 20:07:21 +0100 Subject: [PATCH 150/325] tweak docstring in some generic easyblocks so it renders nicely in auto-generated documentation --- .../easyblocks/generic/configuremakepythonpackage.py | 9 +++++---- easybuild/easyblocks/generic/intelbase.py | 1 + easybuild/easyblocks/generic/rpm.py | 1 + easybuild/easyblocks/generic/tarball.py | 3 +-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/generic/configuremakepythonpackage.py b/easybuild/easyblocks/generic/configuremakepythonpackage.py index 8c5dc9f983..9cfd40d829 100644 --- a/easybuild/easyblocks/generic/configuremakepythonpackage.py +++ b/easybuild/easyblocks/generic/configuremakepythonpackage.py @@ -36,9 +36,10 @@ class ConfigureMakePythonPackage(ConfigureMake, PythonPackage): """ - Build a Python package and module with 'python configure/make/make install'. + Build a Python package and module with ``python configure``/``make``/``make install``. Implemented by using: + - a custom implementation of configure_step - using the build_step and install_step from ConfigureMake - using the sanity_check_step and make_module_extra from PythonPackage @@ -54,13 +55,13 @@ def __init__(self, *args, **kwargs): PythonPackage.__init__(self, *args, **kwargs) def configure_step(self, *args, **kwargs): - """Configure build using 'python configure'.""" + """Configure build using ``python configure``.""" PythonPackage.configure_step(self, *args, **kwargs) cmd = ' '.join([self.cfg['preconfigopts'], self.python_cmd, self.cfg['configopts']]) run_cmd(cmd, log_all=True) def build_step(self, *args, **kwargs): - """Build Python package with 'make'.""" + """Build Python package with ``make``.""" return ConfigureMake.build_step(self, *args, **kwargs) def test_step(self, *args, **kwargs): @@ -68,7 +69,7 @@ def test_step(self, *args, **kwargs): PythonPackage.test_step(self, *args, **kwargs) def install_step(self, *args, **kargs): - """Install with 'make install'.""" + """Install with ``make install``.""" return ConfigureMake.install_step(self, *args, **kargs) def sanity_check_step(self, *args, **kwargs): diff --git a/easybuild/easyblocks/generic/intelbase.py b/easybuild/easyblocks/generic/intelbase.py index 2913525749..8ecb656205 100644 --- a/easybuild/easyblocks/generic/intelbase.py +++ b/easybuild/easyblocks/generic/intelbase.py @@ -91,6 +91,7 @@ class IntelBase(EasyBlock): """ Base class for Intel software + - no configure/make : binary release - add license_file variable """ diff --git a/easybuild/easyblocks/generic/rpm.py b/easybuild/easyblocks/generic/rpm.py index e127977c44..3d10b8ab42 100644 --- a/easybuild/easyblocks/generic/rpm.py +++ b/easybuild/easyblocks/generic/rpm.py @@ -94,6 +94,7 @@ def rebuild_rpm(rpm_path, targetdir): class Rpm(Binary): """ Support for installing RPM files. + - sources is a list of rpms - installation is with --nodeps (so the sources list has to be complete) """ diff --git a/easybuild/easyblocks/generic/tarball.py b/easybuild/easyblocks/generic/tarball.py index 09a55a84eb..47514f4e84 100644 --- a/easybuild/easyblocks/generic/tarball.py +++ b/easybuild/easyblocks/generic/tarball.py @@ -46,8 +46,7 @@ class Tarball(ExtensionEasyBlock): """ - Precompiled software supplied as a tarball: - - will unpack binary and copy it to the install dir + Precompiled software supplied as a tarball: will unpack binary and copy it to the install dir """ @staticmethod From 91ff295486150af9532c55250569d4df37481eb7 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 5 Jan 2023 09:13:07 +0100 Subject: [PATCH 151/325] update copyright lines for 2023 --- easybuild/__init__.py | 2 +- easybuild/easyblocks/__init__.py | 2 +- easybuild/easyblocks/a/abaqus.py | 2 +- easybuild/easyblocks/a/acml.py | 2 +- easybuild/easyblocks/a/adf.py | 2 +- easybuild/easyblocks/a/advisor.py | 2 +- easybuild/easyblocks/a/aladin.py | 2 +- easybuild/easyblocks/a/allinea.py | 2 +- easybuild/easyblocks/a/amber.py | 4 ++-- easybuild/easyblocks/a/anaconda.py | 2 +- easybuild/easyblocks/a/ansys.py | 2 +- easybuild/easyblocks/a/ant.py | 2 +- easybuild/easyblocks/a/aocc.py | 2 +- easybuild/easyblocks/a/aomp.py | 2 +- easybuild/easyblocks/a/arb.py | 2 +- easybuild/easyblocks/a/armadillo.py | 2 +- easybuild/easyblocks/a/atlas.py | 2 +- easybuild/easyblocks/b/bamtools.py | 2 +- easybuild/easyblocks/b/bazel.py | 2 +- easybuild/easyblocks/b/berkeleygw.py | 2 +- easybuild/easyblocks/b/binutils.py | 2 +- easybuild/easyblocks/b/bioconductor.py | 2 +- easybuild/easyblocks/b/bisearch.py | 2 +- easybuild/easyblocks/b/blacs.py | 2 +- easybuild/easyblocks/b/blat.py | 2 +- easybuild/easyblocks/b/blender.py | 2 +- easybuild/easyblocks/b/boost.py | 2 +- easybuild/easyblocks/b/bowtie.py | 2 +- easybuild/easyblocks/b/bowtie2.py | 2 +- easybuild/easyblocks/b/bwa.py | 2 +- easybuild/easyblocks/b/bwise.py | 2 +- easybuild/easyblocks/b/bzip2.py | 2 +- easybuild/easyblocks/c/cblas.py | 2 +- easybuild/easyblocks/c/cfdemcoupling.py | 2 +- easybuild/easyblocks/c/cgal.py | 2 +- easybuild/easyblocks/c/chapel.py | 2 +- easybuild/easyblocks/c/charmm.py | 2 +- easybuild/easyblocks/c/clang.py | 4 ++-- easybuild/easyblocks/c/clang_aomp.py | 2 +- easybuild/easyblocks/c/cmake.py | 2 +- easybuild/easyblocks/c/code_server.py | 2 +- easybuild/easyblocks/c/comsol.py | 2 +- easybuild/easyblocks/c/cp2k.py | 2 +- easybuild/easyblocks/c/cplex.py | 2 +- easybuild/easyblocks/c/cppcheck.py | 2 +- easybuild/easyblocks/c/crispr_dav.py | 2 +- easybuild/easyblocks/c/cryptography.py | 2 +- easybuild/easyblocks/c/cuda.py | 2 +- easybuild/easyblocks/c/cudacompat.py | 2 +- easybuild/easyblocks/c/cudnn.py | 2 +- easybuild/easyblocks/c/cufflinks.py | 2 +- easybuild/easyblocks/d/db.py | 2 +- easybuild/easyblocks/d/dl_poly_classic.py | 2 +- easybuild/easyblocks/d/dm_reverb.py | 2 +- easybuild/easyblocks/d/dolfin.py | 2 +- easybuild/easyblocks/d/doris.py | 2 +- easybuild/easyblocks/d/doxygen.py | 2 +- easybuild/easyblocks/e/easybuildmeta.py | 2 +- easybuild/easyblocks/e/egglib.py | 2 +- easybuild/easyblocks/e/eigen.py | 2 +- easybuild/easyblocks/e/elpa.py | 4 ++-- easybuild/easyblocks/e/elsi.py | 2 +- easybuild/easyblocks/e/epd.py | 2 +- easybuild/easyblocks/e/esmf.py | 2 +- easybuild/easyblocks/e/espresso.py | 2 +- easybuild/easyblocks/e/extrae.py | 2 +- easybuild/easyblocks/f/faststructure.py | 2 +- easybuild/easyblocks/f/fdtd_solutions.py | 2 +- easybuild/easyblocks/f/ferret.py | 2 +- easybuild/easyblocks/f/fftw.py | 2 +- easybuild/easyblocks/f/fftwmpi.py | 2 +- easybuild/easyblocks/f/flex.py | 2 +- easybuild/easyblocks/f/flexiblas.py | 2 +- easybuild/easyblocks/f/fluent.py | 2 +- easybuild/easyblocks/f/foldx.py | 2 +- easybuild/easyblocks/f/freefem.py | 2 +- easybuild/easyblocks/f/freesurfer.py | 2 +- easybuild/easyblocks/f/freetype.py | 2 +- easybuild/easyblocks/f/fsl.py | 2 +- easybuild/easyblocks/g/g2clib.py | 2 +- easybuild/easyblocks/g/g2lib.py | 2 +- easybuild/easyblocks/g/gamess_us.py | 2 +- easybuild/easyblocks/g/gate.py | 2 +- easybuild/easyblocks/g/gcc.py | 2 +- easybuild/easyblocks/g/gctf.py | 2 +- easybuild/easyblocks/g/geant4.py | 2 +- easybuild/easyblocks/g/ghc.py | 2 +- easybuild/easyblocks/g/go.py | 2 +- easybuild/easyblocks/g/gromacs.py | 2 +- easybuild/easyblocks/g/gurobi.py | 2 +- easybuild/easyblocks/generic/__init__.py | 2 +- easybuild/easyblocks/generic/binariestarball.py | 2 +- easybuild/easyblocks/generic/binary.py | 2 +- easybuild/easyblocks/generic/buildenv.py | 2 +- easybuild/easyblocks/generic/bundle.py | 2 +- easybuild/easyblocks/generic/cmakemake.py | 2 +- easybuild/easyblocks/generic/cmakemakecp.py | 2 +- easybuild/easyblocks/generic/cmakeninja.py | 2 +- easybuild/easyblocks/generic/cmakepythonpackage.py | 2 +- easybuild/easyblocks/generic/cmdcp.py | 2 +- easybuild/easyblocks/generic/conda.py | 2 +- easybuild/easyblocks/generic/configuremake.py | 2 +- easybuild/easyblocks/generic/configuremakepythonpackage.py | 2 +- easybuild/easyblocks/generic/craytoolchain.py | 2 +- easybuild/easyblocks/generic/fortranpythonpackage.py | 2 +- easybuild/easyblocks/generic/gopackage.py | 2 +- easybuild/easyblocks/generic/intelbase.py | 2 +- easybuild/easyblocks/generic/jar.py | 2 +- easybuild/easyblocks/generic/juliabundle.py | 2 +- easybuild/easyblocks/generic/juliapackage.py | 2 +- easybuild/easyblocks/generic/makecp.py | 2 +- easybuild/easyblocks/generic/mesonninja.py | 2 +- easybuild/easyblocks/generic/modulerc.py | 2 +- easybuild/easyblocks/generic/ocamlpackage.py | 2 +- easybuild/easyblocks/generic/octavepackage.py | 2 +- easybuild/easyblocks/generic/packedbinary.py | 2 +- easybuild/easyblocks/generic/perlmodule.py | 2 +- easybuild/easyblocks/generic/pythonbundle.py | 2 +- easybuild/easyblocks/generic/pythonpackage.py | 2 +- easybuild/easyblocks/generic/rpackage.py | 2 +- easybuild/easyblocks/generic/rpm.py | 2 +- easybuild/easyblocks/generic/rubygem.py | 2 +- easybuild/easyblocks/generic/scons.py | 2 +- easybuild/easyblocks/generic/systemcompiler.py | 2 +- easybuild/easyblocks/generic/systemmpi.py | 2 +- easybuild/easyblocks/generic/tarball.py | 2 +- easybuild/easyblocks/generic/toolchain.py | 2 +- .../easyblocks/generic/versionindependentpythonpackage.py | 2 +- easybuild/easyblocks/generic/vscpythonpackage.py | 2 +- easybuild/easyblocks/generic/waf.py | 2 +- easybuild/easyblocks/h/hadoop.py | 2 +- easybuild/easyblocks/h/hdf5.py | 2 +- easybuild/easyblocks/h/healpix.py | 2 +- easybuild/easyblocks/h/hpcg.py | 2 +- easybuild/easyblocks/h/hpl.py | 2 +- easybuild/easyblocks/h/hypre.py | 2 +- easybuild/easyblocks/i/icc.py | 2 +- easybuild/easyblocks/i/iccifort.py | 2 +- easybuild/easyblocks/i/ifort.py | 2 +- easybuild/easyblocks/i/imkl.py | 2 +- easybuild/easyblocks/i/imkl_fftw.py | 2 +- easybuild/easyblocks/i/imod.py | 2 +- easybuild/easyblocks/i/impi.py | 2 +- easybuild/easyblocks/i/inspector.py | 2 +- easybuild/easyblocks/i/intel_compilers.py | 2 +- easybuild/easyblocks/i/ipp.py | 2 +- easybuild/easyblocks/i/ironpython.py | 2 +- easybuild/easyblocks/i/itac.py | 2 +- easybuild/easyblocks/j/java.py | 2 +- easybuild/easyblocks/j/jaxlib.py | 2 +- easybuild/easyblocks/l/lammps.py | 2 +- easybuild/easyblocks/l/lapack.py | 2 +- easybuild/easyblocks/l/libdrm.py | 2 +- easybuild/easyblocks/l/libint.py | 2 +- easybuild/easyblocks/l/libqglviewer.py | 2 +- easybuild/easyblocks/l/libsmm.py | 2 +- easybuild/easyblocks/l/libxml2.py | 2 +- easybuild/easyblocks/l/llvm.py | 2 +- easybuild/easyblocks/l/lua.py | 2 +- easybuild/easyblocks/m/mamba.py | 2 +- easybuild/easyblocks/m/maple.py | 2 +- easybuild/easyblocks/m/mathematica.py | 2 +- easybuild/easyblocks/m/matlab.py | 2 +- easybuild/easyblocks/m/mcr.py | 2 +- easybuild/easyblocks/m/mesa.py | 2 +- easybuild/easyblocks/m/metagenome_atlas.py | 2 +- easybuild/easyblocks/m/metavelvet.py | 2 +- easybuild/easyblocks/m/metis.py | 2 +- easybuild/easyblocks/m/modeller.py | 2 +- easybuild/easyblocks/m/molpro.py | 2 +- easybuild/easyblocks/m/mono.py | 2 +- easybuild/easyblocks/m/mothur.py | 2 +- easybuild/easyblocks/m/motioncor2.py | 2 +- easybuild/easyblocks/m/mpich.py | 2 +- easybuild/easyblocks/m/mrbayes.py | 2 +- easybuild/easyblocks/m/mrtrix.py | 2 +- easybuild/easyblocks/m/msm.py | 2 +- easybuild/easyblocks/m/mtl4.py | 2 +- easybuild/easyblocks/m/mummer.py | 2 +- easybuild/easyblocks/m/mumps.py | 2 +- easybuild/easyblocks/m/mutil.py | 2 +- easybuild/easyblocks/m/mvapich2.py | 2 +- easybuild/easyblocks/m/mxnet.py | 2 +- easybuild/easyblocks/m/mymedialite.py | 2 +- easybuild/easyblocks/n/namd.py | 2 +- easybuild/easyblocks/n/nccl.py | 2 +- easybuild/easyblocks/n/ncl.py | 2 +- easybuild/easyblocks/n/ncurses.py | 2 +- easybuild/easyblocks/n/nemo.py | 2 +- easybuild/easyblocks/n/netcdf.py | 2 +- easybuild/easyblocks/n/netcdf4_python.py | 2 +- easybuild/easyblocks/n/netcdf_fortran.py | 2 +- easybuild/easyblocks/n/neuron.py | 2 +- easybuild/easyblocks/n/nim.py | 2 +- easybuild/easyblocks/n/nose.py | 2 +- easybuild/easyblocks/n/numexpr.py | 2 +- easybuild/easyblocks/n/numpy.py | 2 +- easybuild/easyblocks/n/nvhpc.py | 4 ++-- easybuild/easyblocks/n/nwchem.py | 2 +- easybuild/easyblocks/o/ocaml.py | 2 +- easybuild/easyblocks/o/octave.py | 2 +- easybuild/easyblocks/o/openbabel.py | 2 +- easybuild/easyblocks/o/opencv.py | 2 +- easybuild/easyblocks/o/openfoam.py | 2 +- easybuild/easyblocks/o/openifs.py | 2 +- easybuild/easyblocks/o/openmpi.py | 2 +- easybuild/easyblocks/o/openssl.py | 2 +- easybuild/easyblocks/o/openssl_wrapper.py | 2 +- easybuild/easyblocks/o/orca.py | 2 +- easybuild/easyblocks/p/paraver.py | 2 +- easybuild/easyblocks/p/parmetis.py | 2 +- easybuild/easyblocks/p/pasha.py | 2 +- easybuild/easyblocks/p/pbdmpi.py | 2 +- easybuild/easyblocks/p/pbdslap.py | 2 +- easybuild/easyblocks/p/pdt.py | 2 +- easybuild/easyblocks/p/perl.py | 2 +- easybuild/easyblocks/p/petsc.py | 2 +- easybuild/easyblocks/p/pgi.py | 4 ++-- easybuild/easyblocks/p/picard.py | 2 +- easybuild/easyblocks/p/pplacer.py | 2 +- easybuild/easyblocks/p/primer3.py | 2 +- easybuild/easyblocks/p/psi.py | 2 +- easybuild/easyblocks/p/psmpi.py | 2 +- easybuild/easyblocks/p/pybind11.py | 2 +- easybuild/easyblocks/p/pyquante.py | 2 +- easybuild/easyblocks/p/python.py | 2 +- easybuild/easyblocks/p/python_meep.py | 2 +- easybuild/easyblocks/p/pytorch.py | 2 +- easybuild/easyblocks/p/pyzmq.py | 2 +- easybuild/easyblocks/q/qscintilla.py | 2 +- easybuild/easyblocks/q/qt.py | 2 +- easybuild/easyblocks/q/quantumespresso.py | 2 +- easybuild/easyblocks/r/__init__.py | 2 +- easybuild/easyblocks/r/r.py | 2 +- easybuild/easyblocks/r/repeatmasker.py | 2 +- easybuild/easyblocks/r/repeatmodeler.py | 2 +- easybuild/easyblocks/r/reticulate.py | 2 +- easybuild/easyblocks/r/rmpi.py | 2 +- easybuild/easyblocks/r/root.py | 2 +- easybuild/easyblocks/r/rosetta.py | 2 +- easybuild/easyblocks/r/rserve.py | 2 +- easybuild/easyblocks/r/ruby.py | 2 +- easybuild/easyblocks/s/samcef.py | 2 +- easybuild/easyblocks/s/samtools.py | 2 +- easybuild/easyblocks/s/sas.py | 2 +- easybuild/easyblocks/s/scalapack.py | 2 +- easybuild/easyblocks/s/scalasca1.py | 2 +- easybuild/easyblocks/s/scipion.py | 2 +- easybuild/easyblocks/s/scipy.py | 2 +- easybuild/easyblocks/s/score_p.py | 2 +- easybuild/easyblocks/s/scotch.py | 2 +- easybuild/easyblocks/s/sepp.py | 2 +- easybuild/easyblocks/s/shrimp.py | 2 +- easybuild/easyblocks/s/siesta.py | 2 +- easybuild/easyblocks/s/slepc.py | 2 +- easybuild/easyblocks/s/snphylo.py | 2 +- easybuild/easyblocks/s/soapdenovo.py | 2 +- easybuild/easyblocks/s/star_ccm.py | 2 +- easybuild/easyblocks/s/stata.py | 2 +- easybuild/easyblocks/s/suitesparse.py | 2 +- easybuild/easyblocks/s/superlu.py | 2 +- easybuild/easyblocks/s/swig.py | 2 +- easybuild/easyblocks/t/tau.py | 2 +- easybuild/easyblocks/t/tbb.py | 2 +- easybuild/easyblocks/t/tensorflow.py | 2 +- easybuild/easyblocks/t/tensorrt.py | 2 +- easybuild/easyblocks/t/tinker.py | 2 +- easybuild/easyblocks/t/tkinter.py | 2 +- easybuild/easyblocks/t/torchvision.py | 2 +- easybuild/easyblocks/t/tornado.py | 2 +- easybuild/easyblocks/t/totalview.py | 4 ++-- easybuild/easyblocks/t/trilinos.py | 2 +- easybuild/easyblocks/t/trinity.py | 2 +- easybuild/easyblocks/u/ucx_plugins.py | 2 +- easybuild/easyblocks/u/ufc.py | 2 +- easybuild/easyblocks/v/velvet.py | 2 +- easybuild/easyblocks/v/vep.py | 2 +- easybuild/easyblocks/v/vmd.py | 4 ++-- easybuild/easyblocks/v/vsc_tools.py | 2 +- easybuild/easyblocks/v/vtune.py | 2 +- easybuild/easyblocks/w/wien2k.py | 2 +- easybuild/easyblocks/w/wps.py | 2 +- easybuild/easyblocks/w/wrf.py | 2 +- easybuild/easyblocks/w/wrf_fire.py | 2 +- easybuild/easyblocks/w/wxpython.py | 2 +- easybuild/easyblocks/x/xalt.py | 2 +- easybuild/easyblocks/x/xcrysden.py | 2 +- easybuild/easyblocks/x/xmipp.py | 2 +- easybuild/easyblocks/x/xml.py | 2 +- setup.py | 2 +- test/__init__.py | 2 +- test/easyblocks/easyblock_specific.py | 2 +- test/easyblocks/general.py | 2 +- test/easyblocks/init_easyblocks.py | 2 +- test/easyblocks/module.py | 2 +- test/easyblocks/suite.py | 2 +- 296 files changed, 303 insertions(+), 303 deletions(-) diff --git a/easybuild/__init__.py b/easybuild/__init__.py index e87b3e3c76..62a579f2dd 100644 --- a/easybuild/__init__.py +++ b/easybuild/__init__.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index 29b70f4815..09144bb9d8 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/abaqus.py b/easybuild/easyblocks/a/abaqus.py index 56d15b93be..50404d75db 100644 --- a/easybuild/easyblocks/a/abaqus.py +++ b/easybuild/easyblocks/a/abaqus.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/acml.py b/easybuild/easyblocks/a/acml.py index 5a0a5cc2e7..b20704a53e 100644 --- a/easybuild/easyblocks/a/acml.py +++ b/easybuild/easyblocks/a/acml.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/adf.py b/easybuild/easyblocks/a/adf.py index 09aeac12c7..b3e4f9166e 100644 --- a/easybuild/easyblocks/a/adf.py +++ b/easybuild/easyblocks/a/adf.py @@ -1,5 +1,5 @@ ## -# Copyright 2016-2022 Ghent University +# Copyright 2016-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/advisor.py b/easybuild/easyblocks/a/advisor.py index f87ffe6fe0..952c94642e 100644 --- a/easybuild/easyblocks/a/advisor.py +++ b/easybuild/easyblocks/a/advisor.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/aladin.py b/easybuild/easyblocks/a/aladin.py index 02ccaa41cf..aa248b831b 100644 --- a/easybuild/easyblocks/a/aladin.py +++ b/easybuild/easyblocks/a/aladin.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/allinea.py b/easybuild/easyblocks/a/allinea.py index 9a5f8c7f23..e15d9bc3b2 100644 --- a/easybuild/easyblocks/a/allinea.py +++ b/easybuild/easyblocks/a/allinea.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/amber.py b/easybuild/easyblocks/a/amber.py index e6c1efda90..0140ac8d10 100644 --- a/easybuild/easyblocks/a/amber.py +++ b/easybuild/easyblocks/a/amber.py @@ -1,6 +1,6 @@ ## -# Copyright 2009-2022 Ghent University -# Copyright 2015-2022 Stanford University +# Copyright 2009-2023 Ghent University +# Copyright 2015-2023 Stanford University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/anaconda.py b/easybuild/easyblocks/a/anaconda.py index 7c6793dfc1..a792c5e498 100644 --- a/easybuild/easyblocks/a/anaconda.py +++ b/easybuild/easyblocks/a/anaconda.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/ansys.py b/easybuild/easyblocks/a/ansys.py index 3473eae8c8..332e1579a7 100644 --- a/easybuild/easyblocks/a/ansys.py +++ b/easybuild/easyblocks/a/ansys.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/ant.py b/easybuild/easyblocks/a/ant.py index a9555afdc1..a345118490 100644 --- a/easybuild/easyblocks/a/ant.py +++ b/easybuild/easyblocks/a/ant.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/aocc.py b/easybuild/easyblocks/a/aocc.py index a8a88d3b8d..8ccdaf1d86 100644 --- a/easybuild/easyblocks/a/aocc.py +++ b/easybuild/easyblocks/a/aocc.py @@ -1,5 +1,5 @@ ## -# Copyright 2020-2022 Forschungszentrum Juelich GmbH +# Copyright 2020-2023 Forschungszentrum Juelich GmbH # # This file is triple-licensed under GPLv2 (see below), MIT, and # BSD three-clause licenses. diff --git a/easybuild/easyblocks/a/aomp.py b/easybuild/easyblocks/a/aomp.py index 4a39adacfa..7ff4126d6d 100644 --- a/easybuild/easyblocks/a/aomp.py +++ b/easybuild/easyblocks/a/aomp.py @@ -1,5 +1,5 @@ ## -# Copyright 2021-2022 Ghent University +# Copyright 2021-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/arb.py b/easybuild/easyblocks/a/arb.py index bcc8eb3162..3d184d88bf 100644 --- a/easybuild/easyblocks/a/arb.py +++ b/easybuild/easyblocks/a/arb.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/armadillo.py b/easybuild/easyblocks/a/armadillo.py index 286f29bafe..a2faa04317 100644 --- a/easybuild/easyblocks/a/armadillo.py +++ b/easybuild/easyblocks/a/armadillo.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/a/atlas.py b/easybuild/easyblocks/a/atlas.py index d7ed1f42cd..da8fdefbc9 100644 --- a/easybuild/easyblocks/a/atlas.py +++ b/easybuild/easyblocks/a/atlas.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/bamtools.py b/easybuild/easyblocks/b/bamtools.py index 63ab90a9eb..0a11f2e4cb 100644 --- a/easybuild/easyblocks/b/bamtools.py +++ b/easybuild/easyblocks/b/bamtools.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 The Cyprus Institute +# Copyright 2009-2023 The Cyprus Institute # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/bazel.py b/easybuild/easyblocks/b/bazel.py index f2798184d9..e626457001 100644 --- a/easybuild/easyblocks/b/bazel.py +++ b/easybuild/easyblocks/b/bazel.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/berkeleygw.py b/easybuild/easyblocks/b/berkeleygw.py index 386d9f83f3..e9a9b87f8e 100644 --- a/easybuild/easyblocks/b/berkeleygw.py +++ b/easybuild/easyblocks/b/berkeleygw.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/binutils.py b/easybuild/easyblocks/b/binutils.py index 6bc27f5413..306a535d99 100644 --- a/easybuild/easyblocks/b/binutils.py +++ b/easybuild/easyblocks/b/binutils.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/bioconductor.py b/easybuild/easyblocks/b/bioconductor.py index d1e4209404..c343d75773 100644 --- a/easybuild/easyblocks/b/bioconductor.py +++ b/easybuild/easyblocks/b/bioconductor.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/bisearch.py b/easybuild/easyblocks/b/bisearch.py index 57fa97a729..975f5c391f 100644 --- a/easybuild/easyblocks/b/bisearch.py +++ b/easybuild/easyblocks/b/bisearch.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/blacs.py b/easybuild/easyblocks/b/blacs.py index ae3f570259..a600c5285c 100644 --- a/easybuild/easyblocks/b/blacs.py +++ b/easybuild/easyblocks/b/blacs.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/blat.py b/easybuild/easyblocks/b/blat.py index 15468627fc..53d01c2b8f 100755 --- a/easybuild/easyblocks/b/blat.py +++ b/easybuild/easyblocks/b/blat.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 the Cyprus Institute +# Copyright 2009-2023 the Cyprus Institute # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/blender.py b/easybuild/easyblocks/b/blender.py index cc61453c04..500b65a0e6 100644 --- a/easybuild/easyblocks/b/blender.py +++ b/easybuild/easyblocks/b/blender.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/boost.py b/easybuild/easyblocks/b/boost.py index 53acc8c489..5110105cd8 100644 --- a/easybuild/easyblocks/b/boost.py +++ b/easybuild/easyblocks/b/boost.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/bowtie.py b/easybuild/easyblocks/b/bowtie.py index 0b789e8ccd..4daa8512ba 100644 --- a/easybuild/easyblocks/b/bowtie.py +++ b/easybuild/easyblocks/b/bowtie.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/bowtie2.py b/easybuild/easyblocks/b/bowtie2.py index 97b547c078..285f9b98db 100644 --- a/easybuild/easyblocks/b/bowtie2.py +++ b/easybuild/easyblocks/b/bowtie2.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/b/bwa.py b/easybuild/easyblocks/b/bwa.py index fe6552c8fe..646cc85e4e 100644 --- a/easybuild/easyblocks/b/bwa.py +++ b/easybuild/easyblocks/b/bwa.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Kenneth Hoste # Authors:: George Tsouloupas , Fotis Georgatos # License:: MIT/GPL diff --git a/easybuild/easyblocks/b/bwise.py b/easybuild/easyblocks/b/bwise.py index dab0c0d312..723805ccaf 100644 --- a/easybuild/easyblocks/b/bwise.py +++ b/easybuild/easyblocks/b/bwise.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Free University of Brussels +# Copyright 2018-2023 Free University of Brussels # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/b/bzip2.py b/easybuild/easyblocks/b/bzip2.py index 84fecdc554..5c5d34b8da 100644 --- a/easybuild/easyblocks/b/bzip2.py +++ b/easybuild/easyblocks/b/bzip2.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cblas.py b/easybuild/easyblocks/c/cblas.py index 6b4539aa4f..14b1364b74 100644 --- a/easybuild/easyblocks/c/cblas.py +++ b/easybuild/easyblocks/c/cblas.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cfdemcoupling.py b/easybuild/easyblocks/c/cfdemcoupling.py index 6f2a2b329c..2264ffdeb3 100644 --- a/easybuild/easyblocks/c/cfdemcoupling.py +++ b/easybuild/easyblocks/c/cfdemcoupling.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cgal.py b/easybuild/easyblocks/c/cgal.py index df0bde1aa1..6cb2937cd8 100644 --- a/easybuild/easyblocks/c/cgal.py +++ b/easybuild/easyblocks/c/cgal.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/chapel.py b/easybuild/easyblocks/c/chapel.py index a962e1a5f1..fc7ddebfb7 100644 --- a/easybuild/easyblocks/c/chapel.py +++ b/easybuild/easyblocks/c/chapel.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/c/charmm.py b/easybuild/easyblocks/c/charmm.py index 5a17c1232c..6c92cae548 100644 --- a/easybuild/easyblocks/c/charmm.py +++ b/easybuild/easyblocks/c/charmm.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 0267bdfa19..4f1344187a 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -1,6 +1,6 @@ ## -# Copyright 2013 Dmitri Gribenko -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Dmitri Gribenko +# Copyright 2013-2023 Ghent University # # This file is triple-licensed under GPLv2 (see below), MIT, and # BSD three-clause licenses. diff --git a/easybuild/easyblocks/c/clang_aomp.py b/easybuild/easyblocks/c/clang_aomp.py index 04ebda0da0..ca94ba805f 100644 --- a/easybuild/easyblocks/c/clang_aomp.py +++ b/easybuild/easyblocks/c/clang_aomp.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cmake.py b/easybuild/easyblocks/c/cmake.py index 5d3ff515d1..2c9ff85ddc 100644 --- a/easybuild/easyblocks/c/cmake.py +++ b/easybuild/easyblocks/c/cmake.py @@ -1,5 +1,5 @@ ## -# Copyright 2020-2022 Alexander Grund +# Copyright 2020-2023 Alexander Grund # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/code_server.py b/easybuild/easyblocks/c/code_server.py index 6ae209c498..b975340bf8 100644 --- a/easybuild/easyblocks/c/code_server.py +++ b/easybuild/easyblocks/c/code_server.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/comsol.py b/easybuild/easyblocks/c/comsol.py index 4fa7cdfbfd..09b6e44fcd 100644 --- a/easybuild/easyblocks/c/comsol.py +++ b/easybuild/easyblocks/c/comsol.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cp2k.py b/easybuild/easyblocks/c/cp2k.py index acfbee3a39..c9f4171921 100644 --- a/easybuild/easyblocks/c/cp2k.py +++ b/easybuild/easyblocks/c/cp2k.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cplex.py b/easybuild/easyblocks/c/cplex.py index 02c0efee3a..cc6ec0e52f 100644 --- a/easybuild/easyblocks/c/cplex.py +++ b/easybuild/easyblocks/c/cplex.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cppcheck.py b/easybuild/easyblocks/c/cppcheck.py index b70d819ce4..ec43ceda09 100644 --- a/easybuild/easyblocks/c/cppcheck.py +++ b/easybuild/easyblocks/c/cppcheck.py @@ -1,5 +1,5 @@ ## -# Copyright 2016-2022 Forschungszentrum Juelich GmbH +# Copyright 2016-2023 Forschungszentrum Juelich GmbH # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/crispr_dav.py b/easybuild/easyblocks/c/crispr_dav.py index 86c172926b..b528fd1056 100644 --- a/easybuild/easyblocks/c/crispr_dav.py +++ b/easybuild/easyblocks/c/crispr_dav.py @@ -1,5 +1,5 @@ ## -# Copyright 2020-2022 Ghent University +# Copyright 2020-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cryptography.py b/easybuild/easyblocks/c/cryptography.py index a785ecac84..bfb6688358 100644 --- a/easybuild/easyblocks/c/cryptography.py +++ b/easybuild/easyblocks/c/cryptography.py @@ -1,5 +1,5 @@ ## -# Copyright 2017-2022 Ghent University +# Copyright 2017-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cuda.py b/easybuild/easyblocks/c/cuda.py index 666824ec9e..d5d6489bd0 100644 --- a/easybuild/easyblocks/c/cuda.py +++ b/easybuild/easyblocks/c/cuda.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cudacompat.py b/easybuild/easyblocks/c/cudacompat.py index 07e7bdb175..e97db8e2c0 100644 --- a/easybuild/easyblocks/c/cudacompat.py +++ b/easybuild/easyblocks/c/cudacompat.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cudnn.py b/easybuild/easyblocks/c/cudnn.py index a843f8ae78..39e04fe8d5 100644 --- a/easybuild/easyblocks/c/cudnn.py +++ b/easybuild/easyblocks/c/cudnn.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/c/cufflinks.py b/easybuild/easyblocks/c/cufflinks.py index d1542a70cc..62f2cb7bf2 100644 --- a/easybuild/easyblocks/c/cufflinks.py +++ b/easybuild/easyblocks/c/cufflinks.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/d/db.py b/easybuild/easyblocks/d/db.py index f62f02c116..065df60a14 100644 --- a/easybuild/easyblocks/d/db.py +++ b/easybuild/easyblocks/d/db.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/d/dl_poly_classic.py b/easybuild/easyblocks/d/dl_poly_classic.py index 6975df2747..823df870b9 100644 --- a/easybuild/easyblocks/d/dl_poly_classic.py +++ b/easybuild/easyblocks/d/dl_poly_classic.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/d/dm_reverb.py b/easybuild/easyblocks/d/dm_reverb.py index c847aea331..802edca1d2 100644 --- a/easybuild/easyblocks/d/dm_reverb.py +++ b/easybuild/easyblocks/d/dm_reverb.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/d/dolfin.py b/easybuild/easyblocks/d/dolfin.py index c9e78d23dc..6cb323636c 100644 --- a/easybuild/easyblocks/d/dolfin.py +++ b/easybuild/easyblocks/d/dolfin.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/d/doris.py b/easybuild/easyblocks/d/doris.py index 86f0a27601..cac0909ba1 100644 --- a/easybuild/easyblocks/d/doris.py +++ b/easybuild/easyblocks/d/doris.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/d/doxygen.py b/easybuild/easyblocks/d/doxygen.py index 8498fed336..7a8a16365d 100644 --- a/easybuild/easyblocks/d/doxygen.py +++ b/easybuild/easyblocks/d/doxygen.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/e/easybuildmeta.py b/easybuild/easyblocks/e/easybuildmeta.py index b1e9970d00..baac89baa0 100644 --- a/easybuild/easyblocks/e/easybuildmeta.py +++ b/easybuild/easyblocks/e/easybuildmeta.py @@ -1,5 +1,5 @@ # # -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/e/egglib.py b/easybuild/easyblocks/e/egglib.py index 3233fd0ca2..f4aa262042 100644 --- a/easybuild/easyblocks/e/egglib.py +++ b/easybuild/easyblocks/e/egglib.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/e/eigen.py b/easybuild/easyblocks/e/eigen.py index acdfbc168d..70dc6a4e36 100644 --- a/easybuild/easyblocks/e/eigen.py +++ b/easybuild/easyblocks/e/eigen.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index cd488cade1..8ac4856207 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -1,6 +1,6 @@ ## -# Copyright 2009-2022 Ghent University -# Copyright 2019-2022 Micael Oliveira +# Copyright 2009-2023 Ghent University +# Copyright 2019-2023 Micael Oliveira # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/e/elsi.py b/easybuild/easyblocks/e/elsi.py index e216833760..e3e26dea00 100644 --- a/easybuild/easyblocks/e/elsi.py +++ b/easybuild/easyblocks/e/elsi.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/e/epd.py b/easybuild/easyblocks/e/epd.py index d278afaa3b..26e2610fdb 100644 --- a/easybuild/easyblocks/e/epd.py +++ b/easybuild/easyblocks/e/epd.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/e/esmf.py b/easybuild/easyblocks/e/esmf.py index 0a2f2fa6c5..03ff400619 100644 --- a/easybuild/easyblocks/e/esmf.py +++ b/easybuild/easyblocks/e/esmf.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/e/espresso.py b/easybuild/easyblocks/e/espresso.py index b8510c974e..3d1795fe41 100644 --- a/easybuild/easyblocks/e/espresso.py +++ b/easybuild/easyblocks/e/espresso.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Josh Berryman , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/e/extrae.py b/easybuild/easyblocks/e/extrae.py index 39006eb433..fcb10677a1 100644 --- a/easybuild/easyblocks/e/extrae.py +++ b/easybuild/easyblocks/e/extrae.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/faststructure.py b/easybuild/easyblocks/f/faststructure.py index cfafbb7d65..5504335056 100644 --- a/easybuild/easyblocks/f/faststructure.py +++ b/easybuild/easyblocks/f/faststructure.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/fdtd_solutions.py b/easybuild/easyblocks/f/fdtd_solutions.py index 167885eaa1..4e044d2788 100644 --- a/easybuild/easyblocks/f/fdtd_solutions.py +++ b/easybuild/easyblocks/f/fdtd_solutions.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/ferret.py b/easybuild/easyblocks/f/ferret.py index 8bc8380939..37e38e9a0b 100644 --- a/easybuild/easyblocks/f/ferret.py +++ b/easybuild/easyblocks/f/ferret.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/fftw.py b/easybuild/easyblocks/f/fftw.py index 8594e278f2..6f10c711c9 100644 --- a/easybuild/easyblocks/f/fftw.py +++ b/easybuild/easyblocks/f/fftw.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/fftwmpi.py b/easybuild/easyblocks/f/fftwmpi.py index bb4e467287..3736362493 100644 --- a/easybuild/easyblocks/f/fftwmpi.py +++ b/easybuild/easyblocks/f/fftwmpi.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/flex.py b/easybuild/easyblocks/f/flex.py index b65b008cc5..a7fd414f8d 100644 --- a/easybuild/easyblocks/f/flex.py +++ b/easybuild/easyblocks/f/flex.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/flexiblas.py b/easybuild/easyblocks/f/flexiblas.py index b6edc0226c..2a63c1650e 100644 --- a/easybuild/easyblocks/f/flexiblas.py +++ b/easybuild/easyblocks/f/flexiblas.py @@ -1,5 +1,5 @@ ## -# Copyright 2021-2022 Ghent University +# Copyright 2021-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/fluent.py b/easybuild/easyblocks/f/fluent.py index e67d891589..5976f8ea4f 100644 --- a/easybuild/easyblocks/f/fluent.py +++ b/easybuild/easyblocks/f/fluent.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/foldx.py b/easybuild/easyblocks/f/foldx.py index 1a4300f18b..8166c9b68a 100644 --- a/easybuild/easyblocks/f/foldx.py +++ b/easybuild/easyblocks/f/foldx.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/freefem.py b/easybuild/easyblocks/f/freefem.py index 7caad3acb5..15c0fdd31c 100644 --- a/easybuild/easyblocks/f/freefem.py +++ b/easybuild/easyblocks/f/freefem.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/freesurfer.py b/easybuild/easyblocks/f/freesurfer.py index 6419caf8f0..c60059c149 100644 --- a/easybuild/easyblocks/f/freesurfer.py +++ b/easybuild/easyblocks/f/freesurfer.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/freetype.py b/easybuild/easyblocks/f/freetype.py index feddc3a29f..fa3487a1cd 100644 --- a/easybuild/easyblocks/f/freetype.py +++ b/easybuild/easyblocks/f/freetype.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/f/fsl.py b/easybuild/easyblocks/f/fsl.py index 94a8350415..e8ebaa9b21 100644 --- a/easybuild/easyblocks/f/fsl.py +++ b/easybuild/easyblocks/f/fsl.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/g2clib.py b/easybuild/easyblocks/g/g2clib.py index 48eaa80aae..15ad20f57b 100644 --- a/easybuild/easyblocks/g/g2clib.py +++ b/easybuild/easyblocks/g/g2clib.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/g2lib.py b/easybuild/easyblocks/g/g2lib.py index 55f708f8f1..8b3e9643de 100644 --- a/easybuild/easyblocks/g/g2lib.py +++ b/easybuild/easyblocks/g/g2lib.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/gamess_us.py b/easybuild/easyblocks/g/gamess_us.py index 4d658a7c0e..973309d0c9 100644 --- a/easybuild/easyblocks/g/gamess_us.py +++ b/easybuild/easyblocks/g/gamess_us.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/gate.py b/easybuild/easyblocks/g/gate.py index 51338d19e2..572204b836 100644 --- a/easybuild/easyblocks/g/gate.py +++ b/easybuild/easyblocks/g/gate.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/gcc.py b/easybuild/easyblocks/g/gcc.py index dbe1039c54..9069e3ea37 100644 --- a/easybuild/easyblocks/g/gcc.py +++ b/easybuild/easyblocks/g/gcc.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/gctf.py b/easybuild/easyblocks/g/gctf.py index 0e3ca2d16a..9e2ca40b86 100644 --- a/easybuild/easyblocks/g/gctf.py +++ b/easybuild/easyblocks/g/gctf.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Ghent University +# Copyright 2019-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (https://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/geant4.py b/easybuild/easyblocks/g/geant4.py index 77b8c17f4d..ca431ca946 100644 --- a/easybuild/easyblocks/g/geant4.py +++ b/easybuild/easyblocks/g/geant4.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/ghc.py b/easybuild/easyblocks/g/ghc.py index 2112cd6c20..20c6edcd75 100644 --- a/easybuild/easyblocks/g/ghc.py +++ b/easybuild/easyblocks/g/ghc.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/go.py b/easybuild/easyblocks/g/go.py index 2a19f2c468..932df72f3e 100644 --- a/easybuild/easyblocks/g/go.py +++ b/easybuild/easyblocks/g/go.py @@ -1,5 +1,5 @@ ## -# Copyright 2014-2022 Ghent University +# Copyright 2014-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/gromacs.py b/easybuild/easyblocks/g/gromacs.py index fbffd6535d..973b3f323a 100644 --- a/easybuild/easyblocks/g/gromacs.py +++ b/easybuild/easyblocks/g/gromacs.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/g/gurobi.py b/easybuild/easyblocks/g/gurobi.py index 34e1eb9a2a..a02938ac12 100644 --- a/easybuild/easyblocks/g/gurobi.py +++ b/easybuild/easyblocks/g/gurobi.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/__init__.py b/easybuild/easyblocks/generic/__init__.py index e87b3e3c76..62a579f2dd 100644 --- a/easybuild/easyblocks/generic/__init__.py +++ b/easybuild/easyblocks/generic/__init__.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/binariestarball.py b/easybuild/easyblocks/generic/binariestarball.py index 259f7d9073..fc74fbe313 100644 --- a/easybuild/easyblocks/generic/binariestarball.py +++ b/easybuild/easyblocks/generic/binariestarball.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/binary.py b/easybuild/easyblocks/generic/binary.py index cfc795acc9..66ec571dea 100644 --- a/easybuild/easyblocks/generic/binary.py +++ b/easybuild/easyblocks/generic/binary.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/buildenv.py b/easybuild/easyblocks/generic/buildenv.py index 8f4200ef98..cb75e3a348 100644 --- a/easybuild/easyblocks/generic/buildenv.py +++ b/easybuild/easyblocks/generic/buildenv.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/bundle.py b/easybuild/easyblocks/generic/bundle.py index a574ba2db4..61cc7125fd 100644 --- a/easybuild/easyblocks/generic/bundle.py +++ b/easybuild/easyblocks/generic/bundle.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/cmakemake.py b/easybuild/easyblocks/generic/cmakemake.py index 0f1a7610cb..f747702fc9 100644 --- a/easybuild/easyblocks/generic/cmakemake.py +++ b/easybuild/easyblocks/generic/cmakemake.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/cmakemakecp.py b/easybuild/easyblocks/generic/cmakemakecp.py index bfa4229fbe..866ffe9e86 100644 --- a/easybuild/easyblocks/generic/cmakemakecp.py +++ b/easybuild/easyblocks/generic/cmakemakecp.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/cmakeninja.py b/easybuild/easyblocks/generic/cmakeninja.py index 1b3d554ff7..db344470f1 100644 --- a/easybuild/easyblocks/generic/cmakeninja.py +++ b/easybuild/easyblocks/generic/cmakeninja.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Ghent University +# Copyright 2019-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/cmakepythonpackage.py b/easybuild/easyblocks/generic/cmakepythonpackage.py index 1f76be306c..f70fd83340 100644 --- a/easybuild/easyblocks/generic/cmakepythonpackage.py +++ b/easybuild/easyblocks/generic/cmakepythonpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/cmdcp.py b/easybuild/easyblocks/generic/cmdcp.py index be15601c39..5a91112a4e 100644 --- a/easybuild/easyblocks/generic/cmdcp.py +++ b/easybuild/easyblocks/generic/cmdcp.py @@ -1,5 +1,5 @@ ## -# Copyright 2014-2022 Ghent University +# Copyright 2014-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/conda.py b/easybuild/easyblocks/generic/conda.py index f40cc2d398..b3e0fed5b0 100644 --- a/easybuild/easyblocks/generic/conda.py +++ b/easybuild/easyblocks/generic/conda.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/configuremake.py b/easybuild/easyblocks/generic/configuremake.py index 548332190d..a8527e1088 100644 --- a/easybuild/easyblocks/generic/configuremake.py +++ b/easybuild/easyblocks/generic/configuremake.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/configuremakepythonpackage.py b/easybuild/easyblocks/generic/configuremakepythonpackage.py index 9cfd40d829..8da38021a2 100644 --- a/easybuild/easyblocks/generic/configuremakepythonpackage.py +++ b/easybuild/easyblocks/generic/configuremakepythonpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/craytoolchain.py b/easybuild/easyblocks/generic/craytoolchain.py index 41ae34643d..e324b72e7f 100644 --- a/easybuild/easyblocks/generic/craytoolchain.py +++ b/easybuild/easyblocks/generic/craytoolchain.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/fortranpythonpackage.py b/easybuild/easyblocks/generic/fortranpythonpackage.py index 01270f0028..849dacf54b 100644 --- a/easybuild/easyblocks/generic/fortranpythonpackage.py +++ b/easybuild/easyblocks/generic/fortranpythonpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index cfde24848c..d6f00f51a0 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/intelbase.py b/easybuild/easyblocks/generic/intelbase.py index 8ecb656205..cab94b770c 100644 --- a/easybuild/easyblocks/generic/intelbase.py +++ b/easybuild/easyblocks/generic/intelbase.py @@ -1,5 +1,5 @@ # # -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/jar.py b/easybuild/easyblocks/generic/jar.py index dcfc772e31..55765f11ab 100644 --- a/easybuild/easyblocks/generic/jar.py +++ b/easybuild/easyblocks/generic/jar.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/juliabundle.py b/easybuild/easyblocks/generic/juliabundle.py index 9aa033420b..28c8035068 100644 --- a/easybuild/easyblocks/generic/juliabundle.py +++ b/easybuild/easyblocks/generic/juliabundle.py @@ -1,5 +1,5 @@ ## -# Copyright 2022-2022 Vrije Universiteit Brussel +# Copyright 2022-2023 Vrije Universiteit Brussel # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index d68fb249ff..239ed5f5d3 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2022-2022 Vrije Universiteit Brussel +# Copyright 2022-2023 Vrije Universiteit Brussel # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/makecp.py b/easybuild/easyblocks/generic/makecp.py index 02b2ad12d0..f02937570b 100644 --- a/easybuild/easyblocks/generic/makecp.py +++ b/easybuild/easyblocks/generic/makecp.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 the Cyprus Institute +# Copyright 2013-2023 the Cyprus Institute # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/mesonninja.py b/easybuild/easyblocks/generic/mesonninja.py index 2c097cbb67..fab1a79296 100644 --- a/easybuild/easyblocks/generic/mesonninja.py +++ b/easybuild/easyblocks/generic/mesonninja.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/modulerc.py b/easybuild/easyblocks/generic/modulerc.py index 8c2d1736bb..aa67e90fe3 100644 --- a/easybuild/easyblocks/generic/modulerc.py +++ b/easybuild/easyblocks/generic/modulerc.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/ocamlpackage.py b/easybuild/easyblocks/generic/ocamlpackage.py index 6dbc168718..d0b460d2ca 100644 --- a/easybuild/easyblocks/generic/ocamlpackage.py +++ b/easybuild/easyblocks/generic/ocamlpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/octavepackage.py b/easybuild/easyblocks/generic/octavepackage.py index 11b1024abd..cff63cc9c6 100644 --- a/easybuild/easyblocks/generic/octavepackage.py +++ b/easybuild/easyblocks/generic/octavepackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/packedbinary.py b/easybuild/easyblocks/generic/packedbinary.py index fe6ac9c5ee..2520397b3e 100644 --- a/easybuild/easyblocks/generic/packedbinary.py +++ b/easybuild/easyblocks/generic/packedbinary.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/perlmodule.py b/easybuild/easyblocks/generic/perlmodule.py index 28d8137475..f58163d6e8 100644 --- a/easybuild/easyblocks/generic/perlmodule.py +++ b/easybuild/easyblocks/generic/perlmodule.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/pythonbundle.py b/easybuild/easyblocks/generic/pythonbundle.py index 732f44eb79..8e38e0cfa5 100644 --- a/easybuild/easyblocks/generic/pythonbundle.py +++ b/easybuild/easyblocks/generic/pythonbundle.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index b73eede999..449f699792 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/rpackage.py b/easybuild/easyblocks/generic/rpackage.py index 3caf702d22..572dab6935 100644 --- a/easybuild/easyblocks/generic/rpackage.py +++ b/easybuild/easyblocks/generic/rpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/rpm.py b/easybuild/easyblocks/generic/rpm.py index 3d10b8ab42..0a3f284c7f 100644 --- a/easybuild/easyblocks/generic/rpm.py +++ b/easybuild/easyblocks/generic/rpm.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/rubygem.py b/easybuild/easyblocks/generic/rubygem.py index 8297677534..58ecfa05c4 100644 --- a/easybuild/easyblocks/generic/rubygem.py +++ b/easybuild/easyblocks/generic/rubygem.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/scons.py b/easybuild/easyblocks/generic/scons.py index 4b2fe3de34..9820cb5855 100644 --- a/easybuild/easyblocks/generic/scons.py +++ b/easybuild/easyblocks/generic/scons.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/systemcompiler.py b/easybuild/easyblocks/generic/systemcompiler.py index 2d937897cd..def79c8543 100644 --- a/easybuild/easyblocks/generic/systemcompiler.py +++ b/easybuild/easyblocks/generic/systemcompiler.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/systemmpi.py b/easybuild/easyblocks/generic/systemmpi.py index 3b4ad8915e..5ba5a3f812 100644 --- a/easybuild/easyblocks/generic/systemmpi.py +++ b/easybuild/easyblocks/generic/systemmpi.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/tarball.py b/easybuild/easyblocks/generic/tarball.py index 47514f4e84..5ad887cc81 100644 --- a/easybuild/easyblocks/generic/tarball.py +++ b/easybuild/easyblocks/generic/tarball.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/toolchain.py b/easybuild/easyblocks/generic/toolchain.py index 326aa35fa9..389182c684 100644 --- a/easybuild/easyblocks/generic/toolchain.py +++ b/easybuild/easyblocks/generic/toolchain.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/versionindependentpythonpackage.py b/easybuild/easyblocks/generic/versionindependentpythonpackage.py index 0f1da9c1c5..f6cc181b41 100644 --- a/easybuild/easyblocks/generic/versionindependentpythonpackage.py +++ b/easybuild/easyblocks/generic/versionindependentpythonpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/vscpythonpackage.py b/easybuild/easyblocks/generic/vscpythonpackage.py index 4dee7968c7..772aeb3946 100644 --- a/easybuild/easyblocks/generic/vscpythonpackage.py +++ b/easybuild/easyblocks/generic/vscpythonpackage.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/generic/waf.py b/easybuild/easyblocks/generic/waf.py index bc0f2885b7..30d36a72dd 100644 --- a/easybuild/easyblocks/generic/waf.py +++ b/easybuild/easyblocks/generic/waf.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/h/hadoop.py b/easybuild/easyblocks/h/hadoop.py index 26805dcd54..aa1ec66619 100644 --- a/easybuild/easyblocks/h/hadoop.py +++ b/easybuild/easyblocks/h/hadoop.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/h/hdf5.py b/easybuild/easyblocks/h/hdf5.py index f96942e841..6ee28991e3 100644 --- a/easybuild/easyblocks/h/hdf5.py +++ b/easybuild/easyblocks/h/hdf5.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/h/healpix.py b/easybuild/easyblocks/h/healpix.py index 08170825e5..badc564abb 100644 --- a/easybuild/easyblocks/h/healpix.py +++ b/easybuild/easyblocks/h/healpix.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/h/hpcg.py b/easybuild/easyblocks/h/hpcg.py index be80012ba3..8d68fa34ea 100644 --- a/easybuild/easyblocks/h/hpcg.py +++ b/easybuild/easyblocks/h/hpcg.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/h/hpl.py b/easybuild/easyblocks/h/hpl.py index 21e700141b..d408a7b05e 100644 --- a/easybuild/easyblocks/h/hpl.py +++ b/easybuild/easyblocks/h/hpl.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/h/hypre.py b/easybuild/easyblocks/h/hypre.py index 229f323203..556d40ff7b 100644 --- a/easybuild/easyblocks/h/hypre.py +++ b/easybuild/easyblocks/h/hypre.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/icc.py b/easybuild/easyblocks/i/icc.py index 55534a2897..37651f9e30 100644 --- a/easybuild/easyblocks/i/icc.py +++ b/easybuild/easyblocks/i/icc.py @@ -1,5 +1,5 @@ # # -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/iccifort.py b/easybuild/easyblocks/i/iccifort.py index 3e41077951..b2f0d01492 100644 --- a/easybuild/easyblocks/i/iccifort.py +++ b/easybuild/easyblocks/i/iccifort.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Bart Oldeman, McGill University, Compute Canada +# Copyright 2019-2023 Bart Oldeman, McGill University, Compute Canada # # This file is triple-licensed under GPLv2 (see below), MIT, and # BSD three-clause licenses. diff --git a/easybuild/easyblocks/i/ifort.py b/easybuild/easyblocks/i/ifort.py index 679d7d410c..d47013a510 100644 --- a/easybuild/easyblocks/i/ifort.py +++ b/easybuild/easyblocks/i/ifort.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/imkl.py b/easybuild/easyblocks/i/imkl.py index 487915edda..c2bb129b2e 100644 --- a/easybuild/easyblocks/i/imkl.py +++ b/easybuild/easyblocks/i/imkl.py @@ -1,5 +1,5 @@ # # -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/imkl_fftw.py b/easybuild/easyblocks/i/imkl_fftw.py index 80d4c26a0a..e8f8ee4cce 100644 --- a/easybuild/easyblocks/i/imkl_fftw.py +++ b/easybuild/easyblocks/i/imkl_fftw.py @@ -1,5 +1,5 @@ # # -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/imod.py b/easybuild/easyblocks/i/imod.py index 97393a3a61..75d0760041 100644 --- a/easybuild/easyblocks/i/imod.py +++ b/easybuild/easyblocks/i/imod.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/impi.py b/easybuild/easyblocks/i/impi.py index ee443ff2f2..7eee0df099 100644 --- a/easybuild/easyblocks/i/impi.py +++ b/easybuild/easyblocks/i/impi.py @@ -1,5 +1,5 @@ # # -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/inspector.py b/easybuild/easyblocks/i/inspector.py index 0db52d56d9..e3ce7653b1 100644 --- a/easybuild/easyblocks/i/inspector.py +++ b/easybuild/easyblocks/i/inspector.py @@ -1,5 +1,5 @@ # # -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/intel_compilers.py b/easybuild/easyblocks/i/intel_compilers.py index 28089de5af..3d6d9b030e 100644 --- a/easybuild/easyblocks/i/intel_compilers.py +++ b/easybuild/easyblocks/i/intel_compilers.py @@ -1,5 +1,5 @@ # # -# Copyright 2021-2022 Ghent University +# Copyright 2021-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/ipp.py b/easybuild/easyblocks/i/ipp.py index 8ff436685d..789a44d71c 100644 --- a/easybuild/easyblocks/i/ipp.py +++ b/easybuild/easyblocks/i/ipp.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/ironpython.py b/easybuild/easyblocks/i/ironpython.py index 07874520fb..9b5eee4111 100644 --- a/easybuild/easyblocks/i/ironpython.py +++ b/easybuild/easyblocks/i/ironpython.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/i/itac.py b/easybuild/easyblocks/i/itac.py index 197d154fae..1f37b8ab01 100644 --- a/easybuild/easyblocks/i/itac.py +++ b/easybuild/easyblocks/i/itac.py @@ -1,5 +1,5 @@ # # -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/j/java.py b/easybuild/easyblocks/j/java.py index 2c3535969d..63e0499321 100644 --- a/easybuild/easyblocks/j/java.py +++ b/easybuild/easyblocks/j/java.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/j/jaxlib.py b/easybuild/easyblocks/j/jaxlib.py index 0776da73d0..dac39bf16c 100644 --- a/easybuild/easyblocks/j/jaxlib.py +++ b/easybuild/easyblocks/j/jaxlib.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/lammps.py b/easybuild/easyblocks/l/lammps.py index e4ad3962db..5c3d77fdb0 100644 --- a/easybuild/easyblocks/l/lammps.py +++ b/easybuild/easyblocks/l/lammps.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/lapack.py b/easybuild/easyblocks/l/lapack.py index b60ecf791d..112875a8fa 100644 --- a/easybuild/easyblocks/l/lapack.py +++ b/easybuild/easyblocks/l/lapack.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/libdrm.py b/easybuild/easyblocks/l/libdrm.py index ece8c023ae..5cc2786f69 100644 --- a/easybuild/easyblocks/l/libdrm.py +++ b/easybuild/easyblocks/l/libdrm.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/libint.py b/easybuild/easyblocks/l/libint.py index f2e6fa4ba8..aa76bb6020 100644 --- a/easybuild/easyblocks/l/libint.py +++ b/easybuild/easyblocks/l/libint.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/libqglviewer.py b/easybuild/easyblocks/l/libqglviewer.py index ec9dfd0c16..55d6a5d0a6 100644 --- a/easybuild/easyblocks/l/libqglviewer.py +++ b/easybuild/easyblocks/l/libqglviewer.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/libsmm.py b/easybuild/easyblocks/l/libsmm.py index 6addd7081e..19a9f6c145 100644 --- a/easybuild/easyblocks/l/libsmm.py +++ b/easybuild/easyblocks/l/libsmm.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/libxml2.py b/easybuild/easyblocks/l/libxml2.py index cab458fec5..73e83cc804 100644 --- a/easybuild/easyblocks/l/libxml2.py +++ b/easybuild/easyblocks/l/libxml2.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/llvm.py b/easybuild/easyblocks/l/llvm.py index 36c376b4fd..c7f06d6b6e 100644 --- a/easybuild/easyblocks/l/llvm.py +++ b/easybuild/easyblocks/l/llvm.py @@ -1,5 +1,5 @@ ## -# Copyright 2020-2022 Ghent University +# Copyright 2020-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/l/lua.py b/easybuild/easyblocks/l/lua.py index fce55919ce..16fc4065e1 100644 --- a/easybuild/easyblocks/l/lua.py +++ b/easybuild/easyblocks/l/lua.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mamba.py b/easybuild/easyblocks/m/mamba.py index bba972ae1a..c6cfd49e0b 100644 --- a/easybuild/easyblocks/m/mamba.py +++ b/easybuild/easyblocks/m/mamba.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/maple.py b/easybuild/easyblocks/m/maple.py index e41e47517f..14621e8515 100644 --- a/easybuild/easyblocks/m/maple.py +++ b/easybuild/easyblocks/m/maple.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mathematica.py b/easybuild/easyblocks/m/mathematica.py index 288321d063..13a3080ff4 100644 --- a/easybuild/easyblocks/m/mathematica.py +++ b/easybuild/easyblocks/m/mathematica.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index bb0487560e..e1b65d77a8 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mcr.py b/easybuild/easyblocks/m/mcr.py index f3f3830d26..49cb3b36f4 100644 --- a/easybuild/easyblocks/m/mcr.py +++ b/easybuild/easyblocks/m/mcr.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mesa.py b/easybuild/easyblocks/m/mesa.py index 02c6dba274..684f37c2be 100644 --- a/easybuild/easyblocks/m/mesa.py +++ b/easybuild/easyblocks/m/mesa.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/metagenome_atlas.py b/easybuild/easyblocks/m/metagenome_atlas.py index 90536059d6..3658b5cfa6 100644 --- a/easybuild/easyblocks/m/metagenome_atlas.py +++ b/easybuild/easyblocks/m/metagenome_atlas.py @@ -1,5 +1,5 @@ ## -# Copyright 2020-2022 Ghent University +# Copyright 2020-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/metavelvet.py b/easybuild/easyblocks/m/metavelvet.py index bcbda38285..57311202e1 100644 --- a/easybuild/easyblocks/m/metavelvet.py +++ b/easybuild/easyblocks/m/metavelvet.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/m/metis.py b/easybuild/easyblocks/m/metis.py index 2e4aa03f1c..b8582b7842 100644 --- a/easybuild/easyblocks/m/metis.py +++ b/easybuild/easyblocks/m/metis.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/modeller.py b/easybuild/easyblocks/m/modeller.py index 57ea0aa3e2..feb1876b16 100755 --- a/easybuild/easyblocks/m/modeller.py +++ b/easybuild/easyblocks/m/modeller.py @@ -1,5 +1,5 @@ ## -# Copyright 2014-2022 Ghent University +# Copyright 2014-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of the University of Ghent (http://ugent.be/hpc). diff --git a/easybuild/easyblocks/m/molpro.py b/easybuild/easyblocks/m/molpro.py index e65bed2401..86358f0dcd 100644 --- a/easybuild/easyblocks/m/molpro.py +++ b/easybuild/easyblocks/m/molpro.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mono.py b/easybuild/easyblocks/m/mono.py index 31e04439c7..b23088ba65 100644 --- a/easybuild/easyblocks/m/mono.py +++ b/easybuild/easyblocks/m/mono.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mothur.py b/easybuild/easyblocks/m/mothur.py index 406294779e..78f5f0f832 100644 --- a/easybuild/easyblocks/m/mothur.py +++ b/easybuild/easyblocks/m/mothur.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/motioncor2.py b/easybuild/easyblocks/m/motioncor2.py index 12201abb0f..9224e89d9b 100644 --- a/easybuild/easyblocks/m/motioncor2.py +++ b/easybuild/easyblocks/m/motioncor2.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Ghent University +# Copyright 2019-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mpich.py b/easybuild/easyblocks/m/mpich.py index 9ab7c65e92..df97d7265b 100644 --- a/easybuild/easyblocks/m/mpich.py +++ b/easybuild/easyblocks/m/mpich.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University, Forschungszentrum Juelich +# Copyright 2009-2023 Ghent University, Forschungszentrum Juelich # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mrbayes.py b/easybuild/easyblocks/m/mrbayes.py index 097f73839a..8fc399b5d3 100644 --- a/easybuild/easyblocks/m/mrbayes.py +++ b/easybuild/easyblocks/m/mrbayes.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mrtrix.py b/easybuild/easyblocks/m/mrtrix.py index 094d368f4f..7b148131a8 100644 --- a/easybuild/easyblocks/m/mrtrix.py +++ b/easybuild/easyblocks/m/mrtrix.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/msm.py b/easybuild/easyblocks/m/msm.py index 04f3903831..1269e198ad 100644 --- a/easybuild/easyblocks/m/msm.py +++ b/easybuild/easyblocks/m/msm.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mtl4.py b/easybuild/easyblocks/m/mtl4.py index fc922cb1eb..e788498643 100644 --- a/easybuild/easyblocks/m/mtl4.py +++ b/easybuild/easyblocks/m/mtl4.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mummer.py b/easybuild/easyblocks/m/mummer.py index 244ae489bd..a5038cb895 100644 --- a/easybuild/easyblocks/m/mummer.py +++ b/easybuild/easyblocks/m/mummer.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of the University of Ghent (http://ugent.be/hpc). diff --git a/easybuild/easyblocks/m/mumps.py b/easybuild/easyblocks/m/mumps.py index fcbf206cd9..26c43adbf9 100644 --- a/easybuild/easyblocks/m/mumps.py +++ b/easybuild/easyblocks/m/mumps.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mutil.py b/easybuild/easyblocks/m/mutil.py index dcb8e3d10e..bb0d8dc11b 100644 --- a/easybuild/easyblocks/m/mutil.py +++ b/easybuild/easyblocks/m/mutil.py @@ -1,5 +1,5 @@ ## -# Copyright 2016-2022 Ghent University +# Copyright 2016-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mvapich2.py b/easybuild/easyblocks/m/mvapich2.py index e319aab8b8..3aecd40103 100644 --- a/easybuild/easyblocks/m/mvapich2.py +++ b/easybuild/easyblocks/m/mvapich2.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University, Forschungszentrum Juelich +# Copyright 2009-2023 Ghent University, Forschungszentrum Juelich # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mxnet.py b/easybuild/easyblocks/m/mxnet.py index e8a865ef20..7dee5aeed6 100644 --- a/easybuild/easyblocks/m/mxnet.py +++ b/easybuild/easyblocks/m/mxnet.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Free University of Brussels (VUB) +# Copyright 2018-2023 Free University of Brussels (VUB) # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/m/mymedialite.py b/easybuild/easyblocks/m/mymedialite.py index 6b78a342ce..d4876e2d31 100644 --- a/easybuild/easyblocks/m/mymedialite.py +++ b/easybuild/easyblocks/m/mymedialite.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/namd.py b/easybuild/easyblocks/n/namd.py index b48503bf2b..4c84f9bcfd 100644 --- a/easybuild/easyblocks/n/namd.py +++ b/easybuild/easyblocks/n/namd.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2013-2022 CaSToRC, The Cyprus Institute +# Copyright:: Copyright 2013-2023 CaSToRC, The Cyprus Institute # Authors:: George Tsouloupas # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/n/nccl.py b/easybuild/easyblocks/n/nccl.py index 33ec98b675..e51707013f 100644 --- a/easybuild/easyblocks/n/nccl.py +++ b/easybuild/easyblocks/n/nccl.py @@ -1,5 +1,5 @@ ## -# Copyright 2021-2022 Ghent University +# Copyright 2021-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/ncl.py b/easybuild/easyblocks/n/ncl.py index 34cebdd2b6..ddc0b3cc99 100644 --- a/easybuild/easyblocks/n/ncl.py +++ b/easybuild/easyblocks/n/ncl.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/ncurses.py b/easybuild/easyblocks/n/ncurses.py index e8a0a75af9..019d31b153 100644 --- a/easybuild/easyblocks/n/ncurses.py +++ b/easybuild/easyblocks/n/ncurses.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/n/nemo.py b/easybuild/easyblocks/n/nemo.py index 3116e4c23c..bb6cfad970 100644 --- a/easybuild/easyblocks/n/nemo.py +++ b/easybuild/easyblocks/n/nemo.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/netcdf.py b/easybuild/easyblocks/n/netcdf.py index 83289a936e..9ac62ff72c 100644 --- a/easybuild/easyblocks/n/netcdf.py +++ b/easybuild/easyblocks/n/netcdf.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/netcdf4_python.py b/easybuild/easyblocks/n/netcdf4_python.py index 4c24e96e0e..a78dab4f4b 100644 --- a/easybuild/easyblocks/n/netcdf4_python.py +++ b/easybuild/easyblocks/n/netcdf4_python.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/netcdf_fortran.py b/easybuild/easyblocks/n/netcdf_fortran.py index 774e63c50c..9de127e0a0 100644 --- a/easybuild/easyblocks/n/netcdf_fortran.py +++ b/easybuild/easyblocks/n/netcdf_fortran.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/neuron.py b/easybuild/easyblocks/n/neuron.py index 6084b87a91..a094670be6 100644 --- a/easybuild/easyblocks/n/neuron.py +++ b/easybuild/easyblocks/n/neuron.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/nim.py b/easybuild/easyblocks/n/nim.py index fa524380fe..3ecc804cff 100644 --- a/easybuild/easyblocks/n/nim.py +++ b/easybuild/easyblocks/n/nim.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/nose.py b/easybuild/easyblocks/n/nose.py index 7cbc785585..091f6a756d 100644 --- a/easybuild/easyblocks/n/nose.py +++ b/easybuild/easyblocks/n/nose.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/numexpr.py b/easybuild/easyblocks/n/numexpr.py index cce57b69ea..b5d23e73d0 100644 --- a/easybuild/easyblocks/n/numexpr.py +++ b/easybuild/easyblocks/n/numexpr.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Ghent University +# Copyright 2019-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/numpy.py b/easybuild/easyblocks/n/numpy.py index 484a8d9f72..f72e2671d4 100644 --- a/easybuild/easyblocks/n/numpy.py +++ b/easybuild/easyblocks/n/numpy.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/n/nvhpc.py b/easybuild/easyblocks/n/nvhpc.py index eabb8f0600..2eafd4a807 100644 --- a/easybuild/easyblocks/n/nvhpc.py +++ b/easybuild/easyblocks/n/nvhpc.py @@ -1,6 +1,6 @@ ## -# Copyright 2015-2022 Bart Oldeman -# Copyright 2016-2022 Forschungszentrum Juelich +# Copyright 2015-2023 Bart Oldeman +# Copyright 2016-2023 Forschungszentrum Juelich # # This file is triple-licensed under GPLv2 (see below), MIT, and # BSD three-clause licenses. diff --git a/easybuild/easyblocks/n/nwchem.py b/easybuild/easyblocks/n/nwchem.py index b3ba6d8b1a..667b0bbd1e 100644 --- a/easybuild/easyblocks/n/nwchem.py +++ b/easybuild/easyblocks/n/nwchem.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/ocaml.py b/easybuild/easyblocks/o/ocaml.py index e514aea86c..fb43648798 100644 --- a/easybuild/easyblocks/o/ocaml.py +++ b/easybuild/easyblocks/o/ocaml.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/octave.py b/easybuild/easyblocks/o/octave.py index 06ad78d0bb..d810251351 100644 --- a/easybuild/easyblocks/o/octave.py +++ b/easybuild/easyblocks/o/octave.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/openbabel.py b/easybuild/easyblocks/o/openbabel.py index 11858d37e4..b054cc56b0 100644 --- a/easybuild/easyblocks/o/openbabel.py +++ b/easybuild/easyblocks/o/openbabel.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/opencv.py b/easybuild/easyblocks/o/opencv.py index 564b41bc35..4b1511af1b 100644 --- a/easybuild/easyblocks/o/opencv.py +++ b/easybuild/easyblocks/o/opencv.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2022 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/openfoam.py b/easybuild/easyblocks/o/openfoam.py index 82327581b0..7c8717b455 100644 --- a/easybuild/easyblocks/o/openfoam.py +++ b/easybuild/easyblocks/o/openfoam.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/openifs.py b/easybuild/easyblocks/o/openifs.py index fc06601b0f..2fd8c5a137 100644 --- a/easybuild/easyblocks/o/openifs.py +++ b/easybuild/easyblocks/o/openifs.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/openmpi.py b/easybuild/easyblocks/o/openmpi.py index a017cc3171..dc510f723f 100644 --- a/easybuild/easyblocks/o/openmpi.py +++ b/easybuild/easyblocks/o/openmpi.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Ghent University +# Copyright 2019-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/openssl.py b/easybuild/easyblocks/o/openssl.py index 2235e4d19c..8238772899 100644 --- a/easybuild/easyblocks/o/openssl.py +++ b/easybuild/easyblocks/o/openssl.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/openssl_wrapper.py b/easybuild/easyblocks/o/openssl_wrapper.py index 908313214c..bd6c50341e 100644 --- a/easybuild/easyblocks/o/openssl_wrapper.py +++ b/easybuild/easyblocks/o/openssl_wrapper.py @@ -1,5 +1,5 @@ ## -# Copyright 2021 Vrije Universiteit Brussel +# Copyright 2021-2023 Vrije Universiteit Brussel # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/o/orca.py b/easybuild/easyblocks/o/orca.py index 636544976e..e6066a28eb 100644 --- a/easybuild/easyblocks/o/orca.py +++ b/easybuild/easyblocks/o/orca.py @@ -1,5 +1,5 @@ ## -# Copyright 2021 Vrije Universiteit Brussel +# Copyright 2021-2023 Vrije Universiteit Brussel # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/paraver.py b/easybuild/easyblocks/p/paraver.py index 2b113a0578..181d660707 100644 --- a/easybuild/easyblocks/p/paraver.py +++ b/easybuild/easyblocks/p/paraver.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/parmetis.py b/easybuild/easyblocks/p/parmetis.py index 8a73ff3d47..a9885b1c75 100644 --- a/easybuild/easyblocks/p/parmetis.py +++ b/easybuild/easyblocks/p/parmetis.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pasha.py b/easybuild/easyblocks/p/pasha.py index 0f9e05a21b..7d1c87e81c 100644 --- a/easybuild/easyblocks/p/pasha.py +++ b/easybuild/easyblocks/p/pasha.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pbdmpi.py b/easybuild/easyblocks/p/pbdmpi.py index b2f83d8146..73e23b0ae5 100644 --- a/easybuild/easyblocks/p/pbdmpi.py +++ b/easybuild/easyblocks/p/pbdmpi.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pbdslap.py b/easybuild/easyblocks/p/pbdslap.py index a15fc1a7fb..f30d131ff4 100644 --- a/easybuild/easyblocks/p/pbdslap.py +++ b/easybuild/easyblocks/p/pbdslap.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pdt.py b/easybuild/easyblocks/p/pdt.py index bf9cef0021..253c2f5bbb 100644 --- a/easybuild/easyblocks/p/pdt.py +++ b/easybuild/easyblocks/p/pdt.py @@ -1,7 +1,7 @@ ## # This is an easyblock for EasyBuild, see https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2015-2022 Juelich Supercomputing Centre, Germany +# Copyright:: Copyright 2015-2023 Juelich Supercomputing Centre, Germany # Authors:: Bernd Mohr # Markus Geimer # License:: 3-clause BSD diff --git a/easybuild/easyblocks/p/perl.py b/easybuild/easyblocks/p/perl.py index cc2593c1e7..d96505ce7d 100644 --- a/easybuild/easyblocks/p/perl.py +++ b/easybuild/easyblocks/p/perl.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py index 00af8bf532..a335132c6b 100644 --- a/easybuild/easyblocks/p/petsc.py +++ b/easybuild/easyblocks/p/petsc.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pgi.py b/easybuild/easyblocks/p/pgi.py index 2b033afd12..8d34ae7b06 100644 --- a/easybuild/easyblocks/p/pgi.py +++ b/easybuild/easyblocks/p/pgi.py @@ -1,6 +1,6 @@ ## -# Copyright 2015-2022 Bart Oldeman -# Copyright 2016-2022 Forschungszentrum Juelich +# Copyright 2015-2023 Bart Oldeman +# Copyright 2016-2023 Forschungszentrum Juelich # # This file is triple-licensed under GPLv2 (see below), MIT, and # BSD three-clause licenses. diff --git a/easybuild/easyblocks/p/picard.py b/easybuild/easyblocks/p/picard.py index 957b7e9cc4..b9f2d1a9b1 100644 --- a/easybuild/easyblocks/p/picard.py +++ b/easybuild/easyblocks/p/picard.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pplacer.py b/easybuild/easyblocks/p/pplacer.py index feb7d090bc..8e85666dd6 100644 --- a/easybuild/easyblocks/p/pplacer.py +++ b/easybuild/easyblocks/p/pplacer.py @@ -1,5 +1,5 @@ ## -# Copyright 2016-2022 Ghent University +# Copyright 2016-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/primer3.py b/easybuild/easyblocks/p/primer3.py index 64acf988bd..31995b2550 100644 --- a/easybuild/easyblocks/p/primer3.py +++ b/easybuild/easyblocks/p/primer3.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/psi.py b/easybuild/easyblocks/p/psi.py index 20c1344f8f..af400c3cec 100644 --- a/easybuild/easyblocks/p/psi.py +++ b/easybuild/easyblocks/p/psi.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/psmpi.py b/easybuild/easyblocks/p/psmpi.py index 2ed83d18e8..755cc1f809 100644 --- a/easybuild/easyblocks/p/psmpi.py +++ b/easybuild/easyblocks/p/psmpi.py @@ -1,5 +1,5 @@ ## -# Copyright 2016-2022 Ghent University, Forschungszentrum Juelich +# Copyright 2016-2023 Ghent University, Forschungszentrum Juelich # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pybind11.py b/easybuild/easyblocks/p/pybind11.py index 799a604bba..09d711b28c 100644 --- a/easybuild/easyblocks/p/pybind11.py +++ b/easybuild/easyblocks/p/pybind11.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pyquante.py b/easybuild/easyblocks/p/pyquante.py index e2476fb17f..8bfaf5be3f 100644 --- a/easybuild/easyblocks/p/pyquante.py +++ b/easybuild/easyblocks/p/pyquante.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/python.py b/easybuild/easyblocks/p/python.py index 536aa07aca..465d069a67 100644 --- a/easybuild/easyblocks/p/python.py +++ b/easybuild/easyblocks/p/python.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/python_meep.py b/easybuild/easyblocks/p/python_meep.py index 94877e561c..106d31392a 100644 --- a/easybuild/easyblocks/p/python_meep.py +++ b/easybuild/easyblocks/p/python_meep.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index bc1cf90e12..9a7637fed1 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -1,5 +1,5 @@ ## -# Copyright 2020-2022 Ghent University +# Copyright 2020-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/p/pyzmq.py b/easybuild/easyblocks/p/pyzmq.py index 2d719efef8..8007d936bb 100644 --- a/easybuild/easyblocks/p/pyzmq.py +++ b/easybuild/easyblocks/p/pyzmq.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/q/qscintilla.py b/easybuild/easyblocks/q/qscintilla.py index c7b993d840..a712222c48 100644 --- a/easybuild/easyblocks/q/qscintilla.py +++ b/easybuild/easyblocks/q/qscintilla.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/q/qt.py b/easybuild/easyblocks/q/qt.py index 034065f475..cc23f27a99 100644 --- a/easybuild/easyblocks/q/qt.py +++ b/easybuild/easyblocks/q/qt.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 89c94b0058..b5a232817b 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/__init__.py b/easybuild/easyblocks/r/__init__.py index 119b78d134..d1e94b14c8 100644 --- a/easybuild/easyblocks/r/__init__.py +++ b/easybuild/easyblocks/r/__init__.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/r.py b/easybuild/easyblocks/r/r.py index 0e93e9c7a0..5f73952873 100644 --- a/easybuild/easyblocks/r/r.py +++ b/easybuild/easyblocks/r/r.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/repeatmasker.py b/easybuild/easyblocks/r/repeatmasker.py index 5634b12ce1..0a4d10329b 100644 --- a/easybuild/easyblocks/r/repeatmasker.py +++ b/easybuild/easyblocks/r/repeatmasker.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/repeatmodeler.py b/easybuild/easyblocks/r/repeatmodeler.py index 5edce4d0c3..122f64cc4c 100644 --- a/easybuild/easyblocks/r/repeatmodeler.py +++ b/easybuild/easyblocks/r/repeatmodeler.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/reticulate.py b/easybuild/easyblocks/r/reticulate.py index a6850c0552..7d5a7a79d5 100644 --- a/easybuild/easyblocks/r/reticulate.py +++ b/easybuild/easyblocks/r/reticulate.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/rmpi.py b/easybuild/easyblocks/r/rmpi.py index dc58e9d813..c9a1528acd 100644 --- a/easybuild/easyblocks/r/rmpi.py +++ b/easybuild/easyblocks/r/rmpi.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/root.py b/easybuild/easyblocks/r/root.py index 5e80a1ec9c..872671eb4b 100644 --- a/easybuild/easyblocks/r/root.py +++ b/easybuild/easyblocks/r/root.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/rosetta.py b/easybuild/easyblocks/r/rosetta.py index d968d76354..71630c7902 100644 --- a/easybuild/easyblocks/r/rosetta.py +++ b/easybuild/easyblocks/r/rosetta.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/rserve.py b/easybuild/easyblocks/r/rserve.py index 444101f207..e06b7007b1 100644 --- a/easybuild/easyblocks/r/rserve.py +++ b/easybuild/easyblocks/r/rserve.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/r/ruby.py b/easybuild/easyblocks/r/ruby.py index d811cc2de8..80b66064f3 100644 --- a/easybuild/easyblocks/r/ruby.py +++ b/easybuild/easyblocks/r/ruby.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/samcef.py b/easybuild/easyblocks/s/samcef.py index 262e6182a2..2f5e7b69d4 100644 --- a/easybuild/easyblocks/s/samcef.py +++ b/easybuild/easyblocks/s/samcef.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/samtools.py b/easybuild/easyblocks/s/samtools.py index f0d88a88e7..6d297c2283 100644 --- a/easybuild/easyblocks/s/samtools.py +++ b/easybuild/easyblocks/s/samtools.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/s/sas.py b/easybuild/easyblocks/s/sas.py index 6321d965d7..31e6c20b50 100644 --- a/easybuild/easyblocks/s/sas.py +++ b/easybuild/easyblocks/s/sas.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/scalapack.py b/easybuild/easyblocks/s/scalapack.py index 7c71c31d4a..466fef57c3 100644 --- a/easybuild/easyblocks/s/scalapack.py +++ b/easybuild/easyblocks/s/scalapack.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/scalasca1.py b/easybuild/easyblocks/s/scalasca1.py index d91b17f5fc..a78398cc9d 100644 --- a/easybuild/easyblocks/s/scalasca1.py +++ b/easybuild/easyblocks/s/scalasca1.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/scipion.py b/easybuild/easyblocks/s/scipion.py index 0d5bd9e348..86d7460a33 100644 --- a/easybuild/easyblocks/s/scipion.py +++ b/easybuild/easyblocks/s/scipion.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Ghent University +# Copyright 2019-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 9f32eb8466..c4ebd92ed9 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/score_p.py b/easybuild/easyblocks/s/score_p.py index d8cdb386a4..410fea4cb7 100644 --- a/easybuild/easyblocks/s/score_p.py +++ b/easybuild/easyblocks/s/score_p.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/scotch.py b/easybuild/easyblocks/s/scotch.py index 5251848124..89c728f7c9 100644 --- a/easybuild/easyblocks/s/scotch.py +++ b/easybuild/easyblocks/s/scotch.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/sepp.py b/easybuild/easyblocks/s/sepp.py index 78141f5efe..389f591219 100644 --- a/easybuild/easyblocks/s/sepp.py +++ b/easybuild/easyblocks/s/sepp.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/shrimp.py b/easybuild/easyblocks/s/shrimp.py index 4e873ad1af..c4a09fab69 100644 --- a/easybuild/easyblocks/s/shrimp.py +++ b/easybuild/easyblocks/s/shrimp.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/siesta.py b/easybuild/easyblocks/s/siesta.py index a5f250c5ce..81b132236e 100644 --- a/easybuild/easyblocks/s/siesta.py +++ b/easybuild/easyblocks/s/siesta.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/slepc.py b/easybuild/easyblocks/s/slepc.py index 395da82436..0254f195ad 100644 --- a/easybuild/easyblocks/s/slepc.py +++ b/easybuild/easyblocks/s/slepc.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/snphylo.py b/easybuild/easyblocks/s/snphylo.py index 26834d2de1..88eb26f7ae 100644 --- a/easybuild/easyblocks/s/snphylo.py +++ b/easybuild/easyblocks/s/snphylo.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/soapdenovo.py b/easybuild/easyblocks/s/soapdenovo.py index 0848bb7d0e..f404470ce8 100644 --- a/easybuild/easyblocks/s/soapdenovo.py +++ b/easybuild/easyblocks/s/soapdenovo.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/s/star_ccm.py b/easybuild/easyblocks/s/star_ccm.py index c3b6658585..7f981e9b36 100644 --- a/easybuild/easyblocks/s/star_ccm.py +++ b/easybuild/easyblocks/s/star_ccm.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2019 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/stata.py b/easybuild/easyblocks/s/stata.py index 1cc4703d30..6fd83d850a 100644 --- a/easybuild/easyblocks/s/stata.py +++ b/easybuild/easyblocks/s/stata.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/suitesparse.py b/easybuild/easyblocks/s/suitesparse.py index 2cff1575ce..f25fc66785 100644 --- a/easybuild/easyblocks/s/suitesparse.py +++ b/easybuild/easyblocks/s/suitesparse.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/superlu.py b/easybuild/easyblocks/s/superlu.py index 40042409ac..eafa3c1e3e 100644 --- a/easybuild/easyblocks/s/superlu.py +++ b/easybuild/easyblocks/s/superlu.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University, University of Luxembourg +# Copyright 2009-2023 Ghent University, University of Luxembourg # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/s/swig.py b/easybuild/easyblocks/s/swig.py index 2322661b60..d434e9f34f 100644 --- a/easybuild/easyblocks/s/swig.py +++ b/easybuild/easyblocks/s/swig.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/tau.py b/easybuild/easyblocks/t/tau.py index 5e4a89cf6c..33ca3ea127 100644 --- a/easybuild/easyblocks/t/tau.py +++ b/easybuild/easyblocks/t/tau.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/tbb.py b/easybuild/easyblocks/t/tbb.py index f5bb348226..1ce9ee6750 100644 --- a/easybuild/easyblocks/t/tbb.py +++ b/easybuild/easyblocks/t/tbb.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 8580cda991..e8912c2b2c 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -1,5 +1,5 @@ ## -# Copyright 2017-2022 Ghent University +# Copyright 2017-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/tensorrt.py b/easybuild/easyblocks/t/tensorrt.py index e438658803..204302e7d6 100644 --- a/easybuild/easyblocks/t/tensorrt.py +++ b/easybuild/easyblocks/t/tensorrt.py @@ -1,5 +1,5 @@ ## -# Copyright 2017-2022 Ghent University +# Copyright 2017-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/tinker.py b/easybuild/easyblocks/t/tinker.py index 0eac1f609b..4892873b0d 100644 --- a/easybuild/easyblocks/t/tinker.py +++ b/easybuild/easyblocks/t/tinker.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/tkinter.py b/easybuild/easyblocks/t/tkinter.py index ec853d89a9..8f4312f4b5 100644 --- a/easybuild/easyblocks/t/tkinter.py +++ b/easybuild/easyblocks/t/tkinter.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/torchvision.py b/easybuild/easyblocks/t/torchvision.py index 1613a79be2..197ff15c67 100644 --- a/easybuild/easyblocks/t/torchvision.py +++ b/easybuild/easyblocks/t/torchvision.py @@ -1,5 +1,5 @@ ## -# Copyright 2021-2022 Ghent University +# Copyright 2021-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/tornado.py b/easybuild/easyblocks/t/tornado.py index 86c4f222ef..98a1c59705 100644 --- a/easybuild/easyblocks/t/tornado.py +++ b/easybuild/easyblocks/t/tornado.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/totalview.py b/easybuild/easyblocks/t/totalview.py index 3e5de8fb82..2cd8234d03 100644 --- a/easybuild/easyblocks/t/totalview.py +++ b/easybuild/easyblocks/t/totalview.py @@ -1,8 +1,8 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA -# Copyright:: Copyright 2016-2022 Forschungszentrum Juelich +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2016-2023 Forschungszentrum Juelich # Authors:: Fotis Georgatos # Authors:: Damian Alvarez # License:: MIT/GPL diff --git a/easybuild/easyblocks/t/trilinos.py b/easybuild/easyblocks/t/trilinos.py index 6261e821f5..4fa0ab9148 100644 --- a/easybuild/easyblocks/t/trilinos.py +++ b/easybuild/easyblocks/t/trilinos.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/t/trinity.py b/easybuild/easyblocks/t/trinity.py index a69d1229df..7eeedf6e09 100644 --- a/easybuild/easyblocks/t/trinity.py +++ b/easybuild/easyblocks/t/trinity.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/u/ucx_plugins.py b/easybuild/easyblocks/u/ucx_plugins.py index e74758f063..10e5a97e13 100644 --- a/easybuild/easyblocks/u/ucx_plugins.py +++ b/easybuild/easyblocks/u/ucx_plugins.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/u/ufc.py b/easybuild/easyblocks/u/ufc.py index 1bb7caaac3..f77cf7ea24 100644 --- a/easybuild/easyblocks/u/ufc.py +++ b/easybuild/easyblocks/u/ufc.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/v/velvet.py b/easybuild/easyblocks/v/velvet.py index 7f410c6657..c79f6ff995 100644 --- a/easybuild/easyblocks/v/velvet.py +++ b/easybuild/easyblocks/v/velvet.py @@ -1,7 +1,7 @@ ## # This file is an EasyBuild reciPY as per https://github.com/easybuilders/easybuild # -# Copyright:: Copyright 2012-2022 Uni.Lu/LCSB, NTUA +# Copyright:: Copyright 2012-2023 Uni.Lu/LCSB, NTUA # Authors:: Cedric Laczny , Fotis Georgatos , Kenneth Hoste # License:: MIT/GPL # $Id$ diff --git a/easybuild/easyblocks/v/vep.py b/easybuild/easyblocks/v/vep.py index c9f5b9233c..c339abbe0a 100644 --- a/easybuild/easyblocks/v/vep.py +++ b/easybuild/easyblocks/v/vep.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/v/vmd.py b/easybuild/easyblocks/v/vmd.py index 43c32354a4..c7273ab5c6 100644 --- a/easybuild/easyblocks/v/vmd.py +++ b/easybuild/easyblocks/v/vmd.py @@ -1,6 +1,6 @@ ## -# Copyright 2009-2022 Ghent University -# Copyright 2015-2022 Stanford University +# Copyright 2009-2023 Ghent University +# Copyright 2015-2023 Stanford University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/v/vsc_tools.py b/easybuild/easyblocks/v/vsc_tools.py index ae520eb1ec..83611fdf73 100644 --- a/easybuild/easyblocks/v/vsc_tools.py +++ b/easybuild/easyblocks/v/vsc_tools.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/v/vtune.py b/easybuild/easyblocks/v/vtune.py index 00724666ec..40253f57af 100644 --- a/easybuild/easyblocks/v/vtune.py +++ b/easybuild/easyblocks/v/vtune.py @@ -1,5 +1,5 @@ # # -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/w/wien2k.py b/easybuild/easyblocks/w/wien2k.py index 1eb6671b8c..07c32ad40c 100644 --- a/easybuild/easyblocks/w/wien2k.py +++ b/easybuild/easyblocks/w/wien2k.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/w/wps.py b/easybuild/easyblocks/w/wps.py index 9536e24e29..d6c6cca849 100644 --- a/easybuild/easyblocks/w/wps.py +++ b/easybuild/easyblocks/w/wps.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/w/wrf.py b/easybuild/easyblocks/w/wrf.py index dc520e08bc..b232400724 100644 --- a/easybuild/easyblocks/w/wrf.py +++ b/easybuild/easyblocks/w/wrf.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/w/wrf_fire.py b/easybuild/easyblocks/w/wrf_fire.py index d3e0017de7..ce5ea7d82a 100644 --- a/easybuild/easyblocks/w/wrf_fire.py +++ b/easybuild/easyblocks/w/wrf_fire.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/w/wxpython.py b/easybuild/easyblocks/w/wxpython.py index b777a669ba..35b22b1867 100644 --- a/easybuild/easyblocks/w/wxpython.py +++ b/easybuild/easyblocks/w/wxpython.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/x/xalt.py b/easybuild/easyblocks/x/xalt.py index 269ad01df2..e5e4f07f45 100644 --- a/easybuild/easyblocks/x/xalt.py +++ b/easybuild/easyblocks/x/xalt.py @@ -1,5 +1,5 @@ ## -# Copyright 2020-2022 NVIDIA +# Copyright 2020-2023 NVIDIA # # This file is triple-licensed under GPLv2 (see below), MIT, and # BSD three-clause licenses. diff --git a/easybuild/easyblocks/x/xcrysden.py b/easybuild/easyblocks/x/xcrysden.py index ad2cfc5d37..2a2c9891f9 100644 --- a/easybuild/easyblocks/x/xcrysden.py +++ b/easybuild/easyblocks/x/xcrysden.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/x/xmipp.py b/easybuild/easyblocks/x/xmipp.py index 6d35526471..95230cd03e 100644 --- a/easybuild/easyblocks/x/xmipp.py +++ b/easybuild/easyblocks/x/xmipp.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/easybuild/easyblocks/x/xml.py b/easybuild/easyblocks/x/xml.py index befe9144fa..14216fa364 100644 --- a/easybuild/easyblocks/x/xml.py +++ b/easybuild/easyblocks/x/xml.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/setup.py b/setup.py index e3c9030cc8..5162b2fe3c 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/test/__init__.py b/test/__init__.py index 461a6de808..01ba03af45 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/test/easyblocks/easyblock_specific.py b/test/easyblocks/easyblock_specific.py index 1db4277b72..4e4d10b4d2 100644 --- a/test/easyblocks/easyblock_specific.py +++ b/test/easyblocks/easyblock_specific.py @@ -1,5 +1,5 @@ ## -# Copyright 2019-2022 Ghent University +# Copyright 2019-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/test/easyblocks/general.py b/test/easyblocks/general.py index 824d4b215d..25b3ccba40 100644 --- a/test/easyblocks/general.py +++ b/test/easyblocks/general.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/test/easyblocks/init_easyblocks.py b/test/easyblocks/init_easyblocks.py index 650257f738..9f7a2a1a09 100644 --- a/test/easyblocks/init_easyblocks.py +++ b/test/easyblocks/init_easyblocks.py @@ -1,5 +1,5 @@ ## -# Copyright 2013-2022 Ghent University +# Copyright 2013-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index 2e302cd864..65b91f942c 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -1,5 +1,5 @@ ## -# Copyright 2015-2022 Ghent University +# Copyright 2015-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), diff --git a/test/easyblocks/suite.py b/test/easyblocks/suite.py index c3f3613b4d..3af803f312 100644 --- a/test/easyblocks/suite.py +++ b/test/easyblocks/suite.py @@ -1,6 +1,6 @@ #!/usr/bin/python ## -# Copyright 2012-2022 Ghent University +# Copyright 2012-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), From f91c0625b021f755894e7712c0a9e4ecd76bf84d Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 5 Jan 2023 13:32:40 +0100 Subject: [PATCH 152/325] update clang_aomp easyblock to handle ver 5.2 and newer --- easybuild/easyblocks/c/clang_aomp.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/c/clang_aomp.py b/easybuild/easyblocks/c/clang_aomp.py index ca94ba805f..944f08ff8c 100644 --- a/easybuild/easyblocks/c/clang_aomp.py +++ b/easybuild/easyblocks/c/clang_aomp.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ## -# Copyright 2009-2023 Ghent University +# Copyright 2009-2022 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), @@ -163,8 +163,7 @@ def sanity_check_step(self): custom_paths = { 'files': ['bin/clang', 'bin/lld', 'lib/libomp.%s' % shlib_ext, 'lib/libomptarget.rtl.amdgpu.%s' % shlib_ext, 'lib/libomptarget.%s' % shlib_ext], - 'dirs': ['amdgcn/bitcode', 'include/clang', 'include/lld', 'include/llvm', - 'lib/libdevice'], + 'dirs': ['amdgcn/bitcode', 'include/clang', 'include/lld', 'include/llvm'], } custom_commands = ['clang --help', 'clang++ --help'] @@ -176,7 +175,8 @@ def sanity_check_step(self): # Check that all AMD GFX libraries were built for gfx in self.amd_gfx_archs: - custom_paths['files'].extend([os.path.join(libdevice, 'lib%s-amdgcn-%s.bc' % (x, gfx)) for x in libs]) + if LooseVersion(self.version) < LooseVersion("5.2"): + custom_paths['files'].extend([os.path.join(libdevice, 'lib%s-amdgcn-%s.bc' % (x, gfx)) for x in libs]) if LooseVersion(self.version) >= LooseVersion("5"): custom_paths['files'].append(os.path.join('lib', 'libomptarget-amdgcn-%s.bc' % gfx)) custom_paths['files'].append(os.path.join('lib', 'libomptarget-new-amdgpu-%s.bc' % gfx)) @@ -267,6 +267,11 @@ def _configure_omp(self, component): '', ]) + if LooseVersion(self.version) >= LooseVersion("5.2"): + component['configopts'] += ' '.join([ + "-DDEVICELIBS_ROOT=%s" % self.device_lib_path, + ]) + if get_software_root('CUDA'): llvm_link = os.path.join(self.installdir, 'bin', 'llvm-link') cuda_path = os.path.join(self.installdir, 'bin', 'clang++') @@ -288,4 +293,10 @@ def _configure_aomp_extras(self, component): "-DAOMP_STANDALONE_BUILD=1", "-DROCDL=%s" % self.device_lib_path, "-DROCM_DIR=%s" % self.installdir, + '', ]) + + if LooseVersion(self.version) >= LooseVersion("5.2"): + component['configopts'] += ' '.join([ + "-DAOMP_VERSION_STRING=%s" % self.version, + ]) From cbbab20a80eb3559b1fc2dfb81217c298f6b2456 Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 5 Jan 2023 13:34:50 +0100 Subject: [PATCH 153/325] adjust copyright years --- easybuild/easyblocks/c/clang_aomp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang_aomp.py b/easybuild/easyblocks/c/clang_aomp.py index 944f08ff8c..0104ab64f9 100644 --- a/easybuild/easyblocks/c/clang_aomp.py +++ b/easybuild/easyblocks/c/clang_aomp.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), From 92e9c2574887e2729c9e7e07a38b4c9f1cdb508e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 5 Jan 2023 17:40:10 +0000 Subject: [PATCH 154/325] Fix execute permissions for ansys INSTALL script --- easybuild/easyblocks/a/ansys.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/a/ansys.py b/easybuild/easyblocks/a/ansys.py index 332e1579a7..5e8ebb0cf9 100644 --- a/easybuild/easyblocks/a/ansys.py +++ b/easybuild/easyblocks/a/ansys.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2023 Ghent University +# Copyright 2009-2022 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), @@ -56,6 +56,8 @@ def install_step(self): if licport is None: licport = os.getenv('EB_ANSYS_LICENSE_SERVER_PORT', '2325:1055') + # Sources (e.g. iso files) may drop the execute permissions + adjust_permissions('INSTALL', stat.S_IXUSR) cmd = "./INSTALL -silent -install_dir %s -licserverinfo %s:%s" % (self.installdir, licport, licserv) run_cmd(cmd, log_all=True, simple=True) From 8cf7a1b4c5e5f7f59fe6b8a49f301daae64af205 Mon Sep 17 00:00:00 2001 From: Simon Branford <4967+branfosj@users.noreply.github.com> Date: Thu, 5 Jan 2023 17:57:16 +0000 Subject: [PATCH 155/325] ansys easyblock copyright date --- easybuild/easyblocks/a/ansys.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/a/ansys.py b/easybuild/easyblocks/a/ansys.py index 5e8ebb0cf9..0c4b834846 100644 --- a/easybuild/easyblocks/a/ansys.py +++ b/easybuild/easyblocks/a/ansys.py @@ -1,5 +1,5 @@ ## -# Copyright 2009-2022 Ghent University +# Copyright 2009-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), From be5c7b421807c1b1fb1a246162e6ee9d5e257588 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 6 Jan 2023 09:47:22 +0100 Subject: [PATCH 156/325] fix TensorFlow easyblock for new versions of Bazel & TensorFlow --- easybuild/easyblocks/t/tensorflow.py | 45 ++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index e8912c2b2c..16f8079c33 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -1,5 +1,5 @@ ## -# Copyright 2017-2023 Ghent University +# Copyright 2017-2022 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), @@ -35,14 +35,13 @@ import re import stat import tempfile -from distutils.version import LooseVersion import easybuild.tools.environment as env import easybuild.tools.toolchain as toolchain from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_python_version from easybuild.easyblocks.python import EXTS_FILTER_PYTHON_PACKAGES from easybuild.framework.easyconfig import CUSTOM -from easybuild.tools import run +from easybuild.tools import run, LooseVersion from easybuild.tools.build_log import EasyBuildError, print_warning from easybuild.tools.config import build_option, IGNORE from easybuild.tools.filetools import adjust_permissions, apply_regex_substitutions, copy_file, mkdir, resolve_path @@ -760,6 +759,11 @@ def build_step(self): self.bazel_opts = [ '--output_user_root=%s' % self.output_user_root_dir, ] + # Environment variables and values needed for Bazel actions. + action_env = {} + # A value of None is interpreted as using the invoking environments value + INHERIT = None # For better readability + jvm_max_memory = self.cfg['jvm_max_memory'] if jvm_max_memory: jvm_startup_memory = min(512, int(jvm_max_memory)) @@ -801,21 +805,17 @@ def build_step(self): # Make TF find our modules. LD_LIBRARY_PATH gets automatically added by configure.py cpaths, libpaths = self.system_libs_info[1:] if cpaths: - self.target_opts.append("--action_env=CPATH='%s'" % ':'.join(cpaths)) + action_env['CPATH'] = ':'.join(cpaths) if libpaths: - self.target_opts.append("--action_env=LIBRARY_PATH='%s'" % ':'.join(libpaths)) - self.target_opts.append('--action_env=PYTHONPATH') + action_env['LIBRARY_PATH'] = ':'.join(libpaths) + action_env['PYTHONPATH'] = INHERIT # Also export $EBPYTHONPREFIXES to handle the multi-deps python setup # See https://github.com/easybuilders/easybuild-easyblocks/pull/1664 if 'EBPYTHONPREFIXES' in os.environ: - self.target_opts.append('--action_env=EBPYTHONPREFIXES') + action_env['EBPYTHONPREFIXES'] = INHERIT # Ignore user environment for Python - self.target_opts.append('--action_env=PYTHONNOUSERSITE=1') - - # Use the same configuration (i.e. environment) for compiling and using host tools - # This means that our action_envs are always passed - self.target_opts.append('--distinct_host_configuration=false') + action_env['PYTHONNOUSERSITE'] = '1' # TF 2 (final) sets this in configure if LooseVersion(self.version) < LooseVersion('2.0'): @@ -851,6 +851,26 @@ def build_step(self): # and download it if needed self.target_opts.append('--config=mkl') + bazel_version = LooseVersion(get_software_version('Bazel')) + if bazel_version.version is None: + raise EasyBuildError('Bazel version not found. Is it a dependency?') + + # Use the same configuration (i.e. environment) for compiling and using host tools + # This means that our action_envs are (almost) always passed + # Fully removed in Bazel 6.0 and limitted effect after at least 3.7 (see --host_action_env) + if bazel_version < '6.0.0': + self.target_opts.append('--distinct_host_configuration=false') + + for key, value in action_env.items(): + option = key + if value is not None: + option += "='%s'" % value + + self.target_opts.append('--action_env=' + option) + if bazel_version >= '3.7.0': + # See https://github.com/bazelbuild/bazel/commit/a463d9095386b22c121d20957222dbb44caef7d4 + self.target_opts.append('--host_action_env=' + option) + # Compose final command cmd = ( [self.cfg['prebuildopts']] @@ -1017,6 +1037,7 @@ def test_step(self): self.log.warning('Test %s failed with output\n%s', test_name, read_file(log_path, log_error=False)) if failed_tests: + failed_tests = sorted(set(failed_tests)) # Make unique to not count retries fail_msg = 'At least %s %s tests failed:\n%s' % ( len(failed_tests), device, ', '.join(failed_tests)) self.report_test_failure(fail_msg) From 93af4609192e4d49f8982efbbbc0ed7cbb3fc2ae Mon Sep 17 00:00:00 2001 From: Miguel Dias Costa Date: Sat, 7 Jan 2023 11:50:47 +0800 Subject: [PATCH 157/325] prepare release notes for EasyBuild v4.7.0 + bump version to 4.7.0 --- RELEASE_NOTES | 44 +++++++++++++++++++++++++++++++- easybuild/easyblocks/__init__.py | 2 +- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 77347cb907..034387c5ff 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,7 +3,49 @@ For more detailed information, please see the git log. These release notes can also be consulted at http://easybuild.readthedocs.org/en/latest/Release_notes.html. -The latest version of easybuild-easyblocks provides 248 software-specific easyblocks and 37 generic easyblocks. +The latest version of easybuild-easyblocks provides 248 software-specific easyblocks and 39 generic easyblocks. + + +v4.7.0 (January 9th 2023) +------------------------- + +feature release + +- add generic easyblocks for installing Julia packages and bundles: JuliaPackage (#2816) and JuliaBundle (#2830) +- minor enhancements and updates, including: + - enhance TensorFlow easyblock to take into account provided OpenSSL dependency (#2575) + - add fix_shebang to install_step of PythonPackage easyblock so that we can fix shebangs when installing extensions (#2680) + - update PETSc easyblock for newer versions (#2796) + - update Xmipp easyblock: versions >= 3.20.07 use `noAsk` option to configure (#2809) + - add extra option for disabling LAPACK in ESMF (#2821) + - remove -openmp build option for MRtrix v3.x (#2822) + - enable building of static libraries for libxml2 >= 2.10 (#2825) + - update xmipp.py to handle effects of CUDA at SYSTEM level and newer CUDA version requirements for stdc++ (#2831) + - update LLVM easyblock to put 'cmake' symlink in place so separate CMake modules requires for LLVM 15+ can be found (#2832) + - set $TEMPDIRPATH for testsuite in the BerkeleyGW easyblock, to avoid polluting /tmp (#2836) + - use fixed names for bazel/wrapper subdirectories used when building TensorFlow, to make debugging easier (#2841) + - add `configure_no_prefix` option to skip addition of prefix to configure command in ConfigureMake easyblock (#2842) + - also run unit tests with Python 3.11 (#2844) + - update qscintilla.py to be compatible with EB install of PyQt5 >= 5.15 (#2845) + - add UCC to known_dependencies in OpenMPI EasyBlock (#2847) + - update Clang-AOMP easyblock to handle version 5.2 and newer (#2851) +- various bug fixes, including: + - fix installing of Clang with RPATH linking (#2799) + - add include/opencv4 to $CPATH for OpenCV versions >= 4.0 (#2818) + - update Clang easyblock to add support for new directory structure in Clang versions >= 14 + support Flang + fix --module-only + fix sanity check for Clang 11.x (#2800) + - create $XDG_CACHE_HOME for PyTorch tests (#2806) + - load module early during PythonPackage's sanity check step via sanity_check_load_module (#2828) + - fix docstring of PythonBundle generic easyblock (#2833) + - fix counting of failures in PyTorch tests (#2834) + - automatically cancel Github Action workflow runs for outdated commits (#2835) + - fix Python 2.7 compatibility of PyTorch easyblock (#2840) + - make sure that ANSYS INSTALL script has execute permissions (#2852) + - fix copyright header line in ANSYS easyblock (#2853) +- other changes: + - update HDF5 easyblock to use --enable-threadsafe configure option to make C API thread safe (#2824) + - use new EasyBuild logo in README (#2827) + - tweak docstring in some generic easyblocks so it renders nicely in auto-generated documentation (#2849) + - update copyright lines for 2023 (#2850) v4.6.2 (October 21st 2022) diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index 09144bb9d8..94dac2bea4 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.6.3.dev0') +VERSION = LooseVersion('4.7.0') UNKNOWN = 'UNKNOWN' From fdc069abcd9e51c8cf6e404dbc3694815fee93cb Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sun, 8 Jan 2023 15:41:30 +0100 Subject: [PATCH 158/325] make NAMD easyblock aware of (pre)testopts --- easybuild/easyblocks/n/namd.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/n/namd.py b/easybuild/easyblocks/n/namd.py index 4c84f9bcfd..a0f4c82b95 100644 --- a/easybuild/easyblocks/n/namd.py +++ b/easybuild/easyblocks/n/namd.py @@ -201,10 +201,12 @@ def test_step(self): ppn = '' if self.toolchain.options.get('openmp', False): ppn = '+ppn 2' - cmd = "%(namd)s %(ppn)s %(testdir)s" % { + cmd = "%(pretestopts)s %(namd)s %(ppn)s %(testopts)s %(testdir)s" % { 'namd': namdcmd, 'ppn': ppn, + 'pretestopts': self.cfg['pretestopts'], 'testdir': os.path.join(self.cfg['start_dir'], self.namd_arch, 'src', 'alanin'), + 'testopts': self.cfg['testopts'], } out, ec = run_cmd(cmd, simple=False) if ec == 0: From 1a6ad61296cce729a4689ce04c5e09419268f833 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sun, 8 Jan 2023 16:30:13 +0100 Subject: [PATCH 159/325] minor tweaks to release notes for EasyBuild v4.7.0 --- RELEASE_NOTES | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 034387c5ff..e71ea4acad 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -11,39 +11,38 @@ v4.7.0 (January 9th 2023) feature release -- add generic easyblocks for installing Julia packages and bundles: JuliaPackage (#2816) and JuliaBundle (#2830) +- add generic easyblocks for installing (bundle of) Julia packages: JuliaPackage (#2816) and JuliaBundle (#2830) - minor enhancements and updates, including: - enhance TensorFlow easyblock to take into account provided OpenSSL dependency (#2575) - add fix_shebang to install_step of PythonPackage easyblock so that we can fix shebangs when installing extensions (#2680) - - update PETSc easyblock for newer versions (#2796) - - update Xmipp easyblock: versions >= 3.20.07 use `noAsk` option to configure (#2809) + - update PETSc easyblock for newer versions (>= 3.17) (#2796) + - update Clang easyblock to add support for new directory structure in Clang versions >= 14 + support Flang (#2800) + - update Xmipp easyblock since versions >= 3.20.07 use `noAsk` option to configure (#2809) + - add include/opencv4 to $CPATH for OpenCV versions >= 4.0 (#2818) - add extra option for disabling LAPACK in ESMF (#2821) - - remove -openmp build option for MRtrix v3.x (#2822) - enable building of static libraries for libxml2 >= 2.10 (#2825) - - update xmipp.py to handle effects of CUDA at SYSTEM level and newer CUDA version requirements for stdc++ (#2831) - - update LLVM easyblock to put 'cmake' symlink in place so separate CMake modules requires for LLVM 15+ can be found (#2832) + - update Xmipp easyblock to handle effects of CUDA at SYSTEM level and newer CUDA version requirements for stdc++ (#2831) + - update LLVM easyblock to put 'cmake' symlink in place so separate CMake modules required for LLVM 15+ can be found (#2832) - set $TEMPDIRPATH for testsuite in the BerkeleyGW easyblock, to avoid polluting /tmp (#2836) - - use fixed names for bazel/wrapper subdirectories used when building TensorFlow, to make debugging easier (#2841) - add `configure_no_prefix` option to skip addition of prefix to configure command in ConfigureMake easyblock (#2842) - - also run unit tests with Python 3.11 (#2844) - update qscintilla.py to be compatible with EB install of PyQt5 >= 5.15 (#2845) - add UCC to known_dependencies in OpenMPI EasyBlock (#2847) - update Clang-AOMP easyblock to handle version 5.2 and newer (#2851) - various bug fixes, including: - fix installing of Clang with RPATH linking (#2799) - - add include/opencv4 to $CPATH for OpenCV versions >= 4.0 (#2818) - - update Clang easyblock to add support for new directory structure in Clang versions >= 14 + support Flang + fix --module-only + fix sanity check for Clang 11.x (#2800) + - fix --module-only for Clang + fix sanity check for Clang 11.x (#2800) - create $XDG_CACHE_HOME for PyTorch tests (#2806) - - load module early during PythonPackage's sanity check step via sanity_check_load_module (#2828) + - make PythonPackage easyblock compatible with --sanity-check-only by loading module early during sanity check step (#2828) - fix docstring of PythonBundle generic easyblock (#2833) - - fix counting of failures in PyTorch tests (#2834) - - automatically cancel Github Action workflow runs for outdated commits (#2835) - - fix Python 2.7 compatibility of PyTorch easyblock (#2840) - - make sure that ANSYS INSTALL script has execute permissions (#2852) - - fix copyright header line in ANSYS easyblock (#2853) + - fix counting of failures in PyTorch tests (#2834, #2840) + - make sure that ANSYS INSTALL script has execute permissions (#2852, #2853) - other changes: + - remove useless -openmp build option for MRtrix v3.x (#2822) - update HDF5 easyblock to use --enable-threadsafe configure option to make C API thread safe (#2824) - use new EasyBuild logo in README (#2827) + - automatically cancel Github Action workflow runs for outdated commits (#2835) + - use fixed names for bazel/wrapper subdirectories used when building TensorFlow, to make debugging easier (#2841) + - also run unit tests with Python 3.11 (#2844) - tweak docstring in some generic easyblocks so it renders nicely in auto-generated documentation (#2849) - update copyright lines for 2023 (#2850) From 652df1dcc52e45cc92f02ef7a13ef2eab235cf2a Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 10 Jan 2023 18:45:09 +0100 Subject: [PATCH 160/325] bump version to 4.7.1dev --- easybuild/easyblocks/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index 94dac2bea4..9619ef8946 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.7.0') +VERSION = LooseVersion('4.7.1.dev0') UNKNOWN = 'UNKNOWN' From 720d392d97013ee3324698f1da10389e1d11641b Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 12 Jan 2023 16:14:36 +0100 Subject: [PATCH 161/325] Increase Bazel start/connect timeout --- easybuild/easyblocks/t/tensorflow.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 16f8079c33..719025a0a2 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -1,5 +1,5 @@ ## -# Copyright 2017-2022 Ghent University +# Copyright 2017-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), @@ -445,7 +445,7 @@ def configure_step(self): # and will hang forever building the TensorFlow package. # So limit to something high but still reasonable while allowing ECs to overwrite it if self.cfg['maxparallel'] is None: - self.cfg['parallel'] = min(self.cfg['parallel'], 64) + self.cfg['parallel'] = min(self.cfg['parallel'], 96) binutils_root = get_software_root('binutils') if not binutils_root: @@ -758,6 +758,7 @@ def build_step(self): # Options passed to the bazel command self.bazel_opts = [ '--output_user_root=%s' % self.output_user_root_dir, + '--local_startup_timeout_secs=600', # 5min for bazel to start ] # Environment variables and values needed for Bazel actions. action_env = {} From 3dddcaa15466605bd8b7a72aa75d3a5f1b27d470 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 12 Jan 2023 16:25:57 +0100 Subject: [PATCH 162/325] Make the maxparallel limitation depend on the Bazel version --- easybuild/easyblocks/t/tensorflow.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 719025a0a2..fbaeab509c 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -210,6 +210,14 @@ def is_version_ok(version_range): return result +def get_bazel_version(): + """Get the Bazel version as a LooseVersion. Error if not found""" + version = get_software_version('Bazel') + if version is None: + raise EasyBuildError('Bazel version not found. Is it a dependency?') + return LooseVersion(version) + + class EB_TensorFlow(PythonPackage): """Support for building/installing TensorFlow.""" @@ -445,7 +453,9 @@ def configure_step(self): # and will hang forever building the TensorFlow package. # So limit to something high but still reasonable while allowing ECs to overwrite it if self.cfg['maxparallel'] is None: - self.cfg['parallel'] = min(self.cfg['parallel'], 96) + # Seemingly Bazel around 3.x got better, so double the max there + bazel_max = 64 if get_bazel_version() < '3.0.0' else 128 + self.cfg['parallel'] = min(self.cfg['parallel'], bazel_max) binutils_root = get_software_root('binutils') if not binutils_root: @@ -852,9 +862,7 @@ def build_step(self): # and download it if needed self.target_opts.append('--config=mkl') - bazel_version = LooseVersion(get_software_version('Bazel')) - if bazel_version.version is None: - raise EasyBuildError('Bazel version not found. Is it a dependency?') + bazel_version = get_bazel_version() # Use the same configuration (i.e. environment) for compiling and using host tools # This means that our action_envs are (almost) always passed From 8c88c719df95614896958bf5e93b9d7800a1ad8a Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 13 Jan 2023 18:03:31 +0100 Subject: [PATCH 163/325] Fix cmdline for Bazel < 4.0 --- easybuild/easyblocks/t/tensorflow.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index fbaeab509c..47c8a48f71 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -758,6 +758,8 @@ def patch_crosstool_files(self): def build_step(self): """Custom build procedure for TensorFlow.""" + bazel_version = get_bazel_version() + # pre-create target installation directory mkdir(os.path.join(self.installdir, self.pylibdir), parents=True) @@ -768,8 +770,10 @@ def build_step(self): # Options passed to the bazel command self.bazel_opts = [ '--output_user_root=%s' % self.output_user_root_dir, - '--local_startup_timeout_secs=600', # 5min for bazel to start ] + if bazel_version >= '4.0.0': + self.bazel_opts.append('--local_startup_timeout_secs=600') # 5min for bazel to start + # Environment variables and values needed for Bazel actions. action_env = {} # A value of None is interpreted as using the invoking environments value @@ -862,8 +866,6 @@ def build_step(self): # and download it if needed self.target_opts.append('--config=mkl') - bazel_version = get_bazel_version() - # Use the same configuration (i.e. environment) for compiling and using host tools # This means that our action_envs are (almost) always passed # Fully removed in Bazel 6.0 and limitted effect after at least 3.7 (see --host_action_env) From 4520a34ba9fc42023dc94e8cb7d3006f9f8c92a9 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Tue, 17 Jan 2023 10:26:11 +0000 Subject: [PATCH 164/325] update MesonNinja easyblock for Meson >=0.64.0 --- easybuild/easyblocks/generic/mesonninja.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/mesonninja.py b/easybuild/easyblocks/generic/mesonninja.py index fab1a79296..601dbe5210 100644 --- a/easybuild/easyblocks/generic/mesonninja.py +++ b/easybuild/easyblocks/generic/mesonninja.py @@ -28,12 +28,16 @@ @author: Kenneth Hoste (Ghent University) """ +from distutils.version import LooseVersion from easybuild.framework.easyblock import EasyBlock from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import change_dir, create_unused_dir, which +from easybuild.tools.modules import get_software_version from easybuild.tools.run import run_cmd +DEFAULT_CONFIGURE_CMD = 'meson' + class MesonNinja(EasyBlock): """ @@ -45,6 +49,7 @@ def extra_options(extra_vars=None): """Define extra easyconfig parameters specific to MesonNinja.""" extra_vars = EasyBlock.extra_options(extra_vars) extra_vars.update({ + 'configure_cmd': [DEFAULT_CONFIGURE_CMD, "Configure command to use", CUSTOM], 'separate_build_dir': [True, "Perform build in a separate directory", CUSTOM], }) return extra_vars @@ -73,8 +78,16 @@ def configure_step(self, cmd_prefix=''): if no_Dlibdir and no_libdir: self.cfg.update('configopts', '-Dlibdir=lib') - cmd = "%(preconfigopts)s meson --prefix %(installdir)s %(configopts)s %(sourcedir)s" % { + configure_cmd = self.cfg.get('configure_cmd') or DEFAULT_CONFIGURE_CMD + # Meson >= 0.64.0 has a deprecatation warning for running `meson [options]` + # instead of `meson setup [options]` + if (LooseVersion(get_software_version('Meson')) >= LooseVersion('0.64.0') + and configure_cmd == DEFAULT_CONFIGURE_CMD): + configure_cmd += ' setup' + + cmd = "%(preconfigopts)s %(configure_cmd)s --prefix %(installdir)s %(configopts)s %(sourcedir)s" % { 'configopts': self.cfg['configopts'], + 'configure_cmd': configure_cmd, 'installdir': self.installdir, 'preconfigopts': self.cfg['preconfigopts'], 'sourcedir': self.start_dir, From fec5e3b8c3c9d73c186dcc49e56a3adfdbfc6c47 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Tue, 17 Jan 2023 10:31:46 +0000 Subject: [PATCH 165/325] linting --- easybuild/easyblocks/generic/mesonninja.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/generic/mesonninja.py b/easybuild/easyblocks/generic/mesonninja.py index 601dbe5210..c8ad0af51b 100644 --- a/easybuild/easyblocks/generic/mesonninja.py +++ b/easybuild/easyblocks/generic/mesonninja.py @@ -81,9 +81,9 @@ def configure_step(self, cmd_prefix=''): configure_cmd = self.cfg.get('configure_cmd') or DEFAULT_CONFIGURE_CMD # Meson >= 0.64.0 has a deprecatation warning for running `meson [options]` # instead of `meson setup [options]` - if (LooseVersion(get_software_version('Meson')) >= LooseVersion('0.64.0') - and configure_cmd == DEFAULT_CONFIGURE_CMD): - configure_cmd += ' setup' + if (LooseVersion(get_software_version('Meson')) >= LooseVersion('0.64.0') and + configure_cmd == DEFAULT_CONFIGURE_CMD): + configure_cmd += ' setup' cmd = "%(preconfigopts)s %(configure_cmd)s --prefix %(installdir)s %(configopts)s %(sourcedir)s" % { 'configopts': self.cfg['configopts'], From 182704176f49880be9f0e686dd4636e9e652fb82 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Tue, 17 Jan 2023 15:48:16 +0000 Subject: [PATCH 166/325] update scipy easyblock for scipy >= 1.9.0 to use meson/ninja --- easybuild/easyblocks/s/scipy.py | 79 +++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index c4ebd92ed9..79acdb95fe 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -30,33 +30,96 @@ @author: Kenneth Hoste (Ghent University) @author: Pieter De Baets (Ghent University) @author: Jens Timmerman (Ghent University) +@author: Jasper Grimm (University of York) """ +import os from distutils.version import LooseVersion +import easybuild.tools.environment as env +import easybuild.tools.toolchain as toolchain from easybuild.easyblocks.generic.fortranpythonpackage import FortranPythonPackage +from easybuild.easyblocks.generic.mesonninja import MesonNinja from easybuild.easyblocks.generic.pythonpackage import det_pylibdir -import easybuild.tools.toolchain as toolchain +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.modules import get_software_root +from easybuild.tools.run import run_cmd -class EB_scipy(FortranPythonPackage): +class EB_scipy(FortranPythonPackage, MesonNinja): """Support for installing the scipy Python package as part of a Python installation.""" def __init__(self, *args, **kwargs): """Set scipy-specific test command.""" super(EB_scipy, self).__init__(*args, **kwargs) + self.use_meson = LooseVersion(self.version) >= LooseVersion('1.9') + self.pylibdir = None self.testinstall = True self.testcmd = "cd .. && %(python)s -c 'import numpy; import scipy; scipy.test(verbose=2)'" def configure_step(self): """Custom configure step for scipy: set extra installation options when needed.""" - super(EB_scipy, self).configure_step() + self.pylibdir = det_pylibdir() + + # scipy >= 1.9.0 uses Meson/Ninja + if self.use_meson: + # configure BLAS/LAPACK library to use with Meson for scipy >= 1.9.0 + lapack_lib = self.toolchain.lapack_family() + if lapack_lib == toolchain.FLEXIBLAS: + blas_lapack = 'flexiblas' + elif lapack_lib == toolchain.INTELMKL: + blas_lapack = 'mkl' + elif lapack_lib == toolchain.OPENBLAS: + blas_lapack = 'openblas' + else: + raise EasyBuildError("Unknown BLAS/LAPACK library used: %s", lapack_lib) + + configopts = '-Dblas=%(blas_lapack)s -Dlapack=%(blas_lapack)s' % {'blas_lapack': blas_lapack} + self.cfg.update('configopts', configopts) + + pythonpath = os.getenv('PYTHONPATH') + env.setvar('PYTHONPATH', os.pathsep.join([os.path.join(self.installdir, self.pylibdir), pythonpath])) + + path = os.getenv('PATH') + env.setvar('PATH', os.pathsep.join([os.path.join(self.installdir, 'bin'), path])) + + MesonNinja.configure_step(self) + else: + super(EB_scipy, self).configure_step() + + if LooseVersion(self.version) >= LooseVersion('0.13'): + # in recent scipy versions, additional compilation is done in the install step, + # which requires unsetting $LDFLAGS + if self.toolchain.comp_family() in [toolchain.GCC, toolchain.CLANGGCC]: # @UndefinedVariable + self.cfg.update('preinstallopts', "unset LDFLAGS && ") + + def build_step(self): + """Custom build step for scipy: use ninja for scipy >= 1.9.0""" + if self.use_meson: + MesonNinja.build_step(self) + else: + super(EB_scipy, self).build_step() + + def test_step(self): + """Custom test step for scipy: skip if scipy >= 1.9.0""" + if self.use_meson: + # need to run `ninja install` before we can run the test + pass + else: + super(EB_scipy, self).build_step() - if LooseVersion(self.version) >= LooseVersion('0.13'): - # in recent scipy versions, additional compilation is done in the install step, - # which requires unsetting $LDFLAGS - if self.toolchain.comp_family() in [toolchain.GCC, toolchain.CLANGGCC]: # @UndefinedVariable - self.cfg.update('preinstallopts', "unset LDFLAGS && ") + def install_step(self): + """Custom install step for scipy: use ninja for scipy >= 1.9.0""" + if self.use_meson: + self.cfg['installopts'] = "" + MesonNinja.install_step(self) + + # also run the test + python_root = get_software_root('Python') + python_bin = os.path.join(python_root, 'bin', 'python') + run_cmd(self.testcmd % {'python': python_bin}, log_all=True, simple=True) + else: + super(EB_scipy, self).install_step() def sanity_check_step(self, *args, **kwargs): """Custom sanity check for scipy.""" From 57d52d990dca8f653e662739f1c4adac9a365670 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Tue, 17 Jan 2023 15:54:38 +0000 Subject: [PATCH 167/325] linting --- easybuild/easyblocks/s/scipy.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 79acdb95fe..826ed358d1 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -60,7 +60,7 @@ def __init__(self, *args, **kwargs): def configure_step(self): """Custom configure step for scipy: set extra installation options when needed.""" self.pylibdir = det_pylibdir() - + # scipy >= 1.9.0 uses Meson/Ninja if self.use_meson: # configure BLAS/LAPACK library to use with Meson for scipy >= 1.9.0 @@ -72,14 +72,14 @@ def configure_step(self): elif lapack_lib == toolchain.OPENBLAS: blas_lapack = 'openblas' else: - raise EasyBuildError("Unknown BLAS/LAPACK library used: %s", lapack_lib) - + raise EasyBuildError("Unknown BLAS/LAPACK library used: %s", lapack_lib) + configopts = '-Dblas=%(blas_lapack)s -Dlapack=%(blas_lapack)s' % {'blas_lapack': blas_lapack} self.cfg.update('configopts', configopts) - + pythonpath = os.getenv('PYTHONPATH') env.setvar('PYTHONPATH', os.pathsep.join([os.path.join(self.installdir, self.pylibdir), pythonpath])) - + path = os.getenv('PATH') env.setvar('PATH', os.pathsep.join([os.path.join(self.installdir, 'bin'), path])) @@ -113,8 +113,8 @@ def install_step(self): if self.use_meson: self.cfg['installopts'] = "" MesonNinja.install_step(self) - - # also run the test + + # also run the test python_root = get_software_root('Python') python_bin = os.path.join(python_root, 'bin', 'python') run_cmd(self.testcmd % {'python': python_bin}, log_all=True, simple=True) From cf9f565d89ee60642c0515665349be1aff9b339c Mon Sep 17 00:00:00 2001 From: Sebastian Achilles Date: Tue, 17 Jan 2023 20:37:03 +0100 Subject: [PATCH 168/325] do not use -g77 option when installing NVHPC 22.9+ --- easybuild/easyblocks/n/nvhpc.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/n/nvhpc.py b/easybuild/easyblocks/n/nvhpc.py index 761fb1e468..b9b27cb009 100644 --- a/easybuild/easyblocks/n/nvhpc.py +++ b/easybuild/easyblocks/n/nvhpc.py @@ -164,7 +164,10 @@ def install_step(self): line = re.sub(r"^PATH=/", r"#PATH=/", line) sys.stdout.write(line) - cmd = "%s -x %s -g77 gfortran" % (makelocalrc_filename, compilers_subdir) + if LooseVersion(self.version) >= LooseVersion('22.9'): + cmd = "%s -x %s" % (makelocalrc_filename, compilers_subdir) + else: + cmd = "%s -x %s -g77 /" % (makelocalrc_filename, compilers_subdir) run_cmd(cmd, log_all=True, simple=True) # If an OS libnuma is NOT found, makelocalrc creates symbolic links to libpgnuma.so From 7f9bf4fb8544c3693d17db2dd197e6d44889bd1f Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 18 Jan 2023 09:52:43 +0100 Subject: [PATCH 169/325] only give read permissions in GitHub Actions workflows --- .github/workflows/linting.yml | 3 +++ .github/workflows/unit_tests.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index d7482ec3f7..bfa19cc1a8 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,6 +1,9 @@ name: Static Analysis on: [push, pull_request] +permissions: + contents: read # to fetch code (actions/checkout) + concurrency: group: ${{format('{0}:{1}:{2}', github.repository, github.ref, github.workflow)}} cancel-in-progress: true diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index c6b163cac3..b5164b143b 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -1,6 +1,9 @@ name: easyblocks unit tests on: [push, pull_request] +permissions: + contents: read # to fetch code (actions/checkout) + concurrency: group: ${{format('{0}:{1}:{2}', github.repository, github.ref, github.workflow)}} cancel-in-progress: true From 795e8b66356edf44fea52f0e7f1baa642dcb6f4b Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 19 Jan 2023 09:46:44 +0100 Subject: [PATCH 170/325] Improve readability --- easybuild/easyblocks/t/tensorflow.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 47c8a48f71..229cc72c1d 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -771,8 +771,9 @@ def build_step(self): self.bazel_opts = [ '--output_user_root=%s' % self.output_user_root_dir, ] + # Increase time to wait for bazel to start, available since 4.0+ if bazel_version >= '4.0.0': - self.bazel_opts.append('--local_startup_timeout_secs=600') # 5min for bazel to start + self.bazel_opts.append('--local_startup_timeout_secs=300') # 5min # Environment variables and values needed for Bazel actions. action_env = {} @@ -868,17 +869,19 @@ def build_step(self): # Use the same configuration (i.e. environment) for compiling and using host tools # This means that our action_envs are (almost) always passed - # Fully removed in Bazel 6.0 and limitted effect after at least 3.7 (see --host_action_env) + # Fully removed in Bazel 6.0 and limited effect after at least 3.7 (see --host_action_env) if bazel_version < '6.0.0': self.target_opts.append('--distinct_host_configuration=false') - for key, value in action_env.items(): + for key, value in sorted(action_env.items()): option = key if value is not None: option += "='%s'" % value self.target_opts.append('--action_env=' + option) if bazel_version >= '3.7.0': + # Since Bazel 3.7 action_env only applies to the "target" environment, not the "host" environment + # As we are not cross-compiling we need both be the same -> Duplicate the setting to host_action_env # See https://github.com/bazelbuild/bazel/commit/a463d9095386b22c121d20957222dbb44caef7d4 self.target_opts.append('--host_action_env=' + option) From 5f93ffc9fd61243d2c0068e0f08bbe6059f135c8 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 19 Jan 2023 09:52:39 +0100 Subject: [PATCH 171/325] Improve bazel error msg --- easybuild/easyblocks/t/tensorflow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 229cc72c1d..d63a4bc3f6 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -214,7 +214,7 @@ def get_bazel_version(): """Get the Bazel version as a LooseVersion. Error if not found""" version = get_software_version('Bazel') if version is None: - raise EasyBuildError('Bazel version not found. Is it a dependency?') + raise EasyBuildError('Failed to determine Bazel version - is it listed as a (build) dependency?') return LooseVersion(version) From 1fec03336db8b93285c9ba2acf823e7b9c3d5cfa Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Thu, 19 Jan 2023 15:21:36 +0000 Subject: [PATCH 172/325] improve scipy testing --- easybuild/easyblocks/s/scipy.py | 84 ++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 17 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 826ed358d1..ecfa42b8ff 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -33,6 +33,7 @@ @author: Jasper Grimm (University of York) """ import os +import tempfile from distutils.version import LooseVersion import easybuild.tools.environment as env @@ -41,6 +42,7 @@ from easybuild.easyblocks.generic.mesonninja import MesonNinja from easybuild.easyblocks.generic.pythonpackage import det_pylibdir from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.filetools import change_dir, mkdir, remove_dir from easybuild.tools.modules import get_software_root from easybuild.tools.run import run_cmd @@ -53,13 +55,16 @@ def __init__(self, *args, **kwargs): super(EB_scipy, self).__init__(*args, **kwargs) self.use_meson = LooseVersion(self.version) >= LooseVersion('1.9') - self.pylibdir = None self.testinstall = True - self.testcmd = "cd .. && %(python)s -c 'import numpy; import scipy; scipy.test(verbose=2)'" + self.testcmd = " && ".join([ + "cd ..", + "touch %(srcdir)s/.coveragerc", + "%(python)s %(srcdir)s/runtests.py -v --no-build --parallel %(parallel)s", + ]) def configure_step(self): """Custom configure step for scipy: set extra installation options when needed.""" - self.pylibdir = det_pylibdir() + pylibdir = det_pylibdir() # scipy >= 1.9.0 uses Meson/Ninja if self.use_meson: @@ -77,21 +82,23 @@ def configure_step(self): configopts = '-Dblas=%(blas_lapack)s -Dlapack=%(blas_lapack)s' % {'blas_lapack': blas_lapack} self.cfg.update('configopts', configopts) + # need to have already installed extensions in PATH, PYTHONPATH for configure/build/install steps pythonpath = os.getenv('PYTHONPATH') - env.setvar('PYTHONPATH', os.pathsep.join([os.path.join(self.installdir, self.pylibdir), pythonpath])) + env.setvar('PYTHONPATH', os.pathsep.join([os.path.join(self.installdir, pylibdir), pythonpath])) path = os.getenv('PATH') env.setvar('PATH', os.pathsep.join([os.path.join(self.installdir, 'bin'), path])) MesonNinja.configure_step(self) + else: super(EB_scipy, self).configure_step() - if LooseVersion(self.version) >= LooseVersion('0.13'): - # in recent scipy versions, additional compilation is done in the install step, - # which requires unsetting $LDFLAGS - if self.toolchain.comp_family() in [toolchain.GCC, toolchain.CLANGGCC]: # @UndefinedVariable - self.cfg.update('preinstallopts', "unset LDFLAGS && ") + if LooseVersion(self.version) >= LooseVersion('0.13'): + # in recent scipy versions, additional compilation is done in the install step, + # which requires unsetting $LDFLAGS + if self.toolchain.comp_family() in [toolchain.GCC, toolchain.CLANGGCC]: # @UndefinedVariable + self.cfg.update('preinstallopts', "unset LDFLAGS && ") def build_step(self): """Custom build step for scipy: use ninja for scipy >= 1.9.0""" @@ -101,23 +108,66 @@ def build_step(self): super(EB_scipy, self).build_step() def test_step(self): - """Custom test step for scipy: skip if scipy >= 1.9.0""" + """Run available scipy unit tests. Adapted from numpy easyblock""" + if self.use_meson: - # need to run `ninja install` before we can run the test - pass + + # temporarily install scipy so we can run the test suite + tmpdir = tempfile.mkdtemp() + cwd = os.getcwd() + + cmd = " && ".join([ + # reconfigure meson to use temp dir + 'meson configure --prefix=%s' % tmpdir, + 'ninja -j %s install' % self.cfg['parallel'], + ]) + run_cmd(cmd, log_all=True, simple=True, verbose=False) + + abs_pylibdirs = [os.path.join(tmpdir, pylibdir) for pylibdir in self.all_pylibdirs] + for pylibdir in abs_pylibdirs: + mkdir(pylibdir, parents=True) + python_root = get_software_root('Python') + python_bin = os.path.join(python_root, 'bin', 'python') + + self.cfg['pretestopts'] = " && ".join([ + # LDFLAGS should not be set when testing numpy/scipy, because it overwrites whatever numpy/scipy sets + # see http://projects.scipy.org/numpy/ticket/182 + "unset LDFLAGS", + "export PYTHONPATH=%s:$PYTHONPATH" % os.pathsep.join(abs_pylibdirs), + "", + ]) + self.cfg['runtest'] = self.testcmd % { + 'python': python_bin, + 'srcdir': self.cfg['start_dir'], + 'parallel': self.cfg['parallel'], + } + + MesonNinja.test_step(self) + + # reconfigure meson to use real install dir + os.chdir(cwd) + cmd = 'meson configure --prefix=%s' % self.installdir + run_cmd(cmd, log_all=True, simple=True, verbose=False) + + try: + remove_dir(tmpdir) + except OSError as err: + raise EasyBuildError("Failed to remove directory %s: %s", tmpdir, err) + else: - super(EB_scipy, self).build_step() + self.testcmd = self.testcmd % { + 'srcdir': self.cfg['start_dir'], + 'parallel': self.cfg['parallel'] + } + super(EB_scipy, self).test_step() def install_step(self): """Custom install step for scipy: use ninja for scipy >= 1.9.0""" if self.use_meson: + # ignore installopts inherited from FortranPythonPackage self.cfg['installopts'] = "" MesonNinja.install_step(self) - # also run the test - python_root = get_software_root('Python') - python_bin = os.path.join(python_root, 'bin', 'python') - run_cmd(self.testcmd % {'python': python_bin}, log_all=True, simple=True) else: super(EB_scipy, self).install_step() From 4e8e47ffb95107c711c6bde33405c4160f5dc510 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Thu, 19 Jan 2023 15:22:44 +0000 Subject: [PATCH 173/325] use change_dir --- easybuild/easyblocks/s/scipy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index ecfa42b8ff..06efba71d3 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -145,7 +145,7 @@ def test_step(self): MesonNinja.test_step(self) # reconfigure meson to use real install dir - os.chdir(cwd) + change_dir(cwd) cmd = 'meson configure --prefix=%s' % self.installdir run_cmd(cmd, log_all=True, simple=True, verbose=False) From b71ca1bff3ae520b3dacda217f3883e114f0451e Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Thu, 19 Jan 2023 18:11:06 +0000 Subject: [PATCH 174/325] fix tests for non-meson builds --- easybuild/easyblocks/s/scipy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 06efba71d3..de8a30f847 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -156,8 +156,9 @@ def test_step(self): else: self.testcmd = self.testcmd % { + 'python': '%(python)s', 'srcdir': self.cfg['start_dir'], - 'parallel': self.cfg['parallel'] + 'parallel': self.cfg['parallel'], } super(EB_scipy, self).test_step() From 34ba9b8be384c1249c2c0ef60f7e6f328f4776cd Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Fri, 20 Jan 2023 11:02:58 +0100 Subject: [PATCH 175/325] check that sanity_check_module_loaded attribute exists before querying it in PythonPackage easyblock (fixes #2864) --- easybuild/easyblocks/generic/pythonpackage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index 449f699792..d89e495122 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -793,7 +793,7 @@ def sanity_check_step(self, *args, **kwargs): # load module early ourselves rather than letting parent sanity_check_step method do so, # since custom actions taken below require that environment is set up properly already # (especially when using --sanity-check-only) - if not self.sanity_check_module_loaded: + if hasattr(self, 'sanity_check_module_loaded') and not self.sanity_check_module_loaded: extension = self.is_extension or kwargs.get('extension', False) extra_modules = kwargs.get('extra_modules', None) self.fake_mod_data = self.sanity_check_load_module(extension=extension, extra_modules=extra_modules) From b18e343b17597ce673c58c0dac1e3374ead18577 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Fri, 20 Jan 2023 11:10:36 +0000 Subject: [PATCH 176/325] add extra variable to enable/disable running of slow scipy tests --- easybuild/easyblocks/s/scipy.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index de8a30f847..895a19cab3 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -41,6 +41,7 @@ from easybuild.easyblocks.generic.fortranpythonpackage import FortranPythonPackage from easybuild.easyblocks.generic.mesonninja import MesonNinja from easybuild.easyblocks.generic.pythonpackage import det_pylibdir +from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import change_dir, mkdir, remove_dir from easybuild.tools.modules import get_software_root @@ -50,6 +51,15 @@ class EB_scipy(FortranPythonPackage, MesonNinja): """Support for installing the scipy Python package as part of a Python installation.""" + @staticmethod + def extra_options(): + """Easyconfig parameters specific to scipy.""" + extra_vars = ({ + 'enable_slow_tests': [False, "Run scipy test suite, including tests marked as slow", CUSTOM], + }) + + return FortranPythonPackage.extra_options(extra_vars=extra_vars) + def __init__(self, *args, **kwargs): """Set scipy-specific test command.""" super(EB_scipy, self).__init__(*args, **kwargs) @@ -61,6 +71,8 @@ def __init__(self, *args, **kwargs): "touch %(srcdir)s/.coveragerc", "%(python)s %(srcdir)s/runtests.py -v --no-build --parallel %(parallel)s", ]) + if self.cfg['enable_slow_tests'] is True: + self.testcmd += " -m full " def configure_step(self): """Custom configure step for scipy: set extra installation options when needed.""" From 0060fa23574695a804b42e5af64c048d7c0f0139 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Fri, 20 Jan 2023 11:44:25 +0000 Subject: [PATCH 177/325] add option to ignore scipy test results --- easybuild/easyblocks/s/scipy.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 895a19cab3..d42c6d92e2 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -56,6 +56,7 @@ def extra_options(): """Easyconfig parameters specific to scipy.""" extra_vars = ({ 'enable_slow_tests': [False, "Run scipy test suite, including tests marked as slow", CUSTOM], + 'ignore_test_result': [False, "Run scipy test suite, but ignore result (only log)", CUSTOM], }) return FortranPythonPackage.extra_options(extra_vars=extra_vars) @@ -66,13 +67,17 @@ def __init__(self, *args, **kwargs): self.use_meson = LooseVersion(self.version) >= LooseVersion('1.9') self.testinstall = True - self.testcmd = " && ".join([ - "cd ..", - "touch %(srcdir)s/.coveragerc", - "%(python)s %(srcdir)s/runtests.py -v --no-build --parallel %(parallel)s", - ]) - if self.cfg['enable_slow_tests'] is True: - self.testcmd += " -m full " + if self.cfg['ignore_test_result']: + # running tests this way exits with 0 regardless + self.testcmd = "cd .. && %(python)s -c 'import numpy; import scipy; scipy.test(verbose=2)'" + else: + self.testcmd = " && ".join([ + "cd ..", + "touch %(srcdir)s/.coveragerc", + "%(python)s %(srcdir)s/runtests.py -v --no-build --parallel %(parallel)s", + ]) + if self.cfg['enable_slow_tests'] is True: + self.testcmd += " -m full " def configure_step(self): """Custom configure step for scipy: set extra installation options when needed.""" From 40deb9f83814fe5e68e67847592ea0c82fe69475 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Fri, 20 Jan 2023 11:56:39 +0000 Subject: [PATCH 178/325] ignore test results by default to maintain current behaviour for older easyconfigs --- easybuild/easyblocks/s/scipy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index d42c6d92e2..13e87d0937 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -56,7 +56,8 @@ def extra_options(): """Easyconfig parameters specific to scipy.""" extra_vars = ({ 'enable_slow_tests': [False, "Run scipy test suite, including tests marked as slow", CUSTOM], - 'ignore_test_result': [False, "Run scipy test suite, but ignore result (only log)", CUSTOM], + # ignore tests by default to maintain behaviour in older easyconfigs + 'ignore_test_result': [True, "Run scipy test suite, but ignore result (only log)", CUSTOM], }) return FortranPythonPackage.extra_options(extra_vars=extra_vars) From f2808b01201ec407f63790b6516cc1bfcd739661 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Mon, 23 Jan 2023 15:50:46 +0000 Subject: [PATCH 179/325] make changes suggested in review --- easybuild/easyblocks/s/scipy.py | 84 ++++++++++++++++----------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 13e87d0937..22a7e1cc40 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -40,15 +40,15 @@ import easybuild.tools.toolchain as toolchain from easybuild.easyblocks.generic.fortranpythonpackage import FortranPythonPackage from easybuild.easyblocks.generic.mesonninja import MesonNinja -from easybuild.easyblocks.generic.pythonpackage import det_pylibdir +from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pylibdir from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import change_dir, mkdir, remove_dir +from easybuild.tools.filetools import change_dir, copy_dir, mkdir from easybuild.tools.modules import get_software_root from easybuild.tools.run import run_cmd -class EB_scipy(FortranPythonPackage, MesonNinja): +class EB_scipy(FortranPythonPackage, PythonPackage, MesonNinja): """Support for installing the scipy Python package as part of a Python installation.""" @staticmethod @@ -57,19 +57,31 @@ def extra_options(): extra_vars = ({ 'enable_slow_tests': [False, "Run scipy test suite, including tests marked as slow", CUSTOM], # ignore tests by default to maintain behaviour in older easyconfigs - 'ignore_test_result': [True, "Run scipy test suite, but ignore result (only log)", CUSTOM], + 'ignore_test_result': [None, "Run scipy test suite, but ignore result (only log)", CUSTOM], }) - return FortranPythonPackage.extra_options(extra_vars=extra_vars) + return PythonPackage.extra_options(extra_vars=extra_vars) def __init__(self, *args, **kwargs): """Set scipy-specific test command.""" - super(EB_scipy, self).__init__(*args, **kwargs) - - self.use_meson = LooseVersion(self.version) >= LooseVersion('1.9') + # calling PythonPackage __init__ also lets MesonNinja work in an extension + PythonPackage.__init__(self, *args, **kwargs) self.testinstall = True + + if LooseVersion(self.version) >= LooseVersion('1.9'): + self.use_meson = True + # enforce scipy test suite results if not explicitly disabled for scipy >= 1.9 + if self.cfg['ignore_test_result'] is None: + self.cfg['ignore_test_result'] = True + # ignore installopts inherited from FortranPythonPackage + self.cfg['installopts'] = "" + else: + self.use_meson = False + if self.cfg['ignore_test_result']: - # running tests this way exits with 0 regardless + # maintains compatibility with easyconfigs predating scipy 1.9. Runs tests (serially) in + # a way that exits with code 0 regardless of test results, see: + # https://github.com/easybuilders/easybuild-easyblocks/issues/2237 self.testcmd = "cd .. && %(python)s -c 'import numpy; import scipy; scipy.test(verbose=2)'" else: self.testcmd = " && ".join([ @@ -77,12 +89,11 @@ def __init__(self, *args, **kwargs): "touch %(srcdir)s/.coveragerc", "%(python)s %(srcdir)s/runtests.py -v --no-build --parallel %(parallel)s", ]) - if self.cfg['enable_slow_tests'] is True: + if self.cfg['enable_slow_tests']: self.testcmd += " -m full " def configure_step(self): """Custom configure step for scipy: set extra installation options when needed.""" - pylibdir = det_pylibdir() # scipy >= 1.9.0 uses Meson/Ninja if self.use_meson: @@ -102,6 +113,7 @@ def configure_step(self): # need to have already installed extensions in PATH, PYTHONPATH for configure/build/install steps pythonpath = os.getenv('PYTHONPATH') + pylibdir = det_pylibdir() env.setvar('PYTHONPATH', os.pathsep.join([os.path.join(self.installdir, pylibdir), pythonpath])) path = os.getenv('PATH') @@ -110,7 +122,7 @@ def configure_step(self): MesonNinja.configure_step(self) else: - super(EB_scipy, self).configure_step() + FortranPythonPackage.configure_step(self) if LooseVersion(self.version) >= LooseVersion('0.13'): # in recent scipy versions, additional compilation is done in the install step, @@ -123,72 +135,60 @@ def build_step(self): if self.use_meson: MesonNinja.build_step(self) else: - super(EB_scipy, self).build_step() + FortranPythonPackage.build_step(self) def test_step(self): """Run available scipy unit tests. Adapted from numpy easyblock""" if self.use_meson: - # temporarily install scipy so we can run the test suite tmpdir = tempfile.mkdtemp() cwd = os.getcwd() - cmd = " && ".join([ - # reconfigure meson to use temp dir - 'meson configure --prefix=%s' % tmpdir, - 'ninja -j %s install' % self.cfg['parallel'], - ]) - run_cmd(cmd, log_all=True, simple=True, verbose=False) + tmp_builddir = os.path.join(tmpdir, 'build') + tmp_installdir = os.path.join(tmpdir, 'install') - abs_pylibdirs = [os.path.join(tmpdir, pylibdir) for pylibdir in self.all_pylibdirs] - for pylibdir in abs_pylibdirs: - mkdir(pylibdir, parents=True) - python_root = get_software_root('Python') - python_bin = os.path.join(python_root, 'bin', 'python') + # create a copy of the builddir + copy_dir(cwd, tmp_builddir) + change_dir(tmp_builddir) + + # reconfigure (to update prefix), and install to tmpdir + MesonNinja.configure_step(self, cmd_prefix=tmp_installdir) + MesonNinja.install_step(self) + + tmp_pylibdir = [os.path.join(tmp_installdir, det_pylibdir())] + self.prepare_python() self.cfg['pretestopts'] = " && ".join([ # LDFLAGS should not be set when testing numpy/scipy, because it overwrites whatever numpy/scipy sets # see http://projects.scipy.org/numpy/ticket/182 "unset LDFLAGS", - "export PYTHONPATH=%s:$PYTHONPATH" % os.pathsep.join(abs_pylibdirs), + "export PYTHONPATH=%s:$PYTHONPATH" % tmp_pylibdir, "", ]) self.cfg['runtest'] = self.testcmd % { - 'python': python_bin, + 'python': self.python_cmd, 'srcdir': self.cfg['start_dir'], 'parallel': self.cfg['parallel'], } MesonNinja.test_step(self) - # reconfigure meson to use real install dir - change_dir(cwd) - cmd = 'meson configure --prefix=%s' % self.installdir - run_cmd(cmd, log_all=True, simple=True, verbose=False) - - try: - remove_dir(tmpdir) - except OSError as err: - raise EasyBuildError("Failed to remove directory %s: %s", tmpdir, err) - else: self.testcmd = self.testcmd % { 'python': '%(python)s', 'srcdir': self.cfg['start_dir'], 'parallel': self.cfg['parallel'], } - super(EB_scipy, self).test_step() + FortranPythonPackage.test_step(self) def install_step(self): """Custom install step for scipy: use ninja for scipy >= 1.9.0""" if self.use_meson: - # ignore installopts inherited from FortranPythonPackage - self.cfg['installopts'] = "" MesonNinja.install_step(self) else: - super(EB_scipy, self).install_step() + FortranPythonPackage.install_step(self) def sanity_check_step(self, *args, **kwargs): """Custom sanity check for scipy.""" @@ -200,4 +200,4 @@ def sanity_check_step(self, *args, **kwargs): 'dirs': [det_pylibdir()], } - return super(EB_scipy, self).sanity_check_step(custom_paths=custom_paths) + return PythonPackage.sanity_check_step(self, custom_paths=custom_paths) From 8d44a255b7f44b5019fbc62547d44867b8322f99 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Mon, 23 Jan 2023 15:53:07 +0000 Subject: [PATCH 180/325] appease the hound --- easybuild/easyblocks/s/scipy.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 22a7e1cc40..1df30766b9 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -43,9 +43,7 @@ from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pylibdir from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import change_dir, copy_dir, mkdir -from easybuild.tools.modules import get_software_root -from easybuild.tools.run import run_cmd +from easybuild.tools.filetools import change_dir, copy_dir class EB_scipy(FortranPythonPackage, PythonPackage, MesonNinja): @@ -77,7 +75,7 @@ def __init__(self, *args, **kwargs): self.cfg['installopts'] = "" else: self.use_meson = False - + if self.cfg['ignore_test_result']: # maintains compatibility with easyconfigs predating scipy 1.9. Runs tests (serially) in # a way that exits with code 0 regardless of test results, see: From b1fc372617ed6b20dbce563a67f0220fbd4e3990 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 26 Jan 2023 15:27:51 +0100 Subject: [PATCH 181/325] use start dir of extension to install R packages --- easybuild/easyblocks/generic/rpackage.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/easybuild/easyblocks/generic/rpackage.py b/easybuild/easyblocks/generic/rpackage.py index 572dab6935..190e416db0 100644 --- a/easybuild/easyblocks/generic/rpackage.py +++ b/easybuild/easyblocks/generic/rpackage.py @@ -134,15 +134,10 @@ def make_cmdline_cmd(self, prefix=None): else: prefix = '' - if self.start_dir: - loc = os.path.join(self.ext_dir or os.path.sep, self.start_dir) - else: - loc = self.ext_dir or self.ext_src - cmd = ' '.join([ self.cfg['preinstallopts'], "R CMD INSTALL", - loc, + self.start_dir, confargs, confvars, prefix, From e357a408feb3b78f4e9a506f826dab2a20629545 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 26 Jan 2023 15:03:05 +0000 Subject: [PATCH 182/325] modified the logic to find the PyQt5 sipdir in more places --- easybuild/easyblocks/q/qscintilla.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/easybuild/easyblocks/q/qscintilla.py b/easybuild/easyblocks/q/qscintilla.py index a712222c48..c4dd6bc3ef 100644 --- a/easybuild/easyblocks/q/qscintilla.py +++ b/easybuild/easyblocks/q/qscintilla.py @@ -118,16 +118,23 @@ def install_step(self): pyshortver = '.'.join(get_software_version('Python').split('.')[:2]) sip_incdir = find_glob_pattern(os.path.join(self.pyqt_root, 'include', 'python%s*' % pyshortver), False) - # in case PyQt5's sip was installed in directories that are specific to each version of python - # as could happen with multi_deps - pyqt_sipdir = find_glob_pattern(os.path.join(self.pyqt_root, 'share', 'python%s*' % pyshortver, - 'site-packages', 'sip', self.pyqt_pkg_name), False) - # fall back to a single sipdir + # depending on PyQt5 versions and how it was installed, the sip directory could be in various places + # test them and figure out the first one that matches + pyqt_sip_subidr = [os.path.join('share', 'python%s*' % pyshortver, 'site-packages', 'sip', + self.pyqt_pkg_name), + os.path.join('share', 'sip', self.pyqt_pkg_name), + os.path.join('share', 'sip'), + os.path.join('lib', 'python%s*' % pyshortver, 'site-packages', self.pyqt_pkg_name, + 'bindings') + ] + pyqt_sipdir_options = [os.path.join(self.pyqt_root, subdir) for subdir in pyqt_sip_subidr] + for pyqt_sipdir_option in pyqt_sipdir_options: + pyqt_sipdir = find_glob_pattern(pyqt_sipdir_option, False) + if pyqt_sipdir: + break + if not pyqt_sipdir: - if LooseVersion(get_software_version(self.pyqt_pkg_name)) >= LooseVersion('5.15'): - pyqt_sipdir = os.path.join(self.pyqt_root, 'share', 'sip') - else: - pyqt_sipdir = os.path.join(self.pyqt_root, 'share', 'sip', self.pyqt_pkg_name) + raise EasyBuildError("Failed to find PyQt5 sip directory") cfgopts = [ '--destdir %s' % os.path.join(self.installdir, pylibdir), From a90d61708a214cd7c72e2767c729c787619a2927 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 26 Jan 2023 15:07:11 +0000 Subject: [PATCH 183/325] appeasing hound --- easybuild/easyblocks/q/qscintilla.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/q/qscintilla.py b/easybuild/easyblocks/q/qscintilla.py index c4dd6bc3ef..ac7a2bbeeb 100644 --- a/easybuild/easyblocks/q/qscintilla.py +++ b/easybuild/easyblocks/q/qscintilla.py @@ -126,7 +126,7 @@ def install_step(self): os.path.join('share', 'sip'), os.path.join('lib', 'python%s*' % pyshortver, 'site-packages', self.pyqt_pkg_name, 'bindings') - ] + ] pyqt_sipdir_options = [os.path.join(self.pyqt_root, subdir) for subdir in pyqt_sip_subidr] for pyqt_sipdir_option in pyqt_sipdir_options: pyqt_sipdir = find_glob_pattern(pyqt_sipdir_option, False) From 3e491c0b28a8692d422d45685885ee4c74b0b91f Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 26 Jan 2023 15:14:26 +0000 Subject: [PATCH 184/325] fixed typos --- easybuild/easyblocks/q/qscintilla.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/q/qscintilla.py b/easybuild/easyblocks/q/qscintilla.py index ac7a2bbeeb..3a64d6c607 100644 --- a/easybuild/easyblocks/q/qscintilla.py +++ b/easybuild/easyblocks/q/qscintilla.py @@ -120,14 +120,14 @@ def install_step(self): sip_incdir = find_glob_pattern(os.path.join(self.pyqt_root, 'include', 'python%s*' % pyshortver), False) # depending on PyQt5 versions and how it was installed, the sip directory could be in various places # test them and figure out the first one that matches - pyqt_sip_subidr = [os.path.join('share', 'python%s*' % pyshortver, 'site-packages', 'sip', + pyqt_sip_subdir = [os.path.join('share', 'python%s*' % pyshortver, 'site-packages', 'sip', self.pyqt_pkg_name), os.path.join('share', 'sip', self.pyqt_pkg_name), os.path.join('share', 'sip'), os.path.join('lib', 'python%s*' % pyshortver, 'site-packages', self.pyqt_pkg_name, 'bindings') ] - pyqt_sipdir_options = [os.path.join(self.pyqt_root, subdir) for subdir in pyqt_sip_subidr] + pyqt_sipdir_options = [os.path.join(self.pyqt_root, subdir) for subdir in pyqt_sip_subdir] for pyqt_sipdir_option in pyqt_sipdir_options: pyqt_sipdir = find_glob_pattern(pyqt_sipdir_option, False) if pyqt_sipdir: From 8f5534a80e5b07f16e44af8e47d29de1354af845 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Thu, 26 Jan 2023 16:31:06 +0100 Subject: [PATCH 185/325] fix JULIA_DEPOT_PATH in installation of multiple JuliaPackage extensions --- easybuild/easyblocks/generic/juliapackage.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index 239ed5f5d3..2490bc2823 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -96,11 +96,12 @@ def install_step(self): """Install Julia package with Pkg""" # prepend installation directory to Julia DEPOT_PATH + # extensions in a bundle can share their DEPOT_PATH # see https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_DEPOT_PATH - depot_path = os.getenv('JULIA_DEPOT_PATH') - if depot_path is not None: - depot_path = ':'.join([self.installdir, depot_path]) - env.setvar('JULIA_DEPOT_PATH', depot_path) + depot_path = os.getenv('JULIA_DEPOT_PATH', '') + if self.installdir not in depot_path: + depot_path = ':'.join([depot for depot in (self.installdir, depot_path) if depot]) + env.setvar('JULIA_DEPOT_PATH', depot_path) # command sequence for Julia.Pkg julia_pkg_cmd = ['using Pkg'] From e30d17fde03fd13a40157dfb0a9808452a5ae89a Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sun, 29 Jan 2023 12:12:20 +0100 Subject: [PATCH 186/325] fix website/docs links in README --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index b651c614a6..fd11b4fe04 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ .. image:: https://github.com/easybuilders/easybuild-easyblocks/workflows/easyblocks%20unit%20tests/badge.svg?branch=develop -`EasyBuild `_ is a software build +`EasyBuild `_ is a software build and installation framework that allows you to manage (scientific) software on High Performance Computing (HPC) systems in an efficient way. @@ -13,7 +13,7 @@ EasyBuild. Easyblocks are Python modules that implement the install procedure fo (group of) software package(s). Together with the EasyBuild framework, they allow to easily build and install supported software packages. -The EasyBuild documentation is available at http://easybuild.readthedocs.org/. +The EasyBuild documentation is available at http://docs.easybuild.io/. The easybuild-easyblocks source code is hosted on GitHub, along with an issue tracker for bug reports and feature requests, see From 2d3de771df47fa0cb63c05cb29c875c7b6abe092 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 30 Jan 2023 14:25:34 +0100 Subject: [PATCH 187/325] Add `testinstall` EC option to PythonPackage --- easybuild/easyblocks/generic/pythonpackage.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index d89e495122..00ea6183a0 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -250,6 +250,7 @@ def extra_options(extra_vars=None): 'sanity_pip_check': [False, "Run 'python -m pip check' to ensure all required Python packages are " "installed and check for any package with an invalid (0.0.0) version.", CUSTOM], 'runtest': [True, "Run unit tests.", CUSTOM], # overrides default + 'testinstall': [False, "Install into temporary directory prior to running the tests.", CUSTOM], 'unpack_sources': [None, "Unpack sources prior to build/install. Defaults to 'True' except for whl files", CUSTOM], # A version of 0.0.0 is usually an error on installation unless the package does really not provide a @@ -283,7 +284,7 @@ def __init__(self, *args, **kwargs): self.sitecfgfn = 'site.cfg' self.sitecfglibdir = None self.sitecfgincdir = None - self.testinstall = False + self.testinstall = self.cfg['testinstall'] self.testcmd = None self.unpack_options = self.cfg['unpack_options'] From 6f10887b1634025fc91ace2c67b5666f5e813119 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Mon, 30 Jan 2023 14:57:29 +0100 Subject: [PATCH 188/325] fix checking of CUDA/ROCR-Runtime dependencies for Clang to determine default build targets (fixes #2871) --- easybuild/easyblocks/c/clang.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 4f1344187a..e9f195b275 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -177,18 +177,19 @@ def __init__(self, *args, **kwargs): build_targets = self.cfg['build_targets'] # define build_targets if not set if build_targets is None: + deps = [dep['name'].lower() for dep in self.cfg.dependencies()] arch = get_cpu_architecture() try: default_targets = DEFAULT_TARGETS_MAP[arch][:] # If CUDA is included as a dep, add NVPTX as a target - if get_software_root("CUDA"): - default_targets += ["NVPTX"] + if 'cuda' in deps: + default_targets += ['NVPTX'] # For AMDGPU support we need ROCR-Runtime and # ROCT-Thunk-Interface, however, since ROCT is a dependency of # ROCR we only check for the ROCR-Runtime here # https://openmp.llvm.org/SupportAndFAQ.html#q-how-to-build-an-openmp-amdgpu-offload-capable-compiler - if get_software_root("ROCR-Runtime"): - default_targets += ["AMDGPU"] + if 'rocr-runtime' in deps: + default_targets += ['AMDGPU'] self.cfg['build_targets'] = build_targets = default_targets self.log.debug("Using %s as default build targets for CPU/GPU architecture %s.", default_targets, arch) except KeyError: From 4f30aab3822002794251fdc94e9b69ff8afed9ed Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Mon, 30 Jan 2023 16:08:22 +0100 Subject: [PATCH 189/325] take into account that CUDA may be an indirect dependency via the toolchain Co-authored-by: ocaisa --- easybuild/easyblocks/c/clang.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index e9f195b275..172811566d 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -182,7 +182,9 @@ def __init__(self, *args, **kwargs): try: default_targets = DEFAULT_TARGETS_MAP[arch][:] # If CUDA is included as a dep, add NVPTX as a target - if 'cuda' in deps: + # There are (old) toolchains with CUDA as part of the toolchain + cuda_toolchain = hasattr(self.toolchain, 'COMPILER_CUDA_FAMILY') + if 'cuda' in deps or cuda_toolchain: default_targets += ['NVPTX'] # For AMDGPU support we need ROCR-Runtime and # ROCT-Thunk-Interface, however, since ROCT is a dependency of From e98c8ea693907979ef23c5d0bcb83addd744e990 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 2 Feb 2023 13:42:31 +0100 Subject: [PATCH 190/325] Show template values of exts_default_options in PythonBundle --- easybuild/easyblocks/generic/pythonbundle.py | 22 ++++++++------------ 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/easybuild/easyblocks/generic/pythonbundle.py b/easybuild/easyblocks/generic/pythonbundle.py index 8e38e0cfa5..292cc275aa 100644 --- a/easybuild/easyblocks/generic/pythonbundle.py +++ b/easybuild/easyblocks/generic/pythonbundle.py @@ -62,21 +62,17 @@ def __init__(self, *args, **kwargs): self.cfg['exts_filter'] = EXTS_FILTER_PYTHON_PACKAGES # need to disable templating to ensure that actual value for exts_default_options is updated... - prev_enable_templating = self.cfg.enable_templating - self.cfg.enable_templating = False + with self.cfg.disable_templating(): + # set default options for extensions according to relevant top-level easyconfig parameters + pypkg_keys = PythonPackage.extra_options().keys() + for key in pypkg_keys: + if key not in self.cfg['exts_default_options']: + self.cfg['exts_default_options'][key] = self.cfg[key] - # set default options for extensions according to relevant top-level easyconfig parameters - pypkg_keys = PythonPackage.extra_options().keys() - for key in pypkg_keys: - if key not in self.cfg['exts_default_options']: - self.cfg['exts_default_options'][key] = self.cfg[key] + self.cfg['exts_default_options']['download_dep_fail'] = True + self.log.info("Detection of downloaded extension dependencies is enabled") - self.cfg['exts_default_options']['download_dep_fail'] = True - self.log.info("Detection of downloaded extension dependencies is enabled") - - self.cfg.enable_templating = prev_enable_templating - - self.log.info("exts_default_options: %s", self.cfg['exts_default_options']) + self.log.info("exts_default_options: %s", self.cfg['exts_default_options']) self.pylibdir = None self.all_pylibdirs = [] From 46c81b79c51c8ba32cdcf3ab54b95049f1a70d3a Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Fri, 3 Feb 2023 15:03:23 +0100 Subject: [PATCH 191/325] Fix missing initialization of CMakeMake in CMakePythonPackage --- easybuild/easyblocks/generic/cmakepythonpackage.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/easybuild/easyblocks/generic/cmakepythonpackage.py b/easybuild/easyblocks/generic/cmakepythonpackage.py index f70fd83340..fac9aeced4 100644 --- a/easybuild/easyblocks/generic/cmakepythonpackage.py +++ b/easybuild/easyblocks/generic/cmakepythonpackage.py @@ -53,11 +53,6 @@ def extra_options(extra_vars=None): extra_vars['runtest'][0] = None return extra_vars - def __init__(self, *args, **kwargs): - """Initialize with PythonPackage.""" - PythonPackage.__init__(self, *args, **kwargs) - self._lib_ext = None # From CMakeMake.__init__ - def configure_step(self, *args, **kwargs): """Main configuration using cmake""" From ebd73924ec5f68b04dbbe8ea7fb9dc69c2877fa7 Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Mon, 6 Feb 2023 12:35:34 +0100 Subject: [PATCH 192/325] Fix error when failing PIP version check during PythonPackage sanity check. The arguments must be passed individually not as a tuple, else you get: > File "/easybuild-easyblocks/easybuild/easyblocks/generic/pythonpackage.py", line 921, in sanity_check_step > pip_version)) > File "/easybuild-framework/easybuild/tools/build_log.py", line 81, in __init__ > msg = msg % args > TypeError: not enough arguments for format string --- easybuild/easyblocks/generic/pythonpackage.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index 00ea6183a0..3e5e5e3a02 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -917,8 +917,9 @@ def sanity_check_step(self, *args, **kwargs): if pip_check_errors: raise EasyBuildError('\n'.join(pip_check_errors)) else: - raise EasyBuildError("pip >= 9.0.0 is required for running '%s', found %s", (pip_check_command, - pip_version)) + raise EasyBuildError("pip >= 9.0.0 is required for running '%s', found %s", + pip_check_command, + pip_version) else: raise EasyBuildError("Failed to determine pip version!") From 844a3a3e95767b03324a889d9f001fe6c2ff4d9c Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Tue, 7 Feb 2023 10:38:23 +0100 Subject: [PATCH 193/325] add debug flag to gopackage easyblock --- easybuild/easyblocks/generic/gopackage.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index d6f00f51a0..b94845b8cd 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -34,6 +34,7 @@ from easybuild.framework.easyblock import EasyBlock from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.config import build_option from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd @@ -126,6 +127,9 @@ def build_step(self): def install_step(self): """Install Go package to a custom path""" + if build_option('debug'): + self.cfg['installopts'] = '-x ' + self.cfg['installopts'] + # actually install Go package cmd = ' '.join([ self.cfg['preinstallopts'], From 0194c09906ac8fa7565bb4acf0381bd2eb0ec638 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 8 Feb 2023 20:55:50 +0000 Subject: [PATCH 194/325] handle templating correctly when playing with configopts --- easybuild/easyblocks/generic/cmakemake.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/easybuild/easyblocks/generic/cmakemake.py b/easybuild/easyblocks/generic/cmakemake.py index f747702fc9..d9ee0d53af 100644 --- a/easybuild/easyblocks/generic/cmakemake.py +++ b/easybuild/easyblocks/generic/cmakemake.py @@ -141,12 +141,18 @@ def build_type(self): def prepend_config_opts(self, config_opts): """Prepends configure options (-Dkey=value) to configopts ignoring those already set""" + # need to disable template resolution or it will remain the same for all runs + self.cfg.enable_templating = False + cfg_configopts = self.cfg['configopts'] # All options are of the form '-D=' new_opts = ' '.join('-D%s=%s' % (key, value) for key, value in config_opts.items() if '-D%s=' % key not in cfg_configopts) self.cfg['configopts'] = ' '.join([new_opts, cfg_configopts]) + #re-enable template resolution + self.cfg.enable_templating = True + def configure_step(self, srcdir=None, builddir=None): """Configure build using cmake""" From 950582fb37a684cf5e20908d8d14d9b491ad2a6e Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Wed, 8 Feb 2023 20:58:28 +0000 Subject: [PATCH 195/325] appeasing hound --- easybuild/easyblocks/generic/cmakemake.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cmakemake.py b/easybuild/easyblocks/generic/cmakemake.py index d9ee0d53af..8bf841f313 100644 --- a/easybuild/easyblocks/generic/cmakemake.py +++ b/easybuild/easyblocks/generic/cmakemake.py @@ -150,7 +150,7 @@ def prepend_config_opts(self, config_opts): if '-D%s=' % key not in cfg_configopts) self.cfg['configopts'] = ' '.join([new_opts, cfg_configopts]) - #re-enable template resolution + # re-enable template resolution self.cfg.enable_templating = True def configure_step(self, srcdir=None, builddir=None): From 84c56102051048f339568fd736afb69afa136582 Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 9 Feb 2023 08:41:22 +0100 Subject: [PATCH 196/325] void pytorch test_step crashing if runtest is not a command --- easybuild/easyblocks/p/pytorch.py | 264 +++++++++++++++--------------- 1 file changed, 135 insertions(+), 129 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 9a7637fed1..53dca5176b 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -248,137 +248,143 @@ def _set_cache_dir(self): def test_step(self): """Run unit tests""" - self._set_cache_dir() - # Pretend to be on FB CI which disables some tests, especially those which download stuff - env.setvar('SANDCASTLE', '1') - # Skip this test(s) which is very flaky - env.setvar('SKIP_TEST_BOTTLENECK', '1') - # Parse excluded_tests and flatten into space separated string - excluded_tests = [] - for arch, tests in self.cfg['excluded_tests'].items(): - if not arch or arch == get_cpu_architecture(): - excluded_tests.extend(tests) - # -x should not be used if there are no excluded tests - if excluded_tests: - excluded_tests = ['-x'] + excluded_tests - self.cfg.template_values.update({ - 'python': self.python_cmd, - 'excluded_tests': ' '.join(excluded_tests) - }) - tests_out, tests_ec = super(EB_PyTorch, self).test_step(return_output_ec=True) - - def get_count_for_pattern(regex, text): - """Match the regexp containing a single group and return the integer value of the matched group. - Return zero if no or more than 1 match was found and warn for the latter case - """ - match = re.findall(regex, text) - if len(match) == 1: - return int(match[0]) - elif len(match) > 1: - # Shouldn't happen, but means something went wrong with the regular expressions. - # Throw warning, as the build might be fine, no need to error on this. - warn_msg = "Error in counting the number of test failures in the output of the PyTorch test suite.\n" - warn_msg += "Please check the EasyBuild log to verify the number of failures (if any) was acceptable." - print_warning(warn_msg) - return 0 - - # Create clear summary report - failure_report = "" - failure_cnt = 0 - error_cnt = 0 - failed_test_suites = [] - - # Grep for patterns like: - # Ran 219 tests in 67.325s - # - # FAILED (errors=10, skipped=190, expected failures=6) - # test_fx failed! - regex = (r"^Ran (?P[0-9]+) tests.*$\n\n" - r"FAILED \((?P.*)\)$\n" - r"(?:^(?:(?!failed!).)*$\n)*" - r"(?P.*) failed!(?: Received signal: \w+)?\s*$") - - for m in re.finditer(regex, tests_out, re.M): - # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' - failure_summary = m.group('failure_summary') - total, test_suite = m.group('test_cnt', 'failed_test_suite_name') - failure_report += "{test_suite} ({total} total tests, {failure_summary})\n".format( - test_suite=test_suite, total=total, failure_summary=failure_summary + # Must not run this unless runtest is actually set to a command, + # otherwise PythonPackage.test_step doesn't return the expected "out, ec" values which makes the code crash + if isinstance(self.cfg['runtest'], string_type): + cmd = self.cfg['runtest'] + if self.cfg['runtest'] and cmd is not None: + self._set_cache_dir() + # Pretend to be on FB CI which disables some tests, especially those which download stuff + env.setvar('SANDCASTLE', '1') + # Skip this test(s) which is very flaky + env.setvar('SKIP_TEST_BOTTLENECK', '1') + # Parse excluded_tests and flatten into space separated string + excluded_tests = [] + for arch, tests in self.cfg['excluded_tests'].items(): + if not arch or arch == get_cpu_architecture(): + excluded_tests.extend(tests) + # -x should not be used if there are no excluded tests + if excluded_tests: + excluded_tests = ['-x'] + excluded_tests + self.cfg.template_values.update({ + 'python': self.python_cmd, + 'excluded_tests': ' '.join(excluded_tests) + }) + + tests_out, tests_ec = super(EB_PyTorch, self).test_step(return_output_ec=True) + + def get_count_for_pattern(regex, text): + """Match the regexp containing a single group and return the integer value of the matched group. + Return zero if no or more than 1 match was found and warn for the latter case + """ + match = re.findall(regex, text) + if len(match) == 1: + return int(match[0]) + elif len(match) > 1: + # Shouldn't happen, but means something went wrong with the regular expressions. + # Throw warning, as the build might be fine, no need to error on this. + warn_msg = "Error in counting the number of test failures in the output of the PyTorch test suite.\n" + warn_msg += "Please check the EasyBuild log to verify the number of failures (if any) was acceptable." + print_warning(warn_msg) + return 0 + + # Create clear summary report + failure_report = "" + failure_cnt = 0 + error_cnt = 0 + failed_test_suites = [] + + # Grep for patterns like: + # Ran 219 tests in 67.325s + # + # FAILED (errors=10, skipped=190, expected failures=6) + # test_fx failed! + regex = (r"^Ran (?P[0-9]+) tests.*$\n\n" + r"FAILED \((?P.*)\)$\n" + r"(?:^(?:(?!failed!).)*$\n)*" + r"(?P.*) failed!(?: Received signal: \w+)?\s*$") + + for m in re.finditer(regex, tests_out, re.M): + # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' + failure_summary = m.group('failure_summary') + total, test_suite = m.group('test_cnt', 'failed_test_suite_name') + failure_report += "{test_suite} ({total} total tests, {failure_summary})\n".format( + test_suite=test_suite, total=total, failure_summary=failure_summary + ) + failure_cnt += get_count_for_pattern(r"(?.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" + + for m in re.finditer(regex, tests_out, re.M): + # E.g. '2 failed, 128 passed, 2 skipped, 2 warnings' + failure_summary = m.group('failure_summary') + test_suite = m.group('failed_test_suite_name') + failure_report += "{test_suite} ({failure_summary})\n".format( + test_suite=test_suite, failure_summary=failure_summary + ) + failure_cnt += get_count_for_pattern(r"([0-9]+) failed", failure_summary) + error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) + failed_test_suites.append(test_suite) + + # Make the names unique and sorted + failed_test_suites = sorted(set(failed_test_suites)) + # Gather all failed tests suites in case we missed any (e.g. when it exited due to syntax errors) + # Also unique and sorted to be able to compare the lists below + all_failed_test_suites = sorted(set( + re.findall(r"^(?P.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M) + )) + # If we missed any test suites prepend a list of all failed test suites + if failed_test_suites != all_failed_test_suites: + failure_report_save = failure_report + failure_report = 'Failed tests (suites/files):\n' + failure_report += '\n'.join('* %s' % t for t in all_failed_test_suites) + if failure_report_save: + failure_report += '\n' + failure_report_save + + # Calculate total number of unsuccesful and total tests + failed_test_cnt = failure_cnt + error_cnt + test_cnt = sum(int(hit) for hit in re.findall(r"^Ran (?P[0-9]+) tests in", tests_out, re.M)) + + if failed_test_cnt > 0: + max_failed_tests = self.cfg['max_failed_tests'] + + failure_or_failures = 'failure' if failure_cnt == 1 else 'failures' + error_or_errors = 'error' if error_cnt == 1 else 'errors' + msg = "%d test %s, %d test %s (out of %d):\n" % ( + failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt ) - failure_cnt += get_count_for_pattern(r"(?.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" - - for m in re.finditer(regex, tests_out, re.M): - # E.g. '2 failed, 128 passed, 2 skipped, 2 warnings' - failure_summary = m.group('failure_summary') - test_suite = m.group('failed_test_suite_name') - failure_report += "{test_suite} ({failure_summary})\n".format( - test_suite=test_suite, failure_summary=failure_summary - ) - failure_cnt += get_count_for_pattern(r"([0-9]+) failed", failure_summary) - error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) - failed_test_suites.append(test_suite) - - # Make the names unique and sorted - failed_test_suites = sorted(set(failed_test_suites)) - # Gather all failed tests suites in case we missed any (e.g. when it exited due to syntax errors) - # Also unique and sorted to be able to compare the lists below - all_failed_test_suites = sorted(set( - re.findall(r"^(?P.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M) - )) - # If we missed any test suites prepend a list of all failed test suites - if failed_test_suites != all_failed_test_suites: - failure_report_save = failure_report - failure_report = 'Failed tests (suites/files):\n' - failure_report += '\n'.join('* %s' % t for t in all_failed_test_suites) - if failure_report_save: - failure_report += '\n' + failure_report_save - - # Calculate total number of unsuccesful and total tests - failed_test_cnt = failure_cnt + error_cnt - test_cnt = sum(int(hit) for hit in re.findall(r"^Ran (?P[0-9]+) tests in", tests_out, re.M)) - - if failed_test_cnt > 0: - max_failed_tests = self.cfg['max_failed_tests'] - - failure_or_failures = 'failure' if failure_cnt == 1 else 'failures' - error_or_errors = 'error' if error_cnt == 1 else 'errors' - msg = "%d test %s, %d test %s (out of %d):\n" % ( - failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt - ) - msg += failure_report - - # If no tests are supposed to fail or some failed for which we were not able to count errors fail now - if max_failed_tests == 0 or failed_test_suites != all_failed_test_suites: - raise EasyBuildError(msg) - else: - msg += '\n\n' + ' '.join([ - "The PyTorch test suite is known to include some flaky tests,", - "which may fail depending on the specifics of the system or the context in which they are run.", - "For this PyTorch installation, EasyBuild allows up to %d tests to fail." % max_failed_tests, - "We recommend to double check that the failing tests listed above ", - "are known to be flaky, or do not affect your intended usage of PyTorch.", - "In case of doubt, reach out to the EasyBuild community (via GitHub, Slack, or mailing list).", - ]) - # Print to console, the user should really be aware that we are accepting failing tests here... - print_warning(msg) - - # Also log this warning in the file log - self.log.warning(msg) - - if failed_test_cnt > max_failed_tests: - raise EasyBuildError("Too many failed tests (%d), maximum allowed is %d", - failed_test_cnt, max_failed_tests) - elif failure_report: - raise EasyBuildError("Test command had non-zero exit code (%s)!\n%s", tests_ec, failure_report) - elif tests_ec: - raise EasyBuildError("Test command had non-zero exit code (%s), but no failed tests found?!", tests_ec) + msg += failure_report + + # If no tests are supposed to fail or some failed for which we were not able to count errors fail now + if max_failed_tests == 0 or failed_test_suites != all_failed_test_suites: + raise EasyBuildError(msg) + else: + msg += '\n\n' + ' '.join([ + "The PyTorch test suite is known to include some flaky tests,", + "which may fail depending on the specifics of the system or the context in which they are run.", + "For this PyTorch installation, EasyBuild allows up to %d tests to fail." % max_failed_tests, + "We recommend to double check that the failing tests listed above ", + "are known to be flaky, or do not affect your intended usage of PyTorch.", + "In case of doubt, reach out to the EasyBuild community (via GitHub, Slack, or mailing list).", + ]) + # Print to console, the user should really be aware that we are accepting failing tests here... + print_warning(msg) + + # Also log this warning in the file log + self.log.warning(msg) + + if failed_test_cnt > max_failed_tests: + raise EasyBuildError("Too many failed tests (%d), maximum allowed is %d", + failed_test_cnt, max_failed_tests) + elif failure_report: + raise EasyBuildError("Test command had non-zero exit code (%s)!\n%s", tests_ec, failure_report) + elif tests_ec: + raise EasyBuildError("Test command had non-zero exit code (%s), but no failed tests found?!", tests_ec) def test_cases_step(self): self._set_cache_dir() From 0a8ebd285f546cc5164c51b00dc993c95700ba80 Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 9 Feb 2023 13:10:27 +0100 Subject: [PATCH 197/325] test return from super(EB_PyTorch, self).test_step and handle the result instead of trying to avoid the problem explicitly. --- easybuild/easyblocks/p/pytorch.py | 272 +++++++++++++++--------------- 1 file changed, 137 insertions(+), 135 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 53dca5176b..f4fd1e80f5 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -248,143 +248,145 @@ def _set_cache_dir(self): def test_step(self): """Run unit tests""" + self._set_cache_dir() + # Pretend to be on FB CI which disables some tests, especially those which download stuff + env.setvar('SANDCASTLE', '1') + # Skip this test(s) which is very flaky + env.setvar('SKIP_TEST_BOTTLENECK', '1') + # Parse excluded_tests and flatten into space separated string + excluded_tests = [] + for arch, tests in self.cfg['excluded_tests'].items(): + if not arch or arch == get_cpu_architecture(): + excluded_tests.extend(tests) + # -x should not be used if there are no excluded tests + if excluded_tests: + excluded_tests = ['-x'] + excluded_tests + self.cfg.template_values.update({ + 'python': self.python_cmd, + 'excluded_tests': ' '.join(excluded_tests) + }) - # Must not run this unless runtest is actually set to a command, - # otherwise PythonPackage.test_step doesn't return the expected "out, ec" values which makes the code crash - if isinstance(self.cfg['runtest'], string_type): - cmd = self.cfg['runtest'] - if self.cfg['runtest'] and cmd is not None: - self._set_cache_dir() - # Pretend to be on FB CI which disables some tests, especially those which download stuff - env.setvar('SANDCASTLE', '1') - # Skip this test(s) which is very flaky - env.setvar('SKIP_TEST_BOTTLENECK', '1') - # Parse excluded_tests and flatten into space separated string - excluded_tests = [] - for arch, tests in self.cfg['excluded_tests'].items(): - if not arch or arch == get_cpu_architecture(): - excluded_tests.extend(tests) - # -x should not be used if there are no excluded tests - if excluded_tests: - excluded_tests = ['-x'] + excluded_tests - self.cfg.template_values.update({ - 'python': self.python_cmd, - 'excluded_tests': ' '.join(excluded_tests) - }) - - tests_out, tests_ec = super(EB_PyTorch, self).test_step(return_output_ec=True) - - def get_count_for_pattern(regex, text): - """Match the regexp containing a single group and return the integer value of the matched group. - Return zero if no or more than 1 match was found and warn for the latter case - """ - match = re.findall(regex, text) - if len(match) == 1: - return int(match[0]) - elif len(match) > 1: - # Shouldn't happen, but means something went wrong with the regular expressions. - # Throw warning, as the build might be fine, no need to error on this. - warn_msg = "Error in counting the number of test failures in the output of the PyTorch test suite.\n" - warn_msg += "Please check the EasyBuild log to verify the number of failures (if any) was acceptable." - print_warning(warn_msg) - return 0 - - # Create clear summary report - failure_report = "" - failure_cnt = 0 - error_cnt = 0 - failed_test_suites = [] - - # Grep for patterns like: - # Ran 219 tests in 67.325s - # - # FAILED (errors=10, skipped=190, expected failures=6) - # test_fx failed! - regex = (r"^Ran (?P[0-9]+) tests.*$\n\n" - r"FAILED \((?P.*)\)$\n" - r"(?:^(?:(?!failed!).)*$\n)*" - r"(?P.*) failed!(?: Received signal: \w+)?\s*$") - - for m in re.finditer(regex, tests_out, re.M): - # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' - failure_summary = m.group('failure_summary') - total, test_suite = m.group('test_cnt', 'failed_test_suite_name') - failure_report += "{test_suite} ({total} total tests, {failure_summary})\n".format( - test_suite=test_suite, total=total, failure_summary=failure_summary - ) - failure_cnt += get_count_for_pattern(r"(?.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" - - for m in re.finditer(regex, tests_out, re.M): - # E.g. '2 failed, 128 passed, 2 skipped, 2 warnings' - failure_summary = m.group('failure_summary') - test_suite = m.group('failed_test_suite_name') - failure_report += "{test_suite} ({failure_summary})\n".format( - test_suite=test_suite, failure_summary=failure_summary - ) - failure_cnt += get_count_for_pattern(r"([0-9]+) failed", failure_summary) - error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) - failed_test_suites.append(test_suite) - - # Make the names unique and sorted - failed_test_suites = sorted(set(failed_test_suites)) - # Gather all failed tests suites in case we missed any (e.g. when it exited due to syntax errors) - # Also unique and sorted to be able to compare the lists below - all_failed_test_suites = sorted(set( - re.findall(r"^(?P.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M) - )) - # If we missed any test suites prepend a list of all failed test suites - if failed_test_suites != all_failed_test_suites: - failure_report_save = failure_report - failure_report = 'Failed tests (suites/files):\n' - failure_report += '\n'.join('* %s' % t for t in all_failed_test_suites) - if failure_report_save: - failure_report += '\n' + failure_report_save - - # Calculate total number of unsuccesful and total tests - failed_test_cnt = failure_cnt + error_cnt - test_cnt = sum(int(hit) for hit in re.findall(r"^Ran (?P[0-9]+) tests in", tests_out, re.M)) - - if failed_test_cnt > 0: - max_failed_tests = self.cfg['max_failed_tests'] - - failure_or_failures = 'failure' if failure_cnt == 1 else 'failures' - error_or_errors = 'error' if error_cnt == 1 else 'errors' - msg = "%d test %s, %d test %s (out of %d):\n" % ( - failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt + test_result = super(EB_PyTorch, self).test_step(return_output_ec=True) + if test_result is None: + if self.cfg['runtest'] or self.cfg['runtest'] is None: + msg = "runtest must be set to a command to run." + else: + msg = "Do not set runtest to False, use --skip-test-step instead." + raise EasyBuildError(msg) + + tests_out, tests_ec = test_result + + def get_count_for_pattern(regex, text): + """Match the regexp containing a single group and return the integer value of the matched group. + Return zero if no or more than 1 match was found and warn for the latter case + """ + match = re.findall(regex, text) + if len(match) == 1: + return int(match[0]) + elif len(match) > 1: + # Shouldn't happen, but means something went wrong with the regular expressions. + # Throw warning, as the build might be fine, no need to error on this. + warn_msg = "Error in counting the number of test failures in the output of the PyTorch test suite.\n" + warn_msg += "Please check the EasyBuild log to verify the number of failures (if any) was acceptable." + print_warning(warn_msg) + return 0 + + # Create clear summary report + failure_report = "" + failure_cnt = 0 + error_cnt = 0 + failed_test_suites = [] + + # Grep for patterns like: + # Ran 219 tests in 67.325s + # + # FAILED (errors=10, skipped=190, expected failures=6) + # test_fx failed! + regex = (r"^Ran (?P[0-9]+) tests.*$\n\n" + r"FAILED \((?P.*)\)$\n" + r"(?:^(?:(?!failed!).)*$\n)*" + r"(?P.*) failed!(?: Received signal: \w+)?\s*$") + + for m in re.finditer(regex, tests_out, re.M): + # E.g. 'failures=3, errors=10, skipped=190, expected failures=6' + failure_summary = m.group('failure_summary') + total, test_suite = m.group('test_cnt', 'failed_test_suite_name') + failure_report += "{test_suite} ({total} total tests, {failure_summary})\n".format( + test_suite=test_suite, total=total, failure_summary=failure_summary ) - msg += failure_report - - # If no tests are supposed to fail or some failed for which we were not able to count errors fail now - if max_failed_tests == 0 or failed_test_suites != all_failed_test_suites: - raise EasyBuildError(msg) - else: - msg += '\n\n' + ' '.join([ - "The PyTorch test suite is known to include some flaky tests,", - "which may fail depending on the specifics of the system or the context in which they are run.", - "For this PyTorch installation, EasyBuild allows up to %d tests to fail." % max_failed_tests, - "We recommend to double check that the failing tests listed above ", - "are known to be flaky, or do not affect your intended usage of PyTorch.", - "In case of doubt, reach out to the EasyBuild community (via GitHub, Slack, or mailing list).", - ]) - # Print to console, the user should really be aware that we are accepting failing tests here... - print_warning(msg) - - # Also log this warning in the file log - self.log.warning(msg) - - if failed_test_cnt > max_failed_tests: - raise EasyBuildError("Too many failed tests (%d), maximum allowed is %d", - failed_test_cnt, max_failed_tests) - elif failure_report: - raise EasyBuildError("Test command had non-zero exit code (%s)!\n%s", tests_ec, failure_report) - elif tests_ec: - raise EasyBuildError("Test command had non-zero exit code (%s), but no failed tests found?!", tests_ec) + failure_cnt += get_count_for_pattern(r"(?.*) in [0-9]+\.*[0-9]*[a-zA-Z]* =+$\n(?P.*) failed!$" + + for m in re.finditer(regex, tests_out, re.M): + # E.g. '2 failed, 128 passed, 2 skipped, 2 warnings' + failure_summary = m.group('failure_summary') + test_suite = m.group('failed_test_suite_name') + failure_report += "{test_suite} ({failure_summary})\n".format( + test_suite=test_suite, failure_summary=failure_summary + ) + failure_cnt += get_count_for_pattern(r"([0-9]+) failed", failure_summary) + error_cnt += get_count_for_pattern(r"([0-9]+) error", failure_summary) + failed_test_suites.append(test_suite) + + # Make the names unique and sorted + failed_test_suites = sorted(set(failed_test_suites)) + # Gather all failed tests suites in case we missed any (e.g. when it exited due to syntax errors) + # Also unique and sorted to be able to compare the lists below + all_failed_test_suites = sorted(set( + re.findall(r"^(?P.*) failed!(?: Received signal: \w+)?\s*$", tests_out, re.M) + )) + # If we missed any test suites prepend a list of all failed test suites + if failed_test_suites != all_failed_test_suites: + failure_report_save = failure_report + failure_report = 'Failed tests (suites/files):\n' + failure_report += '\n'.join('* %s' % t for t in all_failed_test_suites) + if failure_report_save: + failure_report += '\n' + failure_report_save + + # Calculate total number of unsuccesful and total tests + failed_test_cnt = failure_cnt + error_cnt + test_cnt = sum(int(hit) for hit in re.findall(r"^Ran (?P[0-9]+) tests in", tests_out, re.M)) + + if failed_test_cnt > 0: + max_failed_tests = self.cfg['max_failed_tests'] + + failure_or_failures = 'failure' if failure_cnt == 1 else 'failures' + error_or_errors = 'error' if error_cnt == 1 else 'errors' + msg = "%d test %s, %d test %s (out of %d):\n" % ( + failure_cnt, failure_or_failures, error_cnt, error_or_errors, test_cnt + ) + msg += failure_report + + # If no tests are supposed to fail or some failed for which we were not able to count errors fail now + if max_failed_tests == 0 or failed_test_suites != all_failed_test_suites: + raise EasyBuildError(msg) + else: + msg += '\n\n' + ' '.join([ + "The PyTorch test suite is known to include some flaky tests,", + "which may fail depending on the specifics of the system or the context in which they are run.", + "For this PyTorch installation, EasyBuild allows up to %d tests to fail." % max_failed_tests, + "We recommend to double check that the failing tests listed above ", + "are known to be flaky, or do not affect your intended usage of PyTorch.", + "In case of doubt, reach out to the EasyBuild community (via GitHub, Slack, or mailing list).", + ]) + # Print to console, the user should really be aware that we are accepting failing tests here... + print_warning(msg) + + # Also log this warning in the file log + self.log.warning(msg) + + if failed_test_cnt > max_failed_tests: + raise EasyBuildError("Too many failed tests (%d), maximum allowed is %d", + failed_test_cnt, max_failed_tests) + elif failure_report: + raise EasyBuildError("Test command had non-zero exit code (%s)!\n%s", tests_ec, failure_report) + elif tests_ec: + raise EasyBuildError("Test command had non-zero exit code (%s), but no failed tests found?!", tests_ec) def test_cases_step(self): self._set_cache_dir() From 1714017478e60e2fa003f5ebba71ae9128fd1446 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 9 Feb 2023 14:06:28 +0000 Subject: [PATCH 198/325] use with self.cfg.disable_templating(): --- easybuild/easyblocks/generic/cmakemake.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/generic/cmakemake.py b/easybuild/easyblocks/generic/cmakemake.py index 8bf841f313..c16c101bbe 100644 --- a/easybuild/easyblocks/generic/cmakemake.py +++ b/easybuild/easyblocks/generic/cmakemake.py @@ -143,16 +143,14 @@ def prepend_config_opts(self, config_opts): """Prepends configure options (-Dkey=value) to configopts ignoring those already set""" # need to disable template resolution or it will remain the same for all runs self.cfg.enable_templating = False + with self.cfg.disable_templating(): + cfg_configopts = self.cfg['configopts'] - cfg_configopts = self.cfg['configopts'] # All options are of the form '-D=' new_opts = ' '.join('-D%s=%s' % (key, value) for key, value in config_opts.items() if '-D%s=' % key not in cfg_configopts) self.cfg['configopts'] = ' '.join([new_opts, cfg_configopts]) - # re-enable template resolution - self.cfg.enable_templating = True - def configure_step(self, srcdir=None, builddir=None): """Configure build using cmake""" From 7622313e4e7764ded6162056522c5cd07660e93e Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Thu, 9 Feb 2023 14:20:48 +0000 Subject: [PATCH 199/325] removed forgotten enable_templating = False line --- easybuild/easyblocks/generic/cmakemake.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cmakemake.py b/easybuild/easyblocks/generic/cmakemake.py index c16c101bbe..48cdae593a 100644 --- a/easybuild/easyblocks/generic/cmakemake.py +++ b/easybuild/easyblocks/generic/cmakemake.py @@ -142,7 +142,6 @@ def build_type(self): def prepend_config_opts(self, config_opts): """Prepends configure options (-Dkey=value) to configopts ignoring those already set""" # need to disable template resolution or it will remain the same for all runs - self.cfg.enable_templating = False with self.cfg.disable_templating(): cfg_configopts = self.cfg['configopts'] From 8fff3f64e743be21af2131b408253854bc9fe4fb Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Thu, 9 Feb 2023 15:35:36 +0100 Subject: [PATCH 200/325] reverse test of runtest and clarify error message. --- easybuild/easyblocks/p/pytorch.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index f4fd1e80f5..252bc09741 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -268,10 +268,10 @@ def test_step(self): test_result = super(EB_PyTorch, self).test_step(return_output_ec=True) if test_result is None: - if self.cfg['runtest'] or self.cfg['runtest'] is None: - msg = "runtest must be set to a command to run." + if self.cfg['runtest'] is False: + msg = "Do not set 'runtest' to False, use --skip-test-step instead." else: - msg = "Do not set runtest to False, use --skip-test-step instead." + msg = "Tests did not run. Make sure 'runtest' is set to a command." raise EasyBuildError(msg) tests_out, tests_ec = test_result From 1d7fa6225b207ab19898fa61ac93405e131fad8d Mon Sep 17 00:00:00 2001 From: Alexander Grund Date: Thu, 9 Feb 2023 16:18:37 +0100 Subject: [PATCH 201/325] Fix to check for existance of config option in FlexiBLAS Only checking for `key` might match where it should not. Use the full `"-Dkey="` as the search string. --- easybuild/easyblocks/f/flexiblas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/f/flexiblas.py b/easybuild/easyblocks/f/flexiblas.py index 2a63c1650e..ab6fabfc50 100644 --- a/easybuild/easyblocks/f/flexiblas.py +++ b/easybuild/easyblocks/f/flexiblas.py @@ -138,7 +138,7 @@ def configure_step(self): # to allow easyconfig to override specifies settings for key, value in sorted(configopts.items()): opt = '-D%s=' % key - if key not in self.cfg['configopts']: + if opt not in self.cfg['configopts']: self.cfg.update('configopts', opt + "'%s'" % value) # specify compiler commands with absolute paths, to ensure that RPATH wrapper scripts are used From 6e30d90d2ba539f3be24eda20f906270ce82b50a Mon Sep 17 00:00:00 2001 From: Randy Pittman Date: Tue, 14 Feb 2023 14:38:17 -0800 Subject: [PATCH 202/325] Use older `ncgen -H` for older netCDF Fixes #2888. --- easybuild/easyblocks/n/netcdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/n/netcdf.py b/easybuild/easyblocks/n/netcdf.py index 9ac62ff72c..45017748bb 100644 --- a/easybuild/easyblocks/n/netcdf.py +++ b/easybuild/easyblocks/n/netcdf.py @@ -143,7 +143,7 @@ def sanity_check_step(self): custom_commands = [ "nc-config --help", - "ncgen -h", + "ncgen -h" if LooseVersion(self.version) > LooseVersion("4.6.1") else "ncgen -H", ] super(EB_netCDF, self).sanity_check_step(custom_commands=custom_commands, custom_paths=custom_paths) From 566249a3f9ccfd9de8213efe48ecc8f17163fe5d Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Wed, 15 Feb 2023 17:05:55 +0100 Subject: [PATCH 203/325] always use -x option --- easybuild/easyblocks/generic/gopackage.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index b94845b8cd..2dcc34c5d7 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -127,14 +127,12 @@ def build_step(self): def install_step(self): """Install Go package to a custom path""" - if build_option('debug'): - self.cfg['installopts'] = '-x ' + self.cfg['installopts'] - # actually install Go package cmd = ' '.join([ self.cfg['preinstallopts'], 'go', 'install', + '-x', self.cfg['installopts'], ]) run_cmd(cmd, log_all=True, log_ok=True, simple=True) From 574190c5714a7fd7e6c1d44fa4e14df0e8c3eb26 Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Wed, 15 Feb 2023 17:06:54 +0100 Subject: [PATCH 204/325] remove stale update --- easybuild/easyblocks/generic/gopackage.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index 2dcc34c5d7..f60ef94daf 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -34,7 +34,6 @@ from easybuild.framework.easyblock import EasyBlock from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.config import build_option from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd From a2323ecc5419ac1e639fe56b90154c37b78f2a7d Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Wed, 15 Feb 2023 17:42:48 +0100 Subject: [PATCH 205/325] add comment --- easybuild/easyblocks/generic/gopackage.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index f60ef94daf..aa51ea05cb 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -131,6 +131,8 @@ def install_step(self): self.cfg['preinstallopts'], 'go', 'install', + # print commands as they are executed, + # such as downloads and installs of package deps as listed in the go.mod file '-x', self.cfg['installopts'], ]) From 8f1c579a3cf21843411c3b205df85379b4aa6acd Mon Sep 17 00:00:00 2001 From: Samuel Moors Date: Wed, 15 Feb 2023 17:45:12 +0100 Subject: [PATCH 206/325] tweak comment --- easybuild/easyblocks/generic/gopackage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index aa51ea05cb..c06f724437 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -132,7 +132,7 @@ def install_step(self): 'go', 'install', # print commands as they are executed, - # such as downloads and installs of package deps as listed in the go.mod file + # including downloading and installing of package deps as listed in the go.mod file '-x', self.cfg['installopts'], ]) From 00efdf1823d74d84ce6c05b5d61f6ccd134f7b0a Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Wed, 8 Feb 2023 15:54:59 +0100 Subject: [PATCH 207/325] add deprecation notice to RPackage extensions with relative paths in start_dir --- easybuild/easyblocks/generic/rpackage.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/rpackage.py b/easybuild/easyblocks/generic/rpackage.py index 190e416db0..897408503c 100644 --- a/easybuild/easyblocks/generic/rpackage.py +++ b/easybuild/easyblocks/generic/rpackage.py @@ -134,10 +134,19 @@ def make_cmdline_cmd(self, prefix=None): else: prefix = '' + loc = self.start_dir + if loc is None: + loc = self.ext_dir or self.ext_src + elif not os.path.isabs(loc): + # TODO: deprecated behaviour in framework 4.7.1, remove after 5.0 + loc = os.path.join(self.ext_dir or os.path.sep, loc) + deprecation_msg = "Found relative path in start_dir, please upgrade to easybuild-framework>=4.7.1" + self.log.deprecated(deprecation_msg, '5.0') + cmd = ' '.join([ self.cfg['preinstallopts'], "R CMD INSTALL", - self.start_dir, + loc, confargs, confvars, prefix, From 016118af4c54d9b604d91132e65a6020232443f7 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Thu, 16 Feb 2023 11:17:42 +0000 Subject: [PATCH 208/325] apply suggestions from review --- easybuild/easyblocks/s/scipy.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 1df30766b9..9473a2f145 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -54,8 +54,9 @@ def extra_options(): """Easyconfig parameters specific to scipy.""" extra_vars = ({ 'enable_slow_tests': [False, "Run scipy test suite, including tests marked as slow", CUSTOM], - # ignore tests by default to maintain behaviour in older easyconfigs - 'ignore_test_result': [None, "Run scipy test suite, but ignore result (only log)", CUSTOM], + # ignore test failures by default in scipy < 1.9 to maintain behaviour in older easyconfigs + 'ignore_test_result': [None, "Run scipy test suite, but ignore test failures (True/False/None). Default " + "(None) implies True for scipy < 1.9, and False for scipy ?= 1.9", CUSTOM], }) return PythonPackage.extra_options(extra_vars=extra_vars) @@ -68,17 +69,27 @@ def __init__(self, *args, **kwargs): if LooseVersion(self.version) >= LooseVersion('1.9'): self.use_meson = True + # enforce scipy test suite results if not explicitly disabled for scipy >= 1.9 if self.cfg['ignore_test_result'] is None: - self.cfg['ignore_test_result'] = True - # ignore installopts inherited from FortranPythonPackage - self.cfg['installopts'] = "" + self.cfg['ignore_test_result'] = False + + # strip inherited PythonPackage installopts + installopts = self.cfg['installopts'] + pythonpackage_installopts = ['--no-deps', '--ignore-installed', '--no-index', '--egg', + '--zip-ok', '--no-index'] + self.log.info("Stripping inherited PythonPackage installopts %s from installopts %s", + pythonpackage_installopts, installopts) + for i in pythonpackage_installopts: + installopts.replace(i, '') + self.cfg['installopts'] = installopts + else: self.use_meson = False if self.cfg['ignore_test_result']: - # maintains compatibility with easyconfigs predating scipy 1.9. Runs tests (serially) in - # a way that exits with code 0 regardless of test results, see: + # can be used to maintain compatibility with easyconfigs predating scipy 1.9. Runs tests + # (serially) in a way that exits with code 0 regardless of test results, see: # https://github.com/easybuilders/easybuild-easyblocks/issues/2237 self.testcmd = "cd .. && %(python)s -c 'import numpy; import scipy; scipy.test(verbose=2)'" else: @@ -106,8 +117,8 @@ def configure_step(self): else: raise EasyBuildError("Unknown BLAS/LAPACK library used: %s", lapack_lib) - configopts = '-Dblas=%(blas_lapack)s -Dlapack=%(blas_lapack)s' % {'blas_lapack': blas_lapack} - self.cfg.update('configopts', configopts) + for opt in ('blas', 'lapack'): + self.cfg.update('configopts', '-D%(opt)s=%(blas_lapack)s' % {'opt': opt, 'blas_lapack': blas_lapack}) # need to have already installed extensions in PATH, PYTHONPATH for configure/build/install steps pythonpath = os.getenv('PYTHONPATH') @@ -120,6 +131,7 @@ def configure_step(self): MesonNinja.configure_step(self) else: + # scipy < 1.9.0 uses install procedure using setup.py FortranPythonPackage.configure_step(self) if LooseVersion(self.version) >= LooseVersion('0.13'): @@ -184,7 +196,6 @@ def install_step(self): """Custom install step for scipy: use ninja for scipy >= 1.9.0""" if self.use_meson: MesonNinja.install_step(self) - else: FortranPythonPackage.install_step(self) From a69b47f42eef6eddb57c2a403580fc7f89e12b57 Mon Sep 17 00:00:00 2001 From: Jasper <65227842+jfgrimm@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:38:32 +0000 Subject: [PATCH 209/325] Update easybuild/easyblocks/s/scipy.py Co-authored-by: Simon Branford <4967+branfosj@users.noreply.github.com> --- easybuild/easyblocks/s/scipy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 9473a2f145..77504eed40 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -81,7 +81,7 @@ def __init__(self, *args, **kwargs): self.log.info("Stripping inherited PythonPackage installopts %s from installopts %s", pythonpackage_installopts, installopts) for i in pythonpackage_installopts: - installopts.replace(i, '') + installopts = installopts.replace(i, '') self.cfg['installopts'] = installopts else: From f2b4131c0821019b47d96568fc604ee0bcf20de0 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Tue, 21 Feb 2023 13:47:20 +0100 Subject: [PATCH 210/325] split depot path in JuliaPackage with os.pathsep --- easybuild/easyblocks/generic/juliapackage.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index 2490bc2823..ff8bc74298 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -99,8 +99,10 @@ def install_step(self): # extensions in a bundle can share their DEPOT_PATH # see https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_DEPOT_PATH depot_path = os.getenv('JULIA_DEPOT_PATH', '') + if depot_path: + depot_path = depot_path.split(os.pathsep) if self.installdir not in depot_path: - depot_path = ':'.join([depot for depot in (self.installdir, depot_path) if depot]) + depot_path = os.pathsep.join([depot for depot in (self.installdir, depot_path) if depot]) env.setvar('JULIA_DEPOT_PATH', depot_path) # command sequence for Julia.Pkg From b360347928de191ec945dab106dbb8d5e98337d9 Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Tue, 21 Feb 2023 15:44:30 +0000 Subject: [PATCH 211/325] allow disabling pybind11 tests --- easybuild/easyblocks/p/pybind11.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/p/pybind11.py b/easybuild/easyblocks/p/pybind11.py index 09d711b28c..1174d23a13 100644 --- a/easybuild/easyblocks/p/pybind11.py +++ b/easybuild/easyblocks/p/pybind11.py @@ -70,8 +70,9 @@ def configure_step(self): def test_step(self): """Run pybind11 tests""" - # always run tests - self.cfg['runtest'] = 'check' + # always run tests unless explicitly disabled + if self.cfg['runtest'] is not False: + self.cfg['runtest'] = 'check' super(EB_pybind11, self).test_step() def install_step(self): From c99e441abb542ab67f74fb4075e5ce695eb0903d Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Tue, 21 Feb 2023 11:16:37 -0500 Subject: [PATCH 212/325] Update easybuild/easyblocks/p/pybind11.py Co-authored-by: Jasper <65227842+jfgrimm@users.noreply.github.com> --- easybuild/easyblocks/p/pybind11.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/pybind11.py b/easybuild/easyblocks/p/pybind11.py index 1174d23a13..d964ffb9ac 100644 --- a/easybuild/easyblocks/p/pybind11.py +++ b/easybuild/easyblocks/p/pybind11.py @@ -70,7 +70,7 @@ def configure_step(self): def test_step(self): """Run pybind11 tests""" - # always run tests unless explicitly disabled + # run tests unless explicitly disabled if self.cfg['runtest'] is not False: self.cfg['runtest'] = 'check' super(EB_pybind11, self).test_step() From d6e4e25d5d5a10bceb87885fb16d421b7e4f4502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Gonz=C3=A1lez=20Carrillo?= Date: Wed, 22 Feb 2023 12:00:38 +0100 Subject: [PATCH 213/325] Adding support for postinstallcmds in easybuildmeta --- easybuild/easyblocks/e/easybuildmeta.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/e/easybuildmeta.py b/easybuild/easyblocks/e/easybuildmeta.py index baac89baa0..f0ff1f340a 100644 --- a/easybuild/easyblocks/e/easybuildmeta.py +++ b/easybuild/easyblocks/e/easybuildmeta.py @@ -157,6 +157,7 @@ def install_step(self): def post_install_step(self): """Remove setuptools.pth file that hard includes a system-wide (site-packages) path, if it is there.""" + super(EB_EasyBuildMeta, self).post_install_step() setuptools_pth = os.path.join(self.installdir, self.pylibdir, 'setuptools.pth') if os.path.exists(setuptools_pth): setuptools_pth_txt = read_file(setuptools_pth) From 4c11ffaf6bfe91309596bf22cf0f2198d3bde4c7 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 23 Feb 2023 09:40:16 +0100 Subject: [PATCH 214/325] add blank line in post_install_step method of EasyBuildMeta easyblock to improve readability --- easybuild/easyblocks/e/easybuildmeta.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/e/easybuildmeta.py b/easybuild/easyblocks/e/easybuildmeta.py index f0ff1f340a..f4b52ff921 100644 --- a/easybuild/easyblocks/e/easybuildmeta.py +++ b/easybuild/easyblocks/e/easybuildmeta.py @@ -158,6 +158,7 @@ def post_install_step(self): """Remove setuptools.pth file that hard includes a system-wide (site-packages) path, if it is there.""" super(EB_EasyBuildMeta, self).post_install_step() + setuptools_pth = os.path.join(self.installdir, self.pylibdir, 'setuptools.pth') if os.path.exists(setuptools_pth): setuptools_pth_txt = read_file(setuptools_pth) From 91cee1036d35f229f132c94e361456b65598f581 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 24 Feb 2023 13:30:33 +0100 Subject: [PATCH 215/325] Added GPU support to ELPA EasyBlock. If CUDA is specified in the EasyConfig, automatically enable nvidia GPU support --- easybuild/easyblocks/e/elpa.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 8ac4856207..116bd2abea 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -39,7 +39,7 @@ from easybuild.tools.systemtools import get_cpu_features, get_shared_lib_ext from easybuild.tools.toolchain.compiler import OPTARCH_GENERIC from easybuild.tools.utilities import nub - +from easybuild.tools.modules import get_software_root ELPA_CPU_FEATURE_FLAGS = ['avx', 'avx2', 'avx512f', 'vsx', 'sse4_2'] @@ -176,6 +176,28 @@ def run_all_steps(self, *args, **kwargs): return super(EB_ELPA, self).run_all_steps(*args, **kwargs) + def configure_step(self): + """Configure step for ELPA""" + + # Add nvidia GPU support if requested + cuda_root = get_software_root('CUDA') + self.log.info("Got cuda root: %s", cuda_root) + if cuda_root: + self.cfg.update('configopts', '--enable-nvidia-gpu') + self.cfg.update('configopts', '--with-cuda-path=%s' % cuda_root) + self.cfg.update('configopts', '--with-cuda-sdk-path=%s' % cuda_root) + + cuda_cc = build_option('cuda_compute_capabilities') or self.cfg['cuda_compute_capabilities'] + if not cuda_cc: + raise EasyBuildError('List of CUDA compute capabilities must be specified, either via ' + 'cuda_compute_capabilities easyconfig parameter or via ' + '--cuda-compute-capabilities') + cuda_cc_string = ','.join(['sm_%s' % x.replace('.', '') for x in cuda_cc]) + self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=%s' % cuda_cc_string) + self.log.info("Enabling nvidia GPU support for compute capabilitie: %s", cuda_cc_string) + + super(EB_ELPA, self).configure_step() + def patch_step(self, *args, **kwargs): """Patch manual_cpp script to avoid using hardcoded /usr/bin/python.""" super(EB_ELPA, self).patch_step(*args, **kwargs) From ca7775227ef921e480599428ef29ad8002c6480b Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 24 Feb 2023 13:46:58 +0100 Subject: [PATCH 216/325] Currently, ELPA only supports passing one architecture to --with-NVIDIA-GPU-compute-capability=VALUE --- easybuild/easyblocks/e/elpa.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 116bd2abea..189c99068c 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -192,6 +192,12 @@ def configure_step(self): raise EasyBuildError('List of CUDA compute capabilities must be specified, either via ' 'cuda_compute_capabilities easyconfig parameter or via ' '--cuda-compute-capabilities') + + # ELPA's --with-NVIDIA-GPU-compute-capability only accepts a single architecture + if len(cuda_cc) > 1: + raise EasyBuildError('ELPA currently only supports specifying one architecture when ' + 'building. You specified cuda-compute-capabilities: %s', cuda_cc) + cuda_cc_string = ','.join(['sm_%s' % x.replace('.', '') for x in cuda_cc]) self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=%s' % cuda_cc_string) self.log.info("Enabling nvidia GPU support for compute capabilitie: %s", cuda_cc_string) From 4865037803d4b98837845f07c94a94f678995f1b Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 24 Feb 2023 17:35:27 +0100 Subject: [PATCH 217/325] Make sure to set CPP, as newer ELPA configures require it --- easybuild/easyblocks/e/elpa.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 189c99068c..cdbce5f23c 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -31,6 +31,7 @@ """ import os +import easybuild.tools.environment as env from easybuild.easyblocks.generic.configuremake import ConfigureMake from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError @@ -202,6 +203,17 @@ def configure_step(self): self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=%s' % cuda_cc_string) self.log.info("Enabling nvidia GPU support for compute capabilitie: %s", cuda_cc_string) + # From v2022.05.001 onwards, the config complains if CPP is not set + env_dict = env.read_environment({'cxx': 'CXX', 'cpp': 'CPP'}) + if 'cxx' in env_dict: + if 'cpp' in env_dict and env_dict['cxx'] != env_dict['cpp']: + self.log.warning("Overwriting value of CPP (%s) with the value for CXX (%s)", + env_dict['cpp'], env_dict['cxx']) + env.setvar('CPP', env_dict['cxx']) + else: + raise EasyBuildError('ELPA requires CPP to be set. EasyBuild tried setting it based on the value of CXX, ' + 'but could not retreive a value for CXX') + super(EB_ELPA, self).configure_step() def patch_step(self, *args, **kwargs): From 6642b40e99c847f3e30c3ba02e38e31fca2ca457 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Fri, 24 Feb 2023 18:55:57 +0100 Subject: [PATCH 218/325] Set CPP env var to cpp. This is valid for GCC, but we might make to make this neater and read it from the compiler definition from easybuild-framework. Still discussing that on EB slack --- easybuild/easyblocks/e/elpa.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index cdbce5f23c..51742b1d0d 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -204,15 +204,9 @@ def configure_step(self): self.log.info("Enabling nvidia GPU support for compute capabilitie: %s", cuda_cc_string) # From v2022.05.001 onwards, the config complains if CPP is not set - env_dict = env.read_environment({'cxx': 'CXX', 'cpp': 'CPP'}) - if 'cxx' in env_dict: - if 'cpp' in env_dict and env_dict['cxx'] != env_dict['cpp']: - self.log.warning("Overwriting value of CPP (%s) with the value for CXX (%s)", - env_dict['cpp'], env_dict['cxx']) - env.setvar('CPP', env_dict['cxx']) - else: - raise EasyBuildError('ELPA requires CPP to be set. EasyBuild tried setting it based on the value of CXX, ' - 'but could not retreive a value for CXX') + # Need to make this neater so that it is either set by easybuild-framework, OR query the toolchain for something like COMPILER_CPP + # Discussing that right now on EB Slack... + env.setvar('CPP', 'cpp') super(EB_ELPA, self).configure_step() From a11a1a4ddc2e5730df59bb008e7dff9684a804d0 Mon Sep 17 00:00:00 2001 From: Sven Hansen Date: Fri, 24 Feb 2023 23:19:38 +0100 Subject: [PATCH 219/325] update Maple easyblock for v2022 --- easybuild/easyblocks/m/maple.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/m/maple.py b/easybuild/easyblocks/m/maple.py index 14621e8515..bf3b75f2aa 100644 --- a/easybuild/easyblocks/m/maple.py +++ b/easybuild/easyblocks/m/maple.py @@ -30,6 +30,7 @@ @author: Kenneth Hoste (Ghent University) @author: Pieter De Baets (Ghent University) @author: Jens Timmerman (Ghent University) +@author: Sven Hansen (RWTH Aachen University) """ import glob import os @@ -61,6 +62,8 @@ def install_step(self): "Do you accept this license? [y/n]:": 'y', 'ENTER AN ABSOLUTE PATH, OR PRESS TO ACCEPT THE DEFAULT :': self.installdir, 'IS THIS CORRECT? (Y/N):': 'Y', + 'Language Selection\n\nPlease select the installation language\n[1] English - English\n[2] Japanese - \n' + 'Please choose an option [1] : ': '1', 'Do you wish to have a shortcut installed on your desktop? ->1- Yes 2- No ENTER THE NUMBER ' + 'FOR YOUR CHOICE, OR PRESS TO ACCEPT THE DEFAULT::': '2', "Do you wish to have a shortcut installed on your desktop? [Y/n]:": 'n', @@ -83,6 +86,7 @@ def install_step(self): r"\[1\] Single Server.*\n.*\nPlease choose an option \[.\] :": '1', r"Port number \[[0-9]+\]:": '', r"Enable periodic checking for Maple .* updates after installation \[Y/n\]:": 'n', + r'Pre-Installation Summary[\s\S]*': '', } no_qa = [ @@ -91,10 +95,10 @@ def install_step(self): 'Launching installer...', "Configuring the installer for this system's environment...", 'Unpacking the JRE...', - r'\[[-|]*', + r'\[[-|#|]*', ] - run_cmd_qa(cmd, qa, std_qa=std_qa, no_qa=no_qa, log_all=True, simple=True) + run_cmd_qa(cmd, qa, std_qa=std_qa, no_qa=no_qa, log_all=True, simple=True, maxhits=150) upgrade_installers = glob.glob(os.path.join(self.builddir, 'Maple*Upgrade*')) if upgrade_installers: From 1b639923f34f011f5d087b914a293855425e3913 Mon Sep 17 00:00:00 2001 From: Sven Hansen Date: Fri, 24 Feb 2023 23:20:40 +0100 Subject: [PATCH 220/325] allow custom license server ports in Maple easyblock --- easybuild/easyblocks/m/maple.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/m/maple.py b/easybuild/easyblocks/m/maple.py index bf3b75f2aa..65868877ff 100644 --- a/easybuild/easyblocks/m/maple.py +++ b/easybuild/easyblocks/m/maple.py @@ -72,7 +72,7 @@ def install_step(self): 'PRESS TO EXIT THE INSTALLER:': '', 'License server (DEFAULT: ):': self.cfg['license_server'], "License server []:": self.cfg['license_server'], - 'Port number (optional) (DEFAULT: ):': '', + 'Port number (optional) (DEFAULT: ):': self.cfg['license_server_port'] or '', '->1- Configure toolbox for Matlab 2- Do not configure at this time ENTER THE NUMBER FOR YOUR CHOICE, ' + 'OR PRESS TO ACCEPT THE DEFAULT::': '2', "MATLAB Configuration [y/N]:": 'n', @@ -84,7 +84,7 @@ def install_step(self): r"Choose Install Folder \[.*\]:": self.installdir, r"\[2\] Network License.*\nPlease choose an option \[.\] :": '2', r"\[1\] Single Server.*\n.*\nPlease choose an option \[.\] :": '1', - r"Port number \[[0-9]+\]:": '', + r"Port number \[[0-9]+\]:": self.cfg['license_server_port'] or '', r"Enable periodic checking for Maple .* updates after installation \[Y/n\]:": 'n', r'Pre-Installation Summary[\s\S]*': '', } From 41b424c47091f1a6686ace61700a73d87ced8f66 Mon Sep 17 00:00:00 2001 From: Jasper Grimm Date: Sat, 25 Feb 2023 09:00:24 +0000 Subject: [PATCH 221/325] fix default ignore_test_result logic --- easybuild/easyblocks/s/scipy.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 77504eed40..2ba91030dc 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -56,7 +56,7 @@ def extra_options(): 'enable_slow_tests': [False, "Run scipy test suite, including tests marked as slow", CUSTOM], # ignore test failures by default in scipy < 1.9 to maintain behaviour in older easyconfigs 'ignore_test_result': [None, "Run scipy test suite, but ignore test failures (True/False/None). Default " - "(None) implies True for scipy < 1.9, and False for scipy ?= 1.9", CUSTOM], + "(None) implies True for scipy < 1.9, and False for scipy >= 1.9", CUSTOM], }) return PythonPackage.extra_options(extra_vars=extra_vars) @@ -71,9 +71,6 @@ def __init__(self, *args, **kwargs): self.use_meson = True # enforce scipy test suite results if not explicitly disabled for scipy >= 1.9 - if self.cfg['ignore_test_result'] is None: - self.cfg['ignore_test_result'] = False - # strip inherited PythonPackage installopts installopts = self.cfg['installopts'] pythonpackage_installopts = ['--no-deps', '--ignore-installed', '--no-index', '--egg', @@ -87,6 +84,13 @@ def __init__(self, *args, **kwargs): else: self.use_meson = False + if self.cfg['ignore_test_result'] is None: + # enforce scipy test suite results if not explicitly disabled for scipy >= 1.9 + if self.use_meson: + self.cfg['ignore_test_result'] = False + else: + self.cfg['ignore_test_result'] = True + if self.cfg['ignore_test_result']: # can be used to maintain compatibility with easyconfigs predating scipy 1.9. Runs tests # (serially) in a way that exits with code 0 regardless of test results, see: From f53a4c67e8f56155d7dc4ac5ca2a995e0ee8a028 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 25 Feb 2023 10:10:39 +0100 Subject: [PATCH 222/325] simplify logic to set default value for ignore_test_result in scipy easyblock --- easybuild/easyblocks/s/scipy.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 2ba91030dc..1c21a01fc2 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -54,7 +54,6 @@ def extra_options(): """Easyconfig parameters specific to scipy.""" extra_vars = ({ 'enable_slow_tests': [False, "Run scipy test suite, including tests marked as slow", CUSTOM], - # ignore test failures by default in scipy < 1.9 to maintain behaviour in older easyconfigs 'ignore_test_result': [None, "Run scipy test suite, but ignore test failures (True/False/None). Default " "(None) implies True for scipy < 1.9, and False for scipy >= 1.9", CUSTOM], }) @@ -85,16 +84,15 @@ def __init__(self, *args, **kwargs): self.use_meson = False if self.cfg['ignore_test_result'] is None: - # enforce scipy test suite results if not explicitly disabled for scipy >= 1.9 - if self.use_meson: - self.cfg['ignore_test_result'] = False - else: - self.cfg['ignore_test_result'] = True + # automatically ignore scipy test suite results for scipy < 1.9, as we did in older easyconfigs + self.cfg['ignore_test_result'] = LooseVersion(self.version) < '1.9' + self.log.info("ignore_test_result not specified, so automatically set to %s for scipy %s", + self.cfg['ignore_test_result'], self.version) if self.cfg['ignore_test_result']: - # can be used to maintain compatibility with easyconfigs predating scipy 1.9. Runs tests - # (serially) in a way that exits with code 0 regardless of test results, see: - # https://github.com/easybuilders/easybuild-easyblocks/issues/2237 + # used to maintain compatibility with easyconfigs predating scipy 1.9; + # runs tests (serially) in a way that exits with code 0 regardless of test results, + # see https://github.com/easybuilders/easybuild-easyblocks/issues/2237 self.testcmd = "cd .. && %(python)s -c 'import numpy; import scipy; scipy.test(verbose=2)'" else: self.testcmd = " && ".join([ From 82472980646e5117c0783618e6319d4f3f4f0d52 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 25 Feb 2023 19:15:13 +0100 Subject: [PATCH 223/325] relax glob pattern to find Mathematica install script --- easybuild/easyblocks/m/mathematica.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/m/mathematica.py b/easybuild/easyblocks/m/mathematica.py index 13a3080ff4..9f1fb78827 100644 --- a/easybuild/easyblocks/m/mathematica.py +++ b/easybuild/easyblocks/m/mathematica.py @@ -68,7 +68,7 @@ def install_step(self): install_script_glob = '%s_%s_LINUX*.sh' % (self.name, self.version) # Starting at V13, Mathematica have renamed their install file... if LooseVersion(self.version) >= LooseVersion("13"): - install_script_glob = '%s_%s_BNDL_LINUX*.sh' % (self.name, self.version) + install_script_glob = '%s_%s_*LINUX*.sh' % (self.name, self.version) matches = glob.glob(install_script_glob) if len(matches) == 1: From b587ae82fd739f7831fbeb7c1e90b413bc56ee50 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 25 Feb 2023 19:22:25 +0100 Subject: [PATCH 224/325] fix linking numexpr with Intel MKL's VML library for imkl >= 2021.x --- easybuild/easyblocks/n/numexpr.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/n/numexpr.py b/easybuild/easyblocks/n/numexpr.py index b5d23e73d0..81ba8d8f0a 100644 --- a/easybuild/easyblocks/n/numexpr.py +++ b/easybuild/easyblocks/n/numexpr.py @@ -55,12 +55,16 @@ def __init__(self, *args, **kwargs): self.imkl_root = None + def prepare_step(self, *args, **kwargs): + """Custom prepare step for numexpr: check whether we're building on top of Intel MKL.""" + super(EB_numexpr, self).prepare_step(*args, **kwargs) + + self.imkl_root = get_software_root('imkl') + def configure_step(self): """Custom configuration procedure for numexpr.""" super(EB_numexpr, self).configure_step() - self.imkl_root = get_software_root('imkl') - # if Intel MKL is available, set up site.cfg such that the right VML library is used; # this makes a *big* difference in terms of performance; # see also https://github.com/pydata/numexpr/blob/master/site.cfg.example @@ -122,8 +126,15 @@ def sanity_check_step(self): custom_commands = [] + # imkl_root may still be None, for example when running with --sanity-check-only + if self.imkl_root is None: + self.imkl_root = get_software_root('imkl') + # if Intel MKL is available, make sure VML is used if self.imkl_root: - custom_commands.append("python -c 'import numexpr; assert(numexpr.use_vml)'") + custom_commands.extend([ + "python -c 'import numexpr; assert(numexpr.use_vml)'", + """python -c "import numexpr; numexpr.set_vml_accuracy_mode('low')" """, + ]) return super(EB_numexpr, self).sanity_check_step(custom_commands=custom_commands) From b372286d0b1074cdd269e251e4694a0bc1f20970 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 25 Feb 2023 23:00:22 +0100 Subject: [PATCH 225/325] use libmkl_rt to link numexpr with imkl >= 2021.x --- easybuild/easyblocks/n/numexpr.py | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/easybuild/easyblocks/n/numexpr.py b/easybuild/easyblocks/n/numexpr.py index 81ba8d8f0a..deafddb122 100644 --- a/easybuild/easyblocks/n/numexpr.py +++ b/easybuild/easyblocks/n/numexpr.py @@ -28,7 +28,6 @@ import os from distutils.version import LooseVersion -import easybuild.tools.toolchain as toolchain from easybuild.easyblocks.generic.pythonpackage import PythonPackage from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import write_file @@ -55,16 +54,12 @@ def __init__(self, *args, **kwargs): self.imkl_root = None - def prepare_step(self, *args, **kwargs): - """Custom prepare step for numexpr: check whether we're building on top of Intel MKL.""" - super(EB_numexpr, self).prepare_step(*args, **kwargs) - - self.imkl_root = get_software_root('imkl') - def configure_step(self): """Custom configuration procedure for numexpr.""" super(EB_numexpr, self).configure_step() + self.imkl_root = get_software_root('imkl') + # if Intel MKL is available, set up site.cfg such that the right VML library is used; # this makes a *big* difference in terms of performance; # see also https://github.com/pydata/numexpr/blob/master/site.cfg.example @@ -84,20 +79,12 @@ def configure_step(self): mkl_ver = get_software_version('imkl') - comp_fam = self.toolchain.comp_family() - self.log.info("Using toolchain with compiler family %s", comp_fam) - if LooseVersion(mkl_ver) >= LooseVersion('2021'): mkl_lib_dirs = [ os.path.join(self.imkl_root, 'mkl', 'latest', 'lib', 'intel64'), ] mkl_include_dirs = os.path.join(self.imkl_root, 'mkl', 'latest', 'include') - if comp_fam == toolchain.INTELCOMP: - mkl_libs = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5'] - elif comp_fam == toolchain.GCC: - mkl_libs = ['mkl_intel_lp64', 'mkl_gnu_thread', 'mkl_core', 'gomp'] - else: - raise EasyBuildError("Unknown compiler family, don't know how to link MKL libraries: %s", comp_fam) + mkl_libs = ['mkl_rt'] else: mkl_lib_dirs = [ os.path.join(self.imkl_root, 'mkl', 'lib', 'intel64'), From 138b6629be6916e2ab6e3c4f13c3a140e29f268a Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 25 Feb 2023 23:03:33 +0100 Subject: [PATCH 226/325] remove unused import for EasyBuildError in numexpr easyblock --- easybuild/easyblocks/n/numexpr.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/n/numexpr.py b/easybuild/easyblocks/n/numexpr.py index deafddb122..40e01f0cb8 100644 --- a/easybuild/easyblocks/n/numexpr.py +++ b/easybuild/easyblocks/n/numexpr.py @@ -29,7 +29,6 @@ from distutils.version import LooseVersion from easybuild.easyblocks.generic.pythonpackage import PythonPackage -from easybuild.tools.build_log import EasyBuildError from easybuild.tools.filetools import write_file from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.systemtools import get_cpu_features From 88e4b3aab8c60afe8757641c8fb1e015ff290d3e Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sun, 26 Feb 2023 19:43:44 +0100 Subject: [PATCH 227/325] only do a more extensive check for VML support for numexpr >= 2.7.3 --- easybuild/easyblocks/n/numexpr.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/n/numexpr.py b/easybuild/easyblocks/n/numexpr.py index 40e01f0cb8..1c62b4502c 100644 --- a/easybuild/easyblocks/n/numexpr.py +++ b/easybuild/easyblocks/n/numexpr.py @@ -118,9 +118,10 @@ def sanity_check_step(self): # if Intel MKL is available, make sure VML is used if self.imkl_root: - custom_commands.extend([ - "python -c 'import numexpr; assert(numexpr.use_vml)'", - """python -c "import numexpr; numexpr.set_vml_accuracy_mode('low')" """, - ]) + custom_commands.append("python -c 'import numexpr; assert(numexpr.use_vml)'") + + # for sufficiently recent versions of numexpr, also do a more extensive check for VML support + if LooseVersion(self.version) >= LooseVersion('2.7.3'): + custom_commands.append("""python -c "import numexpr; numexpr.set_vml_accuracy_mode('low')" """) return super(EB_numexpr, self).sanity_check_step(custom_commands=custom_commands) From c687f9095d5c0616cd33a963fd7244fb5db4b907 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 27 Feb 2023 12:02:44 +0100 Subject: [PATCH 228/325] Fixed typo, added option to enable dedicated sm80 kernel, set CPP (C preprocessor environment variable) in a way that can easily be extended or modified per toolchain family --- easybuild/easyblocks/e/elpa.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 51742b1d0d..255abe4ee2 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -30,10 +30,13 @@ @author: Kenneth Hoste (Ghent University) """ import os +from distutils.version import LooseVersion import easybuild.tools.environment as env from easybuild.easyblocks.generic.configuremake import ConfigureMake from easybuild.framework.easyconfig import CUSTOM +from easybuild.toolchains.compiler.gcc import TC_CONSTANT_GCC +from easybuild.toolchains.compiler.inteliccifort import TC_CONSTANT_INTELCOMP from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option from easybuild.tools.filetools import apply_regex_substitutions @@ -201,12 +204,24 @@ def configure_step(self): cuda_cc_string = ','.join(['sm_%s' % x.replace('.', '') for x in cuda_cc]) self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=%s' % cuda_cc_string) - self.log.info("Enabling nvidia GPU support for compute capabilitie: %s", cuda_cc_string) + self.log.info("Enabling nvidia GPU support for compute capability: %s", cuda_cc_string) + # There is a dedicated kernel for sm80, but only from version 2021.11.001 onwards + if '8.0' in cuda_cc and LooseVersion(self.version) >= LooseVersion('2021.11.001'): + self.cfg.update('configopts', '--enable-nvidia-sm80-gpu') # From v2022.05.001 onwards, the config complains if CPP is not set - # Need to make this neater so that it is either set by easybuild-framework, OR query the toolchain for something like COMPILER_CPP - # Discussing that right now on EB Slack... - env.setvar('CPP', 'cpp') + # C preprocessor to use for given comp_fam + cpp_dict = { + TC_CONSTANT_GCC: 'cpp', + TC_CONSTANT_INTELCOMP: 'cpp', + } + comp_fam = self.toolchain.comp_family() + if comp_fam in cpp_dict: + env.setvar('CPP', cpp_dict[comp_fam]) + else: + raise EasyBuildError('ELPA EasyBlock does not know which C preprocessor to use for the ' + 'current compiler family (%s). Please add the correct preprocessor ' + 'for this compiler family to cpp_dict in the ELPA EasyBlock', comp_fam) super(EB_ELPA, self).configure_step() From 515e57df7b1184597e3545f58d13f9755bb488fb Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 27 Feb 2023 15:39:43 +0100 Subject: [PATCH 229/325] Clarify comment --- easybuild/easyblocks/e/elpa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 255abe4ee2..a69d657345 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -209,7 +209,7 @@ def configure_step(self): if '8.0' in cuda_cc and LooseVersion(self.version) >= LooseVersion('2021.11.001'): self.cfg.update('configopts', '--enable-nvidia-sm80-gpu') - # From v2022.05.001 onwards, the config complains if CPP is not set + # From v2022.05.001 onwards, the config complains if CPP is not set, resulting in non-zero exit of configure # C preprocessor to use for given comp_fam cpp_dict = { TC_CONSTANT_GCC: 'cpp', From 1f86084c67c75c6caacfaa772ba7a8ef06417c21 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 27 Feb 2023 15:56:37 +0100 Subject: [PATCH 230/325] Pull logic inside the if statement that checks if only a single cuda compute capability has been specified. Also, now check if the cuda_cc is larger or equal to 8.0, since you probably also want to build the 8.0 optimized kernel if you have 8.5 capability in your system --- easybuild/easyblocks/e/elpa.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index a69d657345..5bff3c695b 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -198,17 +198,18 @@ def configure_step(self): '--cuda-compute-capabilities') # ELPA's --with-NVIDIA-GPU-compute-capability only accepts a single architecture - if len(cuda_cc) > 1: + if len(cuda_cc) == 1: + cuda_cc = cuda_cc[0] + cuda_cc_string = cuda_cc.replace('.', '') + self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=%s' % cuda_cc_string) + self.log.info("Enabling nvidia GPU support for compute capability: %s", cuda_cc_string) + # There is a dedicated kernel for sm80, but only from version 2021.11.001 onwards + if float(cuda_cc) >= 8.0 and LooseVersion(self.version) >= LooseVersion('2021.11.001'): + self.cfg.update('configopts', '--enable-nvidia-sm80-gpu') + else: raise EasyBuildError('ELPA currently only supports specifying one architecture when ' 'building. You specified cuda-compute-capabilities: %s', cuda_cc) - cuda_cc_string = ','.join(['sm_%s' % x.replace('.', '') for x in cuda_cc]) - self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=%s' % cuda_cc_string) - self.log.info("Enabling nvidia GPU support for compute capability: %s", cuda_cc_string) - # There is a dedicated kernel for sm80, but only from version 2021.11.001 onwards - if '8.0' in cuda_cc and LooseVersion(self.version) >= LooseVersion('2021.11.001'): - self.cfg.update('configopts', '--enable-nvidia-sm80-gpu') - # From v2022.05.001 onwards, the config complains if CPP is not set, resulting in non-zero exit of configure # C preprocessor to use for given comp_fam cpp_dict = { From c3e7701f583c285d905b6879ef4f4c824d46849a Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Mon, 27 Feb 2023 15:57:59 +0100 Subject: [PATCH 231/325] Make sure sm_ gets prepended in the argument for --with-NVIDIA-GPU-compute-capability --- easybuild/easyblocks/e/elpa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 5bff3c695b..39ea64b41e 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -201,7 +201,7 @@ def configure_step(self): if len(cuda_cc) == 1: cuda_cc = cuda_cc[0] cuda_cc_string = cuda_cc.replace('.', '') - self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=%s' % cuda_cc_string) + self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=sm_%s' % cuda_cc_string) self.log.info("Enabling nvidia GPU support for compute capability: %s", cuda_cc_string) # There is a dedicated kernel for sm80, but only from version 2021.11.001 onwards if float(cuda_cc) >= 8.0 and LooseVersion(self.version) >= LooseVersion('2021.11.001'): From 8b154aba5c1e61db84f432000386907dcd18d811 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Tue, 28 Feb 2023 11:55:00 +0100 Subject: [PATCH 232/325] Reordered if-else statement to reduce indentation. Clarified error message that is raised --- easybuild/easyblocks/e/elpa.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 39ea64b41e..143952cbf7 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -198,17 +198,16 @@ def configure_step(self): '--cuda-compute-capabilities') # ELPA's --with-NVIDIA-GPU-compute-capability only accepts a single architecture - if len(cuda_cc) == 1: - cuda_cc = cuda_cc[0] - cuda_cc_string = cuda_cc.replace('.', '') - self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=sm_%s' % cuda_cc_string) - self.log.info("Enabling nvidia GPU support for compute capability: %s", cuda_cc_string) - # There is a dedicated kernel for sm80, but only from version 2021.11.001 onwards - if float(cuda_cc) >= 8.0 and LooseVersion(self.version) >= LooseVersion('2021.11.001'): - self.cfg.update('configopts', '--enable-nvidia-sm80-gpu') - else: - raise EasyBuildError('ELPA currently only supports specifying one architecture when ' + if len(cuda_cc) != 1: + raise EasyBuildError('ELPA currently only supports specifying one CUDA architecture when ' 'building. You specified cuda-compute-capabilities: %s', cuda_cc) + cuda_cc = cuda_cc[0] + cuda_cc_string = cuda_cc.replace('.', '') + self.cfg.update('configopts', '--with-NVIDIA-GPU-compute-capability=sm_%s' % cuda_cc_string) + self.log.info("Enabling nvidia GPU support for compute capability: %s", cuda_cc_string) + # There is a dedicated kernel for sm80, but only from version 2021.11.001 onwards + if float(cuda_cc) >= 8.0 and LooseVersion(self.version) >= LooseVersion('2021.11.001'): + self.cfg.update('configopts', '--enable-nvidia-sm80-gpu') # From v2022.05.001 onwards, the config complains if CPP is not set, resulting in non-zero exit of configure # C preprocessor to use for given comp_fam From 40bc11790fef31a4f8d0499c5c2e35dc3308e8c1 Mon Sep 17 00:00:00 2001 From: Caspar van Leeuwen Date: Tue, 28 Feb 2023 13:38:07 +0100 Subject: [PATCH 233/325] Moved up from .. import to maintain alphabetical order --- easybuild/easyblocks/e/elpa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/e/elpa.py b/easybuild/easyblocks/e/elpa.py index 143952cbf7..41b81e15e8 100644 --- a/easybuild/easyblocks/e/elpa.py +++ b/easybuild/easyblocks/e/elpa.py @@ -40,10 +40,10 @@ from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option from easybuild.tools.filetools import apply_regex_substitutions +from easybuild.tools.modules import get_software_root from easybuild.tools.systemtools import get_cpu_features, get_shared_lib_ext from easybuild.tools.toolchain.compiler import OPTARCH_GENERIC from easybuild.tools.utilities import nub -from easybuild.tools.modules import get_software_root ELPA_CPU_FEATURE_FLAGS = ['avx', 'avx2', 'avx512f', 'vsx', 'sse4_2'] From 2207b51b4be816425ccf7aa9243988a03eba5b79 Mon Sep 17 00:00:00 2001 From: Alex Domingo Date: Wed, 1 Mar 2023 11:43:50 +0100 Subject: [PATCH 234/325] always handle depot paths in a list in JuliaPackage Co-authored-by: Sam Moors --- easybuild/easyblocks/generic/juliapackage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/generic/juliapackage.py b/easybuild/easyblocks/generic/juliapackage.py index ff8bc74298..2e32047665 100644 --- a/easybuild/easyblocks/generic/juliapackage.py +++ b/easybuild/easyblocks/generic/juliapackage.py @@ -98,11 +98,11 @@ def install_step(self): # prepend installation directory to Julia DEPOT_PATH # extensions in a bundle can share their DEPOT_PATH # see https://docs.julialang.org/en/v1/manual/environment-variables/#JULIA_DEPOT_PATH - depot_path = os.getenv('JULIA_DEPOT_PATH', '') + depot_path = os.getenv('JULIA_DEPOT_PATH', []) if depot_path: depot_path = depot_path.split(os.pathsep) if self.installdir not in depot_path: - depot_path = os.pathsep.join([depot for depot in (self.installdir, depot_path) if depot]) + depot_path = os.pathsep.join([depot for depot in [self.installdir] + depot_path if depot]) env.setvar('JULIA_DEPOT_PATH', depot_path) # command sequence for Julia.Pkg From 54eff72c48218d1589ea956e81a9fb6b173a4fcd Mon Sep 17 00:00:00 2001 From: Simon Branford Date: Wed, 1 Mar 2023 13:51:16 +0000 Subject: [PATCH 235/325] Allow disabling of building tests and forward deps, and support version 13 for Trilinos --- easybuild/easyblocks/t/trilinos.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/t/trilinos.py b/easybuild/easyblocks/t/trilinos.py index 4fa0ab9148..3af9614b0d 100644 --- a/easybuild/easyblocks/t/trilinos.py +++ b/easybuild/easyblocks/t/trilinos.py @@ -54,6 +54,8 @@ def extra_options(): extra_vars = { 'shared_libs': [None, "Deprecated. Use build_shared_libs", CUSTOM], 'openmp': [True, "Enable OpenMP support", CUSTOM], + 'forward_deps': [True, "Enable all forward dependencies", CUSTOM], + 'build_tests': [True, "Enable building tests/examples", CUSTOM], 'all_exts': [True, "Enable all Trilinos packages", CUSTOM], 'skip_exts': [[], "List of Trilinos packages to skip", CUSTOM], 'verbose': [False, "Configure for verbose output", CUSTOM], @@ -106,9 +108,11 @@ def configure_step(self): if self.toolchain.options.get('usempi', None): self.cfg.update('configopts', "-DTPL_ENABLE_MPI:BOOL=ON") - # enable full testing - self.cfg.update('configopts', "-DTrilinos_ENABLE_TESTS:BOOL=ON") - self.cfg.update('configopts', "-DTrilinos_ENABLE_ALL_FORWARD_DEP_PACKAGES:BOOL=ON") + if self.cfg['build_tests']: + # enable full testing + self.cfg.update('configopts', "-DTrilinos_ENABLE_TESTS:BOOL=ON") + if self.cfg['forward_deps']: + self.cfg.update('configopts', "-DTrilinos_ENABLE_ALL_FORWARD_DEP_PACKAGES:BOOL=ON") lib_re = re.compile("^lib(.*).a$") @@ -285,6 +289,11 @@ def sanity_check_step(self): libs.remove('Galeri') libs.extend(['galeri-epetra', 'galeri-xpetra']) + if LooseVersion(self.version) >= LooseVersion('13'): + libs.remove('GlobiPack') + libs.remove('Mesquite') + libs.remove('MOOCHO') + # Get the library extension if self.cfg['build_shared_libs']: lib_ext = get_shared_lib_ext() From f9bfd0d0140d250d0c5ae5f98157b26c93ea5865 Mon Sep 17 00:00:00 2001 From: Simon Branford <4967+branfosj@users.noreply.github.com> Date: Wed, 1 Mar 2023 14:03:24 +0000 Subject: [PATCH 236/325] library changes from ComputeCanada --- easybuild/easyblocks/t/trilinos.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/t/trilinos.py b/easybuild/easyblocks/t/trilinos.py index 3af9614b0d..aa4b911473 100644 --- a/easybuild/easyblocks/t/trilinos.py +++ b/easybuild/easyblocks/t/trilinos.py @@ -289,11 +289,15 @@ def sanity_check_step(self): libs.remove('Galeri') libs.extend(['galeri-epetra', 'galeri-xpetra']) - if LooseVersion(self.version) >= LooseVersion('13'): - libs.remove('GlobiPack') + # Mesquite and MOOCHO packages gone in 12.18: + if LooseVersion(self.version) >= LooseVersion('12.18'): libs.remove('Mesquite') libs.remove('MOOCHO') + # GlobiPack package gone in 13.0: + if LooseVersion(self.version) >= LooseVersion('13.0'): + libs.remove('GlobiPack') + # Get the library extension if self.cfg['build_shared_libs']: lib_ext = get_shared_lib_ext() From 22be21aeb0437fe19d7c639f556ac5467e31bfb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 6 Mar 2023 09:58:28 +0000 Subject: [PATCH 237/325] adding easyblocks: cargo.py --- easybuild/easyblocks/generic/cargo.py | 129 ++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 easybuild/easyblocks/generic/cargo.py diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py new file mode 100644 index 0000000000..d59e0fee16 --- /dev/null +++ b/easybuild/easyblocks/generic/cargo.py @@ -0,0 +1,129 @@ +## +# Copyright 2009-2023 Ghent University +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for installing Cargo packages (Rust lang package system) + +@author: Mikael Oehman (Chalmers University of Technology) +""" + +import os +import glob + +import easybuild.tools.environment as env +from easybuild.framework.easyconfig import CUSTOM +from easybuild.framework.easyblock import EasyBlock +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.run import run_cmd +from easybuild.tools.config import build_option +from easybuild.tools.filetools import remove_file, write_file, extract_file, compute_checksum + +CRATESIO_SOURCE = "https://crates.io/api/v1/crates" + +class Cargo(EasyBlock): + """Support for installing Cargo packages (Rust)""" + + @staticmethod + def extra_options(extra_vars=None): + """Define extra easyconfig parameters specific to Cargo""" + extra_vars = EasyBlock.extra_options(extra_vars) + extra_vars.update({ + #'tests': [True, "Build tests", CUSTOM], + 'offline': [True, "Build tests", CUSTOM], + 'lto': [False, "Build with link time optimization", CUSTOM], + }) + + #if 'source_urls' not in extra_vars: + # extra_vars['source_urls'] = [CRATESIO_SOURCE] + + #extra_vars['download_filename'] = '%(name)s/%(version)s/download' + + return extra_vars + + def __init__(self, *args, **kwargs): + """Constructor for Simpack easyblock.""" + super(Cargo, self).__init__(*args, **kwargs) + env.setvar('CARGO_HOME', os.path.join(self.builddir, '.cargo')) + env.setvar('RUSTC', 'rustc') + env.setvar('RUSTDOC', 'rustdoc') + env.setvar('RUSTFMT', 'rustfmt') + optarch = build_option('optarch') + if not optarch: + optarch = 'native' + env.setvar('RUSTFLAGS', '-C target-cpu=%s' % optarch) + env.setvar('RUST_LOG', 'DEBUG') + env.setvar('RUST_BACKTRACE', '1') + + def configure_step(self): + pass + + def extract_step(self): + """Populate all vendored deps with required .cargo-checksum.json""" + EasyBlock.extract_step(self) + for source in self.src: + dirname = source["name"].rsplit('.', maxsplit=2)[0] + self.log.info('creating .cargo-checksums.json file for : %s', dirname) + chksum = compute_checksum(source['path'], checksum_type='sha256') + chkfile = '%s/%s/.cargo-checksum.json' % (self.builddir, dirname) + write_file(chkfile, '{"files":{},"package":"%s"}' % chksum) + + def build_step(self): + """Build with cargo""" + parallel = '' + if self.cfg['parallel']: + parallel = "-j %s" % self.cfg['parallel'] + + tests = '' + if self.cfg['tests']: + parallel = "--tests" + + offline = '' + if self.cfg['offline']: + parallel = "--offline" + + profile = 'debug' if self.toolchain.options.get('debug', None) else 'release' + + lto = '' + if self.cfg['lto']: + parallel = '--config profile.%s.lto=true' % profile + + run_cmd('rustc --print cfg', log_all=True, simple=True) # for tracking in log file + #remove_file('Cargo.lock') # attempt to circumvent the checksum-check that cargo build does, but it still looks for the checksum json file. + # Can't figure out how to supply this via command line + write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) + cmd = '%s cargo build --profile=%s %s %s %s %s %s' % (self.cfg['prebuildopts'], profile, offline, lto, tests, parallel, self.cfg['buildopts']) + run_cmd(cmd, log_all=True, simple=True) + + def test_step(self): + """Test with cargo""" + if self.cfg['tests']: + profile = 'debug' if self.toolchain.options.get('debug', None) else 'release' + cmd = "%s cargo test --profile=%s %s" % (self.cfg['pretestopts'], profile, self.cfg['testopts']) + run_cmd(cmd, log_all=True, simple=True) + + def install_step(self): + """Install with cargo""" + cmd = "%s cargo install --offline --root %s --path . %s" % (self.cfg['preinstallopts'], self.installdir, self.cfg['installopts']) + run_cmd(cmd, log_all=True, simple=True) + From 7cc78df9e16c19e52da8872301f13b192bb2d3c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 6 Mar 2023 14:54:31 +0000 Subject: [PATCH 238/325] Fix hound errors --- easybuild/easyblocks/generic/cargo.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index d59e0fee16..6e5514b713 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -29,15 +29,14 @@ """ import os -import glob import easybuild.tools.environment as env from easybuild.framework.easyconfig import CUSTOM from easybuild.framework.easyblock import EasyBlock -from easybuild.tools.build_log import EasyBuildError from easybuild.tools.run import run_cmd from easybuild.tools.config import build_option -from easybuild.tools.filetools import remove_file, write_file, extract_file, compute_checksum +from easybuild.tools.filetools import write_file, compute_checksum +# from easybuild.tools.filetools import remove_file CRATESIO_SOURCE = "https://crates.io/api/v1/crates" @@ -49,15 +48,15 @@ def extra_options(extra_vars=None): """Define extra easyconfig parameters specific to Cargo""" extra_vars = EasyBlock.extra_options(extra_vars) extra_vars.update({ - #'tests': [True, "Build tests", CUSTOM], + # 'tests': [True, "Build tests", CUSTOM], 'offline': [True, "Build tests", CUSTOM], 'lto': [False, "Build with link time optimization", CUSTOM], }) - #if 'source_urls' not in extra_vars: + # if 'source_urls' not in extra_vars: # extra_vars['source_urls'] = [CRATESIO_SOURCE] - #extra_vars['download_filename'] = '%(name)s/%(version)s/download' + # extra_vars['download_filename_template'] = '%(name)s/%(version)s/download' return extra_vars @@ -109,10 +108,12 @@ def build_step(self): parallel = '--config profile.%s.lto=true' % profile run_cmd('rustc --print cfg', log_all=True, simple=True) # for tracking in log file - #remove_file('Cargo.lock') # attempt to circumvent the checksum-check that cargo build does, but it still looks for the checksum json file. + # attempt to circumvent the checksum-check that cargo build does, but it still looks for the checksum json file + # remove_file('Cargo.lock') # Can't figure out how to supply this via command line write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) - cmd = '%s cargo build --profile=%s %s %s %s %s %s' % (self.cfg['prebuildopts'], profile, offline, lto, tests, parallel, self.cfg['buildopts']) + cmd = '%s cargo build --profile=%s %s %s %s %s %s' % ( + self.cfg['prebuildopts'], profile, offline, lto, tests, parallel, self.cfg['buildopts']) run_cmd(cmd, log_all=True, simple=True) def test_step(self): @@ -124,6 +125,7 @@ def test_step(self): def install_step(self): """Install with cargo""" - cmd = "%s cargo install --offline --root %s --path . %s" % (self.cfg['preinstallopts'], self.installdir, self.cfg['installopts']) + cmd = "%s cargo install --offline --root %s --path . %s" % ( + self.cfg['preinstallopts'], self.installdir, self.cfg['installopts']) run_cmd(cmd, log_all=True, simple=True) From df16d823e370b15d75a2471c4dc43a2372894e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 6 Mar 2023 14:55:09 +0000 Subject: [PATCH 239/325] Fix hound errors --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 6e5514b713..1967a91686 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -40,6 +40,7 @@ CRATESIO_SOURCE = "https://crates.io/api/v1/crates" + class Cargo(EasyBlock): """Support for installing Cargo packages (Rust)""" @@ -128,4 +129,3 @@ def install_step(self): cmd = "%s cargo install --offline --root %s --path . %s" % ( self.cfg['preinstallopts'], self.installdir, self.cfg['installopts']) run_cmd(cmd, log_all=True, simple=True) - From 863dfb82bb27664becfad6d23983472aa492a7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 6 Mar 2023 14:55:41 +0000 Subject: [PATCH 240/325] Fix hound errors --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 1967a91686..fd717f11c5 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -114,7 +114,7 @@ def build_step(self): # Can't figure out how to supply this via command line write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) cmd = '%s cargo build --profile=%s %s %s %s %s %s' % ( - self.cfg['prebuildopts'], profile, offline, lto, tests, parallel, self.cfg['buildopts']) + self.cfg['prebuildopts'], profile, offline, lto, tests, parallel, self.cfg['buildopts']) run_cmd(cmd, log_all=True, simple=True) def test_step(self): From f93988fe1f6e4da05f3e43b14b3b4aa868dc6825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 6 Mar 2023 15:10:36 +0000 Subject: [PATCH 241/325] Use profile consistently --- easybuild/easyblocks/generic/cargo.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index fd717f11c5..29a9bf03d6 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -88,6 +88,10 @@ def extract_step(self): chkfile = '%s/%s/.cargo-checksum.json' % (self.builddir, dirname) write_file(chkfile, '{"files":{},"package":"%s"}' % chksum) + @property + def profile(self): + return 'debug' if self.toolchain.options.get('debug', None) else 'release' + def build_step(self): """Build with cargo""" parallel = '' @@ -102,11 +106,9 @@ def build_step(self): if self.cfg['offline']: parallel = "--offline" - profile = 'debug' if self.toolchain.options.get('debug', None) else 'release' - lto = '' if self.cfg['lto']: - parallel = '--config profile.%s.lto=true' % profile + parallel = '--config profile.%s.lto=true' % self.profile run_cmd('rustc --print cfg', log_all=True, simple=True) # for tracking in log file # attempt to circumvent the checksum-check that cargo build does, but it still looks for the checksum json file @@ -114,18 +116,17 @@ def build_step(self): # Can't figure out how to supply this via command line write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) cmd = '%s cargo build --profile=%s %s %s %s %s %s' % ( - self.cfg['prebuildopts'], profile, offline, lto, tests, parallel, self.cfg['buildopts']) + self.cfg['prebuildopts'], self.profile, offline, lto, tests, parallel, self.cfg['buildopts']) run_cmd(cmd, log_all=True, simple=True) def test_step(self): """Test with cargo""" if self.cfg['tests']: - profile = 'debug' if self.toolchain.options.get('debug', None) else 'release' - cmd = "%s cargo test --profile=%s %s" % (self.cfg['pretestopts'], profile, self.cfg['testopts']) + cmd = "%s cargo test --profile=%s %s" % (self.cfg['pretestopts'], self.profile, self.cfg['testopts']) run_cmd(cmd, log_all=True, simple=True) def install_step(self): """Install with cargo""" - cmd = "%s cargo install --offline --root %s --path . %s" % ( - self.cfg['preinstallopts'], self.installdir, self.cfg['installopts']) + cmd = "%s cargo install --profile=%s --offline --root %s --path . %s" % ( + self.cfg['preinstallopts'], self.profile, self.installdir, self.cfg['installopts']) run_cmd(cmd, log_all=True, simple=True) From 3740be163d3f7be92417a1b6f2d075d6c06c0237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 6 Mar 2023 15:14:58 +0000 Subject: [PATCH 242/325] Fix copy/paste typo --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 29a9bf03d6..86e4335d4f 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -62,7 +62,7 @@ def extra_options(extra_vars=None): return extra_vars def __init__(self, *args, **kwargs): - """Constructor for Simpack easyblock.""" + """Constructor for Cargo easyblock.""" super(Cargo, self).__init__(*args, **kwargs) env.setvar('CARGO_HOME', os.path.join(self.builddir, '.cargo')) env.setvar('RUSTC', 'rustc') From de55fd4f28aaf79b3eec21c6c433e592c79c8219 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 9 Mar 2023 09:52:56 +0100 Subject: [PATCH 243/325] update scipy easyblock to copy PKG-INFO to scipy-.egg-info when installing with Meson/Ninja + enhance add sanity check command using 'pip list' --- easybuild/easyblocks/s/scipy.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 1c21a01fc2..4c8d7e0398 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -42,8 +42,8 @@ from easybuild.easyblocks.generic.mesonninja import MesonNinja from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pylibdir from easybuild.framework.easyconfig import CUSTOM -from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import change_dir, copy_dir +from easybuild.tools.build_log import EasyBuildError, print_warning +from easybuild.tools.filetools import change_dir, copy_dir, copy_file class EB_scipy(FortranPythonPackage, PythonPackage, MesonNinja): @@ -198,6 +198,18 @@ def install_step(self): """Custom install step for scipy: use ninja for scipy >= 1.9.0""" if self.use_meson: MesonNinja.install_step(self) + + # copy PKG-INFO file included in scipy source tarball to scipy-.egg-info in installation, + # so pip is aware of the scipy installation (required for 'pip list', 'pip check', etc.); + # see also https://github.com/easybuilders/easybuild-easyblocks/issues/2901 + pkg_info = 'PKG-INFO' + target_egg_info = os.path.join(self.installdir, self.pylibdir, 'scipy-%s.egg-info' % self.version) + if os.path.isfile(pkg_info): + copy_file(pkg_info, target_egg_info) + else: + cwd = os.getcwd() + print_warning("%s not found in %s, so can't use it to create %s!", pkg_info, cwd, target_egg_info, + log=self.log) else: FortranPythonPackage.install_step(self) @@ -211,4 +223,9 @@ def sanity_check_step(self, *args, **kwargs): 'dirs': [det_pylibdir()], } - return PythonPackage.sanity_check_step(self, custom_paths=custom_paths) + # make sure that scipy is included in output of 'pip list', + # so that 'pip check' passes if scipy is a required dependency for another Python package; + # use case-insensitive match, since name is sometimes reported as 'SciPy' + custom_commands = [r"pip list | grep -i '^scipy[ \t]*%s[ \t]*$'" % self.version] + + return PythonPackage.sanity_check_step(self, custom_paths=custom_paths, custom_commands=custom_commands) From bd9e6938e17a56baf61873bea2553c4175e87988 Mon Sep 17 00:00:00 2001 From: Simon Branford <4967+branfosj@users.noreply.github.com> Date: Fri, 10 Mar 2023 11:30:27 +0000 Subject: [PATCH 244/325] correct directory to find PKG-INFO and improve sanity check test Co-authored-by: Jasper <65227842+jfgrimm@users.noreply.github.com> --- easybuild/easyblocks/s/scipy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 4c8d7e0398..823116e1e8 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -202,7 +202,7 @@ def install_step(self): # copy PKG-INFO file included in scipy source tarball to scipy-.egg-info in installation, # so pip is aware of the scipy installation (required for 'pip list', 'pip check', etc.); # see also https://github.com/easybuilders/easybuild-easyblocks/issues/2901 - pkg_info = 'PKG-INFO' + pkg_info = os.path.join(self.cfg['start_dir'], 'PKG-INFO') target_egg_info = os.path.join(self.installdir, self.pylibdir, 'scipy-%s.egg-info' % self.version) if os.path.isfile(pkg_info): copy_file(pkg_info, target_egg_info) @@ -226,6 +226,6 @@ def sanity_check_step(self, *args, **kwargs): # make sure that scipy is included in output of 'pip list', # so that 'pip check' passes if scipy is a required dependency for another Python package; # use case-insensitive match, since name is sometimes reported as 'SciPy' - custom_commands = [r"pip list | grep -i '^scipy[ \t]*%s[ \t]*$'" % self.version] + custom_commands = [r"pip list | grep -iE '^scipy\s+%s\s*$'" % self.version.replace('.', r'\.')] return PythonPackage.sanity_check_step(self, custom_paths=custom_paths, custom_commands=custom_commands) From 42d5b98cb433d718af73e326eab70c7ca3843dc5 Mon Sep 17 00:00:00 2001 From: Viktor Rehnberg <35767167+VRehnberg@users.noreply.github.com> Date: Tue, 14 Mar 2023 08:33:06 +0100 Subject: [PATCH 245/325] Create non-versioned symlink for python-config As discussed here https://easybuild.slack.com/archives/C34UA1HT7/p1678728109206609?thread_ts=1678722749.081689&cid=C34UA1HT7 --- easybuild/easyblocks/p/python.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/python.py b/easybuild/easyblocks/p/python.py index 465d069a67..f839da581b 100644 --- a/easybuild/easyblocks/p/python.py +++ b/easybuild/easyblocks/p/python.py @@ -444,10 +444,13 @@ def install_step(self): super(EB_Python, self).install_step() - # Create non-versioned, relative symlinks for python and pip + # Create non-versioned, relative symlinks for python, python-config and pip python_binary_path = os.path.join(self.installdir, 'bin', 'python') if not os.path.isfile(python_binary_path): symlink('python' + self.pyshortver, python_binary_path, use_abspath_source=False) + python_config_binary_path = os.path.join(self.installdir, 'bin', 'python-config') + if not os.path.isfile(python_config_binary_path): + symlink('python' + self.pyshortver + '-config', python_config_binary_path, use_abspath_source=False) if self.install_pip: pip_binary_path = os.path.join(self.installdir, 'bin', 'pip') if not os.path.isfile(pip_binary_path): From f5649005218c00a2382f7350dec25a5faa7b170d Mon Sep 17 00:00:00 2001 From: Viktor Rehnberg <35767167+VRehnberg@users.noreply.github.com> Date: Tue, 14 Mar 2023 11:12:37 +0100 Subject: [PATCH 246/325] Add extra sanity checks --- easybuild/easyblocks/p/python.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/python.py b/easybuild/easyblocks/p/python.py index f839da581b..09a954d9f0 100644 --- a/easybuild/easyblocks/p/python.py +++ b/easybuild/easyblocks/p/python.py @@ -537,7 +537,13 @@ def sanity_check_step(self): pyver = 'python' + self.pyshortver custom_paths = { - 'files': [os.path.join('bin', pyver), os.path.join('lib', 'lib' + pyver + abiflags + '.' + shlib_ext)], + 'files': [ + os.path.join('bin', pyver), + os.path.join('bin', 'python'), + os.path.join('bin', pyver + '-config'), + os.path.join('bin', 'python-config'), + os.path.join('lib', 'lib' + pyver + abiflags + '.' + shlib_ext), + ], 'dirs': [os.path.join('include', pyver + abiflags), os.path.join('lib', pyver, 'lib-dynload')], } @@ -549,6 +555,7 @@ def sanity_check_step(self): "python -c 'import _ctypes'", # make sure that foreign function interface (libffi) works "python -c 'import _ssl'", # make sure SSL support is enabled one way or another "python -c 'import readline'", # make sure readline support was built correctly + "python-config --help", # make sure that symlink was created correctly ] if self.install_pip: From 7b7ad98305fee35ae1a65892e06055219a1cd6b1 Mon Sep 17 00:00:00 2001 From: Viktor Rehnberg <35767167+VRehnberg@users.noreply.github.com> Date: Wed, 15 Mar 2023 08:30:34 +0100 Subject: [PATCH 247/325] Move python-config --help sanity check --- easybuild/easyblocks/p/python.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/p/python.py b/easybuild/easyblocks/p/python.py index 09a954d9f0..975935cdfb 100644 --- a/easybuild/easyblocks/p/python.py +++ b/easybuild/easyblocks/p/python.py @@ -552,10 +552,10 @@ def sanity_check_step(self): custom_commands = [ "python --version", + "python-config --help", # make sure that symlink was created correctly "python -c 'import _ctypes'", # make sure that foreign function interface (libffi) works "python -c 'import _ssl'", # make sure SSL support is enabled one way or another "python -c 'import readline'", # make sure readline support was built correctly - "python-config --help", # make sure that symlink was created correctly ] if self.install_pip: From c2d40b20429e155209c9e9a87a4bf9317847224f Mon Sep 17 00:00:00 2001 From: Simon Branford <4967+branfosj@users.noreply.github.com> Date: Thu, 16 Mar 2023 08:57:27 +0000 Subject: [PATCH 248/325] Fail out if the MATLAB install key is not set --- easybuild/easyblocks/m/matlab.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index e1b65d77a8..50405f4a8d 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -159,7 +159,10 @@ def install_step(self): keys = self.cfg['key'] if keys is None: - keys = os.getenv('EB_MATLAB_KEY', '00000-00000-00000-00000-00000-00000-00000-00000-00000-00000') + try: + keys = os.environ['EB_MATLAB_KEY'] + except KeyError: + raise EasyBuildError("The MATLAB install key is not set.") if isinstance(keys, string_type): keys = keys.split(',') From 1b42d6feb7d1a52ff848c76a84beb94ee38e5510 Mon Sep 17 00:00:00 2001 From: Xin Wu Date: Thu, 16 Mar 2023 13:57:47 +0100 Subject: [PATCH 249/325] inform users that gpu package (instead of kokkos) is used for building LAMMPS --- easybuild/easyblocks/l/lammps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/l/lammps.py b/easybuild/easyblocks/l/lammps.py index 5c3d77fdb0..4bcfc42d9d 100644 --- a/easybuild/easyblocks/l/lammps.py +++ b/easybuild/easyblocks/l/lammps.py @@ -372,6 +372,7 @@ def configure_step(self, **kwargs): # CUDA only elif self.cuda: + print_msg("Using gpu (not Kokkos) arch: CPU - %s, GPU - %s" % (processor_arch, gpu_arch)) self.cfg.update('configopts', '-D%sGPU=on' % self.pkg_prefix) self.cfg.update('configopts', '-DGPU_API=cuda') self.cfg.update('configopts', '-DGPU_ARCH=%s' % get_cuda_gpu_arch(cuda_cc)) From 474f4566c10d93e522e8c5b412480ff093d43fd1 Mon Sep 17 00:00:00 2001 From: Sebastian Achilles Date: Thu, 16 Mar 2023 22:08:37 +0100 Subject: [PATCH 250/325] prepare release notes for EasyBuild v4.7.1 + bump version to 4.7.1 --- RELEASE_NOTES | 40 ++++++++++++++++++++++++++++++++ easybuild/easyblocks/__init__.py | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index e71ea4acad..c3829c8e86 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -5,6 +5,46 @@ These release notes can also be consulted at http://easybuild.readthedocs.org/en The latest version of easybuild-easyblocks provides 248 software-specific easyblocks and 39 generic easyblocks. +v4.7.1 (March 20th 2023) +------------------------ + +update/bugfix release + +- minor enhancements and updates, including: + - make NAMD easyblock aware of (pre)testopts (#2856) + - update MesonNinja easyblock for Meson >=0.64.0 (#2861) + - update scipy easyblock for scipy >= 1.9.0 to use meson/ninja (#2862) + - modify logic in QScintilla easyblock to find the PyQt5 sipdir in more places (#2868) + - add `testinstall` custom easyconfig parameter to PythonPackage easyblock (#2872) + - use -x option for "go install" in GoPackage generic easyblock (#2878) + - allow disabling pybind11 tests with '`runtest = False`' (#2892) + - call parent post_install_step in EasyBuildMeta easyblock (so postinstallcmds are taken into account) (#2893) + - update and enhance Maple easyblock for recent versions (#2895) + - relax glob pattern to find Mathematica install script (#2896) + - implement CUDA support in the ELPA EasyBlock & fix CPP configure issue on newer ELPA versions (#2898) + - update Trilinos easyblock to allow disabling of building tests and forward deps + support Trilinos v13.x (#2900) + - enhance Python easyblock to create non-versioned symlink for python-config + check for bin/python and bin/python-config in sanity check (#2904) +- various bug fixes, including: + - do not use -g77 option when installing NVHPC 22.9+ (#2819) + - check that sanity_check_module_loaded attribute exists before querying it in PythonPackage easyblock (#2865) + - fix $JULIA_DEPOT_PATH in installation of multiple JuliaPackage extensions (#2869) + - fix website/docs links in README (#2870) + - fix checking of CUDA/ROCR-Runtime dependencies for Clang to determine default build targets (#2873) + - show template values of exts_default_options in PythonBundle (#2874) + - Fix missing initialization of CMakeMake in CMakePythonPackage (#2876) + - fix error when failing pip version check during PythonPackage sanity check (#2877) + - handle templating correctly in CMakeMake when playing with configopts (#2882) + - avoid crash in test step of PyTorch easyblock if runtest is not a command (#2883) + - fix check configure option in FlexiBLAS easyblock (#2886) + - Use older `ncgen -H` for older netCDF (#2889) + - relax glob pattern to find Mathematica install script (#2896) + - fix linking numexpr with Intel MKL's VML library for imkl >= 2021.x (#2897) + - update scipy easyblock to copy PKG-INFO to scipy-.egg-info when installing with Meson/Ninja + add sanity check command using 'pip list' (#2903) +- other changes: + - only give read permissions in GitHub Actions workflows (#2863) + - use start dir of extension to install R packages (#2867) + - add deprecation notice to RPackage extensions with relative paths in start_dir (#2879) + v4.7.0 (January 9th 2023) ------------------------- diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index 9619ef8946..d634d41d22 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.7.1.dev0') +VERSION = LooseVersion('4.7.1') UNKNOWN = 'UNKNOWN' From 9080685cce03807216781dac575a537275feaecc Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Fri, 17 Mar 2023 08:44:52 +0100 Subject: [PATCH 251/325] minor tweaks to release notes for EasyBuild v4.7.1 --- RELEASE_NOTES | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index c3829c8e86..96346e430c 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -11,13 +11,14 @@ v4.7.1 (March 20th 2023) update/bugfix release - minor enhancements and updates, including: + - fix TensorFlow easyblock for new versions of Bazel & TensorFlow (#2854) - make NAMD easyblock aware of (pre)testopts (#2856) - update MesonNinja easyblock for Meson >=0.64.0 (#2861) - - update scipy easyblock for scipy >= 1.9.0 to use meson/ninja (#2862) + - update scipy easyblock for scipy >= 1.9.0 to use meson/ninja (#2862, #2903) - modify logic in QScintilla easyblock to find the PyQt5 sipdir in more places (#2868) - add `testinstall` custom easyconfig parameter to PythonPackage easyblock (#2872) - - use -x option for "go install" in GoPackage generic easyblock (#2878) - - allow disabling pybind11 tests with '`runtest = False`' (#2892) + - use -x option for "go install" in GoPackage generic easyblock, to print commands as they are executed (#2878) + - allow disabling pybind11 tests with `runtest = False` (#2892) - call parent post_install_step in EasyBuildMeta easyblock (so postinstallcmds are taken into account) (#2893) - update and enhance Maple easyblock for recent versions (#2895) - relax glob pattern to find Mathematica install script (#2896) @@ -28,21 +29,19 @@ update/bugfix release - do not use -g77 option when installing NVHPC 22.9+ (#2819) - check that sanity_check_module_loaded attribute exists before querying it in PythonPackage easyblock (#2865) - fix $JULIA_DEPOT_PATH in installation of multiple JuliaPackage extensions (#2869) - - fix website/docs links in README (#2870) - fix checking of CUDA/ROCR-Runtime dependencies for Clang to determine default build targets (#2873) - show template values of exts_default_options in PythonBundle (#2874) - - Fix missing initialization of CMakeMake in CMakePythonPackage (#2876) + - fix missing initialization of CMakeMake in CMakePythonPackage (#2876) - fix error when failing pip version check during PythonPackage sanity check (#2877) - handle templating correctly in CMakeMake when playing with configopts (#2882) - avoid crash in test step of PyTorch easyblock if runtest is not a command (#2883) - fix check configure option in FlexiBLAS easyblock (#2886) - - Use older `ncgen -H` for older netCDF (#2889) - - relax glob pattern to find Mathematica install script (#2896) + - use older `ncgen -H` for older netCDF (#2889) - fix linking numexpr with Intel MKL's VML library for imkl >= 2021.x (#2897) - - update scipy easyblock to copy PKG-INFO to scipy-.egg-info when installing with Meson/Ninja + add sanity check command using 'pip list' (#2903) - other changes: - only give read permissions in GitHub Actions workflows (#2863) - use start dir of extension to install R packages (#2867) + - fix website/docs links in README (#2870) - add deprecation notice to RPackage extensions with relative paths in start_dir (#2879) From b1a7072d0848d52b6f8c0e178e5663777aca1343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Sun, 19 Mar 2023 22:53:56 +0000 Subject: [PATCH 252/325] Add support for crate list, minor other fixes --- easybuild/easyblocks/generic/cargo.py | 31 +++++++++++++++------------ 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 86e4335d4f..a2093b642a 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -36,7 +36,6 @@ from easybuild.tools.run import run_cmd from easybuild.tools.config import build_option from easybuild.tools.filetools import write_file, compute_checksum -# from easybuild.tools.filetools import remove_file CRATESIO_SOURCE = "https://crates.io/api/v1/crates" @@ -49,16 +48,12 @@ def extra_options(extra_vars=None): """Define extra easyconfig parameters specific to Cargo""" extra_vars = EasyBlock.extra_options(extra_vars) extra_vars.update({ - # 'tests': [True, "Build tests", CUSTOM], - 'offline': [True, "Build tests", CUSTOM], + 'enable_tests': [True, "Enable building of tests", CUSTOM], + 'offline': [True, "Build offline", CUSTOM], 'lto': [False, "Build with link time optimization", CUSTOM], + 'crates': [[], "List of (crate, version) tuples to use", CUSTOM], }) - # if 'source_urls' not in extra_vars: - # extra_vars['source_urls'] = [CRATESIO_SOURCE] - - # extra_vars['download_filename_template'] = '%(name)s/%(version)s/download' - return extra_vars def __init__(self, *args, **kwargs): @@ -75,6 +70,16 @@ def __init__(self, *args, **kwargs): env.setvar('RUST_LOG', 'DEBUG') env.setvar('RUST_BACKTRACE', '1') + # Populate sources from "crates" list of tuples + sources = self.cfg['sources'] + for crate, version in self.cfg['crates']: + sources.append({ + 'download_filename': crate + '/' + version + '/download', + 'filename': crate + '-' + version + '.tar.gz', + 'source_urls': CRATESIO_SOURCE, + }) + self.cfg.update('sources', sources) + def configure_step(self): pass @@ -99,29 +104,27 @@ def build_step(self): parallel = "-j %s" % self.cfg['parallel'] tests = '' - if self.cfg['tests']: + if self.cfg['enable_tests']: parallel = "--tests" offline = '' if self.cfg['offline']: parallel = "--offline" + # Replace crates-io with vendored sources + write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) lto = '' if self.cfg['lto']: parallel = '--config profile.%s.lto=true' % self.profile run_cmd('rustc --print cfg', log_all=True, simple=True) # for tracking in log file - # attempt to circumvent the checksum-check that cargo build does, but it still looks for the checksum json file - # remove_file('Cargo.lock') - # Can't figure out how to supply this via command line - write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) cmd = '%s cargo build --profile=%s %s %s %s %s %s' % ( self.cfg['prebuildopts'], self.profile, offline, lto, tests, parallel, self.cfg['buildopts']) run_cmd(cmd, log_all=True, simple=True) def test_step(self): """Test with cargo""" - if self.cfg['tests']: + if self.cfg['enable_tests']: cmd = "%s cargo test --profile=%s %s" % (self.cfg['pretestopts'], self.profile, self.cfg['testopts']) run_cmd(cmd, log_all=True, simple=True) From 5fc85e06050286960f32548ac54a5e1f5784188d Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Mon, 20 Mar 2023 16:34:04 +0100 Subject: [PATCH 253/325] bump version to 4.7.2dev --- easybuild/easyblocks/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index d634d41d22..fdd68d6024 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.7.1') +VERSION = LooseVersion('4.7.2.dev0') UNKNOWN = 'UNKNOWN' From 20dca5b087a7ba26b4666d32dc6935184159d7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 20 Mar 2023 23:30:24 +0000 Subject: [PATCH 254/325] Use alt location for crates --- easybuild/easyblocks/generic/cargo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index a2093b642a..037cf9300c 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -76,7 +76,8 @@ def __init__(self, *args, **kwargs): sources.append({ 'download_filename': crate + '/' + version + '/download', 'filename': crate + '-' + version + '.tar.gz', - 'source_urls': CRATESIO_SOURCE, + 'source_urls': [CRATESIO_SOURCE], + 'alt_location': 'crates.io', }) self.cfg.update('sources', sources) From 0274027cca85e1fbb41146f7445ef7893f45160c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bob=20Dr=C3=B6ge?= Date: Wed, 22 Mar 2023 18:57:43 +0100 Subject: [PATCH 255/325] don't check for RPATH sections in binaries compiled with Go --- easybuild/easyblocks/generic/gopackage.py | 77 ++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index c06f724437..aca57c99d0 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -28,14 +28,17 @@ @author: Pavel Grochal (INUITS) """ import os +import re from distutils.version import LooseVersion import easybuild.tools.environment as env -from easybuild.framework.easyblock import EasyBlock +from easybuild.framework.easyblock import DEFAULT_BIN_LIB_SUBDIRS, EasyBlock from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.config import build_option from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd +from easybuild.tools.systemtools import get_linked_libs_raw class GoPackage(EasyBlock): @@ -149,3 +152,75 @@ def sanity_check_step(self): custom_commands = ['%s --help' % self.name.lower()] super(GoPackage, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands) + + def sanity_check_rpath(self, rpath_dirs=None): + """Sanity check binaries/libraries w.r.t. RPATH linking.""" + + self.log.info("Checking RPATH linkage for binaries/libraries...") + + fails = [] + + # hard reset $LD_LIBRARY_PATH before running RPATH sanity check + orig_env = env.unset_env_vars(['LD_LIBRARY_PATH']) + + self.log.debug("$LD_LIBRARY_PATH during RPATH sanity check: %s", os.getenv('LD_LIBRARY_PATH', '(empty)')) + self.log.debug("List of loaded modules: %s", self.modules_tool.list()) + + not_found_regex = re.compile(r'(\S+)\s*\=\>\s*not found') + readelf_rpath_regex = re.compile('(RPATH)', re.M) + + # List of libraries that should be exempt from the RPATH sanity check; + # For example, libcuda.so.1 should never be RPATH-ed by design, + # see https://github.com/easybuilders/easybuild-framework/issues/4095 + filter_rpath_sanity_libs = build_option('filter_rpath_sanity_libs') + msg = "Ignoring the following libraries if they are not found by RPATH sanity check: %s" + self.log.info(msg, filter_rpath_sanity_libs) + + if rpath_dirs is None: + rpath_dirs = self.cfg['bin_lib_subdirs'] or self.bin_lib_subdirs() + + if not rpath_dirs: + rpath_dirs = DEFAULT_BIN_LIB_SUBDIRS + self.log.info("Using default subdirectories for binaries/libraries to verify RPATH linking: %s", + rpath_dirs) + else: + self.log.info("Using specified subdirectories for binaries/libraries to verify RPATH linking: %s", + rpath_dirs) + + for dirpath in [os.path.join(self.installdir, d) for d in rpath_dirs]: + if os.path.exists(dirpath): + self.log.debug("Sanity checking RPATH for files in %s", dirpath) + + for path in [os.path.join(dirpath, x) for x in os.listdir(dirpath)]: + self.log.debug("Sanity checking RPATH for %s", path) + + out = get_linked_libs_raw(path) + + if out is None: + msg = "Failed to determine dynamically linked libraries for %s, " + msg += "so skipping it in RPATH sanity check" + self.log.debug(msg, path) + else: + # check whether all required libraries are found via 'ldd' + matches = re.findall(not_found_regex, out) + if len(matches) > 0: # Some libraries are not found via 'ldd' + # For each match, check if the library is in the exception list + for match in matches: + if match in filter_rpath_sanity_libs: + msg = "Library %s not found for %s, but ignored " + msg += "since it is on the rpath exception list: %s" + self.log.info(msg, match, path, filter_rpath_sanity_libs) + else: + fail_msg = "Library %s not found for %s; " % (match, path) + fail_msg += "RPATH linking is enabled, but not implemented for Go packages." + fail_msg += "See https://github.com/easybuilders/easybuild-easyconfigs/issues/17516" + self.log.warning(fail_msg) + fails.append(fail_msg) + else: + self.log.debug("Output of 'ldd %s' checked, looks OK", path) + else: + self.log.debug("Not sanity checking files in non-existing directory %s", dirpath) + + env.restore_env_vars(orig_env) + + return fails From bb3a98fc0a2f885d45a11c48f3f8de774981ab05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bob=20Dr=C3=B6ge?= Date: Wed, 22 Mar 2023 22:12:33 +0100 Subject: [PATCH 256/325] remove unused variable --- easybuild/easyblocks/generic/gopackage.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index aca57c99d0..16e2a2d1d7 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -167,7 +167,6 @@ def sanity_check_rpath(self, rpath_dirs=None): self.log.debug("List of loaded modules: %s", self.modules_tool.list()) not_found_regex = re.compile(r'(\S+)\s*\=\>\s*not found') - readelf_rpath_regex = re.compile('(RPATH)', re.M) # List of libraries that should be exempt from the RPATH sanity check; # For example, libcuda.so.1 should never be RPATH-ed by design, From e4553ff3a0117e5654f2e07d76bef79fc3f336a1 Mon Sep 17 00:00:00 2001 From: Simon Branford <4967+branfosj@users.noreply.github.com> Date: Mon, 27 Mar 2023 11:13:43 +0100 Subject: [PATCH 257/325] use string '0' instead of to avoid problems when opensll version is not determined --- easybuild/easyblocks/o/openssl_wrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/o/openssl_wrapper.py b/easybuild/easyblocks/o/openssl_wrapper.py index bd6c50341e..f73a5e5295 100644 --- a/easybuild/easyblocks/o/openssl_wrapper.py +++ b/easybuild/easyblocks/o/openssl_wrapper.py @@ -162,7 +162,7 @@ def __init__(self, *args, **kwargs): for solib in solibs: system_solib = find_library_path(solib) if system_solib: - openssl_version = 0 + openssl_version = '0' # get version of system library filename try: openssl_version = full_version_regex.search(os.path.realpath(system_solib)).group(0) From 2fff8d2e5eb4d4fb69b2847da492a113e9116c6c Mon Sep 17 00:00:00 2001 From: Simon Branford <4967+branfosj@users.noreply.github.com> Date: Wed, 29 Mar 2023 08:53:48 +0100 Subject: [PATCH 258/325] better error message --- easybuild/easyblocks/m/matlab.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index 50405f4a8d..7c493abb4e 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -162,7 +162,8 @@ def install_step(self): try: keys = os.environ['EB_MATLAB_KEY'] except KeyError: - raise EasyBuildError("The MATLAB install key is not set.") + raise EasyBuildError("The MATLAB install key is not set. This can be set either with the environment " + "variable EB_MATLAB_KEY or by the easyconfig variable 'key'.") if isinstance(keys, string_type): keys = keys.split(',') From a98f4a5aa26d40b7d51f89bdf2de364ee924047a Mon Sep 17 00:00:00 2001 From: Simon Branford <4967+branfosj@users.noreply.github.com> Date: Wed, 29 Mar 2023 08:54:25 +0100 Subject: [PATCH 259/325] spaces vs tabs --- easybuild/easyblocks/m/matlab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index 7c493abb4e..643fa73878 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -163,7 +163,7 @@ def install_step(self): keys = os.environ['EB_MATLAB_KEY'] except KeyError: raise EasyBuildError("The MATLAB install key is not set. This can be set either with the environment " - "variable EB_MATLAB_KEY or by the easyconfig variable 'key'.") + "variable EB_MATLAB_KEY or by the easyconfig variable 'key'.") if isinstance(keys, string_type): keys = keys.split(',') From f10d6a1f3daa4f904e2be455ca6cc22462d8fd71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 29 Mar 2023 18:52:38 +0200 Subject: [PATCH 260/325] Join argument list, fix typos --- easybuild/easyblocks/generic/cargo.py | 62 ++++++++++++++++++++------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 037cf9300c..e99457857a 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -85,14 +85,25 @@ def configure_step(self): pass def extract_step(self): - """Populate all vendored deps with required .cargo-checksum.json""" - EasyBlock.extract_step(self) - for source in self.src: - dirname = source["name"].rsplit('.', maxsplit=2)[0] - self.log.info('creating .cargo-checksums.json file for : %s', dirname) - chksum = compute_checksum(source['path'], checksum_type='sha256') - chkfile = '%s/%s/.cargo-checksum.json' % (self.builddir, dirname) - write_file(chkfile, '{"files":{},"package":"%s"}' % chksum) + """ + Unpack the source files and populate them with required .cargo-checksum.json if offline + """ + for src in self.src: + self.log.info("Unpacking source %s" % src['name']) + srcdir = extract_file(src['path'], self.builddir, cmd=src['cmd'], + extra_options=self.cfg['unpack_options'], change_into_dir=False) + change_dir(srcdir) + if srcdir: + self.src[self.src.index(src)]['finalpath'] = srcdir + else: + raise EasyBuildError("Unpacking source %s failed", src['name']) + + # Create checksum file for all sources required for + if self.cfg['offline']: + self.log.info('creating .cargo-checksums.json file for : %s', srcdir) + chksum = compute_checksum(src['path'], checksum_type='sha256') + chkfile = '%s/%s/.cargo-checksum.json' % (self.builddir, srcdir) + write_file(chkfile, '{"files":{},"package":"%s"}' % chksum) @property def profile(self): @@ -106,31 +117,50 @@ def build_step(self): tests = '' if self.cfg['enable_tests']: - parallel = "--tests" + tests = "--tests" offline = '' if self.cfg['offline']: - parallel = "--offline" + offline = "--offline" # Replace crates-io with vendored sources write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) lto = '' if self.cfg['lto']: - parallel = '--config profile.%s.lto=true' % self.profile + lto = '--config profile.%s.lto=true' % self.profile run_cmd('rustc --print cfg', log_all=True, simple=True) # for tracking in log file - cmd = '%s cargo build --profile=%s %s %s %s %s %s' % ( - self.cfg['prebuildopts'], self.profile, offline, lto, tests, parallel, self.cfg['buildopts']) + cmd = ' '.join([ + self.cfg['prebuildopts'], + 'cargo build', + '--profile=' + self.profile, + offline, + lto, + tests, + parallel, + self.cfg['buildopts'], + ]) run_cmd(cmd, log_all=True, simple=True) def test_step(self): """Test with cargo""" if self.cfg['enable_tests']: - cmd = "%s cargo test --profile=%s %s" % (self.cfg['pretestopts'], self.profile, self.cfg['testopts']) + cmd = ' '.join([ + self.cfg['pretestopts'], + 'cargo test', + '--profile=' + self.profile, + self.cfg['testopts'], + ]) run_cmd(cmd, log_all=True, simple=True) def install_step(self): """Install with cargo""" - cmd = "%s cargo install --profile=%s --offline --root %s --path . %s" % ( - self.cfg['preinstallopts'], self.profile, self.installdir, self.cfg['installopts']) + cmd = ' '.join([ + self.cfg['preinstallopts'], + 'cargo install' + '--profile=' + self.profile, + '--root=' + self.installdir, + '--path=.', + self.cfg['installopts'], + ]) run_cmd(cmd, log_all=True, simple=True) From 7904bf08fdad4dc4a400a2682706f8b9893f48bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 29 Mar 2023 19:15:17 +0200 Subject: [PATCH 261/325] Add missing import for change_dir --- easybuild/easyblocks/generic/cargo.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index e99457857a..f184b70b8b 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -31,8 +31,10 @@ import os import easybuild.tools.environment as env +from easybuild.tools.build_log import EasyBuildError from easybuild.framework.easyconfig import CUSTOM from easybuild.framework.easyblock import EasyBlock +from easybuild.tools.filetools import extract_file, change_dir from easybuild.tools.run import run_cmd from easybuild.tools.config import build_option from easybuild.tools.filetools import write_file, compute_checksum From ecf69fd3caabd71330af83fc8796a97b91ac24b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 29 Mar 2023 19:19:15 +0200 Subject: [PATCH 262/325] Fix trailing space --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index f184b70b8b..e658ec15c8 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -100,7 +100,7 @@ def extract_step(self): else: raise EasyBuildError("Unpacking source %s failed", src['name']) - # Create checksum file for all sources required for + # Create checksum file for all sources required by vendored crates.io sources if self.cfg['offline']: self.log.info('creating .cargo-checksums.json file for : %s', srcdir) chksum = compute_checksum(src['path'], checksum_type='sha256') From 9d4225bcdf220ea5d928b57c502d9da805a00797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 29 Mar 2023 20:26:06 +0200 Subject: [PATCH 263/325] Fix cargo checksum into each extracted dir --- easybuild/easyblocks/generic/cargo.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index e658ec15c8..c33d3b3551 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -90,7 +90,9 @@ def extract_step(self): """ Unpack the source files and populate them with required .cargo-checksum.json if offline """ + dirs = set() for src in self.src: + existing_dirs = set(os.listdir(self.builddir)) self.log.info("Unpacking source %s" % src['name']) srcdir = extract_file(src['path'], self.builddir, cmd=src['cmd'], extra_options=self.cfg['unpack_options'], change_into_dir=False) @@ -101,10 +103,12 @@ def extract_step(self): raise EasyBuildError("Unpacking source %s failed", src['name']) # Create checksum file for all sources required by vendored crates.io sources - if self.cfg['offline']: - self.log.info('creating .cargo-checksums.json file for : %s', srcdir) + new_dirs = set(os.listdir(self.builddir)) - existing_dirs + if self.cfg['offline'] and len(new_dirs) == 1: + cratedir = new_dirs.pop() + self.log.info('creating .cargo-checksums.json file for : %s', cratedir) chksum = compute_checksum(src['path'], checksum_type='sha256') - chkfile = '%s/%s/.cargo-checksum.json' % (self.builddir, srcdir) + chkfile = os.path.join(self.builddir, cratedir, '.cargo-checksum.json') write_file(chkfile, '{"files":{},"package":"%s"}' % chksum) @property @@ -159,7 +163,7 @@ def install_step(self): """Install with cargo""" cmd = ' '.join([ self.cfg['preinstallopts'], - 'cargo install' + 'cargo install', '--profile=' + self.profile, '--root=' + self.installdir, '--path=.', From 10b604dc3d2b614198ca6daa82ca492b8222b27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 29 Mar 2023 20:27:39 +0200 Subject: [PATCH 264/325] Remove unused var --- easybuild/easyblocks/generic/cargo.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index c33d3b3551..b87898ad9a 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -90,7 +90,6 @@ def extract_step(self): """ Unpack the source files and populate them with required .cargo-checksum.json if offline """ - dirs = set() for src in self.src: existing_dirs = set(os.listdir(self.builddir)) self.log.info("Unpacking source %s" % src['name']) From 827e30092811aa8b537c0b94b46ebf3363cacf94 Mon Sep 17 00:00:00 2001 From: ocaisa Date: Thu, 30 Mar 2023 09:18:45 +0200 Subject: [PATCH 265/325] Update both messages for Kokkos and GPU package --- easybuild/easyblocks/l/lammps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/l/lammps.py b/easybuild/easyblocks/l/lammps.py index 4bcfc42d9d..d026696a4d 100644 --- a/easybuild/easyblocks/l/lammps.py +++ b/easybuild/easyblocks/l/lammps.py @@ -346,7 +346,7 @@ def configure_step(self, **kwargs): # https://lammps.sandia.gov/doc/Build_extras.html # KOKKOS if self.cfg['kokkos']: - print_msg("Using Kokkos arch: CPU - %s, GPU - %s" % (processor_arch, gpu_arch)) + print_msg("Using Kokkos package with arch: CPU - %s, GPU - %s" % (processor_arch, gpu_arch)) self.cfg.update('configopts', '-D%sKOKKOS=on' % self.pkg_prefix) if self.toolchain.options.get('openmp', None): @@ -372,7 +372,7 @@ def configure_step(self, **kwargs): # CUDA only elif self.cuda: - print_msg("Using gpu (not Kokkos) arch: CPU - %s, GPU - %s" % (processor_arch, gpu_arch)) + print_msg("Using GPU package (not Kokkos) with arch: CPU - %s, GPU - %s" % (processor_arch, gpu_arch)) self.cfg.update('configopts', '-D%sGPU=on' % self.pkg_prefix) self.cfg.update('configopts', '-DGPU_API=cuda') self.cfg.update('configopts', '-DGPU_ARCH=%s' % get_cuda_gpu_arch(cuda_cc)) From 1ee031d9de457a0003b47320f31e0c7ecc79aa0b Mon Sep 17 00:00:00 2001 From: Simon Branford Date: Sat, 1 Apr 2023 14:22:02 +0100 Subject: [PATCH 266/325] use FlexiBLAS for newer PyTorch versions --- easybuild/easyblocks/p/pytorch.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index 252bc09741..2783db4707 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -155,6 +155,9 @@ def configure_step(self): if get_software_root('imkl'): options.append('BLAS=MKL') options.append('INTEL_MKL_DIR=$MKLROOT') + elif pytorch_version >= '1.11.0' and get_software_root('FlexiBLAS'): + options.append('BLAS=FlexiBLAS') + options.append('WITH_BLAS=flexi') elif pytorch_version >= '1.9.0' and get_software_root('BLIS'): options.append('BLAS=BLIS') options.append('BLIS_HOME=' + get_software_root('BLIS')) From d04f012061fa8a559834b1b22afdf8bd32019bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 13 Apr 2023 04:13:17 +0200 Subject: [PATCH 267/325] Include script for generating crate list --- easybuild/easyblocks/generic/cargo.py | 55 +++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index b87898ad9a..588c0be6a1 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -52,7 +52,7 @@ def extra_options(extra_vars=None): extra_vars.update({ 'enable_tests': [True, "Enable building of tests", CUSTOM], 'offline': [True, "Build offline", CUSTOM], - 'lto': [False, "Build with link time optimization", CUSTOM], + 'lto': [None, "Override default LTO flag ('fat', 'thin', 'off')", CUSTOM], 'crates': [[], "List of (crate, version) tuples to use", CUSTOM], }) @@ -131,8 +131,8 @@ def build_step(self): write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) lto = '' - if self.cfg['lto']: - lto = '--config profile.%s.lto=true' % self.profile + if self.cfg['lto'] is not None: + lto = '--config profile.%s.lto=\\"%s\\"' % (self.profile, self.cfg['lto']) run_cmd('rustc --print cfg', log_all=True, simple=True) # for tracking in log file cmd = ' '.join([ @@ -150,22 +150,71 @@ def build_step(self): def test_step(self): """Test with cargo""" if self.cfg['enable_tests']: + offline = '' + if self.cfg['offline']: + offline = "--offline" + cmd = ' '.join([ self.cfg['pretestopts'], 'cargo test', '--profile=' + self.profile, + offline, self.cfg['testopts'], ]) run_cmd(cmd, log_all=True, simple=True) def install_step(self): """Install with cargo""" + offline = '' + if self.cfg['offline']: + offline = "--offline" + cmd = ' '.join([ self.cfg['preinstallopts'], 'cargo install', '--profile=' + self.profile, + offline, '--root=' + self.installdir, '--path=.', self.cfg['installopts'], ]) run_cmd(cmd, log_all=True, simple=True) + + +def generate_crate_list(sourcedir): + """Helper for generating crate list""" + import toml + + cargo_toml = toml.load(os.path.join(sourcedir, 'Cargo.toml')) + cargo_lock = toml.load(os.path.join(sourcedir, 'Cargo.lock')) + + app_name = cargo_toml['package']['name'] + deps = cargo_lock['package'] + + app_in_cratesio = False + crates = [] + other_crates = [] + for dep in deps: + name = dep['name'] + version = dep['version'] + if 'source' in dep and dep['source'] == 'registry+https://github.com/rust-lang/crates.io-index': + if name == app_name: + app_in_cratesio = True # exclude app itself, needs to be first in crates list + else: + crates.append((name, version)) + else: + other_crates.append((name, version)) + return app_in_cratesio, crates, other_crates + + +if __name__ == '__main__': + import sys + app_in_cratesio, crates, _ = generate_crate_list(sys.argv[1]) + if app_in_cratesio or crates: + print('crates = [') + if app_in_cratesio: + print(' (name, version),') + for name, version in crates: + print(" ('" + name + "', '" + version + "'),") + print(']') + From e83b8c6efc5e05499cc803a79ea84b71e0d3322d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 13 Apr 2023 10:19:47 +0200 Subject: [PATCH 268/325] Trailing whitespace --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 588c0be6a1..4187edaeae 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -217,4 +217,4 @@ def generate_crate_list(sourcedir): for name, version in crates: print(" ('" + name + "', '" + version + "'),") print(']') - + From 00c0f101c78e3d29c091544ee5540b3e3a453582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 13 Apr 2023 11:06:35 +0200 Subject: [PATCH 269/325] blank line --- easybuild/easyblocks/generic/cargo.py | 1 - 1 file changed, 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 4187edaeae..1890d373aa 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -217,4 +217,3 @@ def generate_crate_list(sourcedir): for name, version in crates: print(" ('" + name + "', '" + version + "'),") print(']') - From 94b8c73743b1e2086c5433b74254d74a3068fd6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bob=20Dr=C3=B6ge?= Date: Fri, 21 Apr 2023 17:29:24 +0200 Subject: [PATCH 270/325] prevent copy-pasting of code by using the parameter added in https://github.com/easybuilders/easybuild-framework/pull/4249 --- easybuild/easyblocks/generic/gopackage.py | 78 +---------------------- 1 file changed, 2 insertions(+), 76 deletions(-) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index 16e2a2d1d7..55695fc51e 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -28,17 +28,14 @@ @author: Pavel Grochal (INUITS) """ import os -import re from distutils.version import LooseVersion import easybuild.tools.environment as env -from easybuild.framework.easyblock import DEFAULT_BIN_LIB_SUBDIRS, EasyBlock +from easybuild.framework.easyblock import EasyBlock from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.config import build_option from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd -from easybuild.tools.systemtools import get_linked_libs_raw class GoPackage(EasyBlock): @@ -134,9 +131,6 @@ def install_step(self): self.cfg['preinstallopts'], 'go', 'install', - # print commands as they are executed, - # including downloading and installing of package deps as listed in the go.mod file - '-x', self.cfg['installopts'], ]) run_cmd(cmd, log_all=True, log_ok=True, simple=True) @@ -154,72 +148,4 @@ def sanity_check_step(self): super(GoPackage, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands) def sanity_check_rpath(self, rpath_dirs=None): - """Sanity check binaries/libraries w.r.t. RPATH linking.""" - - self.log.info("Checking RPATH linkage for binaries/libraries...") - - fails = [] - - # hard reset $LD_LIBRARY_PATH before running RPATH sanity check - orig_env = env.unset_env_vars(['LD_LIBRARY_PATH']) - - self.log.debug("$LD_LIBRARY_PATH during RPATH sanity check: %s", os.getenv('LD_LIBRARY_PATH', '(empty)')) - self.log.debug("List of loaded modules: %s", self.modules_tool.list()) - - not_found_regex = re.compile(r'(\S+)\s*\=\>\s*not found') - - # List of libraries that should be exempt from the RPATH sanity check; - # For example, libcuda.so.1 should never be RPATH-ed by design, - # see https://github.com/easybuilders/easybuild-framework/issues/4095 - filter_rpath_sanity_libs = build_option('filter_rpath_sanity_libs') - msg = "Ignoring the following libraries if they are not found by RPATH sanity check: %s" - self.log.info(msg, filter_rpath_sanity_libs) - - if rpath_dirs is None: - rpath_dirs = self.cfg['bin_lib_subdirs'] or self.bin_lib_subdirs() - - if not rpath_dirs: - rpath_dirs = DEFAULT_BIN_LIB_SUBDIRS - self.log.info("Using default subdirectories for binaries/libraries to verify RPATH linking: %s", - rpath_dirs) - else: - self.log.info("Using specified subdirectories for binaries/libraries to verify RPATH linking: %s", - rpath_dirs) - - for dirpath in [os.path.join(self.installdir, d) for d in rpath_dirs]: - if os.path.exists(dirpath): - self.log.debug("Sanity checking RPATH for files in %s", dirpath) - - for path in [os.path.join(dirpath, x) for x in os.listdir(dirpath)]: - self.log.debug("Sanity checking RPATH for %s", path) - - out = get_linked_libs_raw(path) - - if out is None: - msg = "Failed to determine dynamically linked libraries for %s, " - msg += "so skipping it in RPATH sanity check" - self.log.debug(msg, path) - else: - # check whether all required libraries are found via 'ldd' - matches = re.findall(not_found_regex, out) - if len(matches) > 0: # Some libraries are not found via 'ldd' - # For each match, check if the library is in the exception list - for match in matches: - if match in filter_rpath_sanity_libs: - msg = "Library %s not found for %s, but ignored " - msg += "since it is on the rpath exception list: %s" - self.log.info(msg, match, path, filter_rpath_sanity_libs) - else: - fail_msg = "Library %s not found for %s; " % (match, path) - fail_msg += "RPATH linking is enabled, but not implemented for Go packages." - fail_msg += "See https://github.com/easybuilders/easybuild-easyconfigs/issues/17516" - self.log.warning(fail_msg) - fails.append(fail_msg) - else: - self.log.debug("Output of 'ldd %s' checked, looks OK", path) - else: - self.log.debug("Not sanity checking files in non-existing directory %s", dirpath) - - env.restore_env_vars(orig_env) - - return fails + super(GoPackage, self).sanity_check_rpath(rpath_dirs=rpath_dirs, check_readelf_rpath=False) From d4e6a94c5b4124a67aa700d72ec8c4c445c170fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bob=20Dr=C3=B6ge?= Date: Fri, 21 Apr 2023 17:36:04 +0200 Subject: [PATCH 271/325] Merge latest changes from develop --- easybuild/easyblocks/generic/gopackage.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easybuild/easyblocks/generic/gopackage.py b/easybuild/easyblocks/generic/gopackage.py index 55695fc51e..5c2d96bdc9 100644 --- a/easybuild/easyblocks/generic/gopackage.py +++ b/easybuild/easyblocks/generic/gopackage.py @@ -131,6 +131,9 @@ def install_step(self): self.cfg['preinstallopts'], 'go', 'install', + # print commands as they are executed, + # including downloading and installing of package deps as listed in the go.mod file + '-x', self.cfg['installopts'], ]) run_cmd(cmd, log_all=True, log_ok=True, simple=True) From 55ec455c6adbc05a6e5beb6f0b69167311370ed0 Mon Sep 17 00:00:00 2001 From: Thomas Roeblitz Date: Fri, 21 Apr 2023 21:57:03 +0200 Subject: [PATCH 272/325] ensure that --sysroot is passed to linker --- easybuild/easyblocks/g/gcc.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/easybuild/easyblocks/g/gcc.py b/easybuild/easyblocks/g/gcc.py index 9069e3ea37..9bf640253c 100644 --- a/easybuild/easyblocks/g/gcc.py +++ b/easybuild/easyblocks/g/gcc.py @@ -357,9 +357,6 @@ def configure_step(self): # (see https://gcc.gnu.org/install/configure.html) self.cfg.update('configopts', '--with-sysroot=%s' % sysroot) - # avoid that --sysroot is passed to linker by patching value for SYSROOT_SPEC in gcc/gcc.c - apply_regex_substitutions(os.path.join('gcc', 'gcc.c'), [('--sysroot=%R', '')]) - # prefix dynamic linkers with sysroot # this patches lines like: # #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2" From f15f3006b5ee7d99ce3934bf3d4a6655564b49ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Tue, 2 May 2023 01:13:28 +0200 Subject: [PATCH 273/325] Add cargopythonpackage --- easybuild/easyblocks/generic/cargo.py | 30 ++++------ .../easyblocks/generic/cargopythonpackage.py | 60 +++++++++++++++++++ 2 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 easybuild/easyblocks/generic/cargopythonpackage.py diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 1890d373aa..29e990e31a 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -83,6 +83,14 @@ def __init__(self, *args, **kwargs): }) self.cfg.update('sources', sources) + if self.cfg['offline']: + # Replace crates-io with vendored sources using build dir wide toml file in CARGO_HOME + # because the rust source subdirectories might differ with python packages + config_toml = os.path.join(self.builddir, '.cargo', 'config.toml') + write_file(config_toml, '[source.crates-io]\ndirectory="%s"' % self.builddir) + # Use environment variable since it would also be passed along to builds triggered via python packages + env.setvar('CARGO_NET_OFFLINE', 'true') + def configure_step(self): pass @@ -124,12 +132,6 @@ def build_step(self): if self.cfg['enable_tests']: tests = "--tests" - offline = '' - if self.cfg['offline']: - offline = "--offline" - # Replace crates-io with vendored sources - write_file('.cargo/config.toml', '[source.crates-io]\ndirectory=".."', append=True) - lto = '' if self.cfg['lto'] is not None: lto = '--config profile.%s.lto=\\"%s\\"' % (self.profile, self.cfg['lto']) @@ -139,7 +141,6 @@ def build_step(self): self.cfg['prebuildopts'], 'cargo build', '--profile=' + self.profile, - offline, lto, tests, parallel, @@ -150,30 +151,20 @@ def build_step(self): def test_step(self): """Test with cargo""" if self.cfg['enable_tests']: - offline = '' - if self.cfg['offline']: - offline = "--offline" - cmd = ' '.join([ self.cfg['pretestopts'], 'cargo test', '--profile=' + self.profile, - offline, self.cfg['testopts'], ]) run_cmd(cmd, log_all=True, simple=True) def install_step(self): """Install with cargo""" - offline = '' - if self.cfg['offline']: - offline = "--offline" - cmd = ' '.join([ self.cfg['preinstallopts'], 'cargo install', '--profile=' + self.profile, - offline, '--root=' + self.installdir, '--path=.', self.cfg['installopts'], @@ -189,6 +180,7 @@ def generate_crate_list(sourcedir): cargo_lock = toml.load(os.path.join(sourcedir, 'Cargo.lock')) app_name = cargo_toml['package']['name'] + print(app_name) deps = cargo_lock['package'] app_in_cratesio = False @@ -199,6 +191,7 @@ def generate_crate_list(sourcedir): version = dep['version'] if 'source' in dep and dep['source'] == 'registry+https://github.com/rust-lang/crates.io-index': if name == app_name: + print('check') app_in_cratesio = True # exclude app itself, needs to be first in crates list else: crates.append((name, version)) @@ -209,7 +202,8 @@ def generate_crate_list(sourcedir): if __name__ == '__main__': import sys - app_in_cratesio, crates, _ = generate_crate_list(sys.argv[1]) + app_in_cratesio, crates, other = generate_crate_list(sys.argv[1]) + print(other) if app_in_cratesio or crates: print('crates = [') if app_in_cratesio: diff --git a/easybuild/easyblocks/generic/cargopythonpackage.py b/easybuild/easyblocks/generic/cargopythonpackage.py new file mode 100644 index 0000000000..ae1292512b --- /dev/null +++ b/easybuild/easyblocks/generic/cargopythonpackage.py @@ -0,0 +1,60 @@ +## +# Copyright 2009-2023 Ghent University +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for installing Cargo packages (Rust lang package system) + +@author: Mikael Oehman (Chalmers University of Technology) +""" + +import os + +from easybuild.easyblocks.generic.cargo import Cargo +from easybuild.easyblocks.generic.pythonpackage import PythonPackage + + +class CargoPythonPackage(PythonPackage, Cargo): # PythonPackage must come first to take precedence + """Build a Python package with setup from Cargo but build/install step from PythonPackage + + The cargo init step will set up the environment variables for rustc and vendor sources + but all the build steps are triggered via normal PythonPackage steps like normal. + """ + + @staticmethod + def extra_options(extra_vars=None): + """Define extra easyconfig parameters specific to Cargo""" + extra_vars = PythonPackage.extra_options(extra_vars) + extra_vars = Cargo.extra_options(extra_vars) # not all extra options here will used here + + return extra_vars + + def __init__(self, *args, **kwargs): + """Constructor for CargoPythonPackage easyblock.""" + Cargo.__init__(self, *args, **kwargs) + return PythonPackage.__init__(self, *args, **kwargs) + + def extract_step(self): + """Specifically use the overloaded variant from Cargo as is populates vendored sources with checksums.""" + return Cargo.extract_step(self) + From 13807fb9ab1a869c135d87c2eb4b13d5b411f3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Tue, 2 May 2023 01:28:58 +0200 Subject: [PATCH 274/325] Fix code style --- easybuild/easyblocks/generic/cargopythonpackage.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/easybuild/easyblocks/generic/cargopythonpackage.py b/easybuild/easyblocks/generic/cargopythonpackage.py index ae1292512b..71a8778fa4 100644 --- a/easybuild/easyblocks/generic/cargopythonpackage.py +++ b/easybuild/easyblocks/generic/cargopythonpackage.py @@ -28,8 +28,6 @@ @author: Mikael Oehman (Chalmers University of Technology) """ -import os - from easybuild.easyblocks.generic.cargo import Cargo from easybuild.easyblocks.generic.pythonpackage import PythonPackage @@ -57,4 +55,3 @@ def __init__(self, *args, **kwargs): def extract_step(self): """Specifically use the overloaded variant from Cargo as is populates vendored sources with checksums.""" return Cargo.extract_step(self) - From 85113256cd16e38edcce8c0ae10f813652f6bc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Tue, 2 May 2023 02:28:33 +0200 Subject: [PATCH 275/325] Move config.toml modifications to extract step --- easybuild/easyblocks/generic/cargo.py | 20 ++++++++++--------- .../easyblocks/generic/cargopythonpackage.py | 2 ++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 29e990e31a..562a1f69fe 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -61,7 +61,8 @@ def extra_options(extra_vars=None): def __init__(self, *args, **kwargs): """Constructor for Cargo easyblock.""" super(Cargo, self).__init__(*args, **kwargs) - env.setvar('CARGO_HOME', os.path.join(self.builddir, '.cargo')) + self.cargo_home = os.path.join(self.builddir, '.cargo') + env.setvar('CARGO_HOME', self.cargo_home) env.setvar('RUSTC', 'rustc') env.setvar('RUSTDOC', 'rustdoc') env.setvar('RUSTFMT', 'rustfmt') @@ -83,14 +84,6 @@ def __init__(self, *args, **kwargs): }) self.cfg.update('sources', sources) - if self.cfg['offline']: - # Replace crates-io with vendored sources using build dir wide toml file in CARGO_HOME - # because the rust source subdirectories might differ with python packages - config_toml = os.path.join(self.builddir, '.cargo', 'config.toml') - write_file(config_toml, '[source.crates-io]\ndirectory="%s"' % self.builddir) - # Use environment variable since it would also be passed along to builds triggered via python packages - env.setvar('CARGO_NET_OFFLINE', 'true') - def configure_step(self): pass @@ -98,6 +91,15 @@ def extract_step(self): """ Unpack the source files and populate them with required .cargo-checksum.json if offline """ + if self.cfg['offline']: + self.log.info("Setting vendored crates-io dir") + # Replace crates-io with vendored sources using build dir wide toml file in CARGO_HOME + # because the rust source subdirectories might differ with python packages + config_toml = os.path.join(self.cargo_home, 'config.toml') + write_file(config_toml, '[source.crates-io]\ndirectory="%s"' % self.builddir) + # Use environment variable since it would also be passed along to builds triggered via python packages + env.setvar('CARGO_NET_OFFLINE', 'true') + for src in self.src: existing_dirs = set(os.listdir(self.builddir)) self.log.info("Unpacking source %s" % src['name']) diff --git a/easybuild/easyblocks/generic/cargopythonpackage.py b/easybuild/easyblocks/generic/cargopythonpackage.py index 71a8778fa4..21011d9e97 100644 --- a/easybuild/easyblocks/generic/cargopythonpackage.py +++ b/easybuild/easyblocks/generic/cargopythonpackage.py @@ -49,7 +49,9 @@ def extra_options(extra_vars=None): def __init__(self, *args, **kwargs): """Constructor for CargoPythonPackage easyblock.""" + print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 2") Cargo.__init__(self, *args, **kwargs) + self.log.info("CHECK B") return PythonPackage.__init__(self, *args, **kwargs) def extract_step(self): From 9067045460fa50f78577b34cb3a73c57b7be5c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Tue, 2 May 2023 02:34:27 +0200 Subject: [PATCH 276/325] Remove debug prints --- easybuild/easyblocks/generic/cargopythonpackage.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/easybuild/easyblocks/generic/cargopythonpackage.py b/easybuild/easyblocks/generic/cargopythonpackage.py index 21011d9e97..71a8778fa4 100644 --- a/easybuild/easyblocks/generic/cargopythonpackage.py +++ b/easybuild/easyblocks/generic/cargopythonpackage.py @@ -49,9 +49,7 @@ def extra_options(extra_vars=None): def __init__(self, *args, **kwargs): """Constructor for CargoPythonPackage easyblock.""" - print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 2") Cargo.__init__(self, *args, **kwargs) - self.log.info("CHECK B") return PythonPackage.__init__(self, *args, **kwargs) def extract_step(self): From 86aca20d15def4261c22a8af57b1aee467daa893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 3 May 2023 03:33:17 +0200 Subject: [PATCH 277/325] Add output log to matlab installs, parse for common errors --- easybuild/easyblocks/m/matlab.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index 643fa73878..1bd4ef1b6b 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -55,6 +55,7 @@ def __init__(self, *args, **kwargs): super(EB_MATLAB, self).__init__(*args, **kwargs) self.comp_fam = None self.configfile = os.path.join(self.builddir, 'my_installer_input.txt') + self.outputfile = os.path.join(self.builddir, 'my_installer_output.txt') @staticmethod def extra_options(): @@ -98,12 +99,14 @@ def configure_step(self): regagree = re.compile(br"^# agreeToLicense=.*", re.M) regmode = re.compile(br"^# mode=.*", re.M) reglicpath = re.compile(br"^# licensePath=.*", re.M) + regoutfile = re.compile(br"^# outputFile=.*", re.M) # must use byte-strings here when using Python 3, see above config = regdest.sub(b"destinationFolder=%s" % self.installdir.encode('utf-8'), config) config = regagree.sub(b"agreeToLicense=Yes", config) config = regmode.sub(b"mode=silent", config) config = reglicpath.sub(b"licensePath=%s" % licfile.encode('utf-8'), config) + config = regoutfile.sub(b"outputFile=\"%s\"" % self.outputfile, config) write_file(self.configfile, config) @@ -188,6 +191,9 @@ def install_step(self): # check installer output for known signs of trouble patterns = [ "Error: You have entered an invalid File Installation Key", + "Not a valid key", + "Exiting with status -2", + "End - Unsuccessful", ] for pattern in patterns: @@ -195,6 +201,12 @@ def install_step(self): if regex.search(out): raise EasyBuildError("Found error pattern '%s' in output of installation command '%s': %s", regex.pattern, cmd, out) + + with open(self.outputfile) as f: + if regex.search(f.read()): + raise EasyBuildError("Found error pattern '%s' in output file of installer", + regex.pattern) + def sanity_check_step(self): """Custom sanity check for MATLAB.""" From 0264c37d531156e1fe89361afb3d3f0da3a6922a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 3 May 2023 03:36:54 +0200 Subject: [PATCH 278/325] Fix style --- easybuild/easyblocks/m/matlab.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index 1bd4ef1b6b..575cf94b4f 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -201,13 +201,11 @@ def install_step(self): if regex.search(out): raise EasyBuildError("Found error pattern '%s' in output of installation command '%s': %s", regex.pattern, cmd, out) - with open(self.outputfile) as f: if regex.search(f.read()): raise EasyBuildError("Found error pattern '%s' in output file of installer", regex.pattern) - def sanity_check_step(self): """Custom sanity check for MATLAB.""" custom_paths = { From 5f3d769ab3c38308e4fbd06e22fc2619e51fa197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 3 May 2023 03:47:42 +0200 Subject: [PATCH 279/325] Add missing utf-8 encoding --- easybuild/easyblocks/m/matlab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index 575cf94b4f..8c1a4df514 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -106,7 +106,7 @@ def configure_step(self): config = regagree.sub(b"agreeToLicense=Yes", config) config = regmode.sub(b"mode=silent", config) config = reglicpath.sub(b"licensePath=%s" % licfile.encode('utf-8'), config) - config = regoutfile.sub(b"outputFile=\"%s\"" % self.outputfile, config) + config = regoutfile.sub(b"outputFile=\"%s\"" % self.outputfile.encode('utf-8'), config) write_file(self.configfile, config) From c1fbbae8beb821bc348f26a099baf8fe572822e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 3 May 2023 03:58:47 +0200 Subject: [PATCH 280/325] Remove quotes around file path as matlab doesn't like that --- easybuild/easyblocks/m/matlab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index 8c1a4df514..f147bc993c 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -106,7 +106,7 @@ def configure_step(self): config = regagree.sub(b"agreeToLicense=Yes", config) config = regmode.sub(b"mode=silent", config) config = reglicpath.sub(b"licensePath=%s" % licfile.encode('utf-8'), config) - config = regoutfile.sub(b"outputFile=\"%s\"" % self.outputfile.encode('utf-8'), config) + config = regoutfile.sub(b"outputFile=%s" % self.outputfile.encode('utf-8'), config) write_file(self.configfile, config) From f0ededc1afc7e6261d330797eab67e877465ea31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 3 May 2023 16:18:29 +0200 Subject: [PATCH 281/325] Broaden patterns to find in matlab errors --- easybuild/easyblocks/m/matlab.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index f147bc993c..a0f04b1748 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -192,7 +192,9 @@ def install_step(self): patterns = [ "Error: You have entered an invalid File Installation Key", "Not a valid key", - "Exiting with status -2", + "All selected products are already installed", + "The application encountered an unexpected error and needs to close", + "Exiting with status -\\d", "End - Unsuccessful", ] From f04ea9604ff3c13070a2388978d87962d22c52ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 4 May 2023 00:16:00 +0200 Subject: [PATCH 282/325] Allow gurobi to use EB_GUROBI_LICENSE_FILE environment variable --- easybuild/easyblocks/g/gurobi.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/easybuild/easyblocks/g/gurobi.py b/easybuild/easyblocks/g/gurobi.py index a02938ac12..923cc28f2f 100644 --- a/easybuild/easyblocks/g/gurobi.py +++ b/easybuild/easyblocks/g/gurobi.py @@ -55,22 +55,25 @@ def __init__(self, *args, **kwargs): """Easyblock constructor, define custom class variables specific to Gurobi.""" super(EB_Gurobi, self).__init__(*args, **kwargs) - self.license_file = self.cfg['license_file'] - + # make sure license file is available + self.orig_license_file = self.cfg['license_file'] + if self.orig_license_file is None: + self.orig_license_file = os.getenv('EB_GUROBI_LICENSE_FILE', None) + + if self.orig_license_file is None or not os.path.exists(self.cfg['license_file']): + raise EasyBuildError("No existing license file specified: %s", self.orig_license_file) + if self.cfg['copy_license_file']: self.license_file = os.path.join(self.installdir, 'gurobi.lic') + else: + self.license_file = self.orig_license_file def install_step(self): """Install Gurobi and license file.""" - - # make sure license file is available - if self.cfg['license_file'] is None or not os.path.exists(self.cfg['license_file']): - raise EasyBuildError("No existing license file specified: %s", self.cfg['license_file']) - super(EB_Gurobi, self).install_step() if self.cfg['copy_license_file']: - copy_file(self.cfg['license_file'], self.license_file) + copy_file(self.orig_license_file, self.license_file) if get_software_root('Python'): run_cmd("python setup.py install --prefix=%s" % self.installdir) From 5b357e482825ef0ff52d4584537169ab26e5df3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 4 May 2023 00:17:40 +0200 Subject: [PATCH 283/325] Fix code style in gurobi.py --- easybuild/easyblocks/g/gurobi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/g/gurobi.py b/easybuild/easyblocks/g/gurobi.py index 923cc28f2f..45b6506916 100644 --- a/easybuild/easyblocks/g/gurobi.py +++ b/easybuild/easyblocks/g/gurobi.py @@ -59,10 +59,10 @@ def __init__(self, *args, **kwargs): self.orig_license_file = self.cfg['license_file'] if self.orig_license_file is None: self.orig_license_file = os.getenv('EB_GUROBI_LICENSE_FILE', None) - + if self.orig_license_file is None or not os.path.exists(self.cfg['license_file']): raise EasyBuildError("No existing license file specified: %s", self.orig_license_file) - + if self.cfg['copy_license_file']: self.license_file = os.path.join(self.installdir, 'gurobi.lic') else: From d1fa20a71c1e2d9fc5920f5a2d51311cb8815843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 4 May 2023 00:32:59 +0200 Subject: [PATCH 284/325] Move check for non-noneness of gurobi license file into install step --- easybuild/easyblocks/g/gurobi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/g/gurobi.py b/easybuild/easyblocks/g/gurobi.py index 45b6506916..309511bb29 100644 --- a/easybuild/easyblocks/g/gurobi.py +++ b/easybuild/easyblocks/g/gurobi.py @@ -60,9 +60,6 @@ def __init__(self, *args, **kwargs): if self.orig_license_file is None: self.orig_license_file = os.getenv('EB_GUROBI_LICENSE_FILE', None) - if self.orig_license_file is None or not os.path.exists(self.cfg['license_file']): - raise EasyBuildError("No existing license file specified: %s", self.orig_license_file) - if self.cfg['copy_license_file']: self.license_file = os.path.join(self.installdir, 'gurobi.lic') else: @@ -73,6 +70,9 @@ def install_step(self): super(EB_Gurobi, self).install_step() if self.cfg['copy_license_file']: + if self.orig_license_file is None or not os.path.exists(self.cfg['license_file']): + raise EasyBuildError("No existing license file specified: %s", self.orig_license_file) + copy_file(self.orig_license_file, self.license_file) if get_software_root('Python'): From 2bc61b48c70fa5161c180a96f8d8da5cbe229115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 4 May 2023 13:52:33 +0200 Subject: [PATCH 285/325] Fix use of incorrect license file variable --- easybuild/easyblocks/g/gurobi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/g/gurobi.py b/easybuild/easyblocks/g/gurobi.py index 309511bb29..49147d9a2f 100644 --- a/easybuild/easyblocks/g/gurobi.py +++ b/easybuild/easyblocks/g/gurobi.py @@ -70,7 +70,7 @@ def install_step(self): super(EB_Gurobi, self).install_step() if self.cfg['copy_license_file']: - if self.orig_license_file is None or not os.path.exists(self.cfg['license_file']): + if self.orig_license_file is None or not os.path.exists(self.orig_license_file): raise EasyBuildError("No existing license file specified: %s", self.orig_license_file) copy_file(self.orig_license_file, self.license_file) From 53410d2989a45214a951a831782b9901792f4c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 4 May 2023 15:55:28 +0200 Subject: [PATCH 286/325] Update easybuild/easyblocks/m/matlab.py Co-authored-by: Sam Moors --- easybuild/easyblocks/m/matlab.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py index a0f04b1748..b260e703de 100644 --- a/easybuild/easyblocks/m/matlab.py +++ b/easybuild/easyblocks/m/matlab.py @@ -194,6 +194,7 @@ def install_step(self): "Not a valid key", "All selected products are already installed", "The application encountered an unexpected error and needs to close", + "Error: Unable to write to", "Exiting with status -\\d", "End - Unsuccessful", ] From 84af134d2d983ff795680e38ebd8566906cc4335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 4 May 2023 15:56:03 +0200 Subject: [PATCH 287/325] Add partial support for vendoring of non-crates.io crates --- easybuild/easyblocks/generic/cargo.py | 61 +++++++++++++------ .../easyblocks/generic/cargopythonpackage.py | 2 +- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 562a1f69fe..43d9c29bcb 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -53,7 +53,7 @@ def extra_options(extra_vars=None): 'enable_tests': [True, "Enable building of tests", CUSTOM], 'offline': [True, "Build offline", CUSTOM], 'lto': [None, "Override default LTO flag ('fat', 'thin', 'off')", CUSTOM], - 'crates': [[], "List of (crate, version) tuples to use", CUSTOM], + 'crates': [[], "List of (crate, version, [repo, rev]) tuples to use", CUSTOM], }) return extra_vars @@ -74,14 +74,25 @@ def __init__(self, *args, **kwargs): env.setvar('RUST_BACKTRACE', '1') # Populate sources from "crates" list of tuples - sources = self.cfg['sources'] - for crate, version in self.cfg['crates']: - sources.append({ - 'download_filename': crate + '/' + version + '/download', - 'filename': crate + '-' + version + '.tar.gz', - 'source_urls': [CRATESIO_SOURCE], - 'alt_location': 'crates.io', - }) + sources = [] + for crate_info in self.cfg['crates']: + if len(crate_info) == 2: + crate, version = crate_info + sources.append({ + 'download_filename': crate + '/' + version + '/download', + 'filename': crate + '-' + version + '.tar.gz', + 'source_urls': [CRATESIO_SOURCE], + 'alt_location': 'crates.io', + }) + else: + crate, version, repo, rev = crate_info + url, repo_name_git = repo.rsplit('/', maxsplit=1) + sources.append({ + 'git_config': {'url': url, 'repo_name': repo_name_git[:-4], 'commit': rev}, + 'filename': crate + '-' + version + '.tar.gz', + 'source_urls': [CRATESIO_SOURCE], + }) + self.cfg.update('sources', sources) def configure_step(self): @@ -96,10 +107,24 @@ def extract_step(self): # Replace crates-io with vendored sources using build dir wide toml file in CARGO_HOME # because the rust source subdirectories might differ with python packages config_toml = os.path.join(self.cargo_home, 'config.toml') - write_file(config_toml, '[source.crates-io]\ndirectory="%s"' % self.builddir) + write_file(config_toml, '[source.vendored-sources]\ndirectory = "%s"\n\n' % self.builddir, append=True) + write_file(config_toml, '[source.crates-io]\ndirectory = "vendored-sources"\n\n', append=True) + + # also vendor sources from other git sources: + # note that one repo can contain multiple packages but we should specify the source once + git_sources = set() + for crate_info in self.cfg['crates']: + if len(crate_info) == 4: + _, _, repo, rev = crate_info + git_sources.add((repo, rev)) + for repo, rev in git_sources: + write_file(config_toml, '[source."%s"]\ngit = "%s"\nrev = "%s"\ndirectory = "vendored-sources"\n\n' % ( + repo, repo, rev), append=True) + # Use environment variable since it would also be passed along to builds triggered via python packages env.setvar('CARGO_NET_OFFLINE', 'true') + # More work is needed here for git sources to work, especially those repos with multiple packages. for src in self.src: existing_dirs = set(os.listdir(self.builddir)) self.log.info("Unpacking source %s" % src['name']) @@ -182,7 +207,6 @@ def generate_crate_list(sourcedir): cargo_lock = toml.load(os.path.join(sourcedir, 'Cargo.lock')) app_name = cargo_toml['package']['name'] - print(app_name) deps = cargo_lock['package'] app_in_cratesio = False @@ -191,12 +215,15 @@ def generate_crate_list(sourcedir): for dep in deps: name = dep['name'] version = dep['version'] - if 'source' in dep and dep['source'] == 'registry+https://github.com/rust-lang/crates.io-index': + if 'source' in dep: if name == app_name: - print('check') - app_in_cratesio = True # exclude app itself, needs to be first in crates list + app_in_cratesio = True # exclude app itself, needs to be first in crates list or taken from pypi else: - crates.append((name, version)) + if dep['source'] == 'registry+https://github.com/rust-lang/crates.io-index': + crates.append((name, version)) + else: + # Lock file has revision#revision in the url for some reason. + crates.append((name, version, dep['source'].rsplit('#', maxsplit=1)[0])) else: other_crates.append((name, version)) return app_in_cratesio, crates, other_crates @@ -210,6 +237,6 @@ def generate_crate_list(sourcedir): print('crates = [') if app_in_cratesio: print(' (name, version),') - for name, version in crates: - print(" ('" + name + "', '" + version + "'),") + for crate_info in crates: + print(" ('" + "', '".join(crate_info) + "'),") print(']') diff --git a/easybuild/easyblocks/generic/cargopythonpackage.py b/easybuild/easyblocks/generic/cargopythonpackage.py index 71a8778fa4..a935e190a0 100644 --- a/easybuild/easyblocks/generic/cargopythonpackage.py +++ b/easybuild/easyblocks/generic/cargopythonpackage.py @@ -50,7 +50,7 @@ def extra_options(extra_vars=None): def __init__(self, *args, **kwargs): """Constructor for CargoPythonPackage easyblock.""" Cargo.__init__(self, *args, **kwargs) - return PythonPackage.__init__(self, *args, **kwargs) + PythonPackage.__init__(self, *args, **kwargs) def extract_step(self): """Specifically use the overloaded variant from Cargo as is populates vendored sources with checksums.""" From 348332b4fd004f9ab457677b9b7c9fd70f6babce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Fri, 5 May 2023 16:56:58 +0200 Subject: [PATCH 288/325] Fix mistake in vendoring of sources --- easybuild/easyblocks/generic/cargo.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 43d9c29bcb..69fbfb62ae 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -103,22 +103,21 @@ def extract_step(self): Unpack the source files and populate them with required .cargo-checksum.json if offline """ if self.cfg['offline']: - self.log.info("Setting vendored crates-io dir") + self.log.info("Setting vendored crates dir") # Replace crates-io with vendored sources using build dir wide toml file in CARGO_HOME # because the rust source subdirectories might differ with python packages config_toml = os.path.join(self.cargo_home, 'config.toml') write_file(config_toml, '[source.vendored-sources]\ndirectory = "%s"\n\n' % self.builddir, append=True) - write_file(config_toml, '[source.crates-io]\ndirectory = "vendored-sources"\n\n', append=True) + write_file(config_toml, '[source.crates-io]\nreplace-with = "vendored-sources"\n\n', append=True) - # also vendor sources from other git sources: - # note that one repo can contain multiple packages but we should specify the source once + # also vendor sources from other git sources (could be many crates for one git source) git_sources = set() for crate_info in self.cfg['crates']: if len(crate_info) == 4: _, _, repo, rev = crate_info git_sources.add((repo, rev)) for repo, rev in git_sources: - write_file(config_toml, '[source."%s"]\ngit = "%s"\nrev = "%s"\ndirectory = "vendored-sources"\n\n' % ( + write_file(config_toml, '[source."%s"]\ngit = "%s"\nrev = "%s"\nreplace-with = "vendored-sources"\n\n' % ( repo, repo, rev), append=True) # Use environment variable since it would also be passed along to builds triggered via python packages From 0803ce991acf3c2494669f7a1701293c827e9bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Fri, 5 May 2023 16:59:13 +0200 Subject: [PATCH 289/325] Break up long line --- easybuild/easyblocks/generic/cargo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 69fbfb62ae..323573eb5b 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -117,8 +117,8 @@ def extract_step(self): _, _, repo, rev = crate_info git_sources.add((repo, rev)) for repo, rev in git_sources: - write_file(config_toml, '[source."%s"]\ngit = "%s"\nrev = "%s"\nreplace-with = "vendored-sources"\n\n' % ( - repo, repo, rev), append=True) + write_file(config_toml, '[source."%s"]\ngit = "%s"\nrev = "%s"\n' \ + 'replace-with = "vendored-sources"\n\n' % (repo, repo, rev), append=True) # Use environment variable since it would also be passed along to builds triggered via python packages env.setvar('CARGO_NET_OFFLINE', 'true') From 480ffdc0076f5069a0e8be3b68decbdd2cbe2133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Fri, 5 May 2023 17:09:42 +0200 Subject: [PATCH 290/325] Fix style --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 323573eb5b..c538f5c244 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -117,7 +117,7 @@ def extract_step(self): _, _, repo, rev = crate_info git_sources.add((repo, rev)) for repo, rev in git_sources: - write_file(config_toml, '[source."%s"]\ngit = "%s"\nrev = "%s"\n' \ + write_file(config_toml, '[source."%s"]\ngit = "%s"\nrev = "%s"\n' 'replace-with = "vendored-sources"\n\n' % (repo, repo, rev), append=True) # Use environment variable since it would also be passed along to builds triggered via python packages From b34fd4613ff19950b1ea911d7184578e618a7097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Wed, 10 May 2023 18:29:14 +0200 Subject: [PATCH 291/325] Switch cargo to extensioneasyblock to allow use as an extension --- easybuild/easyblocks/generic/cargo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index c538f5c244..50ef5542b5 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -33,7 +33,7 @@ import easybuild.tools.environment as env from easybuild.tools.build_log import EasyBuildError from easybuild.framework.easyconfig import CUSTOM -from easybuild.framework.easyblock import EasyBlock +from easybuild.framework.extensioneasyblock import ExtensionEasyBlock from easybuild.tools.filetools import extract_file, change_dir from easybuild.tools.run import run_cmd from easybuild.tools.config import build_option @@ -42,13 +42,13 @@ CRATESIO_SOURCE = "https://crates.io/api/v1/crates" -class Cargo(EasyBlock): +class Cargo(ExtensionEasyBlock): """Support for installing Cargo packages (Rust)""" @staticmethod def extra_options(extra_vars=None): """Define extra easyconfig parameters specific to Cargo""" - extra_vars = EasyBlock.extra_options(extra_vars) + extra_vars = ExtensionEasyBlock.extra_options(extra_vars) extra_vars.update({ 'enable_tests': [True, "Enable building of tests", CUSTOM], 'offline': [True, "Build offline", CUSTOM], From 6a9cba4ee8eac503ab68378ff4287cfb60d05f67 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 23 May 2023 15:32:28 +0200 Subject: [PATCH 292/325] force building torchvision with CUDA support if CUDA is included as dependency by setting $FORCE_CUDA --- easybuild/easyblocks/t/torchvision.py | 48 +++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/easybuild/easyblocks/t/torchvision.py b/easybuild/easyblocks/t/torchvision.py index 197ff15c67..7ef971a8b9 100644 --- a/easybuild/easyblocks/t/torchvision.py +++ b/easybuild/easyblocks/t/torchvision.py @@ -26,12 +26,12 @@ EasyBuild support for building and installing torchvision, implemented as an easyblock @author: Alexander Grund (TU Dresden) +@author: Kenneth Hoste (HPC-UGent) """ - from easybuild.easyblocks.generic.pythonpackage import PythonPackage from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option -from easybuild.tools.modules import get_software_root, get_software_version +from easybuild.tools.modules import get_software_version import easybuild.tools.environment as env @@ -40,24 +40,60 @@ class EB_torchvision(PythonPackage): @staticmethod def extra_options(): - """Change some defaults.""" + """Change some defaults for easyconfig parameters.""" extra_vars = PythonPackage.extra_options() extra_vars['use_pip'][0] = True extra_vars['download_dep_fail'][0] = True extra_vars['sanity_pip_check'][0] = True return extra_vars + def __init__(self, *args, **kwargs): + """Initialize torchvision easyblock.""" + super(EB_torchvision, self).__init__(*args, **kwargs) + + dep_names = set(dep['name'] for dep in self.cfg.dependencies()) + + # require that PyTorch is listed as dependency + if 'PyTorch' not in dep_names: + raise EasyBuildError('PyTorch not found as a dependency') + + # enable building with GPU support if CUDA is included as dependency + if 'CUDA' in dep_names: + self.with_cuda = True + else: + self.with_cuda = False + def configure_step(self): """Set up torchvision config""" - if not get_software_root('PyTorch'): - raise EasyBuildError('PyTorch not found as a dependency') # Note: Those can be overwritten by e.g. preinstallopts env.setvar('BUILD_VERSION', self.version) env.setvar('PYTORCH_VERSION', get_software_version('PyTorch')) - if get_software_root('CUDA'): + + if self.with_cuda: + # make sure that torchvision is installed with CUDA support by setting $FORCE_CUDA + env.setvar('FORCE_CUDA', '1') + # specify CUDA compute capabilities via $TORCH_CUDA_ARCH_LIST cuda_cc = self.cfg['cuda_compute_capabilities'] or build_option('cuda_compute_capabilities') if cuda_cc: env.setvar('TORCH_CUDA_ARCH_LIST', ';'.join(cuda_cc)) super(EB_torchvision, self).configure_step() + + def sanity_check_step(self): + """Custom sanity check for torchvision.""" + custom_commands = [] + + # check whether torchvision was indeed built with CUDA support, + # cfr. https://discuss.pytorch.org/t/notimplementederror-could-not-run-torchvision-nms-with-arguments-from-\ + # the-cuda-backend-this-could-be-because-the-operator-doesnt-exist-for-this-backend/132352/4 + if self.with_cuda: + python_code = '; '.join([ + "import torch, torchvision", + "boxes = torch.tensor([[0., 1., 2., 3.]]).to('cuda')", + "scores = torch.randn(1).to('cuda')", + "print(torchvision.ops.nms(boxes, scores, 0.5))", + ]) + custom_commands.append('python -c "%s"' % python_code) + + super(EB_torchvision, self).sanity_check_step(custom_commands=custom_commands) From f912a8416e00095d46681af5519a829a0cb43ceb Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 23 May 2023 16:20:35 +0200 Subject: [PATCH 293/325] add required PyTorch dependency to test easyconfig used to initialize torchvision easyblock --- test/easyblocks/init_easyblocks.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/easyblocks/init_easyblocks.py b/test/easyblocks/init_easyblocks.py index 9f7a2a1a09..9a53f4b898 100644 --- a/test/easyblocks/init_easyblocks.py +++ b/test/easyblocks/init_easyblocks.py @@ -96,7 +96,7 @@ def tearDown(self): self.log.error("Failed to remove %s: %s" % (self.eb_file, err)) -def template_init_test(self, easyblock, name='foo', version='1.3.2', toolchain=None): +def template_init_test(self, easyblock, name='foo', version='1.3.2', toolchain=None, deps=None): """Test whether all easyblocks can be initialized.""" def check_extra_options_format(extra_options): @@ -164,6 +164,9 @@ def check_extra_options_format(extra_options): test_param = 'foo' extra_txt += '%s = "%s"\n' % (key, test_param) + if deps: + extra_txt += 'dependencies = %s' % str(deps) + # write easyconfig file self.write_ec(ebname, name=name, version=version, toolchain=toolchain, extratxt=extra_txt) @@ -224,6 +227,9 @@ def innertest(self): elif easyblock_fn == 'openssl_wrapper.py': # easyblock to create OpenSSL wrapper expects an OpenSSL version innertest = make_inner_test(easyblock, version='1.1') + elif easyblock_fn == 'torchvision.py': + # torchvision easyblock requires that PyTorch is listed as dependency + innertest = make_inner_test(easyblock, name='torchvision', deps=[('PyTorch', '1.12.1')]) else: innertest = make_inner_test(easyblock) From d48fdc9ed1e2dacbad71ded5d6c5d5c4b930373c Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 23 May 2023 16:27:13 +0200 Subject: [PATCH 294/325] also add required PyTorch dependency when test torchvision easyblock with --module-only --- test/easyblocks/module.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index 65b91f942c..e75a707532 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -333,7 +333,7 @@ def template_module_only_test(self, easyblock, name, version='1.3.2', extra_txt= self.writeEC(ebname, name=name, version=version, extratxt=extra_txt, toolchain=toolchain) # take into account that for some easyblock, particular dependencies are hard required early on - # (in prepare_step for exampel); + # (in prepare_step for example); # we just set the corresponding $EBROOT* environment variables here to fool it... req_deps = { # QScintilla easyblock requires that either PyQt or PyQt5 are available as dependency @@ -460,6 +460,10 @@ def innertest(self): elif eb_fn == 'openssl_wrapper.py': # easyblock to create OpenSSL wrapper expects an OpenSSL version innertest = make_inner_test(easyblock, name='OpenSSL-wrapper', version='1.1') + elif eb_fn == 'torchvision.py': + # torchvision easyblock requires that PyTorch is listed as dependency + extra_txt = "dependencies = [('PyTorch', '1.12.1')]" + innertest = make_inner_test(easyblock, name='torchvision', extra_txt=extra_txt) elif eb_fn == 'ucx_plugins.py': # install fake ucx_info command (used in make_module_extra) tmpdir = tempfile.mkdtemp() From eaab6fafd5ea9148687a2aeef1e0025cc8b22744 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 23 May 2023 16:41:36 +0200 Subject: [PATCH 295/325] create empty module file for requied PyTorch dependency when testing torchvision easyblock --- test/easyblocks/module.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/easyblocks/module.py b/test/easyblocks/module.py index e75a707532..db44834031 100644 --- a/test/easyblocks/module.py +++ b/test/easyblocks/module.py @@ -118,7 +118,7 @@ class ModuleOnlyTest(TestCase): def writeEC(self, easyblock, name='foo', version='1.3.2', extratxt='', toolchain=None): """ create temporary easyconfig file """ if toolchain is None: - toolchain = {'name': 'dummy', 'version': 'dummy'} + toolchain = {'name': 'system', 'version': 'system'} txt = '\n'.join([ 'easyblock = "%s"', @@ -434,8 +434,9 @@ def innertest(self): for prgenv in ['PrgEnv-cray', 'PrgEnv-gnu', 'PrgEnv-intel', 'PrgEnv-pgi']: write_file(os.path.join(TMPDIR, 'modules', 'all', prgenv, '1.2.3'), "#%Module") - # add foo/1.3.2.1.1 module, required for testing ModuleAlias easyblock - write_file(os.path.join(TMPDIR, 'modules', 'all', 'foo', '1.2.3.4.5'), "#%Module") + # add empty module files for dependencies that are required for testing easyblocks + for dep_mod_name in ('foo/1.2.3.4.5', 'PyTorch/1.12.1'): + write_file(os.path.join(TMPDIR, 'modules', 'all', dep_mod_name), "#%Module") for easyblock in easyblocks: eb_fn = os.path.basename(easyblock) From 45202911698f35a307f7bbc350ef6de4bb7e8929 Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Tue, 23 May 2023 16:50:50 +0200 Subject: [PATCH 296/325] comsol: Fix exec permission on files in arch bindir --- easybuild/easyblocks/c/comsol.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/easybuild/easyblocks/c/comsol.py b/easybuild/easyblocks/c/comsol.py index 09b6e44fcd..38d778a623 100644 --- a/easybuild/easyblocks/c/comsol.py +++ b/easybuild/easyblocks/c/comsol.py @@ -114,6 +114,11 @@ def install_step(self): # make sure setup script is executable adjust_permissions(setup_script, stat.S_IXUSR) + # make sure binaries in arch bindir is executable + archpath = os.path.join(self.start_dir, 'bin', 'glnxa64') + adjust_permissions(os.path.join(archpath, 'inflate'), stat.S_IXUSR) + adjust_permissions(os.path.join(archpath, 'setuplauncher'), stat.S_IXUSR) + # make sure $DISPLAY is not defined, which may lead to (hard to trace) problems # this is a workaround for not being able to specify --nodisplay to the install scripts env.unset_env_vars(['DISPLAY']) From 8c1662302a02b74e2fbfcd5640d3fd96a97f6245 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 24 May 2023 16:54:22 +0200 Subject: [PATCH 297/325] enhance Cargo constructor to avoid processing list of crates multiple times into sources --- easybuild/easyblocks/generic/cargo.py | 56 ++++++++++++++++----------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 50ef5542b5..0918f9b881 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -73,30 +73,36 @@ def __init__(self, *args, **kwargs): env.setvar('RUST_LOG', 'DEBUG') env.setvar('RUST_BACKTRACE', '1') - # Populate sources from "crates" list of tuples - sources = [] - for crate_info in self.cfg['crates']: - if len(crate_info) == 2: - crate, version = crate_info - sources.append({ - 'download_filename': crate + '/' + version + '/download', - 'filename': crate + '-' + version + '.tar.gz', - 'source_urls': [CRATESIO_SOURCE], - 'alt_location': 'crates.io', - }) - else: - crate, version, repo, rev = crate_info - url, repo_name_git = repo.rsplit('/', maxsplit=1) - sources.append({ - 'git_config': {'url': url, 'repo_name': repo_name_git[:-4], 'commit': rev}, - 'filename': crate + '-' + version + '.tar.gz', - 'source_urls': [CRATESIO_SOURCE], - }) + # Populate sources from "crates" list of tuples (only once) + if self.cfg['crates']: + # copy list of crates, so we can wipe 'crates' easyconfig paramter, + # to avoid that creates are processed into 'sources' easyconfig parameter again + # when easyblock is initialized again using same parsed easyconfig + # (for example when check_sha256_checksums function is called, like in easyconfigs test suite) + self.crates = self.cfg['crates'][:] + sources = [] + for crate_info in self.cfg['crates']: + if len(crate_info) == 2: + crate, version = crate_info + sources.append({ + 'download_filename': crate + '/' + version + '/download', + 'filename': crate + '-' + version + '.tar.gz', + 'source_urls': [CRATESIO_SOURCE], + 'alt_location': 'crates.io', + }) + else: + crate, version, repo, rev = crate_info + url, repo_name_git = repo.rsplit('/', maxsplit=1) + sources.append({ + 'git_config': {'url': url, 'repo_name': repo_name_git[:-4], 'commit': rev}, + 'filename': crate + '-' + version + '.tar.gz', + 'source_urls': [CRATESIO_SOURCE], + }) - self.cfg.update('sources', sources) + self.cfg.update('sources', sources) - def configure_step(self): - pass + # set 'crates' easyconfig parameter to empty list to prevent re-processing into sources + self.cfg['crates'] = [] def extract_step(self): """ @@ -112,7 +118,7 @@ def extract_step(self): # also vendor sources from other git sources (could be many crates for one git source) git_sources = set() - for crate_info in self.cfg['crates']: + for crate_info in self.crates: if len(crate_info) == 4: _, _, repo, rev = crate_info git_sources.add((repo, rev)) @@ -144,6 +150,10 @@ def extract_step(self): chkfile = os.path.join(self.builddir, cratedir, '.cargo-checksum.json') write_file(chkfile, '{"files":{},"package":"%s"}' % chksum) + def configure_step(self): + """Empty configuration step.""" + pass + @property def profile(self): return 'debug' if self.toolchain.options.get('debug', None) else 'release' From f6c717a5383ef6f5b02b0b7814884c5ac458de6f Mon Sep 17 00:00:00 2001 From: ocaisa Date: Wed, 24 May 2023 17:08:02 +0200 Subject: [PATCH 298/325] Update easybuild/easyblocks/generic/cargo.py --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 0918f9b881..b511b851bc 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -75,7 +75,7 @@ def __init__(self, *args, **kwargs): # Populate sources from "crates" list of tuples (only once) if self.cfg['crates']: - # copy list of crates, so we can wipe 'crates' easyconfig paramter, + # copy list of crates, so we can wipe 'crates' easyconfig parameter, # to avoid that creates are processed into 'sources' easyconfig parameter again # when easyblock is initialized again using same parsed easyconfig # (for example when check_sha256_checksums function is called, like in easyconfigs test suite) From 37ffbf6d001b82e1c3b117ddfc4f53a7b406bcdd Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 25 May 2023 11:59:41 +0000 Subject: [PATCH 299/325] Patch gcc.c* only for older sysroot-ed installations. Check the contents of libc.so: only if the entries are prefixed, patch gcc.c (or gcc.cc for GCC 12+), to account for the changes in https://github.com/gentoo/gentoo/pull/28851 --- easybuild/easyblocks/g/gcc.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/g/gcc.py b/easybuild/easyblocks/g/gcc.py index 9bf640253c..7ee469763e 100644 --- a/easybuild/easyblocks/g/gcc.py +++ b/easybuild/easyblocks/g/gcc.py @@ -48,7 +48,7 @@ from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option from easybuild.tools.filetools import apply_regex_substitutions, change_dir, copy_file, move_file, symlink -from easybuild.tools.filetools import which, write_file +from easybuild.tools.filetools import which, read_file, write_file from easybuild.tools.modules import get_software_root from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import RISCV, check_os_dependency, get_cpu_architecture, get_cpu_family @@ -357,6 +357,20 @@ def configure_step(self): # (see https://gcc.gnu.org/install/configure.html) self.cfg.update('configopts', '--with-sysroot=%s' % sysroot) + libc_so_candidates = [os.path.join(sysroot, x, 'libc.so') for x in + ['lib', 'lib64', os.path.join('usr', 'lib'), os.path.join('usr', 'lib64')]] + for libc_so in libc_so_candidates: + if os.path.exists(libc_so): + # only patch gcc.c or gcc.cc if entries in libc.so are prefixed with sysroot + if '\nGROUP ( ' + sysroot in read_file(libc_so): + gccfile = os.path.join('gcc', 'gcc.c') + # renamed to gcc.cc in GCC 12 + if not os.path.exists(gccfile): + gccfile = os.path.join('gcc', 'gcc.cc') + # avoid that --sysroot is passed to linker by patching value for SYSROOT_SPEC in gcc/gcc.c* + apply_regex_substitutions(gccfile, [('--sysroot=%R', '')]) + break + # prefix dynamic linkers with sysroot # this patches lines like: # #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2" From cb078d85a9bb12c447a73577137fcd8d5568b819 Mon Sep 17 00:00:00 2001 From: Sebastian Achilles Date: Fri, 26 May 2023 11:40:45 +0200 Subject: [PATCH 300/325] prepare release notes for EasyBuild v4.7.2 + bump version to 4.7.2 --- RELEASE_NOTES | 17 +++++++++++++++++ easybuild/easyblocks/__init__.py | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 96346e430c..4210cd2941 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -5,6 +5,23 @@ These release notes can also be consulted at http://easybuild.readthedocs.org/en The latest version of easybuild-easyblocks provides 248 software-specific easyblocks and 39 generic easyblocks. +v4.7.2 (May 30th 2023) +---------------------- + +- new generic easyblock for installing Rust crates with cargo (#2902) +- minor enhancements and updates, including: + - let MATLAB easyblock raise an error if the MATLAB installation key is not provided (#2905) + - print message to inform that GPU package (instead of Kokkos) is used for LAMMPS (#2906) + - enhance PyTorch easyblock to use FlexiBLAS for PyTorch >= 1.11.0 (#2915) +- various bug fixes, including: + - use custom RPATH sanity check for Go packages that doesn't actually check for an RPATH section in the binary (#2913) + - use string '0' to avoid problems when openssl version is not determined (#2914) + - add output log to MATLAB installs, actually parse for common errors (#2924) + - enhance Gurobi easyblock to allow using $EB_GUROBI_LICENSE_FILE environment variable (#2926) + - force building torchvision with CUDA support if CUDA is included as dependency by setting `$FORCE_CUDA` (#2931) + - fix exec permission on files in arch bindir for COMSOL (#2932) + - enhance Cargo constructor to avoid processing list of crates multiple times into sources (#2934) + v4.7.1 (March 20th 2023) ------------------------ diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index fdd68d6024..f740a2523e 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.7.2.dev0') +VERSION = LooseVersion('4.7.2') UNKNOWN = 'UNKNOWN' From 7c7e756a17f5111ae83d1980d274f75f0e0b89d0 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 27 May 2023 11:24:43 +0200 Subject: [PATCH 301/325] minor tweaks for EasyBuild v4.7.2 in release notes + fix release date --- RELEASE_NOTES | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 4210cd2941..350cf6b031 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,12 +3,13 @@ For more detailed information, please see the git log. These release notes can also be consulted at http://easybuild.readthedocs.org/en/latest/Release_notes.html. -The latest version of easybuild-easyblocks provides 248 software-specific easyblocks and 39 generic easyblocks. +The latest version of easybuild-easyblocks provides 248 software-specific easyblocks and 41 generic easyblocks. -v4.7.2 (May 30th 2023) ----------------------- -- new generic easyblock for installing Rust crates with cargo (#2902) +v4.7.2 (27 May 2023) +-------------------- + +- new generic easyblock for installing Rust crates with cargo: Cargo and CargoPythonPackage (#2902, #2934) - minor enhancements and updates, including: - let MATLAB easyblock raise an error if the MATLAB installation key is not provided (#2905) - print message to inform that GPU package (instead of Kokkos) is used for LAMMPS (#2906) @@ -20,7 +21,6 @@ v4.7.2 (May 30th 2023) - enhance Gurobi easyblock to allow using $EB_GUROBI_LICENSE_FILE environment variable (#2926) - force building torchvision with CUDA support if CUDA is included as dependency by setting `$FORCE_CUDA` (#2931) - fix exec permission on files in arch bindir for COMSOL (#2932) - - enhance Cargo constructor to avoid processing list of crates multiple times into sources (#2934) v4.7.1 (March 20th 2023) ------------------------ From 42c96e4d81ee56ad8a2f308b3bd1c99745f6617f Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Sat, 27 May 2023 21:01:56 +0200 Subject: [PATCH 302/325] include #2921 in release notes for EasyBuild v4.7.2 --- RELEASE_NOTES | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 350cf6b031..f117aa07a1 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -17,6 +17,7 @@ v4.7.2 (27 May 2023) - various bug fixes, including: - use custom RPATH sanity check for Go packages that doesn't actually check for an RPATH section in the binary (#2913) - use string '0' to avoid problems when openssl version is not determined (#2914) + - update GCC easyblock to ensure that --sysroot is passed to linker (but only when it needs to be) (#2921) - add output log to MATLAB installs, actually parse for common errors (#2924) - enhance Gurobi easyblock to allow using $EB_GUROBI_LICENSE_FILE environment variable (#2926) - force building torchvision with CUDA support if CUDA is included as dependency by setting `$FORCE_CUDA` (#2931) From 98d696e39ff2adb676ce38b78c873dbcc5d2c674 Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Mon, 29 May 2023 16:06:27 +0200 Subject: [PATCH 303/325] fix incorrect sanity_check_step for torchvision. --- easybuild/easyblocks/t/torchvision.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/t/torchvision.py b/easybuild/easyblocks/t/torchvision.py index 7ef971a8b9..cfc5d840c2 100644 --- a/easybuild/easyblocks/t/torchvision.py +++ b/easybuild/easyblocks/t/torchvision.py @@ -28,7 +28,10 @@ @author: Alexander Grund (TU Dresden) @author: Kenneth Hoste (HPC-UGent) """ -from easybuild.easyblocks.generic.pythonpackage import PythonPackage + +import os + +from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pylibdir from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option from easybuild.tools.modules import get_software_version @@ -82,12 +85,14 @@ def configure_step(self): def sanity_check_step(self): """Custom sanity check for torchvision.""" - custom_commands = [] + custom_commands = None + custom_paths = None # check whether torchvision was indeed built with CUDA support, # cfr. https://discuss.pytorch.org/t/notimplementederror-could-not-run-torchvision-nms-with-arguments-from-\ # the-cuda-backend-this-could-be-because-the-operator-doesnt-exist-for-this-backend/132352/4 if self.with_cuda: + custom_commands = [] python_code = '; '.join([ "import torch, torchvision", "boxes = torch.tensor([[0., 1., 2., 3.]]).to('cuda')", @@ -95,5 +100,9 @@ def sanity_check_step(self): "print(torchvision.ops.nms(boxes, scores, 0.5))", ]) custom_commands.append('python -c "%s"' % python_code) + custom_paths = { + 'files': [], + 'dirs': [det_pylibdir()], + } - super(EB_torchvision, self).sanity_check_step(custom_commands=custom_commands) + return super(EB_torchvision, self).sanity_check_step(custom_commands=custom_commands, custom_paths=custom_paths) From a897e4524f72f78cb32c38131845a3dca82eca46 Mon Sep 17 00:00:00 2001 From: Ake Sandgren Date: Mon, 29 May 2023 16:09:44 +0200 Subject: [PATCH 304/325] drop import os which is not used --- easybuild/easyblocks/t/torchvision.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/easybuild/easyblocks/t/torchvision.py b/easybuild/easyblocks/t/torchvision.py index cfc5d840c2..5536b89139 100644 --- a/easybuild/easyblocks/t/torchvision.py +++ b/easybuild/easyblocks/t/torchvision.py @@ -28,9 +28,6 @@ @author: Alexander Grund (TU Dresden) @author: Kenneth Hoste (HPC-UGent) """ - -import os - from easybuild.easyblocks.generic.pythonpackage import PythonPackage, det_pylibdir from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option From e6f0c5dfafb97e1748ba74111f70f342fef46a67 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Tue, 30 May 2023 16:54:34 +0200 Subject: [PATCH 305/325] bump version to 4.7.3dev --- easybuild/easyblocks/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/__init__.py b/easybuild/easyblocks/__init__.py index f740a2523e..445fac1632 100644 --- a/easybuild/easyblocks/__init__.py +++ b/easybuild/easyblocks/__init__.py @@ -43,7 +43,7 @@ # recent setuptools versions will *TRANSFORM* something like 'X.Y.Zdev' into 'X.Y.Z.dev0', with a warning like # UserWarning: Normalizing '2.4.0dev' to '2.4.0.dev0' # This causes problems further up the dependency chain... -VERSION = LooseVersion('4.7.2') +VERSION = LooseVersion('4.7.3.dev0') UNKNOWN = 'UNKNOWN' From 995954c43be99f56c0351478a217a058b5e06097 Mon Sep 17 00:00:00 2001 From: Xin Wu Date: Tue, 30 May 2023 20:02:53 +0200 Subject: [PATCH 306/325] add support for NVIDIA Hopper CC 9.0 in LAMMPS --- easybuild/easyblocks/l/lammps.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/easybuild/easyblocks/l/lammps.py b/easybuild/easyblocks/l/lammps.py index d026696a4d..8b4b4dbe2e 100644 --- a/easybuild/easyblocks/l/lammps.py +++ b/easybuild/easyblocks/l/lammps.py @@ -86,6 +86,7 @@ 'TURING75', # NVIDIA Turing generation CC 7.5 GPU 'AMPERE80', # NVIDIA Ampere generation CC 8.0 GPU 'AMPERE86', # NVIDIA Ampere generation CC 8.6 GPU + 'HOPPER90', # NVIDIA Hopper generation CC 9.0 GPU 'VEGA900', # AMD GPU MI25 GFX900 'VEGA906', # AMD GPU MI50/MI60 GFX906 'VEGA908', # AMD GPU MI100 GFX908 @@ -135,6 +136,7 @@ '7.5': 'TURING75', # NVIDIA Turing generation CC 7.5 '8.0': 'AMPERE80', # NVIDIA Ampere generation CC 8.0 '8.6': 'AMPERE86', # NVIDIA Ampere generation CC 8.6 + '9.0': 'HOPPER90', # NVIDIA Hopper generation CC 9.0 } # lammps version, which caused the most changes. This may not be precise, but it does work with existing easyconfigs From e120a39060d7df2360ca8da7a3f2563ca3f0137b Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 1 Jun 2023 19:28:47 +0200 Subject: [PATCH 307/325] stop running tests with Python 2.7 since it is no longer supported in GitHub Actions --- .github/workflows/unit_tests.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index b5164b143b..b1cf6dc64a 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -13,12 +13,12 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11'] + python: [3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11'] modules_tool: [Lmod-6.6.3, Lmod-7.8.22, Lmod-8.1.14, modules-tcl-1.147, modules-3.2.10, modules-4.1.4] module_syntax: [Lua, Tcl] # exclude some configuration for non-Lmod modules tool: # - don't test with Lua module syntax (only supported in Lmod) - # - don't test with Python 3.5 and 3.7+ (only with 2.7 and 3.6), to limit test configurations + # - don't test with Python 3.5 and 3.7+ (only with 3.6), to limit test configurations exclude: - modules_tool: modules-tcl-1.147 module_syntax: Lua @@ -36,6 +36,8 @@ jobs: python: 3.9 - modules_tool: modules-tcl-1.147 python: '3.10' + - modules_tool: modules-tcl-1.147 + python: '3.11' - modules_tool: modules-3.2.10 python: 3.5 - modules_tool: modules-3.2.10 @@ -46,6 +48,8 @@ jobs: python: 3.9 - modules_tool: modules-3.2.10 python: '3.10' + - modules_tool: modules-3.2.10 + python: '3.11' - modules_tool: modules-4.1.4 python: 3.5 - modules_tool: modules-4.1.4 @@ -56,6 +60,8 @@ jobs: python: 3.9 - modules_tool: modules-4.1.4 python: '3.10' + - modules_tool: modules-4.1.4 + python: '3.11' fail-fast: false steps: - uses: actions/checkout@v2 From 2707ab7cf6f558699bda3edfea35284ec42b9050 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Fri, 2 Jun 2023 12:45:43 +0000 Subject: [PATCH 308/325] `make shared` is necessary and sufficient with 0.3.23 + xianyi/OpenBLAS#3983 --- easybuild/easyblocks/o/openblas.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/o/openblas.py b/easybuild/easyblocks/o/openblas.py index 9ce5034ba0..996dd280e1 100644 --- a/easybuild/easyblocks/o/openblas.py +++ b/easybuild/easyblocks/o/openblas.py @@ -70,10 +70,13 @@ def build_step(self): """ Custom build step excluding the tests """ # Equivalent to `make all` without the tests - build_parts = ['libs', 'netlib'] - for buildopt in self.cfg['buildopts'].split(): - if 'BUILD_RELAPACK' in buildopt and '1' in buildopt: - build_parts += ['re_lapack'] + build_parts = [] + if LooseVersion(self.version) < LooseVersion('0.3.23'): + build_parts += ['libs', 'netlib'] + for buildopt in self.cfg['buildopts'].split(): + if 'BUILD_RELAPACK' in buildopt and '1' in buildopt: + build_parts += ['re_lapack'] + # just shared is necessary and sufficient with 0.3.23 + xianyi/OpenBLAS#3983 build_parts += ['shared'] # Pass CFLAGS through command line to avoid redefinitions (issue xianyi/OpenBLAS#818) From a3057c6a0a177b604caf4098086b7cd5d09c1715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 5 Jun 2023 11:37:57 +0200 Subject: [PATCH 309/325] adding easyblocks: perlbundle.py --- easybuild/easyblocks/generic/perlbundle.py | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 easybuild/easyblocks/generic/perlbundle.py diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py new file mode 100644 index 0000000000..cbce05e239 --- /dev/null +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -0,0 +1,109 @@ +## +# Copyright 2018-2021 Ghent University +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for installing a bundle of Perl modules, implemented as a generic easyblock + +@author: Mikael Öhman (Chalmers University of Technology) +""" +import os +import sys + +from easybuild.easyblocks.generic.bundle import Bundle +from easybuild.easyblocks.generic.perlmodule import PerlModule +from easybuild.easyblocks.perl import EXTS_FILTER_PERL_MODULES, get_major_perl_version, get_site_suffix +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.config import build_option +from easybuild.tools.modules import get_software_root, get_software_version +from easybuild.tools.environment import setvar + + +class PerlBundle(Bundle): + """ + Bundle of perl modules + """ + + @staticmethod + def extra_options(): + """Easyconfig parameters specific to bundles of Perl modules.""" + # combine custom easyconfig parameters of Bundle & PerlModule + extra_vars = PerlModule.extra_options() + return Bundle.extra_options(extra_vars) + + def __init__(self, *args, **kwargs): + """Initialize PerlBundle easyblock.""" + super(PerlBundle, self).__init__(*args, **kwargs) + + self.cfg['exts_defaultclass'] = 'PerlModule' + self.cfg['exts_filter'] = EXTS_FILTER_PERL_MODULES + + def prepare_step(self, *args, **kwargs): + """Prepare for installing bundle of Perl packages.""" + super(Bundle, self).prepare_step(*args, **kwargs) + + perl_root = get_software_root('Perl') + if perl_root is None: + raise EasyBuildError("Perl not included as dependency!") + + def extensions_step(self, *args, **kwargs): + """Install extensions""" + + # define $OPENSSL_PREFIX to ensure that e.g. Net-SSLeay extension picks up OpenSSL + # from specified sysroot rather than from host OS + sysroot = build_option('sysroot') + if sysroot: + setvar('OPENSSL_PREFIX', sysroot) + + super(PerlBundle, self).extensions_step(*args, **kwargs) + + def test_step(self): + """No global test step for bundle of Perl modules.""" + # required since runtest is set to True by default + pass + + def sanity_check_step(self, *args, **kwargs): + """Custom sanity check for bundle of Perl modules.""" + + if not self.cfg['sanity_check_paths']: + majver = get_major_perl_version() + self.cfg['sanity_check_paths'] = { + 'files': [], + 'dirs': [os.path.join('lib', 'perl%s' % self.majver)], + } + + super(Bundle, self).sanity_check_step(*args, **kwargs) + + def make_module_req_guess(self): + """Customized dictionary of paths to look for with PERL*LIB.""" + majver = get_major_perl_version() + sitearchsuffix = get_site_suffix('sitearch') + sitelibsuffix = get_site_suffix('sitelib') + + print(sitelibsuffix) + print(sitearchsuffix) + guesses = super(Bundle, self).make_module_req_guess() + guesses.update({ + "PERL%sLIB" % majver: ['', sitearchsuffix, sitelibsuffix], + }) + return guesses From 9e3124dd0053c0fef229939db2a449c1deae91ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 5 Jun 2023 11:39:38 +0200 Subject: [PATCH 310/325] Fix hound --- easybuild/easyblocks/generic/perlbundle.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py index cbce05e239..3c96a3f6d5 100644 --- a/easybuild/easyblocks/generic/perlbundle.py +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -28,14 +28,13 @@ @author: Mikael Öhman (Chalmers University of Technology) """ import os -import sys from easybuild.easyblocks.generic.bundle import Bundle from easybuild.easyblocks.generic.perlmodule import PerlModule from easybuild.easyblocks.perl import EXTS_FILTER_PERL_MODULES, get_major_perl_version, get_site_suffix from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option -from easybuild.tools.modules import get_software_root, get_software_version +from easybuild.tools.modules import get_software_root from easybuild.tools.environment import setvar @@ -89,7 +88,7 @@ def sanity_check_step(self, *args, **kwargs): majver = get_major_perl_version() self.cfg['sanity_check_paths'] = { 'files': [], - 'dirs': [os.path.join('lib', 'perl%s' % self.majver)], + 'dirs': [os.path.join('lib', 'perl%s' % majver)], } super(Bundle, self).sanity_check_step(*args, **kwargs) From 4a8464f0a3a749b55190967c48b8db9b07d26e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 5 Jun 2023 19:12:21 +0200 Subject: [PATCH 311/325] Improve cargo optarch flags --- easybuild/easyblocks/generic/cargo.py | 35 ++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index b511b851bc..9275aeed91 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -58,6 +58,36 @@ def extra_options(extra_vars=None): return extra_vars + def rustc_optarch(self): + """Determines what architecture to target. + Translates GENERIC optarch, and respects rustc specific optarch. + General optarchs are ignored as there is no direct translation. + """ + if systemtools.X86_64 == systemtools.get_cpu_architecture(): + generic = '-C target-cpu=x86-64' + else: + generic = '-C target-cpu=generic' + + optimal = '-C target-cpu=native' + + optarch = build_option('optarch') + if optarch: + if type(optarch) == dict: + if 'rustc' in optarch: + rust_optarch = optarch['rustc'] + if rust_optarch == OPTARCH_GENERIC: + return generic + else: + return '-' + rust_optarch + else: + if optarch == OPTARCH_GENERIC: + return generic + else: + self.log.warning("optarch is ignored as there is no translation for rustc") + return optimal + else: + return optimal + def __init__(self, *args, **kwargs): """Constructor for Cargo easyblock.""" super(Cargo, self).__init__(*args, **kwargs) @@ -66,10 +96,7 @@ def __init__(self, *args, **kwargs): env.setvar('RUSTC', 'rustc') env.setvar('RUSTDOC', 'rustdoc') env.setvar('RUSTFMT', 'rustfmt') - optarch = build_option('optarch') - if not optarch: - optarch = 'native' - env.setvar('RUSTFLAGS', '-C target-cpu=%s' % optarch) + env.setvar('RUSTFLAGS', self.rustc_optarch()) env.setvar('RUST_LOG', 'DEBUG') env.setvar('RUST_BACKTRACE', '1') From 3ce91feb0e5b5542b1d160fe3781e7946ecbf025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 5 Jun 2023 19:28:32 +0200 Subject: [PATCH 312/325] Fix imports --- easybuild/easyblocks/generic/cargo.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 9275aeed91..4ca50be02b 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -31,6 +31,7 @@ import os import easybuild.tools.environment as env +import easybuild.tools.systemtools as systemtools from easybuild.tools.build_log import EasyBuildError from easybuild.framework.easyconfig import CUSTOM from easybuild.framework.extensioneasyblock import ExtensionEasyBlock @@ -38,6 +39,7 @@ from easybuild.tools.run import run_cmd from easybuild.tools.config import build_option from easybuild.tools.filetools import write_file, compute_checksum +from easybuild.tools.toolchain.compiler import OPTARCH_GENERIC CRATESIO_SOURCE = "https://crates.io/api/v1/crates" @@ -67,7 +69,7 @@ def rustc_optarch(self): generic = '-C target-cpu=x86-64' else: generic = '-C target-cpu=generic' - + optimal = '-C target-cpu=native' optarch = build_option('optarch') From 1c89273ba0d50fdc35a3aa97fe59111244886be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 5 Jun 2023 19:30:05 +0200 Subject: [PATCH 313/325] Drop strict perl requirement --- easybuild/easyblocks/generic/perlbundle.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py index 3c96a3f6d5..ed8c63eae6 100644 --- a/easybuild/easyblocks/generic/perlbundle.py +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -57,14 +57,6 @@ def __init__(self, *args, **kwargs): self.cfg['exts_defaultclass'] = 'PerlModule' self.cfg['exts_filter'] = EXTS_FILTER_PERL_MODULES - def prepare_step(self, *args, **kwargs): - """Prepare for installing bundle of Perl packages.""" - super(Bundle, self).prepare_step(*args, **kwargs) - - perl_root = get_software_root('Perl') - if perl_root is None: - raise EasyBuildError("Perl not included as dependency!") - def extensions_step(self, *args, **kwargs): """Install extensions""" From 34c10c703f5a37812a689e331e71f4e312e16edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Mon, 5 Jun 2023 19:36:38 +0200 Subject: [PATCH 314/325] Remove unused imports --- easybuild/easyblocks/generic/perlbundle.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py index ed8c63eae6..fcc753214e 100644 --- a/easybuild/easyblocks/generic/perlbundle.py +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -32,9 +32,7 @@ from easybuild.easyblocks.generic.bundle import Bundle from easybuild.easyblocks.generic.perlmodule import PerlModule from easybuild.easyblocks.perl import EXTS_FILTER_PERL_MODULES, get_major_perl_version, get_site_suffix -from easybuild.tools.build_log import EasyBuildError from easybuild.tools.config import build_option -from easybuild.tools.modules import get_software_root from easybuild.tools.environment import setvar From c9d847a3a0456c4a5b9cdb4371c652c1fc6da69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Tue, 6 Jun 2023 00:31:49 +0200 Subject: [PATCH 315/325] Fix rust optarch logic when optarch isn't specified for compiler --- easybuild/easyblocks/generic/cargo.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 4ca50be02b..996e54c137 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -86,9 +86,7 @@ def rustc_optarch(self): return generic else: self.log.warning("optarch is ignored as there is no translation for rustc") - return optimal - else: - return optimal + return optimal def __init__(self, *args, **kwargs): """Constructor for Cargo easyblock.""" From 7f168eb0c4e31bed23903ec99208d3cf3c9662a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 8 Jun 2023 14:21:47 +0200 Subject: [PATCH 316/325] Update easybuild/easyblocks/generic/cargo.py Co-authored-by: Simon Branford <4967+branfosj@users.noreply.github.com> --- easybuild/easyblocks/generic/cargo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 996e54c137..a16ce70797 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -81,6 +81,7 @@ def rustc_optarch(self): return generic else: return '-' + rust_optarch + self.log.info("no rustc information in the optarch dict, so using %s" % optimal) else: if optarch == OPTARCH_GENERIC: return generic From f0f903c2c22d4214f4bc25b316dc3211faf538cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Thu, 8 Jun 2023 14:21:54 +0200 Subject: [PATCH 317/325] Update easybuild/easyblocks/generic/cargo.py Co-authored-by: Simon Branford <4967+branfosj@users.noreply.github.com> --- easybuild/easyblocks/generic/cargo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index a16ce70797..56cda395fb 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -86,7 +86,7 @@ def rustc_optarch(self): if optarch == OPTARCH_GENERIC: return generic else: - self.log.warning("optarch is ignored as there is no translation for rustc") + self.log.warning("optarch is ignored as there is no translation for rustc, so using %s" % optimal) return optimal def __init__(self, *args, **kwargs): From 0edd5ae16685ecb733879d911a8d74248a8a6999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Fri, 9 Jun 2023 11:41:25 +0200 Subject: [PATCH 318/325] Use fixed modextrapaths --- easybuild/easyblocks/generic/perlbundle.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py index fcc753214e..be525f71ad 100644 --- a/easybuild/easyblocks/generic/perlbundle.py +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -83,16 +83,11 @@ def sanity_check_step(self, *args, **kwargs): super(Bundle, self).sanity_check_step(*args, **kwargs) - def make_module_req_guess(self): - """Customized dictionary of paths to look for with PERL*LIB.""" + def make_module_extra(self): + """Extra module entries for Perl bundles.""" majver = get_major_perl_version() - sitearchsuffix = get_site_suffix('sitearch') - sitelibsuffix = get_site_suffix('sitelib') - - print(sitelibsuffix) - print(sitearchsuffix) - guesses = super(Bundle, self).make_module_req_guess() - guesses.update({ - "PERL%sLIB" % majver: ['', sitearchsuffix, sitelibsuffix], - }) - return guesses + sitelibsuffix = get_site_suffix('sitelib') # use this! + + txt = super(Bundle, self).make_module_extra() + txt += self.module_generator.prepend_paths("PERL%sLIB" % majver, [sitelibsuffix]) + return txt From 326b14612551255dc125365a8c3fd498e74ada99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Sun, 11 Jun 2023 15:53:40 +0200 Subject: [PATCH 319/325] Add arch path as well --- easybuild/easyblocks/generic/perlbundle.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py index be525f71ad..78d57cd629 100644 --- a/easybuild/easyblocks/generic/perlbundle.py +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -86,8 +86,9 @@ def sanity_check_step(self, *args, **kwargs): def make_module_extra(self): """Extra module entries for Perl bundles.""" majver = get_major_perl_version() - sitelibsuffix = get_site_suffix('sitelib') # use this! + sitearchsuffix = get_site_suffix('sitearch') # Some parl modules use this path instead. + sitelibsuffix = get_site_suffix('sitelib') txt = super(Bundle, self).make_module_extra() - txt += self.module_generator.prepend_paths("PERL%sLIB" % majver, [sitelibsuffix]) + txt += self.module_generator.prepend_paths("PERL%sLIB" % majver, [sitelibsuffix, sitearchsuffix]) return txt From ab1c8927d38fefa0803f04a48e587b0d61b61da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20=C3=96hman?= Date: Sun, 11 Jun 2023 17:13:09 +0200 Subject: [PATCH 320/325] Use only correct perl_lib path --- easybuild/easyblocks/generic/perlbundle.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py index 78d57cd629..747d518439 100644 --- a/easybuild/easyblocks/generic/perlbundle.py +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -31,7 +31,7 @@ from easybuild.easyblocks.generic.bundle import Bundle from easybuild.easyblocks.generic.perlmodule import PerlModule -from easybuild.easyblocks.perl import EXTS_FILTER_PERL_MODULES, get_major_perl_version, get_site_suffix +from easybuild.easyblocks.perl import get_major_perl_version, get_site_suffix from easybuild.tools.config import build_option from easybuild.tools.environment import setvar @@ -53,11 +53,12 @@ def __init__(self, *args, **kwargs): super(PerlBundle, self).__init__(*args, **kwargs) self.cfg['exts_defaultclass'] = 'PerlModule' - self.cfg['exts_filter'] = EXTS_FILTER_PERL_MODULES + self.cfg['exts_filter'] = ("perl -e 'require %(ext_name)s'", '') def extensions_step(self, *args, **kwargs): """Install extensions""" + setvar('INSTALLDIRS', 'site') # define $OPENSSL_PREFIX to ensure that e.g. Net-SSLeay extension picks up OpenSSL # from specified sysroot rather than from host OS sysroot = build_option('sysroot') @@ -86,9 +87,8 @@ def sanity_check_step(self, *args, **kwargs): def make_module_extra(self): """Extra module entries for Perl bundles.""" majver = get_major_perl_version() - sitearchsuffix = get_site_suffix('sitearch') # Some parl modules use this path instead. sitelibsuffix = get_site_suffix('sitelib') txt = super(Bundle, self).make_module_extra() - txt += self.module_generator.prepend_paths("PERL%sLIB" % majver, [sitelibsuffix, sitearchsuffix]) + txt += self.module_generator.prepend_paths("PERL%sLIB" % majver, [sitelibsuffix]) return txt From 476da8f0ebe08ec2219116c27078b42c03dc026a Mon Sep 17 00:00:00 2001 From: Maxime Boissonneault Date: Mon, 19 Jun 2023 21:18:41 +0000 Subject: [PATCH 321/325] reset modules loaded by PythonPackage to let ExtensionEasyBlock handle multideps correctly --- easybuild/easyblocks/generic/pythonpackage.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/easybuild/easyblocks/generic/pythonpackage.py b/easybuild/easyblocks/generic/pythonpackage.py index 3e5e5e3a02..412d005270 100644 --- a/easybuild/easyblocks/generic/pythonpackage.py +++ b/easybuild/easyblocks/generic/pythonpackage.py @@ -923,6 +923,12 @@ def sanity_check_step(self, *args, **kwargs): else: raise EasyBuildError("Failed to determine pip version!") + # ExtensionEasyBlock handles loading modules correctly for multi_deps, so we clean up fake_mod_data + # and let ExtensionEasyBlock do its job + if 'Python' in self.cfg["multi_deps"] and self.fake_mod_data: + self.clean_up_fake_module(self.fake_mod_data) + self.sanity_check_module_loaded = False + parent_success, parent_fail_msg = super(PythonPackage, self).sanity_check_step(*args, **kwargs) if parent_fail_msg: From 2a6becb8a8748952a69324670ca4eb19c693cb85 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 21 Jun 2023 09:36:56 +0200 Subject: [PATCH 322/325] fix year in copyright line in license header of PerlBundle easyblock --- easybuild/easyblocks/generic/perlbundle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easybuild/easyblocks/generic/perlbundle.py b/easybuild/easyblocks/generic/perlbundle.py index 747d518439..fcb5ce48f8 100644 --- a/easybuild/easyblocks/generic/perlbundle.py +++ b/easybuild/easyblocks/generic/perlbundle.py @@ -1,5 +1,5 @@ ## -# Copyright 2018-2021 Ghent University +# Copyright 2018-2023 Ghent University # # This file is part of EasyBuild, # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), From 00965cc0fd5cfcec279be213529e7a89ab238c9f Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Wed, 21 Jun 2023 16:44:36 +0200 Subject: [PATCH 323/325] add custom easyblock for Rust --- easybuild/easyblocks/r/rust.py | 82 ++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 easybuild/easyblocks/r/rust.py diff --git a/easybuild/easyblocks/r/rust.py b/easybuild/easyblocks/r/rust.py new file mode 100644 index 0000000000..15700eafd5 --- /dev/null +++ b/easybuild/easyblocks/r/rust.py @@ -0,0 +1,82 @@ +## +# Copyright 2023-2023 Ghent University +# +# This file is part of EasyBuild, +# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), +# with support of Ghent University (http://ugent.be/hpc), +# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), +# Flemish Research Foundation (FWO) (http://www.fwo.be/en) +# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). +# +# https://github.com/easybuilders/easybuild +# +# EasyBuild is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation v2. +# +# EasyBuild is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with EasyBuild. If not, see . +## +""" +EasyBuild support for building and installing Rust, implemented as an easyblock + +@author: Kenneth Hoste (Ghent University) +""" +import os + +from easybuild.easyblocks.generic.configuremake import ConfigureMake + + +class EB_Rust(ConfigureMake): + """Support for building/installing Rust.""" + + def __init__(self, *args, **kwargs): + """Custom easyblock constructor for Rust.""" + super(EB_Rust, self).__init__(*args, **kwargs) + + # see https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#what-is-xpy + # note: ConfigureMake.build_step automatically adds '-j ' + self.cfg['build_cmd'] = "./x.py build" + self.cfg['install_cmd'] = "./x.py install -j %(parallel)s" + + def configure_step(self): + """Custom configure step for Rust""" + + # perform extended build, which includes cargo, rustfmt, Rust Language Server (RLS), etc. + self.cfg.update('configopts', "--enable-extended") + + self.cfg.update('configopts', "--sysconfdir=%s" % os.path.join(self.installdir, 'etc')) + + # don't use Ninja if it is not listed as a build dependency; + # may be because Ninja requires Python, and Rust is a build dependency for cryptography + # which may be included as an extension with Python + build_dep_names = set(dep['name'] for dep in self.cfg.dependencies(build_only=True)) + if 'Ninja' not in build_dep_names: + self.cfg.update('configopts', "--set=llvm.ninja=false") + + super(EB_Rust, self).configure_step() + + # avoid failure when home directory is an NFS mount, + # see https://github.com/rust-lang/cargo/issues/6652 + cargo_home = "export CARGO_HOME=%s && " % os.path.join(self.builddir, 'cargo') + self.cfg.update('prebuildopts', cargo_home) + self.cfg.update('preinstallopts', cargo_home) + + def sanity_check_step(self): + """Custom sanity check for Rust""" + + custom_paths = { + 'files': ['bin/cargo', 'bin/rustc', 'bin/rustdoc'], + 'dirs': ['lib/rustlib', 'share/doc', 'share/man'], + } + + custom_commands = [ + "cargo --version", + "rustc --version", + ] + return super(EB_Rust, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands) From 6c34f0579f8195aa31f88da36cb16aaf4ced0ff0 Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 22 Jun 2023 14:47:46 +0200 Subject: [PATCH 324/325] update Rust easyblock to enforce RPATH for shared libraries when --rpath is used --- easybuild/easyblocks/r/rust.py | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/easybuild/easyblocks/r/rust.py b/easybuild/easyblocks/r/rust.py index 15700eafd5..ee66f6854e 100644 --- a/easybuild/easyblocks/r/rust.py +++ b/easybuild/easyblocks/r/rust.py @@ -27,10 +27,17 @@ @author: Kenneth Hoste (Ghent University) """ +import glob import os +import re from easybuild.easyblocks.generic.configuremake import ConfigureMake +from easybuild.tools.build_log import EasyBuildError +from easybuild.tools.config import build_option +from easybuild.tools.run import run_cmd +from easybuild.tools.systemtools import get_shared_lib_ext + class EB_Rust(ConfigureMake): """Support for building/installing Rust.""" @@ -67,6 +74,41 @@ def configure_step(self): self.cfg.update('prebuildopts', cargo_home) self.cfg.update('preinstallopts', cargo_home) + def install_step(self): + """Custom install step for Rust""" + + super(EB_Rust, self).install_step() + + if build_option('rpath'): + # make sure that all shared libraries use RPATH, not RUNPATH; + # cfr. https://github.com/easybuilders/easybuild-easyconfigs/issues/18079 + shlib_ext = get_shared_lib_ext() + shared_libs = glob.glob(os.path.join(self.installdir, 'lib', 'lib*.%s' % shlib_ext)) + + runpath_regex = re.compile(r"\(RUNPATH\)\s+Library runpath") + + for shared_lib in shared_libs: + out, ec = run_cmd("readelf -d %s" % shared_lib, simple=False, trace=False) + if ec: + raise EasyBuildError("Failed to check RPATH section in %s: %s", shared_lib, out) + elif runpath_regex.search(out): + self.log.info("RUNPATH section found in %s - need to change to RPATH", shared_lib) + + # first determine current RUNPATH value + out, ec = run_cmd("patchelf --print-rpath %s" % shared_lib) + if ec: + raise EasyBuildError("Failed to determine current RUNPATH value for %s: %s", shared_lib, out) + else: + runpath = out.strip() + # use RUNPATH value to RPATH value + out, ec = run_cmd("patchelf --set-rpath '%s' --force-rpath %s" % (runpath, shared_lib)) + if ec: + raise EasyBuildError("Failed to set RPATH for %s: %s", shared_lib, out) + else: + self.log.info("RPATH set for %s", shared_lib) + else: + self.log.info("No RUNPATH section found in %s", shared_lib) + def sanity_check_step(self): """Custom sanity check for Rust""" From 94d28c556947bd96d0978df775b15a50a4600c6f Mon Sep 17 00:00:00 2001 From: Kenneth Hoste Date: Thu, 22 Jun 2023 18:44:59 +0200 Subject: [PATCH 325/325] add support for `install_cmds` in `Binary` easyblock --- easybuild/easyblocks/generic/binary.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/easybuild/easyblocks/generic/binary.py b/easybuild/easyblocks/generic/binary.py index 66ec571dea..d9ff3a5bb7 100644 --- a/easybuild/easyblocks/generic/binary.py +++ b/easybuild/easyblocks/generic/binary.py @@ -59,6 +59,7 @@ def extra_options(extra_vars=None): extra_vars.update({ 'extract_sources': [False, "Whether or not to extract sources", CUSTOM], 'install_cmd': [None, "Install command to be used.", CUSTOM], + 'install_cmds': [None, "List of install commands to be used.", CUSTOM], # staged installation can help with the hard (potentially faulty) check on available disk space 'staged_install': [False, "Perform staged installation via subdirectory of build directory", CUSTOM], 'prepend_to_path': [PREPEND_TO_PATH_DEFAULT, "Prepend the given directories (relative to install-dir) to " @@ -104,7 +105,9 @@ def build_step(self): def install_step(self): """Copy all files in build directory to the install directory""" install_cmd = self.cfg.get('install_cmd', None) - if install_cmd is None: + install_cmds = self.cfg.get('install_cmds', []) + + if install_cmd is None and install_cmds is None: try: # shutil.copytree doesn't allow the target directory to exist already remove_dir(self.installdir) @@ -112,9 +115,21 @@ def install_step(self): except OSError as err: raise EasyBuildError("Failed to copy %s to %s: %s", self.cfg['start_dir'], self.installdir, err) else: - cmd = ' '.join([self.cfg['preinstallopts'], install_cmd, self.cfg['installopts']]) - self.log.info("Installing %s using command '%s'..." % (self.name, cmd)) - run_cmd(cmd, log_all=True, simple=True) + if install_cmd: + if not install_cmds: + install_cmds = [install_cmd] + install_cmd = None + else: + raise EasyBuildError("Don't use both install_cmds and install_cmd, pick one!") + + if isinstance(install_cmds, (list, tuple)): + for install_cmd in install_cmds: + cmd = ' '.join([self.cfg['preinstallopts'], install_cmd, self.cfg['installopts']]) + self.log.info("Running install command for %s: '%s'..." % (self.name, cmd)) + run_cmd(cmd, log_all=True, simple=True) + else: + raise EasyBuildError("Incorrect value type for install_cmds, should be list or tuple: ", + install_cmds) def post_install_step(self): """Copy installation to actual installation directory in case of a staged installation."""