Пример запуска HPL-NVIDIA
В этом примере мы запустим модифицированный тест Linpack от NVIDIA для оценки производительности графических ускорителей.
Установка HPL-NVIDIA
Один из самых простых способов запустить HPL-NVIDIA – воспользоваться готовым контейнером hpc-benchmarks
с сайта NVIDIA. На кластере для работы с контейнерами используется пакет Singularity, он доступен в системе загрузки модулей. Для загрузки контейнера hpc-benchmarks
нужно зарегистрироваться на сайте NVIDIA NGC и получить API key.
# загружаем модуль singularity
module load singularity
# скачиваем образ Docker-контейнера и конвертируем в образ Singularity
singularity pull --docker-login hpc-benchmarks:21.4-hpl.sif \
docker://nvcr.io/nvidia/hpc-benchmarks:21.4-hpl
# для скачивания потребуется API key
Образ hpc-benchmarks
будет сохранён в текущей директории в файле hpc-benchmarks:21.4-hpl.sif
.
Запуск HPL-NVIDIA
Запустим расчёт с использованием 4 графических ускорителей Nvidia Tesla V100S. Подготовим файл конфигурации HPL-4xV100.dat и скрипт для очереди задач hpl-nvidia-4-v100.sh.
1HPLinpack benchmark input file
2Innovative Computing Laboratory, University of Tennessee
3HPL.out output file name (if any)
46 device out (6=stdout,7=stderr,file)
51 # of problems sizes (N)
6130560 Ns
71 # of NBs
8384 NBs
90 PMAP process mapping (0=Row-,1=Column-major)
101 # of process grids (P x Q)
112 Ps
122 Qs
1316.0 threshold
141 # of panel fact
151 PFACTs (0=left, 1=Crout, 2=Right)
161 # of recursive stopping criterium
174 NBMINs (>= 1)
181 # of panels in recursion
192 NDIVs
201 # of recursive panel fact.
211 RFACTs (0=left, 1=Crout, 2=Right)
221 # of broadcast
233 BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM)
241 # of lookahead depth
251 DEPTHs (>=0)
261 SWAP (0=bin-exch,1=long,2=mix)
27192 swapping threshold
281 L1 in (0=transposed,1=no-transposed) form
290 U in (0=transposed,1=no-transposed) form
300 Equilibration (0=no,1=yes)
318 memory alignment in double (> 0)
В этом примере файла HPL.dat
мы указываем размер системы в строке 6. Размер N=130560
подобран из соображений максимального использования GPU памяти. 4 карты по 32 Гб памяти в сумме дают 128 Гб памяти, что позволяет хранить плотную матрицу 131072×131072 чисел с плавающей точкой с двойной точностью. Мы немного уменьшим значение N
, чтобы оно стало кратным параметру NB=384
. Разбиение системы на блоки указывается в строках 11-12. Произведение P×Q
должно совпадать с количеством используемых графических ускорителей.
1#!/bin/bash
2#SBATCH --job-name=hpl-nvidia-4-v100 # название задачи
3#SBATCH --partition=gpu # очередь gpu
4#SBATCH --gpus=v100:4 # 4 ускорителя v100
5#SBATCH --nodes=1 # 1 вычислительный узел
6#SBATCH --ntasks-per-node=4 # 4 процесса на один узел
7#SBATCH --cpus-per-task=6 # 6 ядер на один процесс
8#SBATCH --time=0:10:00 # оценка времени 10 минут
9
10# загружаем модуль singularity для контейнера
11module load singularity
12# предполагается, что контейнер hpc-benchmarks:21.4-hpl.sif
13# находится в текущей директории
14srun --mpi=pmi2 singularity run --nv \
15 ./hpc-benchmarks:21.4-hpl.sif hpl.sh \
16 --cpu-affinity all:all:all:all \
17 --cpu-cores-per-rank $SLURM_CPUS_PER_TASK \
18 --gpu-affinity 0:1:2:3 \
19 --dat HPL-4xV100.dat
В скрипте указываются параметры задачи: в строке 2 – название задачи, в строке 3 – название очереди gpu
для серверов с графическими ускорителями, в строке 4 – необходимое количество и тип графических ускорителей, в строке 5 – количество GPU-узлов (в данном случае этот параметр можно опустить), в строке 6 – количество процессов на одном сервере (можно также просто указать --ntasks=4
), в строке 7 – количество CPU ядер на один процесс, в строке 8 – максимальное время выполнения задачи. В строке 11 загружается модуль singularity
для работы с контейнерами Singularity. В строках 14-19 запускается параллельный расчёт задачи: в строке 14 программа srun
запускает 4 процесса singularity
, параметр --nv
у singularity
предоставляет контейнеру доступ к графическим ускорителям, в строке 15 указано название контейнера ./hpc-benchmarks:21.4-hpl.sif
и запускаемый скрипт внутри контейнера hpl.sh
, в строке 16 указывается привязка процессов к ядрам CPU, мы указываем ключевое слово all
, чтобы использовать привязку Slurm, в строке 17 указывается количество ядер на один процесс, мы указываем значение $SLURM_CPUS_PER_TASK
, которое совпадает с параметром --cpus-per-task
, в строке 18 указывается привязка GPU-карт к процессам, в строке 19 указывается имя файла с параметрами HPL.dat
.
Для запуска задачи в системе очередей используется команда sbatch
:
sbatch hpl-nvidia-4-v100.sh
Результаты расчёта будут сохранены в файле slurm-XXX.out
, где XXX
– номер задачи. Время расчёта с указанными параметрами обычно составляет несколько минут.
Сводную таблицу с временем работы и оценкой скорости вычислений можно получить с помощью следующей команды:
# вместо XXX нужно указать номер задачи, или использовать *
grep -B2 WR slurm-XXX.out
# пример вывода:
# T/V N NB P Q Time Gflops
# --------------------------------------------------------------------------------
# WR03C2C4 130560 384 2 2 61.55 2.411e+04
В результате получена производительность R_max = 24110 Gflops
.
В примере выше мы использовали не все доступные ядра на узле g01
. Наш выбор обусловлен особенностями подключения GPU-карт к материнской плате. На узле g01
установлены 4 карты Nvidia Tesla V100S, и все они подключены к PCI-шине первого процессора. Такое подключение позволяет ускорить обмены между GPU-картами через общую PCI-шину. С другой стороны, обмены между вторым процессором и GPU-картами происходят медленнее. При использовании 6 ядер на одну GPU-карту нам достаточно 24 ядер, и они все могут быть размещены на первом процессоре.
Попытка добавить больше ядер приведёт лишь к снижению производительности из-за дополнительных накладных расходов при обменах между вторым процессором и GPU-картами:
# увеличиваем количество ядер на процесс в два раза
sbatch --cpus-per-task=12 hpl-nvidia-4-v100.sh
grep -B2 WR slurm-XXX.out
# пример вывода:
# T/V N NB P Q Time Gflops
# --------------------------------------------------------------------------------
# WR03C2C4 130560 384 2 2 87.42 1.697e+04
В результате подключения к работе второго процессора производительность уменьшилась до R = 16970 Gflops
.
Система очередей Slurm автоматически выбирает свободные ядра первого процессора при запросе графических ускорителей V100 на узле g01
.