Slurm
批作业文件示例
#!/bin/bash
#SBATCH --job-name='submit_command_job1' # 作业名
#SBATCH --chdir=/home/test/test_jobs/output # 工作目录(也是作业日志的输出目录)
#SBATCH --partition=queue2 # 队列名
#SBATCH --nodes=1 # 占用节点数量
#SBATCH --mincpus=64 # 每节点使用cpu的个数
#SBATCH --ntasks-per-node=5 # 每节点最多有几个tasks数量(也可以指定cpu数量,
# 一般有了mincpus就不需要这个参数了)
#SBATCH --gres=gpu:2 # 每节点使用gpu的个数
uuid=`uuidgen`
echo "==> SLURM_CPUS_ON_NODE: ${SLURM_CPUS_ON_NODE}"
echo "$uuid : $(date)" >> /home/test/test_jobs/a.log
sleep 360000
echo "$uuid : $(date)" >> /home/test/test_jobs/a.log
提交任务参数
【】中的内容属于个人补充!!!
sbatch
--array=0-5 # 提交数组作业,作业实际job_id就是job_id,数组id为arraytaskid,具体看restapi释义
--cpus-per-gpu=<cpus> # 作业步骤将需要每个分配的 GPU 的ncpus处理器。 与cpus-per-task不兼容
--cpus-per-task=<cpus> # 每个任务的处理器数量
# NOTE: Beginning with 22.05, srun will not inherit the --cpus-per-task value requested by salloc or sbatch. It must be requested again with the call to srun or set with the SRUN_CPUS_PER_TASK environment variable if desired for the task(s).
--mincpus=<cpus> # 指定每个节点的最小逻辑 CPU/处理器数;【指定多少就分配多少个cpu,不会超出】
# 补充:如果指定了cpus-per-task,此参数无效
--exclusive # 独占节点,将分配全部cpu核数
--mem=<size>[units] # 指定每个节点所需的实际内存。默认单位是兆字节。可以使用后缀 [K|M|G|T] 指定不同的单位。--mem 、--mem -per-cpu和--mem-per-gpu 选项是互斥的。
--mem-per-cpu =<大小>[单位] # 每个可用的已分配 CPU 所需的最小内存。默认单位是兆字节。
--mem-per-gpu =<大小>[单位] # 每个分配的 GPU 所需的最小内存。默认单位是兆字节。可以使用后缀 [K|M|G|T] 指定不同的单位。
--nodes=<num> # 分配的节点数; 【当只有nodes参数时,默认每节点只分配1个cpu】
-n, --ntasks=<num> # Slurm 控制器在分配中运行的作业步骤将启动最大数量的 任务并提供足够的资源;【当只有tasks参数时,如果num未超过节点可运行cpu数,则分配1个节点,如果超过节点可运行的最大cpu数,则会分配多个节点】
--ntasks-per-core=<ntasks> # 请求在每个核心上调用最大的ntasks
--ntasks-per-node=<ntasks> # 请求在每个节点上调用ntasks
--ntasks-per-socket=<ntasks> # 请求在每个套接字上调用最大的ntasks
--ntasks-per-gpu =< ntasks > # 请求为每个 GPU 调用ntasks任务。
--threads-per-core=<threads> # 将节点选择限制为每个内核至少具有指定线程数的节点。在任务布局中,使用每个核心指定的最大线程数。
--gpus=[类型:]<数字> # 指定作业所需的 GPU 总数。注意:分配必须包含每个节点至少一个 GPU。
--gpus-per-node =[类型:]<数字> # 指定作业资源分配中包含的每个节点上作业所需的 GPU 数量。
--gpus-per-socket =[类型:]<数字> # 指定作业资源分配中包含的每个插槽上作业所需的 GPU 数量。
--gpus-per-task =[类型:]<数字> # 在作业的资源分配中指定要在每个任务上生成的作业所需的 GPU 数量。此选项需要明确的任务计数,例如 -n、--ntasks 或“--gpus=X --gpus-per-task=Y”,而不是带有 -N、--nodes 的模糊节点范围。
--gpu-freq=[<type]=value>[,<type=value>][,verbose] # 请求分配给作业的gpu配置为特定的频率值。
srun
-c , --cpus-per-task=<cpus> # 请求为每个进程分配的cpus。
-N , --nodes=<minnodes>[-maxnodes] # 分配的节点数; 【当只有nodes参数时,默认每节点只分配1个cpu】
-n , --ntasks=<数字> # 指定要运行的任务数。
--ntasks-per-core=<ntasks> # 请求在每个核心上调用最大的ntasks
--ntasks-per-node=<ntasks> # 请求在每个节点上调用ntasks 。如果与--ntasks选项一起使用, -- ntasks选项将优先,--ntasks-per-node将被视为每个节点的 最大任务数。
作业命令及状态
scontrol show job <job_id> # 查看作业详情,默认查所有
scontrol suspend <job_id> # 挂起作业
scontrol resume <job_id> # 恢复作业(与 suspend 配合使用)
scontrol hold <job_id> # 阻止作业运行,作业等待时才可使用
scontrol release <job_id> # 允许作业运行(与 hold 配合使用)
scontrol requeue <job_id> # 重新排队 命令行:Restarts=1 RestAPI:restart_cnt=1
scontrol show jobs | grep -E '^JobId|Priority' # 查看作业优先级
scancel job_id # 取消所有作业
scancel jobid_arrayid # 取消数组作业中的具体某一个,例:scancel 83_3
# 挂起恢复后的作业会在原节点运行,如果该节点资源不足,作业将报错退出(slurm-69.out)
srun: error: c1: task 0: Killed
srun: Force Terminated StepId=70.0
sacct --help --helpformat
sacct --format JobIDRaw,JobName,Partition,Submit,Start,End,User,State,WorkDir,Elapsed,ExitCode,AveRSS,NTasks,ReqCPUS,ReqNodes,ReqMem,ReqTRES,Comment,TimelimitRaw,AllocCPUS,AllocTRES,NodeList,AllocNodes -j <scheduler_id> # 计费查看,可以查看历史作业数据
sacct -S <start_time> -E <end_time> --format JobIDRaw,JobName,Partition,Submit,Start,End,User,State # 查看某个时间段内提交的所有作业
状态 | 命令行 | RestAPI |
---|---|---|
运行中 | RUNNING | RUNNING |
完成 | COMPLETED | COMPLETED |
队列中 | PENDING | PENDING |
运行失败(资源不足) | FAILED | FAILED ( state_reason : BadConstraints) |
挂起 suspend | SUSPENDED | SUSPENDED |
终止作业 scancel | CANCELLED | CANCELLED |
正在终止 scancel | COMPLETING | COMPLETING |
作业优先级
官方文档:https://slurm.schedmd.com/priority_multifactor.html#config
默认情况下,Slurm 按照先进先出 (FIFO) 的原则分配作业优先级。当 Slurm 由外部调度程序控制时,应配置 FIFO 调度。
slurm.conf 文件中的PriorityType参数选择优先级插件。此变量的默认值为PriorityType=priority/basic
,它支持简单的 FIFO 调度。(见下面的配置)
在大多数情况下,最好使用 Multifactor Priority 插件,该插件通过设置PriorityType=priority/multifactor启用。这提供了一种非常通用的方法,可以根据多种因素对等待调度的作业队列进行排序。
调度程序在做出调度决策时会考虑几个因素。调度程序按以下顺序选择要评估的作业:
- 可以抢占的工作
- 提前预订的工作
- 分区优先级
- 作业优先级
- 作业提交时间
- 作业编号
记住这一点很重要,因为具有最高优先级的作业可能不是第一个被调度程序评估的作业。当有多个作业可以同时评估时,例如作业请求具有相同 PriorityTier 的分区时,会考虑作业优先级。
scontrol show jobs | grep -E '^JobId|Priority' # 查看作业优先级
# 设置作业优先级 (作业的优先级在0到4294967295之间,数值越大优先级越高)
# 优先级为0时:Job is in held state, pending scheduler release for job 850 # 0时hold时的状态
# 优先级为4294967294,95时: scontrol:error: Invalid Priority value: 4294967294
scontrol update job=818 Priority=4294967293 # maxvalue=4294967293 minvalue=1
scontrol update job=819,817 Priority=4294967293
scontrol top 851 # 单个调整优先级到最顶部(同时会调整队列中其它任务的优先级) (不建议使用)
scontrol top 851,852,853 # 多个调整 (不建议使用)
# 可能出现的错误提示;【提示】:作业运行中也能修改优先级成功!!! 程序错误 rc:1
Access/permission denied for job 219573 # 权限不足
Invalid job id specified for job 20000 # 无效的作业id
Invalid Priority value: 50000000000000 # 无效的优先级
批量提交作业
#!/bin/bash
int=1
while(( $int<=100 ))
do
job_name="command_testjob4_$int"
echo $int $job_name
sbatch --job-name="$job_name" test1.slurm
let "int++"
done
# lsf:
bsub -J $job_name < job.lsf
# pbs:
qsub -N $job_name test.pbs
编译slurm
安装基础软件
yum -y install net-tools wget vim ntpdate chrony htop glances nfs-utils rpcbind python3
部署munge并安装
yum install munge munge-libs munge-devel -y # yum找不到的安装包在各系统官方包找 # rocky8:https://dl.rockylinux.org/pub/rocky/8/PowerTools/x86_64/os/Packages/
安装slurm依赖
yum install gcc gcc-c++ readline-devel perl-ExtUtils-MakeMaker pam-devel rpm-build mysql-devel http-parser-devel json-c-devel libjwt libjwt-devel -y
其中,slurmrestd需要的依赖为:
http-parser-devel
,json-c-devel
,libjwt-devel
,pam-devel
Slurm API
配置及启动
slurmrestd.conf
include /etc/slurm/slurm.conf
AuthType=auth/jwt
restapi启动命令(非root用户启动)
slurmrestd -f /etc/slurm/slurmrestd.conf -a rest_auth/jwt -s openapi/v0.0.36 -vvv 0.0.0.0:6688
配置服务启动,/etc/systemd/system/slurmrestd.service
[Unit]
Description=Slurm REST daemon
After=network-online.target munge.service slurmctld.service
# After=network-online.target slurmctld.service
Wants=network-online.target
ConditionPathExists=/etc/slurm/slurmrestd.conf
# ConditionPathExists=@sysconfdir@/slurm.conf
[Service]
Type=simple
User=test
EnvironmentFile=-/etc/sysconfig/slurmrestd
# EnvironmentFile=-/etc/default/slurmrestd
# slurmrestd should not run as root or the slurm user.
# Please either use the -u and -g options in /etc/sysconfig/slurmrestd or
# /etc/default/slurmrestd, or explicitly set the User and Group in this file
# an unpriviledged user to run as.
# User=
# Group=
# Default to listen on both socket and slurmrestd port
ExecStart=/usr/sbin/slurmrestd -f /etc/slurm/slurmrestd.conf -a rest_auth/jwt -vvv 0.0.0.0:6688
#ExecStart=@sbindir@/slurmrestd $SLURMRESTD_OPTIONS unix:@sharedstatedir@/slurmrestd.socket 0.0.0.0:@SLURMRESTD_PORT@
# Enable auth/jwt be default, comment out the line to disable it for slurmrestd
Environment="SLURM_JWT=daemon"
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
配置完服务启动后执行以下两条命令:
systemctl daemon-reload
systemctl restart slurmrestd.service
生成令牌
scontrol token lifespan=999999999 username=$USER # 给某个用户生成令牌(lifespan默认1800s)
scontrol token # 给自己生成令牌
# 在slurm.conf中配置 AuthAltParameters=disable_token_creation 可以禁止用户自己生成令牌
在python脚本中生成令牌,需要安装jwt且需要读取slurm.conf中配置的jwt公钥
#!/usr/bin/env python3
import sys
import os
import pprint
import json
import time
from datetime import datetime, timedelta, timezone
from jwt import JWT
from jwt.jwa import HS256
from jwt.jwk import jwk_from_dict
from jwt.utils import b64decode,b64encode
if len(sys.argv) != 3:
sys.exit("gen_jwt.py [user name] [expiration time (seconds)]");
# with open("/var/spool/slurm/ctld/jwt_hs256.key", "rb") as f:
with open("jwt_hs256.key", "rb") as f:
priv_key = f.read()
signing_key = jwk_from_dict({
'kty': 'oct',
'k': b64encode(priv_key)
})
message = {
"exp": int(time.time() + int(sys.argv[2])),
"iat": int(time.time()),
"sun": sys.argv[1]
}
a = JWT()
compact_jws = a.encode(message, signing_key, alg='HS256')
print("SLURM_JWT={}".format(compact_jws))
API
获取节点信息
GET /slurm/v0.0.38/nodes
{
'meta': {
'plugin': {
'type': 'openapi/v0.0.38',
'name': 'Slurm OpenAPI v0.0.38'
},
'Slurm': {
'version': {
'major': 22,
'micro': 6,
'minor': 5
},
'release': '22.05.6'
}
},
'errors': [],
'nodes': [{
'architecture': 'x86_64',
'burstbuffer_network_address': '',
'boards': 1,
'boot_time': 1671182613,
'comment': '',
'cores': 1,
'cpu_binding': 0,
'cpu_load': 0,
'extra': '',
'free_memory': 11640,
'cpus': 4,
'last_busy': 1671506981,
'features': '',
'active_features': '',
'gres': '',
'gres_drained': 'N/A',
'gres_used': '',
'mcs_label': '',
'name': 'c1',
'next_state_after_reboot': 'invalid',
'address': 'c1',
'hostname': 'c1',
'state': 'idle',
'state_flags': [],
'next_state_after_reboot_flags': [],
'operating_system': 'Linux 4.18.0-348.el8.0.2.x86_64 #1 SMP Sun Nov 14 00:51:12 UTC 2021',
'owner': None,
'partitions': ['compute'],
'port': 6818,
'real_memory': 8000,
'reason': '',
'reason_changed_at': 0,
'reason_set_by_user': None,
'slurmd_start_time': 1671506976,
'sockets': 4,
'threads': 1,
'temporary_disk': 0,
'weight': 1,
'tres': 'cpu=4,mem=8000M,billing=4',
'slurmd_version': '22.05.6',
'alloc_memory': 0,
'alloc_cpus': 0,
'idle_cpus': 4,
'tres_used': None,
'tres_weighted': 0.0
}]
}
获取队列信息
GET /slurm/v0.0.38/partitions
{
'meta': {
'plugin': {
'type': 'openapi/v0.0.38',
'name': 'Slurm OpenAPI v0.0.38'
},
'Slurm': {
'version': {
'major': 22,
'micro': 6,
'minor': 5
},
'release': '22.05.6'
}
},
'errors': [],
'partitions': [{
'flags': ['default'],
'preemption_mode': ['disabled'],
'allowed_allocation_nodes': '',
'allowed_accounts': '',
'allowed_groups': '',
'allowed_qos': '',
'alternative': '',
'billing_weights': '',
'default_memory_per_cpu': 0,
'default_time_limit': None,
'denied_accounts': '',
'denied_qos': '',
'preemption_grace_time': 0,
'maximum_cpus_per_node': -1,
'maximum_memory_per_node': 0,
'maximum_nodes_per_job': -1,
'max_time_limit': -1,
'min nodes per job': 0,
'name': 'compute',
'nodes': 'c1',
'over_time_limit': None,
'priority_job_factor': 1,
'priority_tier': 1,
'qos': '',
'state': 'UP',
'total_cpus': 4,
'total_nodes': 1,
'tres': 'cpu=4,mem=8000M,node=1,billing=4'
}]
}
获取所有作业信息(队列中或运行中)
GET /slurm/v0.0.38/jobs
{
'meta': {
'plugin': {
'type': 'openapi/v0.0.38',
'name': 'Slurm OpenAPI v0.0.38'
},
'Slurm': {
'version': {
'major': 22,
'micro': 6,
'minor': 5
},
'release': '22.05.6'
}
},
'errors': [],
'jobs': [{
'account': 'root', # 将此作业使用的资源计入指定账户
'accrue_time': 1671529938, # 长时间工作符合运行格式
'admin_comment': '', # 管理员的任意注释
'array_job_id': 0, # 数组作业的job_id 或 0
'array_task_id': None, # 作业数组的task_id
'array_max_tasks': 0, # 最大运行数组任务数
'array_task_string': '', # 这条记录中任务ID的字符串表达式
'association_id': 2, # 作业的关联 ID
'batch_features': '', # 批处理脚本节点所需
'batch_flag': True, # 带脚本的排队作业
'batch_host': 'c1', # 运行批处理脚本的主机的名称
'flags': ['JOB_ACCRUE_OVER', 'JOB_WAS_RUNNING'], # 作业标志
'burst_buffer': '', # 突发缓冲区规范
'burst_buffer_state': '', # 突发缓冲区状态信息
'cluster': 'mycluster', # 作业所在集群的名称
'cluster_features': '', # 所需集群功能的逗号分隔列表
'command': '/home/new/test1.slurm', # 要执行的命令
'comment': '', # 任意注释
'container': '', # OCI 容器包的绝对路径
'contiguous': False, # 作业需要连续的节点
'core_spec': None, # 专用核心数
'thread_spec': None, # 专用线程数
'cores_per_socket': None, # 作业所需的每个插槽的串芯数
'billable_tres': 4.0,
'cpus_per_task': None, # 每个任务所需的处理器
'cpu_frequency_minimum': None, # 最低 CPU 频率
'cpu_frequency_maximum': None, # 最大 CPU 频率
'cpu_frequency_governor': None, # cpu 频率调节器
'cpus_per_tres': '', # 分号分隔的 TRES=# 值列表
'deadline': 0, # 作业开始截止日期
'delay_boot': 0, # 要执行的命令
'dependency': '', # 将作业执行与其他作业同步
'derived_exit_code': 0, # 所有作业步骤的整数最高退出代码
'eligible_time': 1671529938, # 工作符合运行格式
'end_time': 1703065939, # 实际或预期的终止时间长
'excluded_nodes': '', # 排除节点的逗号分隔列表
'exit_code': 0, # 作业的退出代码
'features': '', # 所需功能的逗号分隔列表
'federation_origin': '', # Origin 集群名称
'federation_siblings_active': '', # 活动兄弟名称的字符串
'federation_siblings_viable': '', # 可行兄弟名称的字符串
'gres_detail': [],
'group_id': 0,
'group_name': 'root',
'job_id': 6,
'job_resources': {
'nodes': 'c1',
'allocated_cpus': 4,
'allocated_hosts': 1,
'allocated_nodes': [{
'sockets': {
'0': {
'cores': {
'0': 'allocated'
}
},
'1': {
'cores': {
'0': 'allocated'
}
},
'2': {
'cores': {
'0': 'allocated'
}
},
'3': {
'cores': {
'0': 'allocated'
}
}
},
'nodename': 'c1',
'cpus_used': 0,
'memory_used': 0,
'memory_allocated': 0
}]
},
'job_state': 'RUNNING', # 作业状态
'last_sched_evaluation': 1671529939,
'licenses': '',
'max_cpus': 0,
'max_nodes': 0,
'mcs_label': '',
'memory_per_tres': '',
'name': 'cvat',
'nodes': 'c1', # 分配给作业的节点列表
'nice': None,
'tasks_per_core': None, # 在每个核心上调用的任务数
'tasks_per_node': 4, # Request the maximum ntasks be invoked on each node.
'tasks_per_socket': None, # number of tasks to invoke on each socket
'tasks_per_board': 0, # number of tasks to invoke on each board
'cpus': 4, # 作业所需的最小cpu数量
'node_count': 1, # 作业所需的最小节点数
'tasks': 4, # 请求的任务次数
'het_job_id': 0, # job ID of hetjob leader
'het_job_id_set': '', # job IDs for all components
'het_job_offset': 0, # HetJob component offset from leader
'partition': 'compute',
'prefer': '',
'memory_per_node': None, # Integer minimum real memory per node
'memory_per_cpu': None, # Integer minimum real memory per cpu
'minimum_cpus_per_node': 4, # 每节点最少cpu数
'minimum_tmp_disk_per_node': 0, # Integer minimum tmp disk per node
'preempt_time': 0, # 抢占信号时间
'pre_sus_time': 0,
'priority': 4294901757, # 工作的相对优先级
'profile': None, # Job profiling requested
'qos': 'normal',
'reboot': False, # node reboot requested before start
'required_nodes': '',
'requeue': True, # 启用或禁用作业请求选项
'resize_time': 0, # time of latest size change format: int64
'restart_cnt': 0, # 作业重新启动的次数
'resv_name': '', # reservation name
'shared': None, # String type and if job can share nodes with other jobs
'show_flags': ['SHOW_ALL', 'SHOW_DETAIL', 'SHOW_LOCAL'],
'sockets_per_board': 0,
'sockets_per_node': None,
'start_time': 1671529939, # 实际或预期 执行时间
'state_description': '',
'state_reason': 'None',
'standard_error': '',
'standard_input': '/dev/null', # 作业的stdin文件的路径名
'standard_output': '',
'submit_time': 1671529938, # 作业提交时间
'suspend_time': 0,
'system_comment': '',
'time_limit': 525600, # maximum run time in minutes
'time_minimum': 0,
'threads_per_core': None,
'tres_bind': '',
'tres_freq': '',
'tres_per_job': '',
'tres_per_node': '',
'tres_per_socket': '',
'tres_per_task': '',
'tres_req_str': 'cpu=4,mem=8000M,node=1,billing=4', # tres reqeusted in the job
'tres_alloc_str': 'cpu=4,node=1,billing=4', # tres used in the job
'user_id': 0, # user id the job runs as format
'user_name': 'root', # 运行作业的用户
'wckey': '', # wckey for job
'current_working_directory': '/home/new' # 工作目录的路径名
}, {
'account': 'root', # 将此作业使用的资源计入指定账户
'accrue_time': 1671529958, # 长时间工作符合运行格式
'admin_comment': '', # 管理员的任意注释
'array_job_id': 0, # 数组作业的job_id 或 0
'array_task_id': None, # 作业数组的task_id
'array_max_tasks': 0, # 最大运行数组任务数
'array_task_string': '', # 这条记录中任务ID的字符串表达式
'association_id': 2, # 作业的关联 ID
'batch_features': '', # 批处理脚本节点所需
'batch_flag': True, # 带脚本的排队作业
'batch_host': '', # 运行批处理脚本的主机的名称
'flags': [], #
'burst_buffer': '',
'burst_buffer_state': '',
'cluster': 'mycluster',
'cluster_features': '',
'command': '/home/new/test1.slurm',
'comment': '',
'container': '',
'contiguous': False,
'core_spec': None,
'thread_spec': None,
'cores_per_socket': None,
'billable_tres': None,
'cpus_per_task': None,
'cpu_frequency_minimum': None,
'cpu_frequency_maximum': None,
'cpu_frequency_governor': None,
'cpus_per_tres': '',
'deadline': 0,
'delay_boot': 0,
'dependency': '',
'derived_exit_code': 0,
'eligible_time': 1671529958,
'end_time': 5998033175,
'excluded_nodes': '',
'exit_code': 0,
'features': '',
'federation_origin': '',
'federation_siblings_active': '',
'federation_siblings_viable': '',
'gres_detail': [],
'group_id': 0,
'group_name': 'root',
'job_id': 7,
'job_state': 'PENDING',
'last_sched_evaluation': 1671529969,
'licenses': '',
'max_cpus': 0,
'max_nodes': 1,
'mcs_label': '',
'memory_per_tres': '',
'name': 'cvat',
'nodes': '',
'nice': None,
'tasks_per_core': None,
'tasks_per_node': 2,
'tasks_per_socket': None,
'tasks_per_board': 0,
'cpus': 2,
'node_count': 1,
'tasks': 2,
'het_job_id': 0,
'het_job_id_set': '',
'het_job_offset': 0,
'partition': 'compute',
'prefer': '',
'memory_per_node': None,
'memory_per_cpu': None,
'minimum_cpus_per_node': 2,
'minimum_tmp_disk_per_node': 0,
'preempt_time': 0,
'pre_sus_time': 0,
'priority': 4294901756,
'profile': None,
'qos': 'normal',
'reboot': False,
'required_nodes': '',
'requeue': True,
'resize_time': 0,
'restart_cnt': 0,
'resv_name': '',
'shared': None,
'show_flags': ['SHOW_ALL', 'SHOW_DETAIL', 'SHOW_LOCAL'],
'sockets_per_board': 0,
'sockets_per_node': None,
'start_time': 1703065939,
'state_description': '',
'state_reason': 'Resources',
'standard_error': '',
'standard_input': '/dev/null',
'standard_output': '',
'submit_time': 1671529958,
'suspend_time': 0,
'system_comment': '',
'time_limit': None,
'time_minimum': 0,
'threads_per_core': None,
'tres_bind': '',
'tres_freq': '',
'tres_per_job': '',
'tres_per_node': '',
'tres_per_socket': '',
'tres_per_task': '',
'tres_req_str': 'cpu=2,mem=8000M,node=1,billing=2',
'tres_alloc_str': '',
'user_id': 0,
'user_name': 'root',
'wckey': '',
'current_working_directory': '/home/new'
}]
}
对应job表中字段的取值方式:
for job in ret["jobs"]:
scheduler_id = job["job_id"]
identity_str = ""
job_name = job["name"]
job_content = None
queue = job["partition"]
submit_time = job["submit_time"]
start_time = job["start_time"]
end_time = job["end_time"]
submitter = job["user_name"]
job_file = job["command"]
workspace = job["current_working_directory"]
scheduler_state = job["job_state"]
runtime = None
standard_output_file = job["standard_output"]
error_output_file = job["standard_error"]
exit_code = job["exit_code"]
tres = job["tres_alloc_str"]
Job Table
字段 | /slurm/v0.0.38/jobs | /slurmdb/v0.0.38/job/45 |
---|---|---|
scheduler_id | job[“job_id”] | job[“job_id”] |
identity_str | — | — |
job_name | job[“name”] | job[“name”] |
job_content | — | — |
queue | job[“partition”] | job[“partition “] |
submit_time | job[“submit_time”] | job[“time”][“submission”] |
start_time | job[“start_time”] | job[“time”][“start “] |
end_time | job[“end_time”] | job[“time”][“end”] |
submitter | job[“user_name”] | job[“association”][“user”] |
job_file | job[“command”] | |
workspace | job[“current_working_directory”] | job[“working_directory”] |
scheduler_state | job[“job_state”] | job[“state”][“current”] |
state | — | — |
operate_state | — | — |
delete_flag | — | — |
runtime | — | job[“time”][“elapsed”] # 单位:秒 |
standard_output_file | job[“standard_output”] | — |
error_output_file | job[“standard_error”] | — |
raw_info | — | — |
reason | job[“state_reason”] | job[“state”][“reason”] |
comment | job[“comment”] | job[“comment”][“job”] |
exit_code | job[“exit_code”] | job[“exit_code”][“return_code”] |
tres | job[“tres_alloc_str”] | job[“tres”][“allocated”] |
create_time | — | — |
update_time | — | — |
tags | — | — |
user_comment | — | — |
JobRunning Table
字段 | /slurm/v0.0.38/jobs | /slurmdb/v0.0.38/job/64 |
---|---|---|
hosts | job[“nodes”] # c[1-2] | job[“nodes”] # c[1-2] |
per_host_tres | job[“tres_alloc_str”] | job[“tres”][“allocated”] |
job | — | — |
allocate_time | job[“submit_time”] | job[“time”][“submission”] |
获取作业详情
GET /slurm/v0.0.38/job/{job_id}
{
'meta': {
'plugin': {
'type': 'openapi/v0.0.38',
'name': 'Slurm OpenAPI v0.0.38'
},
'Slurm': {
'version': {
'major': 22,
'micro': 6,
'minor': 5
},
'release': '22.05.6'
}
},
'errors': [],
'jobs': [{
'account': 'root',
'accrue_time': 1671530634,
'admin_comment': '',
'array_job_id': 0,
'array_task_id': None,
'array_max_tasks': 0,
'array_task_string': '',
'association_id': 2,
'batch_features': '',
'batch_flag': True,
'batch_host': 'c1',
'flags': ['JOB_ACCRUE_OVER', 'JOB_WAS_RUNNING'],
'burst_buffer': '',
'burst_buffer_state': '',
'cluster': 'mycluster',
'cluster_features': '',
'command': '/home/new/test1.slurm',
'comment': '',
'container': '',
'contiguous': False,
'core_spec': None,
'thread_spec': None,
'cores_per_socket': None,
'billable_tres': 2.0,
'cpus_per_task': None,
'cpu_frequency_minimum': None,
'cpu_frequency_maximum': None,
'cpu_frequency_governor': None,
'cpus_per_tres': '',
'deadline': 0,
'delay_boot': 0,
'dependency': '',
'derived_exit_code': 0,
'eligible_time': 1671530634,
'end_time': 1703066634,
'excluded_nodes': '',
'exit_code': 0,
'features': '',
'federation_origin': '',
'federation_siblings_active': '',
'federation_siblings_viable': '',
'gres_detail': [],
'group_id': 0,
'group_name': 'root',
'job_id': 8,
'job_resources': {
'nodes': 'c1',
'allocated_cpus': 2,
'allocated_hosts': 1,
'allocated_nodes': [{
'sockets': {
'0': {
'cores': {
'0': 'allocated'
}
},
'1': {
'cores': {
'0': 'allocated'
}
}
},
'nodename': 'c1',
'cpus_used': 0,
'memory_used': 0,
'memory_allocated': 0
}]
},
'job_state': 'RUNNING',
'last_sched_evaluation': 1671530634,
'licenses': '',
'max_cpus': 0,
'max_nodes': 0,
'mcs_label': '',
'memory_per_tres': '',
'name': 'cvat',
'nodes': 'c1',
'nice': None,
'tasks_per_core': None,
'tasks_per_node': 2,
'tasks_per_socket': None,
'tasks_per_board': 0,
'cpus': 2,
'node_count': 1,
'tasks': 2,
'het_job_id': 0,
'het_job_id_set': '',
'het_job_offset': 0,
'partition': 'compute',
'prefer': '',
'memory_per_node': None,
'memory_per_cpu': None,
'minimum_cpus_per_node': 2,
'minimum_tmp_disk_per_node': 0,
'preempt_time': 0,
'pre_sus_time': 0,
'priority': 4294901755,
'profile': None,
'qos': 'normal',
'reboot': False,
'required_nodes': '',
'requeue': True,
'resize_time': 0,
'restart_cnt': 0,
'resv_name': '',
'shared': None,
'show_flags': ['SHOW_ALL', 'SHOW_DETAIL', 'SHOW_LOCAL'],
'sockets_per_board': 0,
'sockets_per_node': None,
'start_time': 1671530634,
'state_description': '',
'state_reason': 'None',
'standard_error': '',
'standard_input': '/dev/null',
'standard_output': '',
'submit_time': 1671530634,
'suspend_time': 0,
'system_comment': '',
'time_limit': None,
'time_minimum': 0,
'threads_per_core': None,
'tres_bind': '',
'tres_freq': '',
'tres_per_job': '',
'tres_per_node': '',
'tres_per_socket': '',
'tres_per_task': '',
'tres_req_str': 'cpu=2,mem=8000M,node=1,billing=2',
'tres_alloc_str': 'cpu=2,node=1,billing=2',
'user_id': 0,
'user_name': 'root',
'wckey': '',
'current_working_directory': '/home/new'
}]
}
停止作业
DELETE /slurm/v0.0.38/job/{job_id}
# 需要相应用户的权限
{
'meta': {
'plugin': {
'type': 'openapi/v0.0.38',
'name': 'Slurm OpenAPI v0.0.38'
},
'Slurm': {
'version': {
'major': 22,
'micro': 6,
'minor': 5
},
'release': '22.05.6'
}
},
'errors': []
}
Slurm Multi Cluster
常用命令
sacctmgr show clusters # 查看当前所有集群
# 查看集群联合配置
sacctmgr show cluster withfed
sacctmgr show federation
# 将集群添加到联合并且启动控制器后,可以使用以下命令从控制器查看其状态:
scontrol show federation
sbatch -M cluster2,cluster3 script.sh # 向集群提交作业