Skip to content

Commit

Permalink
Added resource specs to PBS executor, which were somehow missing.
Browse files Browse the repository at this point in the history
Also split PBS executor into pbs_classic (the one using `:ppn` to specify
processes per node) and the modern pbspro/openpbs (using `select=:ncpus=`).
  • Loading branch information
hategan committed Jan 15, 2024
1 parent 9e6abb9 commit 5706789
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 21 deletions.
11 changes: 11 additions & 0 deletions src/psij-descriptors/pbs_descriptor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from distutils.version import StrictVersion

from psij.descriptor import Descriptor


__PSI_J_EXECUTORS__ = [Descriptor(name='pbs', nice_name='PBS Pro', aliases=['pbspro'],
version=StrictVersion('0.0.2'),
cls='psij.executors.batch.pbs.PBSJobExecutor'),
Descriptor(name='pbs_classic', nice_name='PBS Classic', aliases=['torque'],
version=StrictVersion('0.0.2'),
cls='psij.executors.batch.pbs_classic.PBSClassicJobExecutor')]
8 changes: 0 additions & 8 deletions src/psij-descriptors/pbspro_descriptor.py

This file was deleted.

27 changes: 27 additions & 0 deletions src/psij/executors/batch/pbs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from pathlib import Path
from typing import Optional

from psij.executors.batch.pbs_base import PBSExecutorConfig, GenericPBSJobExecutor
from psij.executors.batch.script_generator import TemplatedScriptGenerator


class PBSJobExecutor(GenericPBSJobExecutor):
"""A :class:`~psij.JobExecutor` for PBS Pro and friends.
This executor uses resource specifications specific to PBS Pro
"""

def __init__(self, url: Optional[str] = None, config: Optional[PBSExecutorConfig] = None):
"""
Parameters
----------
url
Not used, but required by the spec for automatic initialization.
config
An optional configuration for this executor.
"""
if not config:
config = PBSExecutorConfig()
generator = TemplatedScriptGenerator(config, Path(__file__).parent / 'pbspro'
/ 'pbspro.mustache')
super().__init__(generator, url=url, config=config)

Check warning on line 27 in src/psij/executors/batch/pbs.py

View check run for this annotation

Codecov / codecov/patch

src/psij/executors/batch/pbs.py#L27

Added line #L27 was not covered by tests
71 changes: 71 additions & 0 deletions src/psij/executors/batch/pbs/pbs_classic.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/bin/bash


{{#job.name}}
#PBS -N="{{.}}"
{{/job.name}}

{{#job.spec.inherit_environment}}
#PBS -V
{{/job.spec.inherit_environment}}

{{#job.spec.resources}}
{{#process_count}}
#PBS -l nodes={{job.spec.resources.computed_node_count}}:ppn={{.}}{{#job.spec.resources.gpu_cores_per_process}}:gpus={{.}}{{/job.spec.resources.gpu_cores_per_process}}
{{/process_count}}
{{#exclusive_node_use}}
#PBS -n
{{/exclusive_node_use}}
{{/job.spec.resources}}

{{#formatted_job_duration}}
#PBS -l walltime={{.}}
{{/formatted_job_duration}}

{{#job.spec.attributes}}
{{#project_name}}
#PBS -P {{.}}
{{/project_name}}
{{#queue_name}}
#PBS -q {{.}}
{{/queue_name}}
{{!PBS uses specially named queues for reservations, so we send the job to the respective
queue when a reservation ID is specified.}}
{{#reservation_id}}
#PBS -q {{.}}
{{/reservation_id}}
{{/job.spec.attributes}}

{{#custom_attributes}}
{{#pbs}}
#PBS -{{key}} "{{value}}"
{{/pbs}}
{{/custom_attributes}}


{{!since we redirect the output manually, below, tell pbs not to do its own thing, since it
only results in empty files that are not cleaned up}}
#PBS -e /dev/null
#PBS -o /dev/null

{{#job.spec.inherit_environment}}
#PBS -V
{{/job.spec.inherit_environment}}
{{#env}}
#PBS -v {{name}}={{value}}
{{/env}}

PSIJ_NODEFILE="$PBS_NODEFILE"
export PSIJ_NODEFILE


{{#job.spec.directory}}
cd "{{.}}"
{{/job.spec.directory}}

exec &>> "{{psij.script_dir}}/$PBS_JOBID.out"

{{#psij.launch_command}}{{.}} {{/psij.launch_command}}

{{!we redirect to a file tied to the native ID so that we can reach the file with attach().}}
echo "$?" > "{{psij.script_dir}}/$PBS_JOBID.ec"
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/bin/bash

# TODO: job.spec.resources
# TODO: job.spec.attributes

{{#job.name}}
#PBS -N="{{.}}"
Expand All @@ -11,6 +9,18 @@
#PBS -V
{{/job.spec.inherit_environment}}

{{#job.spec.resources}}
{{#process_count}}
#PBS -l select={{job.spec.resources.computed_node_count}}:ncpus={{.}}
{{/process_count}}
{{#exclusive_node_use}}
#PBS -l place=scatter:exclhost
{{/exclusive_node_use}}
{{^exclusive_node_use}}
#PBS -l place=scatter:shared
{{/exclusive_node_use}}
{{/job.spec.resources}}

{{#formatted_job_duration}}
#PBS -l walltime={{.}}
{{/formatted_job_duration}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

_QSTAT_COMMAND = 'qstat'

# This table maps PBS Pro state codes to the corresponding PSI/J
# This table maps PBS state codes to the corresponding PSI/J
# JobState.
# See https://www.altair.com/pdfs/pbsworks/PBSReferenceGuide2021.1.pdf
# page 361, section 8.1 "Job States"
Expand Down Expand Up @@ -39,14 +39,14 @@
}


class PBSProExecutorConfig(BatchSchedulerExecutorConfig):
"""A configuration class for the PBS executor."""
class PBSExecutorConfig(BatchSchedulerExecutorConfig):
"""A generic configuration class for PBS-type executors."""

pass


class PBSProJobExecutor(BatchSchedulerExecutor):
"""A :class:`~psij.JobExecutor` for PBS.
class GenericPBSJobExecutor(BatchSchedulerExecutor):
"""A generic :class:`~psij.JobExecutor` for PBS-type schedulers.
PBS, originally developed by NASA, is one of the oldest resource managers still in use.
A number of variations are available: `PBS Pro <https://www.altair.com/pbs-professional/>`_,
Expand All @@ -60,7 +60,8 @@ class PBSProJobExecutor(BatchSchedulerExecutor):
Creates a batch script with #PBS directives when submitting a job.
"""

def __init__(self, url: Optional[str] = None, config: Optional[PBSProExecutorConfig] = None):
def __init__(self, generator: TemplatedScriptGenerator, url: Optional[str] = None,
config: Optional[PBSExecutorConfig] = None) -> None:
"""
Parameters
----------
Expand All @@ -69,11 +70,8 @@ def __init__(self, url: Optional[str] = None, config: Optional[PBSProExecutorCon
config
An optional configuration for this executor.
"""
if not config:
config = PBSProExecutorConfig()
super().__init__(url=url, config=config)
self.generator = TemplatedScriptGenerator(config, Path(__file__).parent / 'pbspro'
/ 'pbspro.mustache')
self.generator = generator

# Submit methods

Expand Down
29 changes: 29 additions & 0 deletions src/psij/executors/batch/pbs_classic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from pathlib import Path
from typing import Optional

from psij.executors.batch.pbs_base import PBSExecutorConfig, GenericPBSJobExecutor
from psij.executors.batch.script_generator import TemplatedScriptGenerator


class PBSClassicJobExecutor(GenericPBSJobExecutor):
"""A :class:`~psij.JobExecutor` for classic PBS systems.
This executor uses resource specifications specific to Open PBS. Specifically,
this executor uses the `-l nodes=n:ppn=m` way of specifying nodes, which
differs from the scheme used by PBS Pro.
"""

def __init__(self, url: Optional[str] = None, config: Optional[PBSExecutorConfig] = None):
"""
Parameters
----------
url
Not used, but required by the spec for automatic initialization.
config
An optional configuration for this executor.
"""
if not config:
config = PBSExecutorConfig()
generator = TemplatedScriptGenerator(config, Path(__file__).parent / 'pbs'
/ 'pbs_classic.mustache')
super().__init__(generator, url=url, config=config)
2 changes: 1 addition & 1 deletion tests/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def _check_str_attrs(ex: BatchSchedulerExecutor, job: Job, names: List[str],
pytest.fail('Script generation failed for %s' % name)


_PREFIX_TR = {'pbspro': 'pbs'}
_PREFIX_TR = {'pbspro': 'pbs', 'pbs_classic': 'pbs'}


def _get_attr_prefix(exec_name: str) -> str:
Expand Down

0 comments on commit 5706789

Please sign in to comment.