|
1 | | -from pydantic import BaseModel, field_serializer, ConfigDict |
| 1 | +from pydantic import BaseModel, field_serializer, Field, ConfigDict |
2 | 2 | import datetime |
3 | 3 | from enum import IntEnum |
4 | 4 |
|
5 | 5 |
|
6 | 6 | class ResourceSpec(BaseModel): |
7 | | - node_count: int | None = None |
8 | | - process_count: int | None = None |
9 | | - processes_per_node: int | None = None |
10 | | - cpu_cores_per_process: int | None = None |
11 | | - gpu_cores_per_process: int | None = None |
12 | | - exclusive_node_use: bool = True |
13 | | - memory: int | None = None |
| 7 | + """ |
| 8 | + Specification of computational resources required for a job. |
| 9 | + """ |
| 10 | + node_count: int | None = Field(default=None, description="Number of compute nodes to allocate") |
| 11 | + process_count: int | None = Field(default=None, description="Total number of processes to launch") |
| 12 | + processes_per_node: int | None = Field(default=None, description="Number of processes to launch per node") |
| 13 | + cpu_cores_per_process: int | None = Field(default=None, description="Number of CPU cores to allocate per process") |
| 14 | + gpu_cores_per_process: int | None = Field(default=None, description="Number of GPU cores to allocate per process") |
| 15 | + exclusive_node_use: bool = Field(default=True, description="Whether to request exclusive use of allocated nodes") |
| 16 | + memory: int | None = Field(default=None, description="Amount of memory to allocate in bytes") |
14 | 17 |
|
15 | 18 |
|
16 | 19 | class JobAttributes(BaseModel): |
| 20 | + """ |
| 21 | + Additional attributes and scheduling parameters for a job. |
| 22 | + """ |
17 | 23 | duration: int | None = Field( |
18 | 24 | default=None, |
19 | 25 | description="Duration in seconds", |
20 | 26 | ge=0, |
21 | 27 | examples=[30, 60, 120] |
22 | 28 | ) |
23 | | - queue_name: str | None = None |
24 | | - account: str | None = None |
25 | | - reservation_id: str | None = None |
26 | | - custom_attributes: dict[str, str] = {} |
| 29 | + queue_name: str | None = Field(default=None, description="Name of the queue or partition to submit the job to") |
| 30 | + account: str | None = Field(default=None, description="Account or project to charge for resource usage") |
| 31 | + reservation_id: str | None = Field(default=None, description="ID of a reservation to use for the job") |
| 32 | + custom_attributes: dict[str, str] = Field(default={}, description="Custom scheduler-specific attributes as key-value pairs") |
27 | 33 |
|
28 | 34 |
|
29 | 35 | class VolumeMount(BaseModel): |
30 | | - source: str |
31 | | - target: str |
32 | | - read_only: bool = True |
| 36 | + """ |
| 37 | + Represents a volume mount for a container. |
| 38 | + """ |
| 39 | + source: str = Field(description="The source path on the host system to mount") |
| 40 | + target: str = Field(description="The target path inside the container where the volume will be mounted") |
| 41 | + read_only: bool = Field(default=True, description="Whether the mount should be read-only") |
33 | 42 |
|
34 | 43 | class Container(BaseModel): |
35 | | - image: str |
36 | | - volume_mounts: list[VolumeMount] = [] |
| 44 | + """ |
| 45 | + Represents a container specification for job execution. |
| 46 | +
|
| 47 | + Implementation notes: The value of gpu_cores_per_process in ResourceSpec should be used to determine |
| 48 | + if the container should be run with GPU support. Likewise, the value of launcher in JobSpec should be used |
| 49 | + to determine if the container should be run with MPI support. The container should by default. be run with |
| 50 | + host networking. |
| 51 | + """ |
| 52 | + image: str = Field(description="The container image to use (e.g., 'docker.io/library/ubuntu:latest')") |
| 53 | + volume_mounts: list[VolumeMount] = Field(default=[], description="List of volume mounts for the container") |
37 | 54 |
|
38 | 55 |
|
39 | 56 | class JobSpec(BaseModel): |
| 57 | + """ |
| 58 | + Specification for job. |
| 59 | + """ |
40 | 60 | model_config = ConfigDict(extra="forbid") |
41 | | - executable : str | None = None |
42 | | - container: Container | None = None |
43 | | - arguments: list[str] = [] |
44 | | - directory: str | None = None |
45 | | - name: str | None = None |
46 | | - inherit_environment: bool = True |
47 | | - environment: dict[str, str] = {} |
48 | | - stdin_path: str | None = None |
49 | | - stdout_path: str | None = None |
50 | | - stderr_path: str | None = None |
51 | | - resources: ResourceSpec | None = None |
52 | | - attributes: JobAttributes | None = None |
53 | | - pre_launch: str | None = None |
54 | | - post_launch: str | None = None |
55 | | - launcher: str | None = None |
| 61 | + executable: str | None = Field(default=None, description="Path to the executable to run. If container is specified, this will be used as the entrypoint to the container.") |
| 62 | + container: Container | None = Field(default=None, description="Container specification for containerized execution") |
| 63 | + arguments: list[str] = Field(default=[], description="Command-line arguments to pass to the executable or container") |
| 64 | + directory: str | None = Field(default=None, description="Working directory for the job") |
| 65 | + name: str | None = Field(default=None, description="Name of the job") |
| 66 | + inherit_environment: bool = Field(default=True, description="Whether to inherit the environment variables from the submission environment") |
| 67 | + environment: dict[str, str] = Field(default={}, description="Environment variables to set for the job. If container is specified, these will be set inside the container.") |
| 68 | + stdin_path: str | None = Field(default=None, description="Path to file to use as standard input") |
| 69 | + stdout_path: str | None = Field(default=None, description="Path to file to write standard output") |
| 70 | + stderr_path: str | None = Field(default=None, description="Path to file to write standard error") |
| 71 | + resources: ResourceSpec | None = Field(default=None, description="Resource requirements for the job") |
| 72 | + attributes: JobAttributes | None = Field(default=None, description="Additional job attributes such as duration, queue, and account") |
| 73 | + pre_launch: str | None = Field(default=None, description="Script or commands to run before launching the job") |
| 74 | + post_launch: str | None = Field(default=None, description="Script or commands to run after the job completes") |
| 75 | + launcher: str | None = Field(default=None, description="Job launcher to use (e.g., 'mpirun', 'srun')") |
56 | 76 |
|
57 | 77 |
|
58 | 78 | class CommandResult(BaseModel): |
|
0 commit comments