From 32e926e40de7fc8b9f80ff0b3b099dad665f648a Mon Sep 17 00:00:00 2001 From: Cloudac7 <812556867@qq.com> Date: Mon, 9 Dec 2024 18:13:39 +0800 Subject: [PATCH] update: slurm; anaconda --- docs/index.md | 2 +- docs/slurm/salloc.md | 42 ++++++++---- docs/slurm/sbatch.md | 74 +++++++++++++-------- docs/slurm/srun.md | 127 +++++++++++++++++++++--------------- docs/slurm/submission.md | 2 +- docs/usage/apps/anaconda.md | 83 +++++++++++++++++++++++ 6 files changed, 237 insertions(+), 93 deletions(-) create mode 100644 docs/usage/apps/anaconda.md diff --git a/docs/index.md b/docs/index.md index d0a5955..0aab382 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ # 嘉庚创新实验室智算中心用户使用手册 !!! info - 本文档内容更新于 2024-12-06 + 本文档内容更新于 2024-12-09 该文档为高性能计算平台使用文档,内容包括如何登录集群、如何运行作业和如何使用软件等。 diff --git a/docs/slurm/salloc.md b/docs/slurm/salloc.md index bfe11b5..cd8735b 100644 --- a/docs/slurm/salloc.md +++ b/docs/slurm/salloc.md @@ -96,29 +96,43 @@ command可以是任何是用户想要用的程序,典型的为xterm或包含`s ## 例子 -- 获取分配,并打开csh,以便srun可以交互式输入: +### 申请计算节点资源并远程连接 - `salloc -N16 csh` +```bash +salloc -p cpu -N1 -n6 -q normal -t 2:00:00 +``` + +则可以在集群 `cpu` 队列中申请 1 个节点的 6 个核,占用 2 h。 - 将输出: +将输出: ``` -salloc: Granted job allocation 65537 -(在此,将等待用户输入,csh退出后结束) salloc: Relinquishing job -allocation 65537 +salloc: Granted job allocation 369188 +salloc: Waiting for resource configuration +salloc: Nodes cu026 are ready for job ``` -- 获取分配并并行运行应用: +随后自动启动一个新的终端,通过 `squeue` 可以看到在 `cu026` 节点上创建了一个新的作业任务 `369188`: - `salloc -N5 srun -n10 myprogram` - -- 生成三个不同组件的异构作业,每个都是独立节点: +``` +JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) +369188 cpu interact ypliucat R 0:50 1 cu026 +``` - `salloc -w node[2-3] : -w node4 : -w node[5-7] bash` +因此,用户可以通过 `ssh cu026` 到该节点上交互式地执行相关命令。 - 将输出: +当任务结束后,请在打开的 SSH 连接中输入 `exit` 退出,并主动取消创建的任务,例如: +```bash +scancel 369188 ``` -salloc: job 32294 queued and waiting for resources salloc: job 32294 -has been allocated resources salloc: Granted job allocation 32294 + +以确保不会产生额外的费用。 + +### 获取资源以运行并行应用 + +例如想要申请5个节点,每个节点申请1个核,并通过 `srun` 并行地运行 `myprogram`,则: + +```bash +salloc -p cpu -N5 srun -n5 myprogram ``` diff --git a/docs/slurm/sbatch.md b/docs/slurm/sbatch.md index 57083af..66ad1f4 100644 --- a/docs/slurm/sbatch.md +++ b/docs/slurm/sbatch.md @@ -192,10 +192,13 @@ Slurm将在作业脚本中输出以下变量,作业脚本可以使用这些变 1. 直接采用`sbatch -n1 -o job-%j.log -e job-%j.err yourprog`方式运行 2. 编写命名为`serial_job.sh`(此脚本名可以按照用户喜好命名)的串行作业脚本,其内容如下: -```bash +```bash title="serial_job.sh" #!/bin/sh -#An example for serial job. +#SBATCH -N 1 #SBATCH -J job_name +#SBATCH -p [partition] +#SBATCH -A [account] +#SBATCH -q [QOS] #SBATCH -o job-%j.log #SBATCH -e job-%j.err @@ -205,18 +208,22 @@ echo Directory is $PWD echo This job runs on the following nodes: echo $SLURM_JOB_NODELIST -module load intel/2019.update5 +module load intel/2023.2 echo This job has allocated 1 cpu core. ./yourprog ``` -必要时需在脚本文件中利用`module`命令设置所需的环境,如上面的`module load intel/2019.update5`。 +注意请替换队列 (partiton)、账户 (account) 和服务质量 (QOS) 为实际情况。以下不再赘述。 + +必要时需在脚本文件中利用`module`命令设置所需的环境,如上面的`module load intel/2023.2`。 作业脚本编写完成后,可以按照下面命令提交作业: -> `hmli@login01:~/work$ sbatch -n1 -p serail serial_job.sh` +```bash +sbatch serial_job.sh +``` ## OpenMP共享内存并行作业提交 @@ -224,11 +231,15 @@ echo This job has allocated 1 cpu core. ```bash #!/bin/sh -#An example for serial job. #SBATCH -J job_name +#SBATCH -p [partition] +#SBATCH -A [account] +#SBATCH -q [QOS] #SBATCH -o job-%j.log #SBATCH -e job-%j.err -#SBATCH -N 1 -n 8 +#SBATCH -N 1 +#SBATCH -n 1 +#SBATCH -c 8 echo Running on hosts echo Time is `date` @@ -242,11 +253,11 @@ export OMP_NUM_THREADS=8 ./yourprog ``` -相对于串行作业脚本,主要增加`export OMP_NUM_THREADS=8`和 `#SBATCH -N 1 -n 8`,表示使用一个节点内部的八个核,从而保证是在同一个节点内部,需几个核就设置-n为几。-n后跟的不能超过单节点内CPU核数。 +相对于串行作业脚本,主要增加`export OMP_NUM_THREADS=8`和 `#SBATCH -N 1 -n 1 -c 8`,表示使用一个节点内部的八个核,从而保证是在同一个节点内部,需几个核就设置 `-c` 为几。`-c` 后跟的不能超过单节点内CPU核数。 作业脚本编写完成后,可以按照下面命令提交作业: -`hmli@login01:~/work$ sbatch omp_job.sh` +`sbatch omp_job.sh` ## MPI并行作业提交 @@ -254,8 +265,10 @@ export OMP_NUM_THREADS=8 ```bash #!/bin/sh -#An example for MPI job. #SBATCH -J job_name +#SBATCH -p [partition] +#SBATCH -A [account] +#SBATCH -q [QOS] #SBATCH -o job-%j.log #SBATCH -e job-%j.err #SBATCH -N 1 -n 8 @@ -266,29 +279,32 @@ echo This job runs on the following nodes: echo $SLURM_JOB_NODELIST echo This job has allocated $SLURM_JOB_CPUS_PER_NODE cpu cores. -module load intelmpi/5.1.3.210 -#module load mpich/3.2/intel/2016.3.210 -#module load openmpi/2.0.0/intel/2016.3.210 -MPIRUN=mpirun #Intel mpi and Open MPI -#MPIRUN=mpiexec #MPICH -MPIOPT="-env I_MPI_FABRICS shm:ofa" #Intel MPI 2018 -#MPIOPT="-env I_MPI_FABRICS shm:ofi" #Intel MPI 2019 -#MPIOPT="--mca plm_rsh_agent ssh --mca btl self,openib,sm" #Open MPI -#MPIOPT="-iface ib0" #MPICH3 -#目前新版的MPI可以自己找寻高速网络配置,可以设置MPIOPT为空,如去掉下行的# -MPIOPT= -$MPIRUN $MPIOPT ./yourprog +module load intel/2023.2 +mpirun ./yourprog ``` 与串行程序的脚本相比,主要不同之处在于需采用mpirun或mpiexec的命令格式提交并行可执行程序。采用不同MPI提交时,需要打开上述对应的选项。 +总共需要使用多少个核,则设置 `-n` 为多少。 + +需要跨节点并行时,也可以将 `#SBATCH -N -n ` 替换为: + +``` +#SBATCH -N +#SBATCH --ntasks-per-node= +``` + +即定义每个节点使用多少个核,根据申请的资源总量由 Slurm 进行分配。 + 与串行作业类似,可使用下面方式提交: -`hmli@login01:~/work$ sbatch mpi_job.sh` +```bash +sbatch mpi_job.sh +``` ## GPU作业提交 -运行GPU作业,需要提交时利用--gres=gpu等指明需要的GPU资源并用-p指明采用等GPU队列。 +运行GPU作业,需要提交时利用 `--gres=gpu` 等指明需要的GPU资源并用 `-p` 指明采用等GPU队列。 脚本`gpu_job.sh`内容: @@ -296,13 +312,19 @@ $MPIRUN $MPIOPT ./yourprog #!/bin/sh #An example for gpu job. #SBATCH -J job_name +#SBATCH -p gpu +#SBATCH -A [account] +#SBATCH -q [QOS] #SBATCH -o job-%j.log #SBATCH -e job-%j.err -#SBATCH -N 1 -n 8 -p GPU-V100 --gres=gpu:v100:2 +#SBATCH -N 1 -n 8 --gres=gpu:2 ./your-gpu-prog ``` -上面-p GPU-V100指定采用GPU队列GPU-V100,--gres=gpu:v100:2指明每个节点使用2块NVIDIA V100 GPU卡。 +上面 `-p gpu` 指定采用GPU队列,`--gres=gpu:2` 指明每个节点使用 2 块NVIDIA A100 GPU卡。 + +!!! tip + 目前嘉庚智算上的 GPU 均为 NVIDIA A100 80G NVLink 全连接计算卡。 ## 作业获取的节点名及对应CPU核数解析 diff --git a/docs/slurm/srun.md b/docs/slurm/srun.md index c240126..521b2b7 100644 --- a/docs/slurm/srun.md +++ b/docs/slurm/srun.md @@ -181,87 +181,97 @@ Slurm支持一次申请多个节点,在不同节点上同时启动执行不同 ## 常见例子 -- 使用8个CPU核 ( `-n8` ) 运行作业,并在标准输出上显示任务号 (`-l`) : + +### 运行多核并行任务 + +使用8个CPU核 ( `-n8` ) 运行作业,并在标准输出上显示任务号 (`-l`) ```bash - srun -n8 -l hostname - ``` - +srun -n8 -l hostname +``` - 输出结果: +输出结果: ``` -0: node0 -1: node0 -2: node1 -3: node1 -4: node2 -5: node2 -6: node3 -7: node3 +3: cu021 +4: cu021 +5: cu021 +6: cu021 +7: cu021 +1: cu021 +0: cu021 +2: cu021 ``` -- 在脚本中使用 `-r2` 参数使其在第2号(分配的节点号从0开始)开始的两个节点上运行,并采用实时分配模式而不是批处理模式运行: +### 分配任务在不同进程上 - 脚本`test.sh`内容: +在脚本中使用 `-r2` 参数使其在第2号(分配的节点号从0开始)开始的两个节点上运行,并采用实时分配模式而不是批处理模式运行。 -```bash +脚本`test.sh`内容: + +```bash title="test.sh" #!/bin/sh echo $SLURM_NODELIST srun -lN2 -r2 hostname srun -lN2 hostname ``` -运行: `salloc -N4 test.sh` +运行: `salloc -N4 -p cpu test.sh` 输出结果: ``` -dev[7-10] -0: node9 -1: node10 -0: node7 -1: node8 +cu[011-014] +1: cu014 +0: cu013 +1: cu012 +0: cu011 ``` -- 在分配的节点上并行运行两个作业步: +可以看出先启动的任务在 `cu[013-014]` 上运行,即后两个节点。 - 脚本`test.sh`内容: +### 在分配的节点上并行运行两个作业步 -```bash +脚本`test.sh`内容: + +```bash title="test.sh" #!/bin/bash -srun -lN2 -n4 -r 2 sleep 60 & -srun -lN2 -r 0 sleep 60 & +srun -lN2 -n2 -r 2 sleep 60 & +srun -lN2 -n2 -r 0 sleep 60 & sleep 1 squeue squeue -s +wait ``` -运行: `salloc -N4 test.sh` +运行: `salloc -N4 -p cpu test.sh` 输出结果: ``` -JOBID PARTITION NAME USER ST TIME NODES NODELIST -65641 batch test.sh grondo R 0:01 4 dev[7-10] - -STEPID PARTITION USER TIME NODELIST -65641.0 batch grondo 0:01 dev[7-8] -65641.1 batch grondo 0:01 dev[9-10] +JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) +368585 cpu interact ypliucat R 0:04 4 cu[011-014] +STEPID NAME PARTITION USER TIME NODELIST +368585.0 sleep cpu ypliucat 0:01 cu[011-012] +368585.1 sleep cpu ypliucat 0:01 cu[013-014] +368585.extern extern cpu ypliucat 0:04 cu[011-014] ``` -- 运行MPICH作业: +可以看出我们分别创建了两个作业步 (Step),分别运行在后两个和前两个节点上。 - 脚本`test.sh`内容: +### 运行 MPI 作业 -```bash +脚本`test.sh`内容: + +```bash title="test.sh" #!/bin/sh MACHINEFILE="nodes.$SLURM_JOB_ID" -# 生成MPICH所需的包含节点名的machinfile文件 +# 生成 MPI 所需的包含节点名的machinfile文件 +module load intel/2023.2 srun -l /bin/hostname | sort -n | awk ’{print $2}’ > $MACHINEFILE -# 运行MPICH作业 +# 运行 MPI 作业 mpirun -np $SLURM_NTASKS -machinefile $MACHINEFILE mpi-app rm $MACHINEFILE @@ -269,9 +279,11 @@ rm $MACHINEFILE 采用2个节点(-N2)共4个CPU核(-n4)运行:`salloc -N2 -n4 test.sh` -- 利用不同节点号(`SLURM_NODEID`)运行不同作业,节点号从0开始: +### 利用不同节点运行不同作业 - 脚本`test.sh`内容: +利用不同节点号(`SLURM_NODEID`)运行不同作业,节点号从0开始: + +脚本`test.sh`内容: ```bash case $SLURM_NODEID in @@ -288,30 +300,40 @@ case $SLURM_NODEID in 运行: `srun -N2 test.sh` -> 输出: +输出: ``` -dev0 is where I am running I am running on ev1 +cu012 +is where I am running +I am running on +cu011 ``` -- 利用多核选项控制任务执行: +### 利用多核选项控制任务执行 - 采用2个节点(-N2),每节点4颗CPU每颗CPU 2颗CPU核(-B 4-4:2-2),运行作业: +采用2个节点(`-N2`),每节点2颗CPU,每颗CPU 2颗CPU核(`-B 2-2:2-2`),运行作业: - `srun -N2 -B 4-4:2-2 a.out` +```bash +srun -N2 -p cpu -B 2-2:2-2 a.out +``` + +### 运行GPU作业 -- 运行GPU作业: 脚本`gpu.sh`内容: +脚本`gpu.sh`内容: ```bash #!/bin/bash -srun -n1 -p GPU-V100 --gres=gpu:v100:2 prog1 +srun -n1 -p gpu --gres=gpu:2 prog1 ``` --p GPU-V100指定采用GPU队列GPU-V100,--gres=gpu:v100:2指明每个节点使用2块NVIDIA V100 GPU卡。 +`-p gpu` 指定采用GPU队列,`--gres=gpu:2` 指明每个节点使用 2 块 GPU 卡。 -- 排它性独占运行作业: +!!! tip + 目前嘉庚智算上的 GPU 均为 NVIDIA A100 80G NVLink 全连接计算卡。 - 脚本`my.sh`内容: +### 排它性独占运行作业 + +脚本`my.sh`内容: ```bash #!/bin/bash @@ -321,3 +343,6 @@ srun --exclusive -n1 prog3 & srun --exclusive -n1 prog4 & wait ``` + +!!! warning "注意" + 利用 `--exclusive` 开启排他性独占时,默认计费按照 **每个`srun`** 使用其所在节点全部资源进行,即使申请了 1 个 CPU 核或者 1 张 GPU 卡也会按照整个节点(64 个 CPU 核 / 8 张 GPU 卡)来计算。 diff --git a/docs/slurm/submission.md b/docs/slurm/submission.md index 36331ee..9715bfa 100644 --- a/docs/slurm/submission.md +++ b/docs/slurm/submission.md @@ -45,7 +45,7 @@ | `--wrap` | 使用 `sbatch` 时,直接在命令行中指定作业脚本内容。 | --> -!!! tips "提示" +!!! tip "提示" - 每节点申请的 CPU 核数=每节点进程数 (`--ntasks-per-node`) ×每进程核数 (`--cpus-per-task`) - 实际分配的 CPU 核数=节点数(`-N`)×每节点 CPU 核数=总进程数 (`--ntasks`) ×每进程核数 (`--cpus-per-task`) - `sbatch` 仅根据上述资源绑定关系申请对应的资源,实际 MPI 进程数和 OpenMP 线程数须由用户在作业批处理脚本中自行指定。 diff --git a/docs/usage/apps/anaconda.md b/docs/usage/apps/anaconda.md new file mode 100644 index 0000000..db8da6f --- /dev/null +++ b/docs/usage/apps/anaconda.md @@ -0,0 +1,83 @@ +# Anaconda + +目前,嘉庚智算上已经预置了 Anaconda 环境,因此用户可以借助该环境,方便地创建自己的 Python 虚拟环境,可以支持安装任意 Python 版本,并可用于安装一些常用的软件和依赖。 + +!!! tip "提示" + 用户可直接调用此预置环境,无须自行在用户目录下安装 Anaconda 或者 Miniconda。 + +## 加载基础环境 + +首先,加载Anaconda模块,可以通过以下命令加载Anaconda基础环境: +```bash +module load anaconda/2022.5 +``` + +## 创建虚拟环境 +如果你还没有虚拟环境,可以按照以下步骤创建一个新的虚拟环境: + +1. 首先,激活Anaconda的基础环境: + ```bash + source activate base + ``` + +2. 然后,创建一个新的虚拟环境。这里我们推荐使用 `-p ` 的方式创建在用户目录下,便于精确管理 Conda 环境的路径。例如: + ```bash + conda create -p /public/home/username/conda/envs/playground + ``` + + 您也可以在这一步骤指定所需的 Python 环境,例如: + + ```bash + conda create -p /public/home/username/conda/envs/playground python=3.11 + ``` + +3. 创建完成后,激活新创建的虚拟环境: + ```bash + source activate /public/home/username/conda/envs/playground + ``` + +!!! info "注意" + 在集群环境下更推荐使用 `source activate ` 而非 `conda activate `。 + 尽管官方推荐使用后者,但在集群的复杂环境下,前者是更不容易出错的选择。 + 并且使用前者无须确保在 `~/.bashrc` 中写入 `# >>> conda initialize >>>` 字段,可以有效避免潜在的环境冲突问题。 + +## 在使用时加载虚拟环境 + +假设你需要在使用到创建的上述虚拟环境:`/public/home/username/conda/envs/playground`,则可以通过以下命令激活它: + +```bash +module load anaconda/2022.5 +source activate /public/home/username/conda/envs/playground +``` + +当然,如果你想要加载具有指定名称或者路径前缀的 Conda 环境,请将 `/public/home/username/conda/envs/playground` 替换为你的环境名或路径。 + +## 注意事项 + +不建议在 `~/.bashrc` 中引入 `conda init` 创建的初始化指令,因为这可能会导致环境冲突和加载问题。具体原因如下: + +- **环境冲突**:自动加载Conda环境可能会与其他软件或环境发生冲突,导致无法正常工作。 +- **加载问题**:在某些情况下,自动加载Conda环境可能会导致加载顺序问题,影响其他环境的初始化。 + +建议在需要使用Anaconda环境时,手动加载和激活相应的环境,以确保环境的独立性和稳定性。 + +## 其他有用的命令 +以下是一些其他有用的 Conda 命令: + +### 列出所有虚拟环境 + +```bash +conda env list +``` + +### 删除虚拟环境 +```bash +conda remove -p --all +``` + +### 安装包到虚拟环境 +```bash +conda install +``` + +请根据你的实际需求使用这些命令。