Skip to content

Commit f64a54a

Browse files
authored
Merge pull request #3812 from Flamefire/set_parallel-speedup
speed up set_parallel method in EasyBlock class
2 parents af02665 + a99001b commit f64a54a

File tree

3 files changed

+43
-27
lines changed

3 files changed

+43
-27
lines changed

easybuild/framework/easyblock.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,18 +1791,19 @@ def set_parallel(self):
17911791
"""Set 'parallel' easyconfig parameter to determine how many cores can/should be used for parallel builds."""
17921792
# set level of parallelism for build
17931793
par = build_option('parallel')
1794-
if self.cfg['parallel'] is not None:
1795-
if par is None:
1796-
par = self.cfg['parallel']
1797-
self.log.debug("Desired parallelism specified via 'parallel' easyconfig parameter: %s", par)
1798-
else:
1799-
par = min(int(par), int(self.cfg['parallel']))
1800-
self.log.debug("Desired parallelism: minimum of 'parallel' build option/easyconfig parameter: %s", par)
1801-
else:
1794+
cfg_par = self.cfg['parallel']
1795+
if cfg_par is None:
18021796
self.log.debug("Desired parallelism specified via 'parallel' build option: %s", par)
1797+
elif par is None:
1798+
par = cfg_par
1799+
self.log.debug("Desired parallelism specified via 'parallel' easyconfig parameter: %s", par)
1800+
else:
1801+
par = min(int(par), int(cfg_par))
1802+
self.log.debug("Desired parallelism: minimum of 'parallel' build option/easyconfig parameter: %s", par)
18031803

1804-
self.cfg['parallel'] = det_parallelism(par=par, maxpar=self.cfg['maxparallel'])
1805-
self.log.info("Setting parallelism: %s" % self.cfg['parallel'])
1804+
par = det_parallelism(par, maxpar=self.cfg['maxparallel'])
1805+
self.log.info("Setting parallelism: %s" % par)
1806+
self.cfg['parallel'] = par
18061807

18071808
def remove_module_file(self):
18081809
"""Remove module file (if it exists), and check for ghost installation directory (and deal with it)."""

easybuild/tools/systemtools.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -976,31 +976,42 @@ def det_parallelism(par=None, maxpar=None):
976976
Determine level of parallelism that should be used.
977977
Default: educated guess based on # cores and 'ulimit -u' setting: min(# cores, ((ulimit -u) - 15) // 6)
978978
"""
979-
if par is not None:
980-
if not isinstance(par, int):
979+
def get_default_parallelism():
980+
try:
981+
# Get cache value if any
982+
par = det_parallelism._default_parallelism
983+
except AttributeError:
984+
# No cache -> Calculate value from current system values
985+
par = get_avail_core_count()
986+
# check ulimit -u
987+
out, ec = run_cmd('ulimit -u', force_in_dry_run=True, trace=False, stream_output=False)
981988
try:
982-
par = int(par)
989+
if out.startswith("unlimited"):
990+
maxuserproc = 2 ** 32 - 1
991+
else:
992+
maxuserproc = int(out)
983993
except ValueError as err:
984-
raise EasyBuildError("Specified level of parallelism '%s' is not an integer value: %s", par, err)
985-
else:
986-
par = get_avail_core_count()
987-
# check ulimit -u
988-
out, ec = run_cmd('ulimit -u', force_in_dry_run=True, trace=False, stream_output=False)
989-
try:
990-
if out.startswith("unlimited"):
991-
out = 2 ** 32 - 1
992-
maxuserproc = int(out)
994+
raise EasyBuildError("Failed to determine max user processes (%s, %s): %s", ec, out, err)
993995
# assume 6 processes per build thread + 15 overhead
994-
par_guess = int((maxuserproc - 15) // 6)
996+
par_guess = (maxuserproc - 15) // 6
995997
if par_guess < par:
996998
par = par_guess
997-
_log.info("Limit parallel builds to %s because max user processes is %s" % (par, out))
999+
_log.info("Limit parallel builds to %s because max user processes is %s", par, out)
1000+
# Cache value
1001+
det_parallelism._default_parallelism = par
1002+
return par
1003+
1004+
if par is None:
1005+
par = get_default_parallelism()
1006+
else:
1007+
try:
1008+
par = int(par)
9981009
except ValueError as err:
999-
raise EasyBuildError("Failed to determine max user processes (%s, %s): %s", ec, out, err)
1010+
raise EasyBuildError("Specified level of parallelism '%s' is not an integer value: %s", par, err)
10001011

10011012
if maxpar is not None and maxpar < par:
1002-
_log.info("Limiting parallellism from %s to %s" % (par, maxpar))
1003-
par = min(par, maxpar)
1013+
_log.info("Limiting parallellism from %s to %s", par, maxpar)
1014+
par = maxpar
10041015

10051016
return par
10061017

test/framework/easyconfig.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,6 +3052,10 @@ def test_template_constant_dict(self):
30523052
self.assertEqual(res, expected)
30533053

30543054
# mock get_avail_core_count which is used by set_parallel -> det_parallelism
3055+
try:
3056+
del st.det_parallelism._default_parallelism # Remove cache value
3057+
except AttributeError:
3058+
pass # Ignore if not present
30553059
orig_get_avail_core_count = st.get_avail_core_count
30563060
st.get_avail_core_count = lambda: 42
30573061

0 commit comments

Comments
 (0)