.. _hpl_nvidia: ========================= Пример запуска HPL-NVIDIA ========================= В этом примере мы запустим модифицированный тест `Linpack от NVIDIA `_ для оценки производительности графических ускорителей. Установка HPL-NVIDIA -------------------- Один из самых простых способов запустить HPL-NVIDIA – воспользоваться готовым контейнером ``hpc-benchmarks`` с сайта `NVIDIA `_. На кластере для работы с контейнерами используется пакет Singularity, он доступен в системе загрузки модулей. Для загрузки контейнера ``hpc-benchmarks`` нужно зарегистрироваться на сайте `NVIDIA NGC `_ и получить `API key `_. .. code-block:: bash # загружаем модуль 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. Подготовим файл конфигурации :ref:`hpl_nvidia_4_v100_dat` и скрипт для очереди задач :ref:`hpl_nvidia_4_v100_sbatch`. .. code-block:: text :caption: ``HPL-4xV100.dat`` :name: hpl_nvidia_4_v100_dat :linenos: HPLinpack benchmark input file Innovative Computing Laboratory, University of Tennessee HPL.out output file name (if any) 6 device out (6=stdout,7=stderr,file) 1 # of problems sizes (N) 130560 Ns 1 # of NBs 384 NBs 0 PMAP process mapping (0=Row-,1=Column-major) 1 # of process grids (P x Q) 2 Ps 2 Qs 16.0 threshold 1 # of panel fact 1 PFACTs (0=left, 1=Crout, 2=Right) 1 # of recursive stopping criterium 4 NBMINs (>= 1) 1 # of panels in recursion 2 NDIVs 1 # of recursive panel fact. 1 RFACTs (0=left, 1=Crout, 2=Right) 1 # of broadcast 3 BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM) 1 # of lookahead depth 1 DEPTHs (>=0) 1 SWAP (0=bin-exch,1=long,2=mix) 192 swapping threshold 1 L1 in (0=transposed,1=no-transposed) form 0 U in (0=transposed,1=no-transposed) form 0 Equilibration (0=no,1=yes) 8 memory alignment in double (> 0) В этом примере файла ``HPL.dat`` мы указываем размер системы в строке 6. Размер ``N=130560`` подобран из соображений максимального использования GPU памяти. 4 карты по 32 Гб памяти в сумме дают 128 Гб памяти, что позволяет хранить плотную матрицу 131072×131072 чисел с плавающей точкой с двойной точностью. Мы немного уменьшим значение ``N``, чтобы оно стало кратным параметру ``NB=384``. Разбиение системы на блоки указывается в строках 11-12. Произведение ``P×Q`` должно совпадать с количеством используемых графических ускорителей. .. code-block:: slurm :caption: ``hpl-nvidia-4-v100.sh`` :name: hpl_nvidia_4_v100_sbatch :linenos: #!/bin/bash #SBATCH --job-name=hpl-nvidia-4-v100 # название задачи #SBATCH --partition=gpu # очередь gpu #SBATCH --gpus=v100:4 # 4 ускорителя v100 #SBATCH --nodes=1 # 1 вычислительный узел #SBATCH --ntasks-per-node=4 # 4 процесса на один узел #SBATCH --cpus-per-task=6 # 6 ядер на один процесс #SBATCH --time=0:10:00 # оценка времени 10 минут # загружаем модуль singularity для контейнера module load singularity # предполагается, что контейнер hpc-benchmarks:21.4-hpl.sif # находится в текущей директории srun --mpi=pmi2 singularity run --nv \ ./hpc-benchmarks:21.4-hpl.sif hpl.sh \ --cpu-affinity all:all:all:all \ --cpu-cores-per-rank $SLURM_CPUS_PER_TASK \ --gpu-affinity 0:1:2:3 \ --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``: .. code-block:: bash sbatch hpl-nvidia-4-v100.sh Результаты расчёта будут сохранены в файле ``slurm-XXX.out``, где ``XXX`` – номер задачи. Время расчёта с указанными параметрами обычно составляет несколько минут. Сводную таблицу с временем работы и оценкой скорости вычислений можно получить с помощью следующей команды: .. code-block:: bash # вместо 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-картами: .. code-block:: bash # увеличиваем количество ядер на процесс в два раза 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``.