加载中...

Slurm常见用法


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启用。这提供了一种非常通用的方法,可以根据多种因素对等待调度的作业队列进行排序。

调度程序在做出调度决策时会考虑几个因素。调度程序按以下顺序选择要评估的作业:

  1. 可以抢占的工作
  2. 提前预订的工作
  3. 分区优先级
  4. 作业优先级
  5. 作业提交时间
  6. 作业编号

记住这一点很重要,因为具有最高优先级的作业可能不是第一个被调度程序评估的作业。当有多个作业可以同时评估时,例如作业请求具有相同 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

  1. 安装基础软件

    yum -y install net-tools wget vim ntpdate chrony htop glances nfs-utils rpcbind python3
  2. 部署munge并安装

    yum install munge munge-libs munge-devel -y
    # yum找不到的安装包在各系统官方包找
    # rocky8:https://dl.rockylinux.org/pub/rocky/8/PowerTools/x86_64/os/Packages/
  3. 安装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-develjson-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  # 向集群提交作业

文章作者: 无夜
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 无夜 !
评论
  目录