Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions cscs-checks/system/slurm/slurm.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def __init__(self):
self.sanity_patterns = sn.assert_found(
r'error: You have to specify, at least, what sort of node you '
r'need: -C gpu for GPU enabled nodes, or -C mc for multicore '
r'nodes.', self.stderr)
r'nodes.|ERROR: you must specify -C with one of the following: '
r'mc,gpu,storage', self.stderr)


@rfm.simple_test
Expand Down Expand Up @@ -175,11 +176,8 @@ def __init__(self):
@rfm.run_before('run')
def set_slurm_constraint(self):
cabinet = self.cabinets.get(self.current_partition.fullname)
constraint = f'--constraint={self.current_partition.name}'
if cabinet:
constraint += f'&{cabinet}'

self.job.options += [constraint]
self.job.options += [f'--constraint={cabinet}']


@rfm.simple_test
Expand Down
5 changes: 4 additions & 1 deletion docs/manpage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -352,13 +352,16 @@ Options controlling job submission
Any job options specified with this command-line option will be emitted after any job options specified in the :js:attr:`access` system partition configuration parameter.

Especially for the Slurm backends, constraint options, such as ``-J constraint=value``, ``-J C=value``, ``-J --constraint=value`` or ``-J -C=value``, are going to be combined with any constraint options specified in the :js:attr:`access` system partition configuration parameter.
For example, if ``-C x`` is specified in the :js:attr:`access` and ``-J C=y`` is passed to the command-line, ReFrame will pass ``-C x,y`` as a constraint to the scheduler.
For example, if ``-C x`` is specified in the :js:attr:`access` and ``-J C=y`` is passed to the command-line, ReFrame will pass ``-C x&y`` as a constraint to the scheduler.
Notice, however, that if constraint options are specified through multiple :option:`-J` options, only the last one will be considered.
If you wish to completely overwrite any constraint options passed in :js:attr:`access`, you should consider passing explicitly the Slurm directive with ``-J '#SBATCH --constraint=new'``.

.. versionchanged:: 3.0
This option has become more flexible.

.. versionchanged:: 3.1
Use ``&`` to combine constraints.

------------------------
Flexible node allocation
------------------------
Expand Down
4 changes: 2 additions & 2 deletions reframe/core/schedulers/slurm.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def emit_preamble(self, job):

if constraints:
preamble.append(
self._format_option(','.join(constraints), '--constraint={0}')
self._format_option('&'.join(constraints), '--constraint={0}')
)

preamble.append(self._format_option(hint, '--hint={0}'))
Expand Down Expand Up @@ -326,7 +326,7 @@ def filternodes(self, job, nodes):
'available nodes now: %s' % (partitions, len(nodes)))

if constraints:
constraints = set(constraints.strip().split(','))
constraints = set(constraints.strip().split('&'))
nodes = {n for n in nodes if n.active_features >= constraints}
getlogger().debug(
'flex_alloc_nodes: filtering nodes by constraint(s) %s: '
Expand Down
18 changes: 9 additions & 9 deletions unittests/test_schedulers.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,13 @@ def test_no_empty_lines_in_preamble(minimal_job):

def test_combined_access_constraint(make_job, slurm_only):
job = make_job(sched_access=['--constraint=c1'])
job.options = ['-C c2,c3']
job.options = ['-C c2&c3']
prepare_job(job)
with open(job.script_filename) as fp:
script_content = fp.read()

assert re.search(r'(?m)--constraint=c1,c2,c3$', script_content)
assert re.search(r'(?m)--constraint=(c1|c2,c3)$', script_content) is None
assert re.search(r'(?m)--constraint=c1&c2&c3$', script_content)
assert re.search(r'(?m)--constraint=(c1|c2&c3)$', script_content) is None


def test_combined_access_multiple_constraints(make_job, slurm_only):
Expand All @@ -388,7 +388,7 @@ def test_combined_access_multiple_constraints(make_job, slurm_only):
with open(job.script_filename) as fp:
script_content = fp.read()

assert re.search(r'(?m)--constraint=c1,c3$', script_content)
assert re.search(r'(?m)--constraint=c1&c3$', script_content)
assert re.search(r'(?m)--constraint=(c1|c2|c3)$', script_content) is None


Expand Down Expand Up @@ -781,7 +781,7 @@ def test_flex_alloc_valid_constraint_opt(make_flexible_job):

def test_flex_alloc_valid_multiple_constraints(make_flexible_job):
job = make_flexible_job('all')
job.options = ['-C f1,f3']
job.options = ['-C f1&f3']
prepare_job(job)
assert job.num_tasks == 4

Expand All @@ -808,7 +808,7 @@ def test_flex_alloc_valid_multiple_partitions(make_flexible_job):

def test_flex_alloc_valid_constraint_partition(make_flexible_job):
job = make_flexible_job('all')
job.options = ['-C f1,f2', '--partition=p1,p2']
job.options = ['-C f1&f2', '--partition=p1,p2']
prepare_job(job)
assert job.num_tasks == 4

Expand Down Expand Up @@ -867,7 +867,7 @@ def test_flex_alloc_exclude_nodes_opt(make_flexible_job):
def test_flex_alloc_no_num_tasks_per_node(make_flexible_job):
job = make_flexible_job('all')
job.num_tasks_per_node = None
job.options = ['-C f1,f2', '--partition=p1,p2']
job.options = ['-C f1&f2', '--partition=p1,p2']
prepare_job(job)
assert job.num_tasks == 1

Expand All @@ -888,15 +888,15 @@ def test_flex_alloc_maintenance_nodes(make_flexible_job):

def test_flex_alloc_not_enough_nodes_constraint_partition(make_flexible_job):
job = make_flexible_job('all')
job.options = ['-C f1,f2', '--partition=p1,p2']
job.options = ['-C f1&f2', '--partition=p1,p2']
job.num_tasks = -8
with pytest.raises(JobError):
prepare_job(job)


def test_flex_alloc_enough_nodes_constraint_partition(make_flexible_job):
job = make_flexible_job('all')
job.options = ['-C f1,f2', '--partition=p1,p2']
job.options = ['-C f1&f2', '--partition=p1,p2']
job.num_tasks = -4
prepare_job(job)
assert job.num_tasks == 4
Expand Down