diff --git a/easybuild/easyblocks/a/adf.py b/easybuild/easyblocks/a/adf.py index 634c5d4f81a..7a35f73c889 100644 --- a/easybuild/easyblocks/a/adf.py +++ b/easybuild/easyblocks/a/adf.py @@ -80,7 +80,7 @@ def install_step(self): except OSError as err: raise EasyBuildError("Failed to copy %s to %s: %s", src_init_path, target_init_path, err) - cmd = "./bin/foray -j %d" % self.cfg['parallel'] + cmd = f"./bin/foray -j {self.cfg.parallel}" run_shell_cmd(cmd) def sanity_check_step(self): diff --git a/easybuild/easyblocks/a/aomp.py b/easybuild/easyblocks/a/aomp.py index 58ab38187ce..99c4673651a 100644 --- a/easybuild/easyblocks/a/aomp.py +++ b/easybuild/easyblocks/a/aomp.py @@ -85,11 +85,7 @@ def configure_step(self): 'AOMP_APPLY_ROCM_PATCHES=0', 'AOMP_STANDALONE_BUILD=1', ] - if self.cfg['parallel']: - install_options.append( - 'NUM_THREADS={!s}'.format(self.cfg['parallel'])) - else: - install_options.append('NUM_THREADS=1') + install_options.append(f'NUM_THREADS={self.cfg.parallel}') # Check if CUDA is loaded and alternatively build CUDA backend if get_software_root('CUDA') or get_software_root('CUDAcore'): cuda_root = get_software_root('CUDA') or get_software_root('CUDAcore') diff --git a/easybuild/easyblocks/b/bazel.py b/easybuild/easyblocks/b/bazel.py index f9269c834e0..e45c6ee605a 100644 --- a/easybuild/easyblocks/b/bazel.py +++ b/easybuild/easyblocks/b/bazel.py @@ -158,7 +158,7 @@ def configure_step(self): ]) # enable building in parallel - bazel_args = '--jobs=%d' % self.cfg['parallel'] + bazel_args = f'--jobs={self.cfg.parallel}' # Bazel provides a JDK by itself for some architectures # We want to enforce it using the JDK we provided via modules @@ -206,7 +206,7 @@ def test_step(self): # Avoid bazel using $HOME '--output_user_root=%s' % self.output_user_root, runtest, - '--jobs=%d' % self.cfg['parallel'], + f'--jobs={self.cfg.parallel}', '--host_javabase=@local_jdk//:jdk', # Be more verbose '--subcommands', '--verbose_failures', diff --git a/easybuild/easyblocks/b/berkeleygw.py b/easybuild/easyblocks/b/berkeleygw.py index fb6975a3e0e..b7d28798042 100644 --- a/easybuild/easyblocks/b/berkeleygw.py +++ b/easybuild/easyblocks/b/berkeleygw.py @@ -62,7 +62,7 @@ def configure_step(self): def build_step(self): """Custom build step for BerkeleyGW.""" - self.cfg['parallel'] = 1 + self.cfg.parallel = 1 self.cfg['buildopts'] = 'all-flavors' diff --git a/easybuild/easyblocks/b/boost.py b/easybuild/easyblocks/b/boost.py index 5e302152478..e6d3981a829 100644 --- a/easybuild/easyblocks/b/boost.py +++ b/easybuild/easyblocks/b/boost.py @@ -227,8 +227,8 @@ def build_step(self): self.bjamoptions += " -s%s_INCLUDE=%s/include" % (lib.upper(), libroot) self.bjamoptions += " -s%s_LIBPATH=%s/lib" % (lib.upper(), libroot) - if self.cfg['parallel']: - self.paracmd = "-j %s" % self.cfg['parallel'] + if self.cfg.parallel > 1: + self.paracmd = f"-j {self.cfg.parallel}" else: self.paracmd = '' diff --git a/easybuild/easyblocks/c/clang.py b/easybuild/easyblocks/c/clang.py index 7e677345b46..6c700b08741 100644 --- a/easybuild/easyblocks/c/clang.py +++ b/easybuild/easyblocks/c/clang.py @@ -124,7 +124,6 @@ def __init__(self, *args, **kwargs): self.llvm_obj_dir_stage1 = None self.llvm_obj_dir_stage2 = None self.llvm_obj_dir_stage3 = None - self.make_parallel_opts = "" self.runtime_lib_path = "lib" # Bypass the .mod file check for GCCcore installs @@ -404,9 +403,6 @@ def configure_step(self): self.cfg.update('configopts', '-DLLVM_TARGETS_TO_BUILD="%s"' % ';'.join(build_targets)) - if self.cfg['parallel']: - self.make_parallel_opts = "-j %s" % self.cfg['parallel'] - # If hwloc is included as a dep, use it in OpenMP runtime for affinity hwloc_root = get_software_root('hwloc') if hwloc_root: @@ -554,7 +550,7 @@ def build_with_prev_stage(self, prev_obj, next_obj): run_shell_cmd("cmake %s %s" % (' '.join(options), self.llvm_src_dir)) self.log.info("Building") - run_shell_cmd("make %s VERBOSE=1" % self.make_parallel_opts) + run_shell_cmd(f"make {self.parallel_flag} VERBOSE=1") # restore $PATH setvar('PATH', orig_path) @@ -581,7 +577,7 @@ def test_step(self): change_dir(self.llvm_obj_dir_stage3) else: change_dir(self.llvm_obj_dir_stage1) - run_shell_cmd("make %s check-all" % self.make_parallel_opts) + run_shell_cmd(f"make {self.parallel_flag} check-all") def install_step(self): """Install stage 3 binaries.""" diff --git a/easybuild/easyblocks/c/cp2k.py b/easybuild/easyblocks/c/cp2k.py index aa79e89bba9..8251194b100 100644 --- a/easybuild/easyblocks/c/cp2k.py +++ b/easybuild/easyblocks/c/cp2k.py @@ -669,18 +669,17 @@ def build_step(self): change_dir(makefiles) # modify makefile for parallel build - parallel = self.cfg['parallel'] - if parallel: - + parallel = self.cfg.parallel + if parallel > 1: try: for line in fileinput.input('Makefile', inplace=1, backup='.orig.patchictce'): - line = re.sub(r"^PMAKE\s*=.*$", "PMAKE\t= $(SMAKE) -j %s" % parallel, line) + line = re.sub(r"^PMAKE\s*=.*$", f"PMAKE\t= $(SMAKE) -j {parallel}", line) sys.stdout.write(line) except IOError as err: raise EasyBuildError("Can't modify/write Makefile in %s: %s", makefiles, err) # update make options with MAKE - self.cfg.update('buildopts', 'MAKE="make -j %s"' % self.cfg['parallel']) + self.cfg.update('buildopts', f'MAKE="make -j {self.cfg.parallel}"') # update make options with ARCH and VERSION self.cfg.update('buildopts', 'ARCH=%s VERSION=%s' % (self.typearch, self.cfg['type'])) @@ -757,7 +756,7 @@ def test_step(self): self.log.info("No reference output found for regression test, just continuing without it...") # prefer using 4 cores, since some tests require/prefer square (n^2) numbers or powers of 2 (2^n) - test_core_cnt = min(self.cfg['parallel'], 4) + test_core_cnt = min(self.cfg.parallel, 4) if get_avail_core_count() < test_core_cnt: raise EasyBuildError("Cannot run MPI tests as not enough cores (< %s) are available", test_core_cnt) else: diff --git a/easybuild/easyblocks/d/dm_reverb.py b/easybuild/easyblocks/d/dm_reverb.py index 225a0e79195..b94ba015f78 100644 --- a/easybuild/easyblocks/d/dm_reverb.py +++ b/easybuild/easyblocks/d/dm_reverb.py @@ -91,7 +91,7 @@ def build_step(self, *args, **kwargs): # use JDK from EB bazel_build_opts += " --host_javabase=@local_jdk//:jdk" # explicitly set the number of processes - bazel_build_opts += " --jobs=%d" % self.cfg['parallel'] + bazel_build_opts += f" --jobs={self.cfg.parallel}" # print full compilation commands bazel_build_opts += " --subcommands" diff --git a/easybuild/easyblocks/f/flook.py b/easybuild/easyblocks/f/flook.py index 987f979ad86..93c9b047f92 100644 --- a/easybuild/easyblocks/f/flook.py +++ b/easybuild/easyblocks/f/flook.py @@ -55,7 +55,7 @@ def __init__(self, *args, **kwargs): else: local_comp_flags = 'FFLAGS="$FFLAGS" CFLAGS="$CFLAGS"' self.cfg.update('buildopts', 'liball %s' % local_comp_flags) - self.cfg['parallel'] = 1 + self.cfg.parallel = 1 def configure_step(self): # flook has no configure step diff --git a/easybuild/easyblocks/g/gamess_us.py b/easybuild/easyblocks/g/gamess_us.py index 2d879382630..a1717d448de 100644 --- a/easybuild/easyblocks/g/gamess_us.py +++ b/easybuild/easyblocks/g/gamess_us.py @@ -427,11 +427,11 @@ def test_step(self): return # MPI builds can only run tests that support parallel execution - if int(self.cfg['parallel']) < 2: + if self.cfg.parallel < 2: self.log.info("Skipping testing of GAMESS-US as MPI tests need at least 2 CPU cores to run") return - test_procs = str(self.cfg['parallel']) + test_procs = str(self.cfg.parallel) target_tests = [exam for exam in target_tests if exam[0] not in GAMESS_SERIAL_TESTS] if self.toolchain.mpi_family() == toolchain.INTELMPI: diff --git a/easybuild/easyblocks/g/gcc.py b/easybuild/easyblocks/g/gcc.py index d4e207ef657..4e120fbaae1 100644 --- a/easybuild/easyblocks/g/gcc.py +++ b/easybuild/easyblocks/g/gcc.py @@ -741,8 +741,8 @@ def build_step(self): # make and install stage 1 build of GCC paracmd = '' - if self.cfg['parallel']: - paracmd = "-j %s" % self.cfg['parallel'] + if self.cfg.parallel > 1: + paracmd = f"-j {self.cfg.parallel}" cmd = "%s make %s %s" % (self.cfg['prebuildopts'], paracmd, self.cfg['buildopts']) run_shell_cmd(cmd) diff --git a/easybuild/easyblocks/g/gromacs.py b/easybuild/easyblocks/g/gromacs.py index 6e078a6851e..a11b9ba16a0 100644 --- a/easybuild/easyblocks/g/gromacs.py +++ b/easybuild/easyblocks/g/gromacs.py @@ -299,12 +299,12 @@ def configure_step(self): mpi_numprocs = self.cfg.get('mpi_numprocs', 0) if mpi_numprocs == 0: self.log.info("No number of test MPI tasks specified -- using default: %s", - self.cfg['parallel']) - mpi_numprocs = self.cfg['parallel'] + self.cfg.parallel) + mpi_numprocs = self.cfg.parallel - elif mpi_numprocs > self.cfg['parallel']: + elif mpi_numprocs > self.cfg.parallel: self.log.warning("Number of test MPI tasks (%s) is greater than value for 'parallel': %s", - mpi_numprocs, self.cfg['parallel']) + mpi_numprocs, self.cfg.parallel) mpiexec = self.cfg.get('mpiexec') if mpiexec: @@ -511,7 +511,7 @@ def test_step(self): # run 'make check' or whatever the easyconfig specifies # in parallel since it involves more compilation - self.cfg.update('runtest', "-j %s" % self.cfg['parallel']) + self.cfg.update('runtest', f"-j {self.cfg.parallel}") super(EB_GROMACS, self).test_step() if build_option('rpath'): @@ -535,7 +535,7 @@ def install_step(self): self.log.info("skipping install step") else: # run 'make install' in parallel since it involves more compilation - self.cfg.update('installopts', "-j %s" % self.cfg['parallel']) + self.cfg.update('installopts', f"-j {self.cfg.parallel}") super(EB_GROMACS, self).install_step() def extensions_step(self, fetch=False): diff --git a/easybuild/easyblocks/generic/cargo.py b/easybuild/easyblocks/generic/cargo.py index 4b3d9132ed5..89401365fd8 100644 --- a/easybuild/easyblocks/generic/cargo.py +++ b/easybuild/easyblocks/generic/cargo.py @@ -356,8 +356,8 @@ def profile(self): def build_step(self): """Build with cargo""" parallel = '' - if self.cfg['parallel']: - parallel = "-j %s" % self.cfg['parallel'] + if self.cfg.parallel > 1: + parallel = f"-j {self.cfg.parallel}" tests = '' if self.cfg['enable_tests']: diff --git a/easybuild/easyblocks/generic/configuremake.py b/easybuild/easyblocks/generic/configuremake.py index e00941fd80b..408595ac467 100644 --- a/easybuild/easyblocks/generic/configuremake.py +++ b/easybuild/easyblocks/generic/configuremake.py @@ -210,6 +210,11 @@ def __init__(self, *args, **kwargs): self.config_guess = None + @property + def parallel_flag(self): + """Return the flag to enable parallelism or empty for serial""" + return f'-j {self.cfg.parallel}' if self.cfg.parallel > 1 else '' + def obtain_config_guess(self, download_source_path=None, search_source_paths=None): """ Locate or download an up-to-date config.guess for use with ConfigureMake @@ -360,10 +365,6 @@ def build_step(self, verbose=None, path=None): if verbose is not None: self.log.deprecated("The 'verbose' parameter to build_step is deprecated and unneeded.", '6.0') - paracmd = '' - if self.cfg['parallel']: - paracmd = "-j %s" % self.cfg['parallel'] - targets = self.cfg.get('build_cmd_targets') or DEFAULT_BUILD_TARGET # ensure strings are converted to list targets = [targets] if isinstance(targets, str) else targets @@ -373,7 +374,7 @@ def build_step(self, verbose=None, path=None): self.cfg['prebuildopts'], self.cfg.get('build_cmd') or DEFAULT_BUILD_CMD, target, - paracmd, + self.parallel_flag, self.cfg['buildopts'], ]) self.log.info("Building target '%s'", target) diff --git a/easybuild/easyblocks/generic/mesonninja.py b/easybuild/easyblocks/generic/mesonninja.py index 495beef7f35..22bf6ae68eb 100644 --- a/easybuild/easyblocks/generic/mesonninja.py +++ b/easybuild/easyblocks/generic/mesonninja.py @@ -136,9 +136,7 @@ def build_step(self, verbose=False, path=None): """ build_cmd = self.cfg.get('build_cmd', DEFAULT_BUILD_CMD) - parallel = '' - if self.cfg['parallel']: - parallel = "-j %s" % self.cfg['parallel'] + parallel = f'-j {self.cfg.parallel}' if self.cfg.parallel > 1 else '' cmd = "%(prebuildopts)s %(build_cmd)s -v %(parallel)s %(buildopts)s" % { 'buildopts': self.cfg['buildopts'], @@ -164,9 +162,7 @@ def install_step(self): """ install_cmd = self.cfg.get('install_cmd', DEFAULT_INSTALL_CMD) - parallel = '' - if self.cfg['parallel']: - parallel = "-j %s" % self.cfg['parallel'] + parallel = f'-j {self.cfg.parallel}' if self.cfg.parallel > 1 else '' cmd = "%(preinstallopts)s %(install_cmd)s %(parallel)s %(installopts)s install" % { 'installopts': self.cfg['installopts'], diff --git a/easybuild/easyblocks/generic/scons.py b/easybuild/easyblocks/generic/scons.py index 526f7e52b6e..88c55222dee 100644 --- a/easybuild/easyblocks/generic/scons.py +++ b/easybuild/easyblocks/generic/scons.py @@ -56,9 +56,7 @@ def build_step(self, verbose=False): Build with SCons """ - par = '' - if self.cfg['parallel']: - par = "-j %s" % self.cfg['parallel'] + par = f'-j {self.cfg.parallel}' if self.cfg.parallel > 1 else '' cmd = "%(prebuildopts)s scons %(par)s %(buildopts)s %(prefix)s" % { 'buildopts': self.cfg['buildopts'], diff --git a/easybuild/easyblocks/h/hadoop.py b/easybuild/easyblocks/h/hadoop.py index 376b5e4f2f7..b1162f828dd 100644 --- a/easybuild/easyblocks/h/hadoop.py +++ b/easybuild/easyblocks/h/hadoop.py @@ -64,8 +64,8 @@ def build_step(self): raise EasyBuildError("%s not found. Failing install" % native_lib) cmd += ' -Drequire.%s=true -D%s.prefix=%s' % (native_lib, native_lib, lib_root) - if self.cfg['parallel'] > 1: - cmd += " -T%d" % self.cfg['parallel'] + if self.cfg.parallel > 1: + cmd += f" -T{self.cfg.parallel}" run_shell_cmd(cmd) def install_step(self): diff --git a/easybuild/easyblocks/i/impi.py b/easybuild/easyblocks/i/impi.py index b2d80c028cb..d210b48e758 100644 --- a/easybuild/easyblocks/i/impi.py +++ b/easybuild/easyblocks/i/impi.py @@ -106,8 +106,8 @@ def install_step(self): libfabric_installpath = os.path.join(self.installdir, 'intel64', 'libfabric') make = 'make' - if self.cfg['parallel']: - make += ' -j %d' % self.cfg['parallel'] + if self.cfg.parallel > 1: + make += f' -j {self.cfg.parallel}' cmds = [ f"./configure --prefix={libfabric_installpath} {self.cfg['libfabric_configopts']}", @@ -217,7 +217,7 @@ def sanity_check_step(self): build_cmd = "mpicc -cc=%s %s -o %s" % (os.getenv('CC'), impi_testsrc, impi_testexe) # Execute test program with appropriate MPI executable for target toolchain - params = {'nr_ranks': self.cfg['parallel'], 'cmd': impi_testexe} + params = {'nr_ranks': self.cfg.parallel, 'cmd': impi_testexe} mpi_cmd_tmpl, params = get_mpi_cmd_template(toolchain.INTELMPI, params, mpi_version=self.version) custom_commands.extend([ diff --git a/easybuild/easyblocks/j/jaxlib.py b/easybuild/easyblocks/j/jaxlib.py index 2ddf4a2996b..e876258b089 100644 --- a/easybuild/easyblocks/j/jaxlib.py +++ b/easybuild/easyblocks/j/jaxlib.py @@ -88,7 +88,7 @@ def configure_step(self): # Passed to the build command of bazel bazel_options = [ - '--jobs=%s' % self.cfg['parallel'], + f'--jobs={self.cfg.parallel}', '--subcommands', '--action_env=PYTHONPATH', '--action_env=EBPYTHONPREFIXES', diff --git a/easybuild/easyblocks/m/molpro.py b/easybuild/easyblocks/m/molpro.py index c9e7a3b3264..fbeeab78e6d 100644 --- a/easybuild/easyblocks/m/molpro.py +++ b/easybuild/easyblocks/m/molpro.py @@ -157,8 +157,8 @@ def configure_step(self): # determine MPI launcher command that can be used during build/test # obtain command with specific number of cores (required by mpi_cmd_for), then replace that number with '%n' - launcher = self.toolchain.mpi_cmd_for('%x', self.cfg['parallel']) - launcher = launcher.replace(' %s' % self.cfg['parallel'], ' %n') + launcher = self.toolchain.mpi_cmd_for('%x', self.cfg.parallel) + launcher = launcher.replace(f' {self.cfg.parallel}', ' %n') # patch CONFIG file to change LAUNCHER definition, in order to avoid having to start mpd apply_regex_substitutions(cfgfile, [(r"^(LAUNCHER\s*=\s*).*$", r"\1 %s" % launcher)]) @@ -186,7 +186,7 @@ def test_step(self): if build_option('mpi_tests'): # extensive test - run_shell_cmd("make MOLPRO_OPTIONS='-n%s' test" % self.cfg['parallel']) + run_shell_cmd(f"make MOLPRO_OPTIONS='-n{self.cfg.parallel}' test") else: self.log.info("Skipping extensive testing of Molpro since MPI testing is disabled") diff --git a/easybuild/easyblocks/m/mrtrix.py b/easybuild/easyblocks/m/mrtrix.py index 45ab32fb549..df978077f87 100644 --- a/easybuild/easyblocks/m/mrtrix.py +++ b/easybuild/easyblocks/m/mrtrix.py @@ -74,8 +74,7 @@ def configure_step(self): def build_step(self): """Custom build procedure for MRtrix.""" - parallel = self.cfg['parallel'] - env.setvar('NUMBER_OF_PROCESSORS', str(parallel)) + env.setvar('NUMBER_OF_PROCESSORS', str(self.cfg.parallel)) cmd = "python build -verbose" run_shell_cmd(cmd) diff --git a/easybuild/easyblocks/n/namd.py b/easybuild/easyblocks/n/namd.py index 36cb2f13247..ae89f349835 100644 --- a/easybuild/easyblocks/n/namd.py +++ b/easybuild/easyblocks/n/namd.py @@ -147,7 +147,7 @@ def configure_step(self): 'arch': self.cfg['charm_arch'], 'cxxflags': os.environ['CXXFLAGS'] + ' -DMPICH_IGNORE_CXX_SEEK ' + self.cfg['charm_extra_cxxflags'], 'opts': self.cfg['charm_opts'], - 'parallel': self.cfg['parallel'], + 'parallel': self.cfg.parallel, } charm_subdir = '.'.join(os.path.basename(self.charm_tarballs[0]).split('.')[:-1]) self.log.debug("Building Charm++ using cmd '%s' in '%s'" % (cmd, charm_subdir)) diff --git a/easybuild/easyblocks/n/neuron.py b/easybuild/easyblocks/n/neuron.py index 436d138a572..8c2c4c83c3b 100644 --- a/easybuild/easyblocks/n/neuron.py +++ b/easybuild/easyblocks/n/neuron.py @@ -105,7 +105,7 @@ def configure_step(self): def test_step(self): """Custom tests for NEURON.""" if build_option('mpi_tests'): - nproc = self.cfg['parallel'] + nproc = self.cfg.parallel try: hoc_file = os.path.join(self.cfg['start_dir'], 'src', 'parallel', 'test0.hoc') cmd = self.toolchain.mpi_cmd_for(f"bin/nrniv -mpi {hoc_file}", nproc) diff --git a/easybuild/easyblocks/n/nwchem.py b/easybuild/easyblocks/n/nwchem.py index fc7962d0c82..11189ea0295 100644 --- a/easybuild/easyblocks/n/nwchem.py +++ b/easybuild/easyblocks/n/nwchem.py @@ -276,8 +276,8 @@ def build_step(self): # check whether 64-bit integers should be used, and act on it if not self.toolchain.options['i8']: - if self.cfg['parallel']: - self.cfg.update('buildopts', '-j %s' % self.cfg['parallel']) + if self.parallel_flag: + self.cfg.update('buildopts', self.parallel_flag) run_shell_cmd("make %s 64_to_32" % self.cfg['buildopts']) self.setvar_env_makeopt('USE_64TO32', "y") diff --git a/easybuild/easyblocks/o/openblas.py b/easybuild/easyblocks/o/openblas.py index cb6a4ce75a1..3f6ab39db30 100644 --- a/easybuild/easyblocks/o/openblas.py +++ b/easybuild/easyblocks/o/openblas.py @@ -105,9 +105,7 @@ def build_step(self): del os.environ[cflags] self.log.info("Environment variable %s unset and passed through command line" % cflags) - makecmd = 'make' - if self.cfg['parallel']: - makecmd += ' -j %s' % self.cfg['parallel'] + makecmd = f'make {self.parallel_flag}' cmd = ' '.join([self.cfg['prebuildopts'], makecmd, ' '.join(build_parts), self.cfg['buildopts']]) run_shell_cmd(cmd) diff --git a/easybuild/easyblocks/o/openfoam.py b/easybuild/easyblocks/o/openfoam.py index 2d9ef6cae4b..641165a604f 100644 --- a/easybuild/easyblocks/o/openfoam.py +++ b/easybuild/easyblocks/o/openfoam.py @@ -271,7 +271,7 @@ def configure_step(self): env.setvar("WM_COMPILE_OPTION", self.build_type) # parallel build spec - env.setvar("WM_NCOMPPROCS", str(self.cfg['parallel'])) + env.setvar("WM_NCOMPPROCS", str(self.cfg.parallel)) # OpenFOAM >= 3.0.0 can use 64 bit integers if not self.is_extend and self.looseversion >= LooseVersion('3.0'): diff --git a/easybuild/easyblocks/o/openmpi.py b/easybuild/easyblocks/o/openmpi.py index 55128d389f5..44dc9e1aa22 100644 --- a/easybuild/easyblocks/o/openmpi.py +++ b/easybuild/easyblocks/o/openmpi.py @@ -219,7 +219,7 @@ def sanity_check_step(self): # Run with correct MPI launcher mpi_cmd_tmpl, params = get_mpi_cmd_template(toolchain.OPENMPI, dict(), mpi_version=self.version) # Limit number of ranks to 8 to avoid it failing due to hyperthreading - ranks = min(8, self.cfg['parallel']) + ranks = min(8, self.cfg.parallel) for srcdir, src, compiler in ( ('examples', 'hello_c.c', 'mpicc'), ('examples', 'hello_mpifh.f', 'mpifort'), diff --git a/easybuild/easyblocks/p/parmetis.py b/easybuild/easyblocks/p/parmetis.py index 85b076746d5..1b6d5a20b4f 100644 --- a/easybuild/easyblocks/p/parmetis.py +++ b/easybuild/easyblocks/p/parmetis.py @@ -102,9 +102,7 @@ def configure_step(self): def build_step(self): """Build ParMETIS (and METIS) using build_step.""" - paracmd = '' - if self.cfg['parallel']: - paracmd = "-j %s" % self.cfg['parallel'] + paracmd = f'-j {self.cfg.parallel}' if self.cfg.parallel > 1 else '' self.cfg.update('buildopts', 'LIBDIR=""') diff --git a/easybuild/easyblocks/p/pdt.py b/easybuild/easyblocks/p/pdt.py index 1fbc109e2f5..d839f0f2213 100644 --- a/easybuild/easyblocks/p/pdt.py +++ b/easybuild/easyblocks/p/pdt.py @@ -98,8 +98,8 @@ def make_installdir(self): def install_step(self): """Create symlinks into arch-specific directories""" - if self.cfg['parallel']: - self.cfg.update('installopts', '-j %s' % self.cfg['parallel']) + if self.parallel_flag: + self.cfg.update('installopts', self.parallel_flag) super(EB_PDT, self).install_step() diff --git a/easybuild/easyblocks/p/perl.py b/easybuild/easyblocks/p/perl.py index 729a84db172..9e70f5e2a0d 100644 --- a/easybuild/easyblocks/p/perl.py +++ b/easybuild/easyblocks/p/perl.py @@ -122,17 +122,13 @@ def test_step(self): """Test Perl build via 'make test'.""" # allow escaping with runtest = False if self.cfg['runtest'] is None or self.cfg['runtest']: - parallel = self.cfg['parallel'] + parallel = self.cfg.parallel if isinstance(self.cfg['runtest'], str): cmd = "make %s" % self.cfg['runtest'] - elif parallel and LooseVersion(self.version) >= LooseVersion('5.30.0'): + elif parallel > 1 and LooseVersion(self.version) >= LooseVersion('5.30.0'): # run tests in parallel, see https://perldoc.perl.org/perlhack#Parallel-tests; # only do this for Perl 5.30 and newer (conservative choice, actually supported in Perl >= 5.10.1) - cmd = ' '.join([ - 'TEST_JOBS=%s' % parallel, - 'PERL_TEST_HARNESS_ASAP=1', - "make -j %s test_harness" % parallel, - ]) + cmd = f'TEST_JOBS={parallel} PERL_TEST_HARNESS_ASAP=1 make -j {parallel} test_harness', else: cmd = "make test" diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py index 673983e4fce..2a3ee9b4a4f 100644 --- a/easybuild/easyblocks/p/petsc.py +++ b/easybuild/easyblocks/p/petsc.py @@ -193,7 +193,7 @@ def configure_step(self): self.cfg.update('configopts', '--with-mpi=1') # build options - self.cfg.update('configopts', '--with-build-step-np=%s' % self.cfg['parallel']) + self.cfg.update('configopts', f'--with-build-step-np={self.cfg.parallel}') self.cfg.update('configopts', '--with-shared-libraries=%d' % self.cfg['shared_libs']) self.cfg.update('configopts', '--with-debugging=%d' % self.toolchain.options['debug']) self.cfg.update('configopts', '--with-pic=%d' % self.toolchain.options['pic']) @@ -348,14 +348,14 @@ def configure_step(self): else: raise EasyBuildError("Failed to determine PETSC_ARCH setting.") - # Make sure to set test_parallel before self.cfg['parallel'] is set to None - if self.cfg['test_parallel'] is None and self.cfg['parallel']: - self.cfg['test_parallel'] = self.cfg['parallel'] + # Make sure to set test_parallel before self.cfg.parallel is set to 1 + if self.cfg['test_parallel'] is None: + self.cfg['test_parallel'] = self.cfg.parallel # PETSc make does not accept -j # to control parallel build, we need to specify MAKE_NP=... as argument to 'make' command - self.cfg.update('buildopts', "MAKE_NP=%s" % self.cfg['parallel']) - self.cfg['parallel'] = None + self.cfg.update('buildopts', f"MAKE_NP={self.cfg.parallel}") + self.cfg.parallel = 1 # default make should be fine @@ -364,13 +364,13 @@ def test_step(self): Test the compilation """ - # Each PETSc test may use multiple threads, so running "self.cfg['parallel']" of them may lead to + # Each PETSc test may use multiple threads, so running "self.cfg.parallel" of them may lead to # some oversubscription every now and again. Not a big deal, but if needed a reduced parallelism # can be specified with test_parallel - and it takes priority paracmd = '' self.log.info("In test_step: %s" % self.cfg['test_parallel']) - if self.cfg['test_parallel'] is not None: - paracmd = "-j %s" % self.cfg['test_parallel'] + if self.cfg['test_parallel'] > 1: + paracmd = f"-j {self.cfg['test_parallel']}" if self.cfg['runtest']: cmd = "%s make %s %s %s" % (self.cfg['pretestopts'], paracmd, self.cfg['runtest'], self.cfg['testopts']) diff --git a/easybuild/easyblocks/p/psi.py b/easybuild/easyblocks/p/psi.py index feddbecb82a..1b558fe51db 100644 --- a/easybuild/easyblocks/p/psi.py +++ b/easybuild/easyblocks/p/psi.py @@ -218,11 +218,8 @@ def test_step(self): if self.cfg['runtest']: paracmd = '' # Run ctest parallel, but limit to maximum 4 jobs (in case of slow disks) - if self.cfg['parallel']: - if self.cfg['parallel'] > 4: - paracmd = '-j 4' - else: - paracmd = "-j %s" % self.cfg['parallel'] + if self.cfg.parallel > 1: + paracmd = f"-j {min(4, self.cfg.parallel)}" cmd = "ctest %s %s" % (paracmd, self.cfg['runtest']) run_shell_cmd(cmd) else: diff --git a/easybuild/easyblocks/p/pytorch.py b/easybuild/easyblocks/p/pytorch.py index c70aa2237f6..4795f91c52e 100644 --- a/easybuild/easyblocks/p/pytorch.py +++ b/easybuild/easyblocks/p/pytorch.py @@ -338,7 +338,7 @@ def add_enable_option(name, enabled): add_enable_option('VERBOSE', build_option('debug')) # Restrict parallelism - options.append('MAX_JOBS=%s' % self.cfg['parallel']) + options.append(f'MAX_JOBS={self.cfg.parallel}') # BLAS Interface if get_software_root('imkl'): diff --git a/easybuild/easyblocks/q/qt.py b/easybuild/easyblocks/q/qt.py index bd00280b302..e12fd4a30a5 100644 --- a/easybuild/easyblocks/q/qt.py +++ b/easybuild/easyblocks/q/qt.py @@ -161,7 +161,7 @@ def configure_step(self): # note that $NINJAFLAGS is not a generic thing for Ninja, it's very specific to the Qt5 build procedure if LooseVersion(self.version) >= LooseVersion('5'): if get_software_root('Ninja'): - env.setvar('NINJAFLAGS', '-j%s' % self.cfg['parallel']) + env.setvar('NINJAFLAGS', self.parallel_flag) def build_step(self): """Set $LD_LIBRARY_PATH before calling make, to ensure that all required libraries are found during linking.""" diff --git a/easybuild/easyblocks/q/quantumespresso.py b/easybuild/easyblocks/q/quantumespresso.py index 9aa53ccd249..3178c25ff2c 100644 --- a/easybuild/easyblocks/q/quantumespresso.py +++ b/easybuild/easyblocks/q/quantumespresso.py @@ -356,14 +356,10 @@ def test_step(self): return thr = self.cfg.get('test_suite_threshold', 0.97) - concurrent = max(1, self.cfg.get('parallel', 1) // self._test_nprocs) + concurrent = max(1, self.cfg.parallel // self._test_nprocs) allow_fail = self.cfg.get('test_suite_allow_failures', []) - cmd = ' '.join([ - 'ctest', - '-j%d' % concurrent, - '--output-on-failure', - ]) + cmd = f'ctest -j{concurrent} --output-on-failure' res = run_shell_cmd(cmd, fail_on_error=False) out = res.output diff --git a/easybuild/easyblocks/r/rosetta.py b/easybuild/easyblocks/r/rosetta.py index 139cce039c3..f628b878e59 100644 --- a/easybuild/easyblocks/r/rosetta.py +++ b/easybuild/easyblocks/r/rosetta.py @@ -182,9 +182,7 @@ def build_step(self): os.chdir(self.srcdir) except OSError as err: raise EasyBuildError("Failed to change to %s: %s", self.srcdir, err) - par = '' - if self.cfg['parallel']: - par = "-j %s" % self.cfg['parallel'] + par = f"-j {self.cfg.parallel}" if self.cfg.parallel > 1 else "" cmd = "python ./scons.py %s %s bin" % (self.cfg['buildopts'], par) run_shell_cmd(cmd) diff --git a/easybuild/easyblocks/s/scalapack.py b/easybuild/easyblocks/s/scalapack.py index 703bf1f06b2..9e58568cdf4 100644 --- a/easybuild/easyblocks/s/scalapack.py +++ b/easybuild/easyblocks/s/scalapack.py @@ -177,12 +177,7 @@ def build_libscalapack_make(self): self.cfg.update('buildopts', 'lib') self.cfg.update('buildopts', ' '.join(extra_makeopts)) - # Copied from ConfigureMake easyblock - paracmd = '' - if self.cfg['parallel']: - paracmd = "-j %s" % self.cfg['parallel'] - - cmd = "%s make %s %s" % (self.cfg['prebuildopts'], paracmd, self.cfg['buildopts']) + cmd = "%s make %s %s" % (self.cfg['prebuildopts'], self.parallel_flag, self.cfg['buildopts']) # Ignore exit code for parallel run run_shell_cmd(cmd, fail_on_error=False) @@ -192,7 +187,7 @@ def build_libscalapack_make(self): self.cfg.update('buildopts', ' '.join(extra_makeopts)) remove_file('libscalapack.a') - self.cfg['parallel'] = 1 + self.cfg.parallel = 1 def build_step(self): """Build ScaLAPACK using make after setting make options.""" diff --git a/easybuild/easyblocks/s/scipy.py b/easybuild/easyblocks/s/scipy.py index 86217467a63..48728842b3f 100644 --- a/easybuild/easyblocks/s/scipy.py +++ b/easybuild/easyblocks/s/scipy.py @@ -189,7 +189,7 @@ def test_step(self): 'python': self.python_cmd, 'srcdir': self.cfg['start_dir'], 'installdir': tmp_installdir, - 'parallel': self.cfg['parallel'], + 'parallel': self.cfg.parallel, } MesonNinja.test_step(self) @@ -199,7 +199,7 @@ def test_step(self): 'python': '%(python)s', 'srcdir': self.cfg['start_dir'], 'installdir': '', - 'parallel': self.cfg['parallel'], + 'parallel': self.cfg.parallel, } FortranPythonPackage.test_step(self) diff --git a/easybuild/easyblocks/s/siesta.py b/easybuild/easyblocks/s/siesta.py index 663fb9489a6..3fb167f1cb9 100644 --- a/easybuild/easyblocks/s/siesta.py +++ b/easybuild/easyblocks/s/siesta.py @@ -76,7 +76,7 @@ def configure_step(self): par = '' if loose_ver >= LooseVersion('4.1'): - par = '-j %s' % self.cfg['parallel'] + par = f"-j {self.cfg.parallel}" # enable OpenMP support if desired env_var_suff = '' diff --git a/easybuild/easyblocks/s/slepc.py b/easybuild/easyblocks/s/slepc.py index 47afde86d42..1f663c1a43e 100644 --- a/easybuild/easyblocks/s/slepc.py +++ b/easybuild/easyblocks/s/slepc.py @@ -129,7 +129,7 @@ def configure_step(self): # SLEPc > 3.5, make does not accept -j if LooseVersion(self.version) >= LooseVersion("3.5"): - self.cfg['parallel'] = None + self.cfg.parallel = 1 def install_step(self): """ diff --git a/easybuild/easyblocks/t/tensorflow.py b/easybuild/easyblocks/t/tensorflow.py index 8cc7122d320..67b1e7ee5c0 100644 --- a/easybuild/easyblocks/t/tensorflow.py +++ b/easybuild/easyblocks/t/tensorflow.py @@ -473,7 +473,7 @@ def configure_step(self): if self.cfg['maxparallel'] is None: # 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) + self.cfg.parallel = min(self.cfg.parallel, bazel_max) # determine location where binutils' ld command is installed # note that this may be an RPATH wrapper script (when EasyBuild is configured with --rpath) @@ -867,7 +867,7 @@ def build_step(self): # https://docs.bazel.build/versions/master/user-manual.html#flag--verbose_failures self.target_opts.extend(['--subcommands', '--verbose_failures']) - self.target_opts.append('--jobs=%s' % self.cfg['parallel']) + self.target_opts.append(f'--jobs={self.cfg.parallel}') if self.toolchain.options.get('pic', None): self.target_opts.append('--copt="-fPIC"') @@ -989,7 +989,7 @@ def test_step(self): test_opts.append('--build_tests_only') # Don't build tests which won't be executed # determine number of cores/GPUs to use for tests - max_num_test_jobs = int(self.cfg['test_max_parallel'] or self.cfg['parallel']) + max_num_test_jobs = self.cfg['test_max_parallel'] or self.cfg.parallel if self._with_cuda: if not which('nvidia-smi', on_error=IGNORE): print_warning('Could not find nvidia-smi. Assuming a system without GPUs and skipping GPU tests!') diff --git a/easybuild/easyblocks/t/tensorflow_compression.py b/easybuild/easyblocks/t/tensorflow_compression.py index 45b4c96384e..436f1b03cf8 100644 --- a/easybuild/easyblocks/t/tensorflow_compression.py +++ b/easybuild/easyblocks/t/tensorflow_compression.py @@ -85,7 +85,7 @@ def build_step(self): # https://docs.bazel.build/versions/master/user-manual.html#flag--verbose_failures self.target_opts.extend(['--subcommands', '--verbose_failures']) - self.target_opts.append('--jobs=%s' % self.cfg['parallel']) + self.target_opts.append(f'--jobs={self.cfg.parallel}') # include install location of Python packages in $PYTHONPATH, # and specify that value of $PYTHONPATH should be passed down into Bazel build environment, diff --git a/easybuild/easyblocks/w/wrf.py b/easybuild/easyblocks/w/wrf.py index e34ae41dcac..77f6c1b2d33 100644 --- a/easybuild/easyblocks/w/wrf.py +++ b/easybuild/easyblocks/w/wrf.py @@ -252,10 +252,7 @@ def build_step(self): """Build and install WRF and testcases using provided compile script.""" # enable parallel build - par = self.cfg['parallel'] - self.par = '' - if par: - self.par = "-j %s" % par + self.par = f'-j {self.cfg.parallel}' if self.cfg.parallel else '' # fix compile script shebang to use provided tcsh cmpscript = os.path.join(self.start_dir, 'compile') @@ -328,7 +325,7 @@ def test_step(self): # determine number of MPI ranks to use in tests (1/2 of available processors + 1); # we need to limit max number of MPI ranks (8 is too high for some tests, 4 is OK), # since otherwise run may fail because domain size is too small - n_mpi_ranks = min(self.cfg['parallel'] // 2 + 1, 4) + n_mpi_ranks = min(self.cfg.parallel // 2 + 1, 4) # prepare run command