Skip to content

Commit 809cba4

Browse files
committed
Combine Slurm constraints also when sched_access_in_submit is set
1 parent f084223 commit 809cba4

File tree

2 files changed

+48
-32
lines changed

2 files changed

+48
-32
lines changed

reframe/core/schedulers/slurm.py

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -212,40 +212,33 @@ def emit_preamble(self, job):
212212
)
213213
)
214214

215-
constraints = []
216-
constraint_parser = ArgumentParser()
217-
constraint_parser.add_argument('-C', '--constraint')
218-
if not self._sched_access_in_submit:
219-
for opt in job.sched_access:
220-
if not opt.strip().startswith(('-C', '--constraint')):
221-
preamble.append('%s %s' % (self._prefix, opt))
222-
223-
# To avoid overriding a constraint that's passed into
224-
# `sched_access`, we AND it with the `--constraint` option
225-
# passed either in `options` or in `cli_options`
226-
parsed_options, _ = constraint_parser.parse_known_args(
227-
job.sched_access
228-
)
229-
if parsed_options.constraint:
230-
constraints.append(parsed_options.constraint.strip())
231-
232-
# NOTE: Here last of the passed --constraint job options is taken
233-
# into account in order to respect the behavior of slurm.
234-
parsed_options, _ = constraint_parser.parse_known_args(
235-
job.options + job.cli_options
236-
)
237-
if parsed_options.constraint:
238-
constraints.append(parsed_options.constraint.strip())
239-
240-
if constraints:
241-
if len(constraints) == 1:
242-
constr = constraints[0]
215+
# Combine constraints in `sched_access`
216+
#
217+
# We AND the constraints defined in `sched_access` with those in
218+
# either the `job.options` or `job.cli_options`. We essentially "move"
219+
# the option from the source option list to `sched_access` as if the
220+
# user has specified all the constraint in `sched_access`. We can then
221+
# move with the preamble generation or the submission normally.
222+
c_parser = ArgumentParser()
223+
c_parser.add_argument('-C', '--constraint')
224+
access, access_other = c_parser.parse_known_args(job.sched_access)
225+
job_opts, other_job_opts = c_parser.parse_known_args(job.options)
226+
cli_opts, other_cli_opts = c_parser.parse_known_args(job.cli_options)
227+
if access.constraint and (job_opts.constraint or cli_opts.constraint):
228+
constraints = [access.constraint]
229+
if job_opts.constraint:
230+
constraints.append(job_opts.constraint)
231+
job.options = other_job_opts
243232
else:
244-
# Parenthesize the constraints prior to joining them with `&`
245-
# to make sure that precedence is respected.
246-
constr = '&'.join(f'({c})' for c in constraints)
233+
constraints.append(cli_opts.constraint)
234+
job._cli_options = other_cli_opts
235+
236+
arg = '&'.join(f'({c.strip()})' for c in constraints)
237+
job._sched_access = [f'--constraint={arg}']
247238

248-
preamble.append(self._format_option(constr, '--constraint={0}'))
239+
if not self._sched_access_in_submit:
240+
for opt in job.sched_access:
241+
preamble.append(f'{self._prefix} {opt}')
249242

250243
preamble.append(self._format_option(hint, '--hint={0}'))
251244
prefix_patt = re.compile(r'(#\w+)')

unittests/test_schedulers.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ def test_combined_access_constraint(make_job, slurm_only):
617617
with open(job.script_filename) as fp:
618618
script_content = fp.read()
619619

620+
print(script_content)
620621
assert re.search(r'(?m)--constraint=\(c1\)&\(c2&c3\)$', script_content)
621622
assert re.search(r'(?m)--constraint=(c1|c2&c3)$', script_content) is None
622623

@@ -644,6 +645,28 @@ def test_combined_access_verbatim_constraint(make_job, slurm_only):
644645
assert re.search(r'(?m)^#SBATCH -C c3$', script_content)
645646

646647

648+
def test_sched_access_in_submit(make_job):
649+
job = make_job(sched_access=['--constraint=c1', '--foo=bar'])
650+
job.options = ['--constraint=c2', '--xyz']
651+
job.scheduler._sched_access_in_submit = True
652+
653+
if job.scheduler.registered_name in ('local', 'ssh'):
654+
pytest.skip(f'not relevant for this scheduler backend')
655+
656+
prepare_job(job)
657+
with open(job.script_filename) as fp:
658+
script_content = fp.read()
659+
660+
print(script_content)
661+
assert '--xyz' in script_content
662+
assert '--foo=bar' not in script_content
663+
if job.scheduler.registered_name in ('slurm', 'squeue'):
664+
# Constraints are combined in `sched_access` for Slurm backends
665+
assert '--constraint' not in script_content
666+
else:
667+
assert '--constraint=c1' not in script_content
668+
669+
647670
def test_guess_num_tasks(minimal_job, scheduler):
648671
minimal_job.num_tasks = 0
649672
if scheduler.registered_name == 'local':

0 commit comments

Comments
 (0)