Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add missing functions to LSFSettings API #113

Merged
merged 10 commits into from
Dec 9, 2021
3 changes: 3 additions & 0 deletions smartsim/launcher/pbs/pbsParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def parse_qstat_jobid(output, job_id):
"""
result = "NOTFOUND"
for line in output.split("\n"):
fields = line.split()
if len(fields) < 5:
continue
if line.split()[0] == job_id:
line = line.split()
stat = line[4]
Expand Down
6 changes: 5 additions & 1 deletion smartsim/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,14 @@ def __str__(self):


class BatchSettings:
def __init__(self, batch_cmd, batch_args=None):
def __init__(self, batch_cmd, batch_args=None, **kwargs):
self._batch_cmd = batch_cmd
self.batch_args = init_default({}, batch_args, dict)
self._preamble = []
self.set_nodes(kwargs.get("nodes", None))
self.set_walltime(kwargs.get("time", None))
self.set_queue(kwargs.get("queue", None))
self.set_account(kwargs.get("account", None))

@property
def batch_cmd(self):
Expand Down
31 changes: 17 additions & 14 deletions smartsim/settings/cobaltSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,14 @@ def __init__(
:param batch_args: extra batch arguments, defaults to None
:type batch_args: dict[str, str], optional
"""
super().__init__("qsub", batch_args=batch_args)
if nodes:
self.set_nodes(nodes)
if time:
self.set_walltime(time)
if account:
self.set_account(account)
if queue:
self.set_queue(queue)
super().__init__("qsub",
batch_args=batch_args,
nodes=nodes,
account=account,
queue=queue,
time=time,
**kwargs)


def set_walltime(self, walltime):
"""Set the walltime of the job
Expand All @@ -73,7 +72,8 @@ def set_walltime(self, walltime):
"""
# TODO check for formatting errors here
# TODO catch existing "t" in batch_args
self.batch_args["time"] = walltime
if walltime:
self.batch_args["time"] = walltime

def set_nodes(self, num_nodes):
"""Set the number of nodes for this batch job
Expand All @@ -82,7 +82,8 @@ def set_nodes(self, num_nodes):
:type num_nodes: int
"""
# TODO catch existing "n" in batch_args
self.batch_args["nodecount"] = int(num_nodes)
if num_nodes:
self.batch_args["nodecount"] = int(num_nodes)

def set_hostlist(self, host_list):
"""Specify the hostlist for this job
Expand Down Expand Up @@ -115,16 +116,18 @@ def set_queue(self, queue):
:type queue: str
"""
# TODO catch existing "q" in batch args
self.batch_args["queue"] = str(queue)
if queue:
self.batch_args["queue"] = str(queue)

def set_account(self, acct):
def set_account(self, account):
"""Set the account for this batch job

:param acct: account id
:type acct: str
"""
# TODO catch existing "A" in batch_args
self.batch_args["project"] = acct
if account:
self.batch_args["project"] = account

def format_batch_args(self):
"""Get the formatted batch arguments for a preview
Expand Down
158 changes: 104 additions & 54 deletions smartsim/settings/lsfSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@


class JsrunSettings(RunSettings):
def __init__(self, exe, exe_args=None, run_args=None, env_vars=None):
def __init__(self, exe, exe_args=None, run_args=None, env_vars=None, **kwargs):
"""Settings to run job with ``jsrun`` command

``JsrunSettings`` can be used for both the `lsf` launcher.
``JsrunSettings`` should only be used on LSF-based systems.

:param exe: executable
:type exe: str
Expand Down Expand Up @@ -67,61 +67,90 @@ def set_num_rs(self, num_rs):
else:
self.run_args["nrs"] = int(num_rs)

def set_cpus_per_rs(self, num_cpus):
def set_cpus_per_rs(self, cpus_per_rs):
"""Set the number of cpus to use per resource set

This sets ``--cpu_per_rs``

:param num_cpus: number of cpus to use per resource set or ALL_CPUS
:type num_cpus: int or str
:param cpus_per_rs: number of cpus to use per resource set or ALL_CPUS
:type cpus_per_rs: int or str
"""
if isinstance(num_cpus, str):
self.run_args["cpu_per_rs"] = num_cpus
if isinstance(cpus_per_rs, str):
self.run_args["cpu_per_rs"] = cpus_per_rs
else:
self.run_args["cpu_per_rs"] = int(num_cpus)
self.run_args["cpu_per_rs"] = int(cpus_per_rs)

def set_gpus_per_rs(self, num_gpus):
def set_gpus_per_rs(self, gpus_per_rs):
"""Set the number of gpus to use per resource set

This sets ``--gpu_per_rs``

:param num_cpus: number of gpus to use per resource set or ALL_GPUS
:type num_gpus: int or str
:param gpus_per_rs: number of gpus to use per resource set or ALL_GPUS
:type gpus_per_rs: int or str
"""
if isinstance(num_gpus, str):
self.run_args["gpu_per_rs"] = num_gpus
if isinstance(gpus_per_rs, str):
self.run_args["gpu_per_rs"] = gpus_per_rs
else:
self.run_args["gpu_per_rs"] = int(num_gpus)
self.run_args["gpu_per_rs"] = int(gpus_per_rs)

def set_rs_per_host(self, num_rs):
def set_rs_per_host(self, rs_per_host):
"""Set the number of resource sets to use per host

This sets ``--rs_per_host``

:param num_rs: number of resource sets to use per host
:type num_rs: int
:param rs_per_host: number of resource sets to use per host
:type rs_per_host: int
"""
self.run_args["rs_per_host"] = int(num_rs)
self.run_args["rs_per_host"] = int(rs_per_host)

def set_tasks(self, num_tasks):
def set_tasks(self, tasks):
"""Set the number of tasks for this job

This sets ``--np``

:param num_tasks: number of tasks
:type num_tasks: int
:param tasks: number of tasks
:type tasks: int
"""
self.run_args["np"] = int(num_tasks)
self.run_args["np"] = int(tasks)

def set_tasks_per_rs(self, num_tprs):
def set_tasks_per_rs(self, tasks_per_rs):
"""Set the number of tasks per resource set

This sets ``--tasks_per_rs``

:param num_tpn: number of tasks per resource set
:type num_tpn: int
:param tasks_per_rs: number of tasks per resource set
:type tasks_per_rs: int
"""
self.run_args["tasks_per_rs"] = int(num_tprs)
self.run_args["tasks_per_rs"] = int(tasks_per_rs)

def set_tasks_per_node(self, tasks_per_node):
"""Set the number of tasks per resource set.

This function is an alias for `set_tasks_per_rs`.

:param tasks_per_node: number of tasks per resource set
:type tasks_per_node: int
"""
self.set_tasks_per_rs(tasks_per_node)

def set_hostlist(self, host_list):
"""This function has no effect.

This function is only available to unify LSFSettings
to other WLM settings classes.

"""
pass

def set_cpus_per_task(self, cpus_per_task):
"""Set the number of cpus per tasks.

This function is an alias for `set_cpus_per_rs`.

:param cpus_per_task: number of cpus per resource set
:type cpus_per_task: int
"""
self.set_cpus_per_rs(cpus_per_task)

def set_binding(self, binding):
"""Set binding
Expand Down Expand Up @@ -302,37 +331,40 @@ def __init__(
:param smts: SMTs, defaults to None
:type smts: int, optional
"""
super().__init__("bsub", batch_args=batch_args)
if nodes:
self.set_nodes(nodes)
self.set_walltime(time)
self.set_project(project)
if project:
kwargs.pop("account", None)
else:
project = kwargs.pop("account", None)

super().__init__("bsub",
batch_args=batch_args,
nodes=nodes,
account=project,
time=time,
**kwargs)

if smts:
self.set_smts(smts)
else:
self.smts = None
self.expert_mode = False
self.easy_settings = ["ln_slots", "ln_mem", "cn_cu", "nnodes"]

def set_walltime(self, time):
def set_walltime(self, walltime):
"""Set the walltime

This sets ``-W``.

:param time: Time in hh:mm format, e.g. "10:00" for 10 hours
:type time: str
"""
self.walltime = time

def set_queue(self, queue):
"""Set the queue

This sets ``-q``.

:param queue: queue name
:type queue: str
:param walltime: Time in hh:mm format, e.g. "10:00" for 10 hours,
if time is supplied in hh:mm:ss format, seconds
will be ignored and walltime will be set as ``hh:mm``
:type walltime: str
"""
self.batch_args["q"] = queue
# For compatibility with other launchers, as explained in docstring
if walltime:
if len(walltime.split(":")) > 2:
walltime = ":".join(walltime.split(":")[:2])
self.walltime = walltime

def set_smts(self, smts):
"""Set SMTs
Expand All @@ -357,17 +389,26 @@ def set_project(self, project):
self.project = project

def set_account(self, account):
self.project = account
"""Set the project

this function is an alias for `set_project`.

:param account: project name
:type account: str
"""
if account:
self.set_project(account)

def set_nodes(self, num_nodes):
"""Set the number of nodes for this batch job

This sets ``-nnodes``.

:param num_nodes: number of nodes
:type num_nodes: int
:param nodes: number of nodes
:type nodes: int
"""
self.batch_args["nnodes"] = int(num_nodes)
if num_nodes:
self.batch_args["nnodes"] = int(num_nodes)

def set_expert_mode_req(self, res_req, slots):
"""Set allocation for expert mode. This
Expand Down Expand Up @@ -396,15 +437,24 @@ def set_hostlist(self, host_list):
raise TypeError("host_list argument must be list of strings")
self.batch_args["m"] = '"' + " ".join(host_list) + '"'

def set_tasks(self, num_tasks):
def set_tasks(self, tasks):
"""Set the number of tasks for this job

This sets ``-n``

:param num_tasks: number of tasks
:type num_tasks: int
:param tasks: number of tasks
:type tasks: int
"""
self.batch_args["n"] = int(tasks)

def set_queue(self, queue):
"""Set the queue for this job

:param queue: The queue to submit the job on
:type queue: str
"""
self.batch_args["n"] = int(num_tasks)
if queue:
self.batch_args["q"] = queue

def _format_alloc_flags(self):
"""Format ``alloc_flags`` checking if user already
Expand All @@ -431,7 +481,7 @@ def _format_alloc_flags(self):
def format_batch_args(self):
"""Get the formatted batch arguments for a preview

:return: list of batch arguments for bsub
:return: list of batch arguments for Qsub
:rtype: list[str]
"""
opts = []
Expand Down
Loading