Сборка и запуск программ, использующих ускорители NVIDIA A100 (технология CUDA) в разделе «a100»

Сборка программы на языке C/С++

Cборку программ, использующих ускорители NVidia A100, нужно осуществлять с помощью средств CUDA Toolkit начиная с версии 10.0.  В настоящий момент у нас установлены версии 11.2 и 11.3, их можно использовать, загрузив модули cuda/cuda-11.2 или cuda/cuda-11.3:

user@master ~$ module load cuda/cuda-11.2 # или
user@master ~$ module load cuda/cuda-11.3

Если программа содержит не-CUDA модули или использует MPI, то необходимо дополнительно загрузить соответствующие модули для компилятора или MPI-библиотеки.

Компиляция и линковка программы, содержащей код CUDA, производится командой следующего вида:

user@master ~$ echo '#include <stdio.h>
#include <cuda.h>
__global__ void mykernel(void){
    printf("Hello World from thread %d block %d on device\n", threadIdx.x , blockIdx.x);
}
int main (void ) {
    mykernel<<<2,2>>>();
    cudaDeviceSynchronize();
    return 0;
}' >helloCUDA.cu
user@master ~$ nvcc -o helloCUDA --gpu-architecture=sm_80 -lcudart helloCUDA.cu

Запуск программы через систему управления кластером Slurm

Для запуска программы в интерактивном режиме на одном узле кластера (ускорители NVidia A100 установлены на узлах node238 и node239) нужно выполнить команду следующего вида:

user@master ~$ srun -N 1 -n 3 -p a100 --gres=gpu:3 ./helloCUDA
Hello World from thread 0 block 1 on device
Hello World from thread 1 block 1 on device
Hello World from thread 0 block 0 on device
Hello World from thread 1 block 0 on device
Hello World from thread 0 block 0 on device
Hello World from thread 1 block 0 on device
Hello World from thread 0 block 1 on device
Hello World from thread 1 block 1 on device
Hello World from thread 0 block 1 on device
Hello World from thread 1 block 1 on device
Hello World from thread 0 block 0 on device
Hello World from thread 1 block 0 on device

Здесь «-N 1» — запрос на выделение для запуска одного узла, «-n 3» — число создаваемых процессов (значение более одного обычно используется для запуска mpi-программ, для одного процесса параметр можно не указывать), «-p a100» — выбор раздела для запуска (обязательный параметр для запуска на узлах с A100), «—gres=gpu:3» — запрос на выделение 3 ускорителей NVidia A100 (с точки зрения вашей программы ускорители будут иметь номера 0,1,2).

В нашем случае запустилось 3 копии программы, все они использовали одно устройство (для использования различных нужно добавить в код вызов cudaSetDevice()), каждая копия запустила на устройстве код в 2 блока по 2 потока.

Для запуска в пакетном режиме необходимо подготовить файл задания и поставить его в очередь заданий:

user@master ~$ echo '#!/bin/sh
#SBATCH -N 1
#SBATCH --gres=gpu:3
#SBATCH --time=10
#SBATCH --partition=a100
./helloCUDA' >batch_helloCUDA.sh
user@master ~$ sbatch batch_helloCUDA.sh
Submitted batch job 2420539

Параметры запуска задания (time, partition, N etc) могут быть указаны как в файле задания, так и в командной строке sbatch. Номер задания может быть использован для просмотра его состояния. После завершения выполнения задания стандартный вывод и стандартный вывод ошибки записываются в файлы slurm-JOBID.out и slurm-JOBID.err (можно задать файлы с другими именами).

user@master ~$ scontrol show job 2420539
JobId=2420539 JobName=batch_helloCUDA.sh
UserId=user(userid) GroupId=Users(10000) MCS_label=N/A
Priority=1052937772 Nice=0 Account=user QOS=normal
JobState=PENDING Reason=Nodes_required_for_job_are_DOWN,_DRAINED_or_reserved_for_jobs_in_higher_priority_partitions Dependency=(null)
...
user@master ~$ cat slurm-2420539.out
Hello World from thread 0 block 1 on device
Hello World from thread 1 block 1 on device
Hello World from thread 0 block 0 on device
Hello World from thread 1 block 0 on device

Если вы запускаете ранее собранную программу, необходимо предварительно загрузить тот модуль CUDA, который использовался при ее компиляции и линковке.