• A
  • A
  • A
  • АБВ
  • АБВ
  • АБВ
  • А
  • А
  • А
  • А
  • А
Обычная версия сайта

Примеры запуска задач

В данном разделе разобраны способы выделения необходимых ресурсов, необходимых для запуска задачи на суперкомпьютере.  
Если вы не хотите вдаваться в подробности, используйте генератор пакетных файлов (бета-версия): https://lk.hpc.hse.ru/sbatch  

Определить, корректно ли работает ваша задача, Вы можете чрез систему HPC TaskMaster, разработанную Отделом суперкомпьютерного моделирования НИУ ВШЭ [1]. Убедитесь, что все выделенные задаче ядра процессора и GPU загружены полностью. Если ресурсы не заняты, ищите ошибку в программе. Если вы используете готовые программы, прочитайте в документации, сколько ядер и GPU они могут использовать. Не нужно выделять лишние ресурсы, если программа их не поддерживает.

Однопоточная задача 

В данном примере описывается, как задать однопоточную задачу, использующую одно ядро на одном процессоре. Ниже представлена схема вычислительного узла типа D суперкомпьютера cHARISMa. Он состоит из материнской платы с двумя процессорами по 24 процессорных ядра в каждом. Задание на схеме обозначено красным прямоугольником, а используемое ядро отмечено черным. 

A picture containing text, electronics Description automatically generated

Скрипт запуска задачи: 

#!/bin/env bash
#SBATCH --ntasks=1            # Количество MPI процессов
#SBATCH --ntasks-per-node=1   # Количество выделенных процессов на один узел
#SBATCH --cpus-per-task=1     # Количество ядер CPU, выделенных для одного процесса
#SBATCH --constraint=type_d   # Предпочтительный тип узлов

srun 1dwave.o

 

Задача OpenMP 

OpenMP - технология создания многопоточных приложений на системах с общей памятью, т.е. программы OpenMP могут быть запущены только на одном вычислительном узле.  

SLURM не устанавливает переменную OMP_NUM_THREADS в окружении задачи. Пользователь должен самостоятельно добавить её в batch-скрипт и обычно она равна тому же, что и --cpus-per-task. 

Чтобы скомпилировать код с OpenMP:

Компилятор Опции
GCC -fopenmp 
ICC -openmp 

Обратите внимание, что в приведенных ниже командах явно указывается NUMA (https://en.wikipedia.org/wiki/Non-uniform_memory_access/) конфигурация процессов. Вам не нужно указывать команды "per-socket", если это не важно для вас. 

24 ядра на 1-м процессоре 

Предположим, что у нас есть один процесс, который мы хотим запустить на всех ядрах процессора. Размещение всех потоков задачи на одном процессоре улучшает скорость взаимодействия между ядрами. 

 Table Description automatically generated

#!/bin/env bash
#SBATCH --nodes=1                      # Количество используемых узлов
#SBATCH --ntasks=1                     # Количество MPI процессов
#SBATCH --cpus-per-task=24             # Количество ядер CPU, выделенных для одного процесса
#SBATCH --ntasks-per-socket=1          # Количество процессов на одном сокете узла
#SBATCH --constraint=”type_d|type_c”   # Предпочтительный тип узлов

# Задайте OMP_NUM_THREADS тем же значением, что и --cpus-per-task=24
export OMP_NUM_THREADS=24
srun 1dwave.o 

24 ядра на 2-x процессорах 

Теперь предположим, что мы хотим запустить то же задание, но на 12-х ядрах на двух процессорах. Такой вариант запуска может быть эффективнее, если ваша программа делает очень много обращений к оперативной памяти, но мало коммуникаций между процессорными ядрами.  

 Diagram, table Description automatically generated

#!/bin/env bash
#SBATCH --nodes=1                      # Количество используемых узлов
#SBATCH --ntasks=1                     # Количество MPI процессов
#SBATCH --cpus-per-task=24             # Количество ядер CPU, выделенных для одного процесса
#SBATCH --cores-per-socket=12          # Количество ядер на одном сокете узла
#SBATCH --constraint=”type_d|type_c”   # Предпочитаемый тип узлов

# Задайте OMP_NUM_THREADS тем же значением, что и --cpus-per-task=24
export OMP_NUM_THREADS=24
srun 1dwave.o

 

MPI - задача 

Процессы MPI могут быть запущены с помощью команды srun или традиционных mpirun или mpiexec. Нет необходимости указывать количество запускаемых процессов (-np), так как это автоматически считывается из переменных среды SLURM. 

4 процесса на одном процессоре 

Предположим, что мы хотим использовать 4 ядра на одном процессоре для четырех MPI процессов, по одному на ядро. 

 Shape Description automatically generated with medium confidence

#!/bin/env bash
#SBATCH --ntasks=4                     # Количество MPI процессов
#SBATCH --ntasks-per-node=4            # Количество процессов на один узел
#SBATCH --cpus-per-task=1              # Количество ядер CPU, выделенных для одного процесса
#SBATCH --ntasks-per-socket=4          # Количество процессов на один сокет
#SBATCH --constraint=”type_d|type_c”   # Предпочитаемый тип узлов
#SBATCH --nodes=1                      # Количество используемых узлов

module load openmpi # Загрузка модуля openmpi srun 1dwaveMPI.o # или mpirun 1dwaveMPI.o # или # FLAGS="--mca btl_tcp_if_exclude virbr0"
# mpirun -n $SLURM_NTASKS $FLAGS 1dwaveMPI.o 

Четыре процесса, распределенных на двух процессорах 

Предположим, что мы хотим использовать четыре ядра, распределенные между двумя процессорами для запуска четырех MPI процессов (по одному на ядро). Эта конфигурация может свести к минимуму конфликты ввода-вывода памяти, но замедлит передачу данных между ядрами. 

 Shape Description automatically generated

#!/bin/env bash
#SBATCH --ntasks=4                     # Количество MPI процессов
#SBATCH --ntasks-per-socket=2          # Количество процессов на один сокет
#SBATCH --cpus-per-task=1              # Количество ядер CPU, выделенных для одного процесса
#SBATCH --constraint=”type_d|type_c”   # Предпочитаемый тип узлов
#SBATCH --nodes=1                      # Количество используемых узлов

module load openmpi                         # Загрузка модуля openmpi

srun 1dwaveMPI.o # или mpirun mpiProg.exe

# или
# FLAGS="--mca btl_tcp_if_exclude virbr0"
# mpirun -n $SLURM_NTASKS $FLAGS 1dwaveMPI.o 

Использование всех ядер на одном вычислительном узле 

 A picture containing diagram Description automatically generated

#!/bin/env bash
#SBATCH --ntasks=48                    # Количество MPI процессов
#SBATCH --ntasks-per-socket=24         # Количество процессов на один сокет
#SBATCH --cpus-per-task=1              # Количество ядер CPU, выделенных для одного процесса
#SBATCH --constraint=”type_d|type_c”   # Предпочитаемый тип узлов
#SBATCH --nodes=1                      # Количество используемых узлов

module load openmpi                         # Загрузка модуля openmpi

srun 1dwaveMPI.o # или mpirun 1dwaveMPI.o

# или
# FLAGS="--mca btl_tcp_if_exclude virbr0"
# mpirun -n $SLURM_NTASKS $FLAGS 1dwaveMPI.o 

Использование всех ядер на двух вычислительных узлах 

 Diagram Description automatically generated

#!/bin/env bash
#SBATCH --ntasks=96                    # Количество MPI процессов
#SBATCH --cpus-per-task=1              # Количество ядер CPU, выделенных для одного процесса
#SBATCH --constraint=”type_d|type_c”   # Предпочитаемый тип узлов
#SBATCH --nodes=2                      # Количество используемых узлов

module load openmpi                    # Загрузка модуля openmpi

srun 1dwaveMPI.o

# или
# FLAGS="--mca btl_tcp_if_exclude virbr0"
# mpirun -n $SLURM_NTASKS $FLAGS 1dwaveMPI.o

 

Гибридные задачи MPI+OpenMP 

Можно запускать гибридные MPI задачи, многопоточность в которых реализована помощи OpenMP.  

В данном примере запускается по два MPI-процесса на каждом узле, каждый процесс создает по 48 OpenMP-потоков. Так как Hyperthreading не используется, потоки распределятся по физическим процессорным ядрам. 

Diagram Description automatically generated

#!/bin/env bash
#SBATCH --job-name=MPIOpenMP   # Название задачи
#SBATCH --ntasks=2             # Количество MPI процессов
#SBATCH --ntasks-per-node=1    # Количество процессов на один узел
#SBATCH --cpus-per-task=48     # Количество ядер CPU, выделенных для одного процесса

# Задайте OMP_NUM_THREADS тем же значением, что и --cpus-per-task=48 export OMP_NUM_THREADS=48 srun 1dwaveMPI.o

 

Использование GPU 

Ниже представлен способ использования GPU через SLURM. 

Один GPU и одно процессорное ядро 

Отметим, что такой запуск не оптимален. Как правило, для максимальной скорости передачи данных на GPU требуется от 4 ядер. 

Diagram, table Description automatically generated

#!/bin/env bash
#SBATCH --nodes=1               # Количество используемых узлов
#SBATCH --ntasks=1              # Количество MPI процессов
#SBATCH --cpus-per-task=1       # Количество ядер CPU, выделенных для одного процесса
#SBATCH --ntasks-per-socket=1   # Количество процессов на один сокет
#SBATCH --gpus=1                # Количество используемых GPU

./gpu_program.exe 

Четыре GPU и все процессорные ядра 

 Diagram Description automatically generated

#!/bin/env bash
#SBATCH --nodes=1               # Количество используемых узлов
#SBATCH --ntasks=1              # Количество MPI процессов
#SBATCH --cpus-per-task=48      # Количество ядер CPU, выделенных для одного процесса
#SBATCH --gpus=4                # Количество используемых GPU
#SBATCH --constraint=”type_c”   # Предпочитаемый тип узлов

./gpu_program.exe 

Восемь GPU на двух вычислительных узлах 

 A1IXPN83za8UAAAAAElFTkSuQmCC

#!/bin/env bash
#SBATCH --ntasks=2              # Количество MPI процессов
#SBATCH --ntasks-per-node=1     # Количество процессов на один узел
#SBATCH --cpus-per-task=48      # Количество ядер CPU, выделенных для одного процесса
#SBATCH --gpus-per-node=4       # Количество GPU на один узел
#SBATCH --constraint=”type_c”   # Предпочитаемый тип узлов

./gpu_program.exe

ПРИМЕЧАНИЕ: вместо --gpus-per-node=4 при использовании 2 узлов можно было бы указать --gpus=8

Восемь GPU и все процессорные ядра 

Вычислительные узлы типа E имеют 128 ядер на двух процессорах и 8 современных GPU A100 

H93Ii1GbCSylwAAAABJRU5ErkJggg==

#!/bin/env bash
#SBATCH --nodes=1               # Количество используемых узлов
#SBATCH --ntasks=1              # Количество MPI процессов
#SBATCH --cpus-per-task=128     # Количество ядер CPU, выделенных для одного процесса
#SBATCH --gpus=8                # Количество используемых GPU
#SBATCH --constraint=”type_e”   # Предпочитаемый тип узлов   

./gpu_program.exe

ПРИМЕЧАНИЕ: В последних трех примерах важно указывать тип вычислительного узла, так как узлы имеют разное количество ядер и GPU 


 

Нашли опечатку?
Выделите её, нажмите Ctrl+Enter и отправьте нам уведомление. Спасибо за участие!
Сервис предназначен только для отправки сообщений об орфографических и пунктуационных ошибках.