Files
blog-public/content/docs/server/job.md
2024-10-22 18:13:55 +08:00

194 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
weight: 4
title: "使用队列系统"
---
## 队列系统的作用
简而言之:排队。你告诉队列系统使用什么资源(例如多少核的 CPU运行某个程序轮到你的任务执行时队列系统会按照你的要求执行任务。
队列系统会考虑服务器的负载能力(不可以同时运行太多任务把服务器挤垮)、有多人使用服务器时公平分配资源,以及记录任务执行过程中的开销。
队列系统不与某个特定的计算软件(例如 VASP绑定。
也就是说,你可以脱离队列系统直接运行 VASP也可以把别的软件也放到队列系统里运行它们虽然经常在一起使用但本质上是两个分离的概念。[^1]
## 使用队列系统
队列系统与操作系统绑定很深。
* srv1使用 [Slurm](#slurm新)。
* srv1Windows请阅读 [Windows](#windows) 章节,了解相关注意事项。
* xmupc1 和 xmupc2使用 [Slurm](#slurm旧)。
* 厦大超算jykang使用 [LSF](#lsf)。
### Slurm
#### 使用图形界面快速开始
使用命令 `sbatch-tui` 或者 `sbatch` 不带任何参数,就可以看到一个图形界面[^3]。
按照提示,鼠标点选对应按钮,即可提交任务。这可以满足一多半的需求。
以下用一些例子来进一步介绍如何使用 Slurm。更多细节请参考[官方文档](https://slurm.schedmd.com/)。
例子中一些选项是可选的、一些是必写的,会详细说明。
#### 提交任务
使用 `sbatch` 提交任务。当加上参数时,会直接提交任务;当不加任何参数时,会调用 `sbatch-tui` 让你选。
提交一个 VASPCPU任务的例子
```bash
sbatch --ntasks=2 --cpus-per-task=4 --hint=nomultithread --job-name="my great job" --output=output.txt --queue=localhost --export=ALL,OMP_NUM_THREADS=4,OMP_STACKSIZE=512m --nodes=1-1 --mem=28G --wrap="vasp-intel srun --mpi=pmix vasp-std"
```
* `--ntasks=2 --cpus-per-task=4` 两者的乘积指定使用多少 CPU 核[^5],必写。
同样是占用 9 个核,`--ntasks=3 --cpus-per-task=3``--ntasks=9 --cpus-per-task=1` 性能并不相同。
此外,当 `--cpus-per-task` 不为 `1`VASP 的 `NCORE` 等参数也与这里的参数耦合[^9]。
可以照抄下面的设置,或者自己尝试一下如何设置性能更好[^15]
* 对于 xmupc1`--ntasks=3 --cpus-per-task=4`
* 对于 xmupc2`--ntasks=4 --cpus-per-task=10`
* 对于 srv1 的默认队列:`--cpus-per-task=10``--ntasks=8` 或按需设置。
* 对于 srv1 的其它队列:`--ntasks=4 --cpus-per-task=8`
* `--hint=nomultithread` 对于大多软件(包括 VASP都需要写[^6],不写不会出错但会比较慢。
* `--job-name=xxx` 指定任务的名字,可以不写。
* `--queue=xxx` 指定队列的名字,不写时使用默认队列。
* `--export=ALL,OMP_NUM_THREADS=4,OMP_STACKSIZE=512m` 指定环境变量。完全不写这个参数时,相当于 `--export=ALL`
* `ALL` 表示使用当前环境中的所有变量,并额外设置后面追加的值;
* `OMP_NUM_THREADS=4` 表示设置 OpenMP 的线程数为 4。
对于使用 OPENMP 并行的程序(包括 VASPCPU但不包括 VASPGPU`OMP_NUM_THREADS` 必须设置为与 `--cpus-per-task` 相同的值;
即使没有设置 `--cpus-per-task`,也需要设置 `OMP_NUM_THREADS=1`
* `OMP_STACKSIZE` 设置每个 OpenMP 线程的栈大小需要足够大VASP 文档推荐设置为 `512m`,通常已经足够。
如果遇到段错误Segmentation fault可以尝试增大这个值。
* `--nodes=1-1` 强制所有任务分配到一个节点上(即不跨节点运行),推荐在大多情况下使用[^11]。
若要跨节点并行,并且节点 CPU/GPU 相同,不写这个参数就可以。
当要跨的节点的 CPU/GPU 型号不同时,还有别的注意事项,详见[这里](../qa#混合使用不同型号的节点)。
* `--mem=28G` 指定只使用内存大于等于 28 G 的节点,不设置则没有这个限制。
由于 Slurm 看到的内存大小比物理内存小一些[^14](例如 32 G 内存的节点Slurm 可能会认为它只有 31.5 G因此指定时也需要略小一些。
* `--wrap="vasp-intel srun --mpi=pmix vasp-std"` 指调用 std 版本的 VASP[^7]。
要使用 gam 或 ncl 版本,将最后的 `vasp-std` 改为 `vasp-gam``vasp-ncl`
以下是一个提交 VASPGPU任务的例子这个例子适用于旧的打包方式会在下次服务器维护后更改
```bash
sbatch --gpus=1 --ntasks-per-gpu=1 --nodes=1-1 --job-name="my great job" --output=output.txt vasp-nvidia-std
```
* `--gpus` 指定使用哪个 GPU
* 要占用任意一个 GPU排到这个任务时哪个空闲就使用哪个`--gpus=1`。要占用任意两个就写 `--gpus=2`,以此类推。
对于 VASP单个任务不要占用超过一个 GPU是多个显卡的速度会比单个更慢因为显卡之间的通信速度会是瓶颈[^12]。
* 要指定具体使用哪一个 GPU 时,写 `--gpus=4090:1`。2080 Ti 需要写为 `2080_ti`P5000 需要写为 `p5000`
* 当需要使用多个不同型号的 GPU 时(例如,指定使用一个 3090 和一个 4090 ),写 `--gres=gpu:3090:1,gpu:4090:1`
* `--ntasks-per-gpu=1` 对于 VASPGPU来说一定要写且只能设置为 `1`,对于其它任务(例如 LAMMPS可以适当修改。[^4]
* `--cpus-per-task` 对于 VASPGPU来说通常不用指定[^13],其它程序可能需要。这个选项的具体含义参考上一个例子。
* `vasp-nvidia-std` 即要执行的程序[^7],要使用 gam 或 ncl 版本时,写为例如 `vasp-nvidia-gam`
要把其它程序提交到队列里,也是类似的写法。请自行举一反三。
#### 查看任务
要列出正在等待和正在运行的任务:
```bash
squeue -l
```
要列出已经提交(包括已经完成、取消、失败)的任务:
```bash
squeue -t all -l
```
要显示还没有完成的任务的详细信息,或刚刚完成的任务的详细信息:
```bash
scontrol show job 114514
```
要在数据库中查找某一段时间内(例如 2024 年 8 月)提交的所有任务的详细信息[^10]
```bash
sacct --units M --format=ALL --starttime 2024-08-01T00:00:00 --endtime 2024-09-01T00:00:00 | bat -S
```
#### 调整和取消任务
取消一个任务:
```bash
# 按任务的 id 取消
scancel 114514
# 按任务的名字取消
scancel -n my_great_job
# 取消一个用户的所有任务
scancel -u chn
```
如果自己已经提交了许多任务,现在想要把一个任务调整到自己的其它任务前面(不会影响整体的优先级),可以使用:
```bash
scontrol top 114514
```
要无条件将一个任务优先级设置为最高或最低(需要管理员权限):
```bash
# 最高
sudo scontrol update JobId=3337 Nice=-2147483645
# 最低
sudo scontrol update JobId=3337 Nice=2147483645
```
### Slurm
与 Slurm基本相同只是 VASPCPU的打包方式不同使得提交任务的命令略有不同。
下一次服务器维护时xmupc1 和 xmupc2 计划合并为一个集群,并且应用新的打包方式。
提交 VASPCPU任务的例子
```bash
sbatch --ntasks=2 --cpus-per-task=4 --hint=nomultithread --job-name="my great job" --output=output.txt vasp-intel-std
```
### LSF
待补充。
### Windows
Windows 没有通用的队列系统程序,通常手动控制任务依次执行。~~我曾经在2024年暑假答应鹏岗帮他写一个但事实是我把他鸽了有空一定写咕咕咕。~~
你可以使用 FDTD Solutions 自带的一个单用户的队列系统。
在 FDTD Solutions 内的控制台使用 `addjob` 命令将要模拟的文件加入队列,然后它就会依次运行。
文档见[这里](https://optics.ansys.com/hc/en-us/articles/360034410714-addjob-Script-command)。
{{< callout type="warning" >}}
不要同时启动过多的计算任务。
<br/>
例如,如果一个任务需要一个小时跑完,那么按顺序运行两个任务需要两个小时,但是同时运行两个任务需要的时间往往远大于两个小时。
若同时运行 10 个任务,可能连系统都没有反应了。
{{< /callout >}}
{{% details title="一个简易的队列系统的实现" closed="true" %}}
待补充
{{% /details %}}
[^1]: 实际上队列系统与要运行的软件还是有许多耦合的,尤其是使用 MPI 并行的程序(包括绝大多数成熟的大型科学计算软件)。
如何让队列系统与这些软件对接好有时会很麻烦,只是普通用户不需要关心(我替你们搞定了)。
[^3]: 其实这个不能叫“图形用户界面gui应该叫“文本用户界面tui”。但后者会让不熟悉的人误解所以这里还是叫“图形界面”。
[^4]: 这个参数指定的通常是 MPI 进程数(为这个参数指定的数值乘以 GPU 数量),其实就是 `--ntasks` 的另外一种写法。
VASPGPU限制每个 GPU 必须对应且只能对应一个 MPI 进程,不满足这个条件就会报错或者只使用 CPU 计算,因此只能用一个。
[^5]: 通常来说,`--ntasks` 对应 MPI 进程数,`--cpus-per-task` 对应 OpenMP 线程数。
这个对应关系并不是一定的,比如你先请求 10 个 task然后用 `srun` 运行 10 个不相关的程序也是可以的,这个过程中可以根本没有 MPI 和 OpenMP。
[^6]: 这个选项用于忽略 CPU 的超线程,即认为物理核心和对应的虚拟核心总共算一个核心。
Slurm 默认会把超线程核心和物理核各算成一个核,但做科学计算时一般要关掉超线程。
[^7]: 使用 `--wrap` 参数和直接写在 `sbatch` 后面,都可以指定要运行的程序。
区别在于,后者必须是一个脚本(不能是二进制程序),并且在脚本里可以指定一些给 Slurm 看的参数。
[^9]: 具体是如何耦合的,见[官方文档](https://www.vasp.at/wiki/index.php/Combining_MPI_and_OpenMP)。
[^10]: 我不确定这里是否真的是任务的“提交时间”而不是“完成时间”或者别的什么时间,官方文档没有说清楚。
[^11]: 跨节点并行可能会有比较大的损耗。我们的服务器都仅仅使用千兆网互联,比不上学校的超算,可能损耗更大。
[^12]: 如果有 nvlink或许就不会出现这种情况。
[^13]: 按照经验,大多情况下,对于 VASP一个 CPU 核心搭配一个显卡已经足够,增加核心数并不会更快。
少数情况下增加可能会有用例如运行机器学习时VASP 的机器学习使用纯 CPU 实现)。
[^14]: 实际上是在 Slurm 的配置文件中手动指定的。具体每个节点指定了多少,见[系统配置文件](https://github.com/CHN-beta/nixos)。
[^15]: 按照经验OpenMP 线程数等于单个 CPU 或单个 ccx 的核心数或者核心数的一半时,性能最好。
```