Getting Started#
seamm_scheduler talks to queueing systems – SLURM and PBS today – through
one interface. It has no SEAMM-core dependency and no notion of SEAMM’s own job
states; it only speaks the queueing systems’.
Installing#
The library has no runtime dependencies:
pip install seamm-scheduler
Submitting and polling#
from seamm_scheduler import QueueBackend, LocalTransport, SshTransport
from seamm_scheduler import build_script, get_scheduler
slurm = get_scheduler("slurm")
backend = QueueBackend(slurm, SshTransport("tinkercliffs"))
# or, on a login node: QueueBackend(slurm, LocalTransport())
directives = slurm.directives(
{"ntasks": 4, "mem_per_cpu": 2 * 1024**3, "walltime": 3600},
extra={"partition": "normal_q", "account": "seamm", "export": "NONE"},
)
script = build_script(directives, "module load ORCA\norca orca.inp > orca.out")
job_id = backend.submit(script, job_name="demo")
status = backend.poll_many([job_id])[job_id]
print(status.state, status.category, status.task_state)
poll_many takes many ids and uses as few commands as the scheduler allows.
A job the scheduler no longer knows is absent from the result; if the queue
could not be asked at all (backend.scheduler.poll_failed), absence means
nothing.
The historical SLURM classes are still here: LocalSlurm() and
SshSlurm(host) are QueueBackend subclasses with SLURM built in.
Targets#
seamm_scheduler.config reads a JobServer’s <root>/<jobserver-name>.ini.
Each section is a target:
[DEFAULT]
default = local
[local]
type = local
tasks = pool
[arc]
type = local ; the evaluator runs on the JobServer's host
tasks = queue ; its tasks go to a queue
scheduler = slurm
transport = ssh
host = tinkercliffs
remote_root = /projects/seamm/psaxe/tasks
remote_python = /projects/seamm/SEAMM/venv/bin/python
account = seamm
partition = normal_q
qos = tc_normal_short
export = NONE
bundle_tasks = 8
max_queued_tasks = 800
max_walltime = 3-00:00:00 ; retries never ask for more time than this
from seamm_scheduler import list_sections
sections = list_sections("~/SEAMM", "chemai")
arc = sections["arc"]
queue = arc.build_task_backend() # the QueueBackend for its tasks
stager = arc.build_task_stager() # RsyncStager, or LocalStager if shared
A section without tasks = means exactly what it did before the task keys
existed. See seamm_exec’s task layer for what the keys do.
Where the flowchart itself runs is the section’s type:
localas a subprocess on the JobServer’s host;
queueas a batch job on the queueing system named by
scheduler(slurm, the default,pbs, orseammfor a machine’s own TaskServer – see The TaskServer), through the section’stransport;slurmthe original spelling of
queuewithscheduler = slurm; still accepted.
A PBS section may give PBS’s own directives or the portable spellings:
[molssi10]
type = queue
scheduler = pbs
transport = ssh
host = molssi10
remote_root = /home/psaxe/seamm_jobs
remote_run_from_jobserver = /home/psaxe/SEAMM/venv/bin/run_from_jobserver
queue = workq ; or partition =
walltime = 01:00:00 ; or time =, in SLURM's forms too
select = 1:ncpus=1:mem=20gb ; or ntasks =, mem =, mem_per_cpu = ...
The resources become one select chunk, merged into the section’s
select: a job’s or a bundle’s cores replace the section’s, its memory is
kept unless the job sets one. A PBS job starts in the home directory, so the
script begins with a cd into the job’s directory. Like SLURM’s default, a
PBS flowchart job gets the JobServer’s environment (-V); with
export = NONE it gets only PBS’s PBS_O_* variables, so the section must
then use an absolute remote_run_from_jobserver (or a setup = that
prepares the environment), not remote_conda_env.
The remote host needs this version of seamm_scheduler (or later) too: an
older one does not know type = queue and would treat an evaluator running
inside a PBS job as if it had to reach the cluster over ssh.
Adding a queueing system#
Subclass seamm_scheduler.scheduler.Scheduler in a new module (see
pbs.py), implement the directive, command and parsing methods, and add it
to SCHEDULERS in scheduler.py.