Skip to content
1 change: 1 addition & 0 deletions docs/regression_test_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ Mapping of Test Attributes to Job Scheduler Backends
Test attribute Slurm option Torque option PBS option
============================ ============================= ========================================================================================== ==================
:attr:`num_tasks` :obj:`--ntasks`:sup:`1` :obj:`-l nodes={num_tasks//num_tasks_per_node}:ppn={num_tasks_per_node*num_cpus_per_task}` :obj:`-l select={num_tasks//num_tasks_per_node}:mpiprocs={num_tasks_per_node}:ncpus={num_tasks_per_node*num_cpus_per_task}`
:attr:`num_nodes` :obj:`--nodes` n/a n/a
:attr:`num_tasks_per_node` :obj:`--ntasks-per-node` see :attr:`num_tasks` see :attr:`num_tasks`
:attr:`num_tasks_per_core` :obj:`--ntasks-per-core` n/a n/a
:attr:`num_tasks_per_socket` :obj:`--ntasks-per-socket` n/a n/a
Expand Down
3 changes: 3 additions & 0 deletions reframe/core/launchers/mpi.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ def command(self, job):

if job.num_tasks:
ret += ['--ntasks=%s' % str(job.num_tasks)]

if job.num_nodes:
ret += ['--nodes=%s' % str(job.num_nodes)]

if job.num_tasks_per_node:
ret += ['--ntasks-per-node=%s' % str(job.num_tasks_per_node)]
Expand Down
15 changes: 13 additions & 2 deletions reframe/core/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,9 @@ def pipeline_hooks(cls):
#: :attr:`num_tasks` to ``0`` is equivalent to setting it to
#: :attr:`-num_tasks_per_node
#: <reframe.core.pipeline.RegressionTest.num_tasks_per_node>`.
#: If set to :attr:`None` it will be omitted from any job scripts created and when combined with :attr:`num_nodes` this will allow a more flexible number of tasks to be run.
#:
#: :type: integral
#: :type: integral or :class:`None`
#: :default: ``1``
#:
#: .. note::
Expand All @@ -541,7 +542,16 @@ def pipeline_hooks(cls):
#:
#: .. |--flex-alloc-nodes| replace:: :attr:`--flex-alloc-nodes`
#: .. _--flex-alloc-nodes: manpage.html#cmdoption-flex-alloc-nodes
num_tasks = variable(int, value=1, loggable=True)
num_tasks = variable(int,type(None), value=1, loggable=True)


#: Number of nodes for this job.
#:
#: :type: integral or :class:`None`
#: :default: ``None``
#:
#:
num_nodes = variable(int, type(None), value=None,loggable=True)

#: Number of tasks per node required by this test.
#:
Expand Down Expand Up @@ -1872,6 +1882,7 @@ def _get_cp_env():
)

self.job.num_tasks = self.num_tasks
self.job.num_nodes = self.num_nodes
self.job.num_tasks_per_node = self.num_tasks_per_node
self.job.num_tasks_per_core = self.num_tasks_per_core
self.job.num_tasks_per_socket = self.num_tasks_per_socket
Expand Down
14 changes: 12 additions & 2 deletions reframe/core/schedulers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,17 @@ class Job(jsonext.JSONSerializable, metaclass=JobMeta):
#: based on the test information.
#:
#: .. versionadded:: 3.11.0
num_tasks = variable(int, value=1)
num_tasks = variable(int, type(None), value=1)



#: Number of nodes for this job.
#:
#: :type: integral or :class:`None`
#: :default: ``None``
#:
#:
num_nodes = variable(int, type(None), value=None)

#: Number of tasks per node for this job.
#:
Expand Down Expand Up @@ -461,7 +471,7 @@ def submit_time(self):

def prepare(self, commands, environs=None, prepare_cmds=None, **gen_opts):
environs = environs or []
if self.num_tasks <= 0:
if self.num_tasks!=None and self.num_tasks <= 0:
getlogger().debug(f'[F] Flexible node allocation requested')
num_tasks_per_node = self.num_tasks_per_node or 1
min_num_tasks = (-self.num_tasks if self.num_tasks else
Expand Down
3 changes: 2 additions & 1 deletion reframe/core/schedulers/slurm.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def emit_preamble(self, job):
self._format_option(job.num_tasks_per_socket,
'--ntasks-per-socket={0}'),
self._format_option(job.num_cpus_per_task, '--cpus-per-task={0}'),
self._format_option(job.num_nodes, '--nodes={0}')
]

# Determine if job refers to a Slurm job array, by looking into the
Expand Down Expand Up @@ -199,7 +200,7 @@ def emit_preamble(self, job):
self._format_option(job.exclusive_access, '--exclusive')
)

if self._use_nodes_opt:
if self._use_nodes_opt and job.num_nodes==None:
num_nodes = job.num_tasks // job.num_tasks_per_node
preamble.append(self._format_option(num_nodes, '--nodes={0}'))

Expand Down