Содержание

 1 Введение
 2 Быстрый старт
 3 Кластер «Ангара-К1»
  3.1 Общее описание
 4 Поддерживаемые модели программирования
  4.1 Особенности реализации библиотеки MPI
  4.2 MPI+SHMEM
  4.3 Потоки в SHMEM
   4.3.1 SHMEM+pthreads
   4.3.2 SHMEM+OpenMP
  4.4 Потоки в MPI
 5 Компиляция программ
  5.1 Опции для MPI
   5.1.1 Сбор статистики
  5.2 Запуск программ с использованием SLURM
   5.2.1 Команда srun
   5.2.2 Команда sbatch
   5.2.3 Особенности, ограничения, рекомендации
 6 Рекомендации для получения максимальной производительности

1 Введение

Данная страница является руководством по использованию кластера «Ангара-К1».

В руководстве приводится краткое описание поддерживаемых моделей программирования, инфраструктуры запуска и отслеживания выполнения задач.

2 Быстрый старт

3 Кластер «Ангара-К1»

3.1 Общее описание

Кластер состоит из 36 узлов, соединённых сетью Ангара с адаптерами на базе СБИС ЕС8430.

Топология сети — 4D-тор размерности 3 × 3 × 2 × 2 (X × Y × Z × K). Пары узлов по направлению K соединены одним линком, по направлению Z — двумя линками.

Головной узел — head, сборка и запуск программ должны осуществляться только с него.

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

  1. А-узлы (24 шт.):
    • сервер Supermicro X9DRW-3LN4F+/X9DRW-3TF+ (BIOS rev. 1.0);
    • 2 процессора Intel Xeon CPU E5-2630 @ 2.30GHz по 6 ядер (всего 12 ядер);
    • Операционная система: SLES 11 SP4 (kernel 3.0.101-63-default x86_64);
    • Память 64 ГБ ;
  2. В-узлы (12 шт.):
    • сервер Supermicro X9SRG-F (BIOS rev. 1.0);
    • 1 процессор Intel Xeon CPU E5-2660 @ 2.20GHz (8 ядер);
    • Операционная система SLES 11 SP4 (kernel 3.0.101-63-default x86_64);
    • Память 64 ГБ.

На данный момент на всех процессорах кластера включен режим Hyper-Threading, режим Turbo Boost выключен.

Для системы запуска SLURM на кластере «Ангара-К1» доступны следующие разделы: A (только A-узлы), B (только B-узлы), all (все узлы кластера).

На кластере установлены:

4 Поддерживаемые модели программирования

Можно использовать следующие средства параллельного программирования:

4.1 Особенности реализации библиотеки MPI

Библиотека MPI для сети Ангара базируется на MPICH 3.0.4 (реализация стандарта MPI-3).

4.2 MPI+SHMEM

Необходимо явно вызывать как функции MPI_Init с MPI_Finalize, так и shmem_init с shmem_finalize, причём функция MPI_Init должна предшествовать функции shmem_init, а функция MPI_Finalize должна вызываться после функции shmem_finalize.

Пример правильного порядка вызова MPI и SHMEM функций при инициализации MPI и SHMEM в одном процессе:

#include <mpi.h>  
#include <shmem.h>  
 
int main() {  
    /* ... */  
    MPI_Init(...);  
    /* ... */  
    shmem_init();  
    /* ... */  
    shmem_finalize();  
    /* ... */  
    MPI_Finalize();  
    /* ... */  
}

4.3 Потоки в SHMEM

Базовое понятие SHMEM — PE (processing element). В нашем случае PE — это процесс вместе с выделенным регионом памяти (GA-память), доступным для удалённой записи/чтения.

Все потоки одного PE выполняют SHMEM-операции от имени этого PE. Синхронизация и логика работы потоков одного PE определяются целиком и полностью лишь пользователем SHMEM.

Все вызовы SHMEM по отношению к thread safety делятся на 3 категории:

Вызов Sync-shmem функций любым из потоков процесса является вызовом от имени PE, никакой неявной синхронизации между потоками в SHMEM нет, никакого различия при посылке пакетов между разными потоками одного процесса (PE) не делается. Порядок SHMEM-операций выдаваемых разными потоками без явной синхронизации недетерминирован.

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

Библиотека SHMEM предполагает возможность поддержки одного/нескольких из следующих режимов работы с потоками:

Для организации работы с потоками в SHMEM добавлены следующие функции:

4.3.1 SHMEM+pthreads

Основная модель программирования при использовании pthreads вместе с SHMEM: в основном потоке вызвать shmem_init() либо shmem_init_thread() в начале и shmem_finalize() в конце, затем в остальных потоках, которые будут выполнять RW-, Sync-shmem вызовы, вызвать в начале shmem_thread_started() и shmem_thread_exited() в конце.

Пример правильного порядка вызова SHMEM функций при использовании pthreads:

void* thread_func(void *argv) {  
    shmem_thread_started();  
    /* ... */  
    shmem_thread_exited();  
}  
 
int main() {  
    shmem_init();  
    /* ... */  
    for (i = 0; i < ...) {  
        pthread_create(..., thread_func, ...);  
    }  
    /* ... */  
    shmem_finalize();  
}

4.3.2 SHMEM+OpenMP

Основная модель программирования при использовании OpenMP вместе с SHMEM: в головном потоке вызвать shmem_init() либо shmem_init_thread() в начале и shmem_finalize() в конце, в остальных потоках не вызывать специальных функций.

Функция shmem_is_omp_supported() используется для проверки, что текущая версия SHMEM поддерживает OpenMP.

int main() {  
    shmem_init();  
    /* ... */  
    if (!shmem_is_omp_supported()) {  
        printf("This version of SHMEM doesn’t support OpenMP!\n");  
        abort();  
    }  
#   pragma omp parallel  
    {  
        /* SHMEM here */  
    }  
    /* ... */  
    shmem_finalize();  
}

4.4 Потоки в MPI

Для безопасной работы с потоками в MPI есть специальный вызов MPI_Init_thread, заменяющий MPI_Init и инициализирующий среду для работы с потоками:

    int MPI_Init_thread(int *argc, char ***argv, int required, int *provided);

Аргумент required используется для задания требуемого уровеня поддержки потоков. Допустимы следующие значения:

Различные процессы задачи могут требовать различных уровней поддержки потоков.

Вызвращаемое значение provided содержит информацию об уровне поддержки потоков, который будет фактически обеспечен MPI (одно из четырёх перечисленных выше значений). Это значение может зависеть от особенностей реализации (конфигурации) MPI, а также от переменных окуржения, выставленных перед запуском задачи.

В случае успеха, будет возвращено значение provided required, иначе — максимальный доступный уровень поддержки потоков.

Более подробную информацию см. в спецификации MPI.

Функции MPI_Init (MPI_Init_thread) и MPI_Finalize должны вызываться в одном и том же потоке.

5 Компиляция программ

5.1 Опции для MPI

Переменные окружения, которые могут пригодиться при использовании MPI для сети Ангара (AMFCH):

5.1.1 Сбор статистики

Данный раздел посвящён средствам сбора статистики для сети Ангара при выполнении MPI-пересылок. Собственные средства MPI здесь не рассматриваются.

Общая информация На текущий момент поддерживается сбор следующих статистических данных:

Собранные статистические данные могут быть отображены в следующих формах:

  1. исходные данные для построения графа пересылок для пакета Graphviz: вершины графа — MPI-процессы, толщина дуг указывает интенсивность пересылок; интенсивность задаётся числом от 0 до 10, где 10 соотвествует максимальному числу слов, переданных между какой-либо парой MPI-процессов за данный период сбора статистики;
  2. набор таблиц: по одной таблице для каждого MPI-процесса, в строках — данные для каждого возможного адресата;
  3. матрица паттерна инжекции: элементы матрицы — количество переданных 64-битных слов между источником и адресатам, строки — источники, столбцы — адресаты; числа разделены пробелами, данную форму отображения удобно использовать для построения heat map.

Пример вывода данных для построения графа пересылок:

digraph {  
    node [shape=circle,fixedsize=true,width=1];  
    overlap=false;  
    splines=true;  
    A0 [label="A0"];  
    A1 [label="A1"];  
    A0 -> A1 [penwidth=10.000];  
    A1 -> A0 [penwidth=0.468];  
}

Пример вывода набора таблиц:

rank = 0  
| dest | avg_msg,w |   msg_cnt | data_total,w |  
|    0 |      0.00 |         0 |            0 |  
|    1 |   2009.74 |      1685 |      3386419 |  
 
rank = 1  
| dest | avg_msg,w |   msg_cnt | data_total,w |  
|    0 |   1570.75 |       101 |       158646 |  
|    1 |      0.00 |         0 |            0 |

Пример вывода паттерна инжекции:

Injection pattern (rows - sources; columns - destinations; values - 64-bit words sent):  
0 3386419  
158646 0

Включение сбора статистики и управление выводом Сбор статистики возможен, если при сборке AMFCH (администратором кластера) был определён макрос AMFCH_ENABLE_STATISTICS=1. Пользователю доступна функция amfch_statistics_is_enabled, которая возвращает 1, если сбор статистики поддерживается данной версией MPI, и 0 в противном случае.

Форма отображения собранных данных задаётся переменной окружения AMFCH_STATISTICS_PRINT_MODE путём выставления соответствующих битов маски: бит 0 — вывод данных для построения графа пересылок, бит 1 — вывод набора таблиц, бит 2 — вывод паттерна инжекции. Например, AMFCH_STATISTICS_PRINT_MODE=7 задаёт одновременный вывод всех трёх форм отображения. По умолчанию происходит вывод только паттерна инжекции.

Функции для работы со статистикой По умолчанию (при сборке с AMFCH_ENABLE_STATISTICS=1) статистика начинает собираться автоматически сразу после вызова MPI_Init(), а результаты выводятся при вызове функции MPI_Finalize().

Программисту также доступен набор функций для работы со статистикой:

Прототипы данных функций находятся в amfch.h.

5.2 Запуск программ с использованием SLURM

Ниже приведена краткая справочная информация по основным командам SLURM; более подробная информация доступна в man к соответствующей команде.

Для запуска задач в системе SLURM пользователю доступны следующие команды:

5.2.1 Команда srun

Команда srun позволяет запускать задачи в интерактивном режиме; формат команды: srun [OPTIONS] PROG [ARGS].

Основные опции:

Таким образом, при выполнении команды srun -N2 --ntasks-per-node=4 tt программа tt будет запущена на двух узлах по четыре процесса на каждом.

5.2.2 Команда sbatch

Команда sbatch позволяет запускать задачи в пакетном режиме; формат команды: sbatch [OPTIONS] SCRIPT [ARGS].

Основные опции:

Скрипт запускается на первом из выделенных узлов. Запуск нескольких процессов осуществляется командой srun. При этом все опции, указанные в командной строке или самом скрипте в строках #SBATCH, приписываются к каждой команде srun данного скрипта, если не переопределены в ней.

$ cat myscript  
#!/bin/sh  
#SBATCH --ntasks-per-node=4  
srun tt  
 
$ sbatch -N2 myscript

При выполнении данной последовательности команд, программа tt будет запущена на двух узлах по четыре процесса на каждом. Выполнение команды sbatch -N2 --ntasks-per-node=4 --wrap "srun tt" приведет к аналогичным результатам.

5.2.3 Особенности, ограничения, рекомендации

Текущие ограничения:

Текущие особенности выделения узлов:

6 Рекомендации для получения максимальной производительности

  1. Для увеличения производительности рекомендуется использовать опции SLURM для привязки процессов к ядрам и распределения процессов по сокетам.
    • Для А-узлов при запуске более 6 процессов на узле рекомендуется распределять процессы равномерно по сокетам, а для ядер использовать только один аппаратный поток из двух доступных в режиме Hyper Threading. Также необходимо привязывать процессы к аппаратным потокам ядер. Для этого можно использовать опции SLURM --ntasks-per-node, --threads-per-core, --cpu_bind.
      srun -N 16 --ntasks-per-node=8 --ntasks-per-socket=4  
           --threads-per-core=1 --cpu_bind=threads tt

      В данном примере будет использоваться рекомендуемое равномерное распределение процессов по сокетам (в slurm задано по умолчанию).

    • В режиме использования библиотеки MPI в сочетании с технологией OpenMP рекомендуется дополнительно ко всем вышеупомянутым опциям SLURM использовать опцию --cpus-per-task=<omp_num_threads> — на каждый MPI-процесс выделить omp_num_threads виртуальных процессоров (в контексте предыдущих опций — ядер), где omp_num_threads — необходимое количество OpenMP-потоков.
  2. Так как в кластере присутствуют узлы с разными характеристиками, при выполнении задачи на всех вычислительных узлах рекомендуется использовать не больше 8 процессов на узел.