@@ -128,21 +128,18 @@ def post_ready_hook(self, *args, **kwargs):
128
128
Post-ready hook: limit parallellism for selected builds based on software name and CPU target.
129
129
parallelism needs to be limited because some builds require a lot of memory per used core.
130
130
"""
131
- # 'parallel' (EB4) or 'max_parallel' (EB5) easyconfig parameter is set via EasyBlock.set_parallel in ready step
132
- # based on available cores.
133
-
134
- # Check whether we have EasyBuild 4 or 5
135
- parallel_param = 'parallel'
136
- if EASYBUILD_VERSION >= '5' :
137
- parallel_param = 'max_parallel'
138
- # get current parallelism setting
139
- parallel = self .cfg [parallel_param ]
131
+ # 'parallel' easyconfig parameter (EB4) or the parallel property (EB5) is set via EasyBlock.set_parallel
132
+ # in ready step based on available cores
133
+ parallel = getattr (self , 'parallel' , self .cfg ['parallel' ])
134
+
140
135
if parallel == 1 :
141
136
return # no need to limit if already using 1 core
142
137
143
138
# get CPU target
144
139
cpu_target = get_eessi_envvar ('EESSI_SOFTWARE_SUBDIR' )
145
140
141
+ new_parallel = parallel
142
+
146
143
# check if we have limits defined for this software
147
144
if self .name in PARALLELISM_LIMITS :
148
145
limits = PARALLELISM_LIMITS [self .name ]
@@ -158,11 +155,19 @@ def post_ready_hook(self, *args, **kwargs):
158
155
else :
159
156
return # no applicable limits found
160
157
161
- # apply the limit if it's different from current
162
- if new_parallel != parallel :
163
- self .cfg [parallel_param ] = new_parallel
164
- msg = "limiting parallelism to %s (was %s) for %s on %s to avoid out-of-memory failures during building/testing"
165
- print_msg (msg % (new_parallel , parallel , self .name , cpu_target ), log = self .log )
158
+ # check if there's a general limit set for CPU target
159
+ elif cpu_target in PARALLELISM_LIMITS :
160
+ operation_func , operation_args = PARALLELISM_LIMITS [cpu_target ]
161
+ new_parallel = operation_func (parallel , operation_args )
162
+
163
+ # apply the limit if it's different from current
164
+ if new_parallel != parallel :
165
+ if EASYBUILD_VERSION >= '5' :
166
+ self .cfg .parallel = new_parallel
167
+ else :
168
+ self .cfg ['parallel' ] = new_parallel
169
+ msg = "limiting parallelism to %s (was %s) for %s on %s to avoid out-of-memory failures during building/testing"
170
+ print_msg (msg % (new_parallel , parallel , self .name , cpu_target ), log = self .log )
166
171
167
172
168
173
def pre_prepare_hook (self , * args , ** kwargs ):
@@ -1376,27 +1381,22 @@ def set_maximum(parallel, max_value):
1376
1381
# specific CPU target is defined in the data structure below. If not, it checks for
1377
1382
# the generic '*' entry.
1378
1383
PARALLELISM_LIMITS = {
1384
+ # by default, only use quarter of cores when building for A64FX;
1385
+ # this is done because total memory is typically limited on A64FX due to HBM,
1386
+ # Deucalion has 32GB HBM for 48 cores per node
1387
+ CPU_TARGET_A64FX : (divide_by_factor , 4 ),
1388
+ # software-specific limits
1379
1389
'libxc' : {
1380
1390
'*' : (divide_by_factor , 2 ),
1381
- CPU_TARGET_A64FX : (set_maximum , 12 ),
1382
- },
1383
- 'nodejs' : {
1384
- CPU_TARGET_A64FX : (divide_by_factor , 2 ),
1385
1391
},
1386
1392
'MBX' : {
1387
1393
'*' : (divide_by_factor , 2 ),
1388
1394
},
1389
- 'PyTorch' : {
1390
- CPU_TARGET_A64FX : (divide_by_factor , 4 ),
1391
- },
1392
1395
'TensorFlow' : {
1393
1396
'*' : (divide_by_factor , 2 ),
1394
1397
CPU_TARGET_A64FX : (set_maximum , 8 ),
1395
1398
},
1396
1399
'Qt5' : {
1397
1400
CPU_TARGET_A64FX : (set_maximum , 8 ),
1398
1401
},
1399
- 'ROOT' : {
1400
- CPU_TARGET_A64FX : (divide_by_factor , 2 ),
1401
- },
1402
1402
}
0 commit comments