Skip to content

Commit ada1dfc

Browse files
authored
Merge pull request #3327 from vkarak/bugfix/slurm-hyphen-constraints
[bugfix] Treat correctly Slurm constrains with hyphens when filtering nodes
2 parents 3dafd84 + b7e1e3f commit ada1dfc

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

reframe/core/schedulers/slurm.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ def filternodes(self, job, nodes):
351351
option_parser.add_argument('-w', '--nodelist')
352352
option_parser.add_argument('-C', '--constraint')
353353
option_parser.add_argument('-x', '--exclude')
354+
self.log(f'Filtering by Slurm options: {" ".join(options)}')
354355
parsed_args, _ = option_parser.parse_known_args(options)
355356
reservation = parsed_args.reservation
356357
partitions = parsed_args.partition
@@ -363,7 +364,7 @@ def filternodes(self, job, nodes):
363364
else:
364365
nodes = {node for node in nodes if not node.in_state('RESERVED')}
365366

366-
self.log(f'[F] Filtering nodes by reservation={reservation}: '
367+
self.log(f'Filtering nodes by reservation={reservation}: '
367368
f'available nodes now: {len(nodes)}')
368369

369370
if partitions:
@@ -377,27 +378,27 @@ def filternodes(self, job, nodes):
377378
)
378379
partitions = {default_partition} if default_partition else set()
379380
self.log(
380-
f'[F] No partition specified; using {default_partition!r}'
381+
f'No partition specified; using {default_partition!r}'
381382
)
382383

383384
nodes = {n for n in nodes if n.partitions >= partitions}
384-
self.log(f'[F] Filtering nodes by partition(s) {partitions}: '
385+
self.log(f'Filtering nodes by partition(s) {partitions}: '
385386
f'available nodes now: {len(nodes)}')
386387
if constraints:
387388
nodes = {n for n in nodes if n.satisfies(constraints)}
388-
self.log(f'[F] Filtering nodes by constraint(s) {constraints}: '
389+
self.log(f'Filtering nodes by constraint(s) {constraints}: '
389390
f'available nodes now: {len(nodes)}')
390391

391392
if nodelist:
392393
nodelist = nodelist.strip()
393394
nodes &= self._get_nodes_by_name(nodelist)
394-
self.log(f'[F] Filtering nodes by nodelist: {nodelist}: '
395+
self.log(f'Filtering nodes by nodelist: {nodelist}: '
395396
f'available nodes now: {len(nodes)}')
396397

397398
if exclude_nodes:
398399
exclude_nodes = exclude_nodes.strip()
399400
nodes -= self._get_nodes_by_name(exclude_nodes)
400-
self.log(f'[F] Excluding node(s): {exclude_nodes}: '
401+
self.log(f'Excluding node(s): {exclude_nodes}: '
401402
f'available nodes now: {len(nodes)}')
402403

403404
return nodes
@@ -711,17 +712,29 @@ def is_down(self):
711712
return not self.is_avail()
712713

713714
def satisfies(self, slurm_constraint):
715+
def _replacemany(s, replacements):
716+
for src, dst in replacements:
717+
s = s.replace(src, dst)
718+
719+
return s
720+
714721
# Convert the Slurm constraint to a Python expression and evaluate it,
715722
# but restrict our syntax to accept only AND or OR constraints and
716-
# their combinations
717-
if not re.match(r'^[\w\d\(\)\|\&]*$', slurm_constraint):
723+
# their combinations; to properly treat `-` in constraints we need to
724+
# convert them to valid Python identifiers before evaluating the
725+
# constraint.
726+
if not re.match(r'^[\-\w\d\(\)\|\&]*$', slurm_constraint):
718727
return False
719728

720-
names = {grp[0]
721-
for grp in re.finditer(r'(\w(\w|\d)*)', slurm_constraint)}
722-
expr = slurm_constraint.replace('|', ' or ').replace('&', ' and ')
723-
vars = {n: True for n in self.active_features}
724-
vars.update({n: False for n in names - self.active_features})
729+
names = {
730+
grp[0] for grp in re.finditer(r'[\-\w][\-\w\d]*', slurm_constraint)
731+
}
732+
expr = _replacemany(slurm_constraint,
733+
[('-', '_'), ('|', ' or '), ('&', ' and ')])
734+
vars = {n.replace('-', '_'): True for n in self.active_features}
735+
vars.update({
736+
n.replace('-', '_'): False for n in names - self.active_features
737+
})
725738
try:
726739
return eval(expr, {}, vars)
727740
except BaseException:

0 commit comments

Comments
 (0)