Prolog 和 Epilog 指南

Slurm 支持多种 prolog 和 epilog 程序。 请注意出于安全原因,这些程序没有设置搜索路径。 请在程序中指定完全限定的路径名,或者设置 PATH 环境变量。 下面的第一个表格标识了在作业分配中可用的 prolog 和 epilog,以及它们运行的时间和地点。

参数

位置

调用者

用户

执行时间

Prolog (来自 slurm.conf)

计算节点

slurmd 守护进程

SlurmdUser(通常是 root 用户)

在该节点上首次启动作业或作业步骤(默认情况下); PrologFlags=Alloc 将强制在作业分配时执行脚本

PrologSlurmctld (来自 slurm.conf)

主节点(运行 slurmctld 守护进程的地方)

slurmctld 守护进程

SlurmctldUser

在作业分配时

Epilog (来自 slurm.conf)

计算节点

slurmd 守护进程

SlurmdUser(通常是 root 用户)

在作业终止时

EpilogSlurmctld (来自 slurm.conf)

主节点(运行 slurmctld 守护进程的地方)

slurmctld 守护进程

SlurmctldUser

在作业终止时


下面的第二个表格标识了在作业步骤分配中可用的 prolog 和 epilog,以及它们运行的时间和地点。

参数

位置

调用者

用户

执行时间

SrunProlog (来自 slurm.conf) 或 srun --prolog

srun 调用节点

srun 命令

调用 srun 命令的用户

在启动作业步骤之前

TaskProlog (来自 slurm.conf)

计算节点

slurmstepd 守护进程

调用 srun 命令的用户

在启动作业步骤之前

srun --task-prolog

计算节点

slurmstepd 守护进程

调用 srun 命令的用户

在启动作业步骤之前

TaskEpilog (来自 slurm.conf)

计算节点

slurmstepd 守护进程

调用 srun 命令的用户

完成作业步骤

srun --task-epilog

计算节点

slurmstepd 守护进程

调用 srun 命令的用户

完成作业步骤

SrunEpilog (来自 slurm.conf) 或 srun --epilog

srun 调用节点

srun 命令

调用 srun 命令的用户

完成作业步骤

默认情况下,Prolog 脚本仅在任何单个节点首次看到来自新分配的作业步骤时运行;它不会在分配被授予时立即运行 Prolog。 如果在节点上没有运行来自分配的作业步骤,则该节点将永远不会运行该分配的 Prolog。 此 Prolog 行为可以通过 PrologFlags 参数进行更改。 另一方面,Epilog 始终在释放分配时在每个节点上运行。

如果指定了多个 prolog 和/或 epilog 脚本, (例如 "/etc/slurm/prolog.d/*"),它们将按字母逆序运行 (z-a -> Z-A -> 9-0)。

Prolog 和 Epilog 脚本应设计得尽可能简短, 并且不应调用 Slurm 命令(例如 squeue、scontrol、sacctmgr 等)。 长时间运行的脚本可能会导致调度问题,因为作业需要很长时间才能启动或完成。 这些脚本中的 Slurm 命令可能会导致性能问题,因此不应使用。

任务 prolog 在与要启动的用户任务相同的环境中执行。 该程序的标准输出将被读取并处理如下:
export name=value 为用户任务设置一个环境变量
unset name 从用户任务中清除一个环境变量
print ... 写入任务的标准输出。

TaskProlog 脚本可以只是一个 bash 脚本。以下是一个非常基本的示例:

#!/bin/bash

# TaskProlog 脚本可用于在运行作业步骤之前进行任何必要的准备工作,
# 也可以用于修改用户的环境。主要有两种机制可以实现,
# 依赖于将命令打印到标准输出:

# 为用户提供一个变量
echo "export VARIABLE_1=HelloWorld"

# 为用户取消设置变量
echo "unset MANPATH"

# 如果需要,我们也可以打印消息
echo "print 此消息已通过 TaskProlog 打印"

上述功能仅限于任务 prolog 脚本。

除非另有说明,这些环境变量对所有程序可用。

  • CUDA_MPS_ACTIVE_THREAD_PERCENTAGE 指定应分配给作业的 GPU 百分比。 仅在配置了 gres/mps 插件并且作业请求这些资源时设置该值。 仅在 Prolog 和 Epilog 中可用。
  • CUDA_VISIBLE_DEVICES 指定作业分配的 GPU 设备。 仅在配置了 gres/gpu 或 gres/mps 插件并且作业请求这些资源时设置该值。 请注意,如果 Slurm 配置为使用 Linux cgroup 限制作业可见的设备文件,则为作业设置的环境变量可能与为 Prolog 和 Epilog 设置的不同。 这是因为 Prolog 和 Epilog 程序在作业运行时在 外部 运行,而作业在 内部 运行 cgroup,因此可能具有不同的可见设备集。 例如,如果作业分配了设备 "/dev/nvidia1",则 CUDA_VISIBLE_DEVICES 将在 Prolog 和 Epilog 中设置为 "1",而作业的 CUDA_VISIBLE_DEVICES 将设置为 "0"(即作业可见的第一个 GPU 设备)。 CUDA_VISIBLE_DEVICES 将被设置,除非通过 FlagsAutoDetect 选项在 gres.conf 中另行排除。另请参见 SLURM_JOB_GPUS。 仅在 Prolog 和 Epilog 中可用。
  • GPU_DEVICE_ORDINAL 指定作业分配的 GPU 设备。对于 CUDA_VISIBLE_DEVICES 的考虑同样适用于 GPU_DEVICE_ORDINAL
  • ROCR_VISIBLE_DEVICES 指定作业分配的 GPU 设备。对于 CUDA_VISIBLE_DEVICES 的考虑同样适用于 ROCR_VISIBLE_DEVICES
  • SLURM_ARRAY_JOB_ID 如果该作业是作业数组的一部分,则将其设置为作业 ID。 否则将不设置。 要引用作业数组的特定任务,请将 SLURM_ARRAY_JOB_IDSLURM_ARRAY_TASK_ID 结合使用 (例如 scontrol update ${SLURM_ARRAY_JOB_ID}_{$SLURM_ARRAY_TASK_ID} ...); 在 PrologSlurmctld、SrunProlog、TaskProlog、EpilogSlurmctld、 SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_ARRAY_TASK_COUNT 如果该作业是作业数组的一部分,则将其设置为数组中的任务数量。 否则将不设置。 在 PrologSlurmctld、SrunProlog、TaskProlog、EpilogSlurmctld、 SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_ARRAY_TASK_ID 如果该作业是作业数组的一部分,则将其设置为任务 ID。 否则将不设置。 要引用作业数组的特定任务,请将 SLURM_ARRAY_JOB_IDSLURM_ARRAY_TASK_ID 结合使用 (例如 scontrol update ${SLURM_ARRAY_JOB_ID}_{$SLURM_ARRAY_TASK_ID} ...); 在 PrologSlurmctld、SrunProlog、TaskProlog、EpilogSlurmctld、 SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_ARRAY_TASK_MAX 如果该作业是作业数组的一部分,则将其设置为最大任务 ID。 否则将不设置。 在 PrologSlurmctld、SrunProlog、TaskProlog、EpilogSlurmctld、 SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_ARRAY_TASK_MIN 如果该作业是作业数组的一部分,则将其设置为最小任务 ID。 否则将不设置。 在 PrologSlurmctld、SrunProlog、TaskProlog、EpilogSlurmctld、 SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_ARRAY_TASK_STEP 如果该作业是作业数组的一部分,则将其设置为任务 ID 的步长。 否则将不设置。 在 PrologSlurmctld、SrunProlog、TaskProlog、EpilogSlurmctld、 SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_CLUSTER_NAME 执行作业的集群名称。在 Prolog、PrologSlurmctld、 Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_CONF slurm.conf 文件的位置。在 Prolog、SrunProlog、TaskProlog、 Epilog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_CPUS_ON_NODE 当前节点上可用于作业的处理器数量。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_DISTRIBUTION 作业的分发类型。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURMD_NODENAME 运行任务的节点名称。在并行作业在多个计算节点上执行的情况下,各个任务将在每个计算节点上设置此环境变量为不同的值。在 Prolog、SrunProlog、TaskProlog、Epilog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_GPUS 可用于作业的 GPU 数量。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_GTID 在此节点上运行的全局任务 ID。零起始并以逗号分隔。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_JOB_ACCOUNT 用于作业的帐户名称。
  • SLURM_JOB_COMMENT 添加到作业的注释。 在 Prolog、PrologSlurmctld、Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_CONSTRAINTS 运行作业所需的特性。 在 Prolog、PrologSlurmctld、Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_CPUS_PER_NODE 每个节点可用的处理器数量。
  • SLURM_JOB_DERIVED_EC 所有作业步骤的最高退出代码。 在 Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_END_TIME 作业结束时间的 UNIX 时间戳。
  • SLURM_JOB_EXIT_CODE 作业脚本(或 salloc)的退出代码。该值是由 wait() 系统调用返回的状态 (参见 wait(2))。 在 Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_EXIT_CODE2 作业脚本(或 salloc)的退出代码。该值的格式为 <exit>:<sig>。 第一个数字是退出代码,通常由 exit() 函数设置。 第二个数字是导致进程终止的信号(如果它是由信号终止的)。 在 Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_EXTRA 添加到作业的额外字段。 在 Prolog、PrologSlurmctld、Epilog、EpilogSlurmctld 和 ResumeProgram(通过 SLURM_RESUME_FILE)中可用。
  • SLURM_JOB_GID 作业所有者的组 ID。
  • SLURM_JOB_GPUS 作业分配中的 GPU ID(如果有)。 在 Prolog、SrunProlog、TaskProlog、Epilog、SrunEpilog 和 TaskProlog 中可用。
  • SLURM_JOB_GROUP 作业所有者的组名称。 在 PrologSlurmctld 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_ID 作业 ID。
  • SLURM_JOBID 作业 ID。
  • SLURM_JOB_LICENSES 请求的任何许可证的名称和数量。
  • SLURM_JOB_NAME 作业名称。 在 PrologSlurmctld、SrunProlog、TaskProlog、EpilogSlurmctld、 SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_JOB_NODELIST 分配给作业的节点。Slurm 主机列表表达式。 scontrol show hostnames 可用于将其转换为单个主机名称列表。
  • SLURM_NTASKS 作业请求的任务数量。 在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_JOB_NUM_NODES 分配给作业的节点数量。
  • SLURM_JOB_OVERSUBSCRIBE 作业超分配状态。 请参见 squeue 手册页 以获取可能的值。 在 Prolog、PrologSlurmctld、Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_PARTITION 作业运行的分区。
  • SLURM_JOB_QOS 分配给作业的 QOS。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_JOB_RESERVATION 为作业请求的预留。
  • SLURM_JOB_RESTART_COUNT 作业重启的次数。 在 Prolog、PrologSlurmctld、Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_START_TIME 作业开始时间的 UNIX 时间戳。
  • SLURM_JOB_STDERR 作业的 stderr 路径。 在 Prolog、PrologSlurmctld、Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_STDIN 作业的 stdin 路径。 在 Prolog、PrologSlurmctld、Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_STDOUT 作业的 stdout 路径。 在 Prolog、PrologSlurmctld、Epilog 和 EpilogSlurmctld 中可用。
  • SLURM_JOB_UID 作业所有者的用户 ID。
  • SLURM_JOB_USER 作业所有者的用户名。
  • SLURM_JOB_WORK_DIR 作业的工作目录。在 Prolog、PrologSlurmctld、Epilog、 EpilogSlurmctld 中可用。
  • SLURM_LOCAL_GLOBALS_FILE 用于设置测试套件环境的全局文件。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_LOCALID 作业中进程的节点本地任务 ID。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_NNODES 分配给作业的节点数量。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_NODEID 相对于多节点作业中其他节点的当前节点 ID。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_PRIO_PROCESS 提交时的调度优先级(nice 值)。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_PROCID 当前进程的 MPI 排名(或相对进程 ID)。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RESTART_COUNT 作业重启的次数。仅在作业至少重启一次时设置。可在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中使用。
  • SLURM_RLIMIT_AS 作业地址空间的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_CORE 作业能够生成的核心文件大小的资源限制。 在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_CPU 作业能够使用的 CPU 时间的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_DATA 作业数据段大小的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_FSIZE 作业可以创建的最大文件大小的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_MEMLOCK 可以锁定到 RAM 中的数据字节的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_NOFILE 作业可以打开的文件描述符数量的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_NPROC 调用进程可以打开的进程数量的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_RSS 作业的常驻集大小的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_RLIMIT_STACK 作业的进程堆栈的资源限制。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_SCRIPT_CONTEXT 标识当前正在运行的 epilog 或 prolog 程序。 该值为以下之一:
    • prolog_slurmctld
    • epilog_slurmctld
    • prolog_slurmd
    • epilog_slurmd
    • prolog_task
    • epilog_task
    • prolog_srun
    • epilog_srun
  • SLURM_STEP_ID 当前作业的步骤 ID。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_STEPID 当前作业的步骤 ID。在 SrunProlog 和 SrunEpilog 中可用。
  • SLURM_SUBMIT_DIR 提交作业的目录,或者(如适用)由 -D, --chdir 选项指定的目录。在 SrunProlog、Taskprolog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_SUBMIT_HOST 提交作业的主机。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_TASK_PID 为任务启动的进程 ID。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_TASKS_PER_NODE 每个节点的任务数量。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_TOPOLOGY_ADDR 设置为可能参与作业通信的网络交换机或节点的名称。从顶级交换机开始到节点名称。 使用句点分隔每个硬件组件名称。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_TOPOLOGY_ADDR_PATTERN 设置为与 SLURM_TOPOLOGY_ADDR 中名称列表相对应的网络组件类型。 每个组件将被标识为 交换机节点。使用句点分隔每个组件类型。在 SrunProlog、TaskProlog、SrunEpilog 和 TaskEpilog 中可用。
  • SLURM_WCKEY 作业的 wckey 的用户名(如果有)。 仅在 PrologSlurmctld 和 EpilogSlurmctld 中可用。
  • 插件功能也可能在各个明确的点执行逻辑时非常有用。

    SPANK 是另一种机制,可能对在用户命令、slurmd 守护进程和 slurmstepd 守护进程中调用逻辑有用。

    故障处理

    如果 Epilog 失败(返回非零退出代码),则会导致节点设置为 DRAIN 状态。 如果 EpilogSlurmctld 失败(返回非零退出代码),则仅会记录该事件。 如果 Prolog 失败(返回非零退出代码),则会导致节点设置为 DRAIN 状态并重新排队作业。除非在 SchedulerParameters 中配置了 nohold_on_prolog_fail,否则作业将被置于保持状态。 如果 PrologSlurmctld 失败(返回非零退出代码),则会导致作业重新排队。仅批处理作业可以重新排队。如果 PrologSlurmctld 失败,则交互式作业(salloc 和 srun)将被取消。

    如果任务 epilog 或 srun epilog 失败(返回非零退出代码),则仅会记录该事件。 如果任务 prolog 失败(返回非零退出代码),则任务将被取消。 如果 srun prolog 失败(返回非零退出代码),则步骤将被取消。


    基于 Jason Sollom 和 Cray Inc. 的工作,并经许可使用。

    最后修改于 2025 年 3 月 12 日