Заметки об изучении исходного кода Open MPI — введение в архитектуру

Архитектура

Abstract

Введение в открытую архитектуру MPI Заметки для чтения

Ссылаться на:

The Architecture of Open Source Applications (Volume 2): Open MPI (aosabook.org)

woohoo.open-flattering.org/video/inter…

Примечание. Оба этих введения основаны на версии 1.x Open MPI. В более поздних версиях некоторые структуры кода были изменены, и вы должны переключаться на версию 1.x при чтении вместе с исходным кодом, иначе легко возникнет путаница.

open-mpi/ompi: Open MPI main development repository (github.com)

Background

The Message Passing Interface (MPI)

MPI — это набор стандартов связи, состоящий изMPI ForumСоздан и поддерживается (MPI Forum — открытая организация экспертов по высокопроизводительным вычислениям из промышленности и научных кругов).

MPI — это такой API:

  • Портативный
  • Высокопроизводительная IPC-коммуникация

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

MPI определяет ряд платформо-независимых высокоабстрактных API-интерфейсов для передачи сообщений между процессами. Чтобы привести простейший пример, процесс X является процессом-отправителем, и ему нужно только предоставить содержимое сообщения (например, массив двойной точности) и идентификатор другого процесса-получателя (например, процесса Y), а процесс-получатель Y нужно только указать идентификатор процесса-отправителя (например, процесс X), сообщения могут передаваться от X к Y.

Обратите внимание, что в этом примере нет установления соединения, преобразования потока байтов и обмена сетевыми адресами MPI абстрагирует и инкапсулирует эти детали, что не только скрывает сложность, но и позволяет приложениям быть совместимыми с различными платформами, оборудованием и тип сети.

Режимы связи, предоставляемые MPI:

  • point to pint
  • collective
  • broadcast

Uses of MPI

Open-MPI — это реализация интерфейса MPI с открытым исходным кодом. Поддерживаемые типы сетей включают, помимо прочего: различные протоколы через Ethernet (например, TCP, iWARP, UDP, необработанные кадры Ethernet и т. д.), общую память и InfiniBand.

Реализации MPI обычно фокусируются на следующих показателях:

  • Сверхмалая задержка для обмена короткими сообщениями: передача 1-байтовых данных из пользовательского потока Linux в пользовательский поток другого сервера через InfiniBand занимает всего 1 микросекунду (0,000001 секунды).
  • Чрезвычайно высокая скорость вставки сообщений в сеть для обмена короткими сообщениями: некоторые реализации MPI (со специальным оборудованием) могут вводить сообщения в сеть до 28 миллионов в секунду.
  • Quick ramp-up (as a function of message size) to the maximum bandwidth supported by the underlying transport.
  • Низкое использование ресурсов: не может повлиять на производительность приложения.

Рождение открытого MPI

Open MPI объединяет четыре различных реализации MPI:

  • LAM/MPI,
  • LA/MPI (Los Alamos MPI)
  • FT-MPI (Fault-Tolerant MPI)
  • PACX-MPI

Architecture

Открытый MPI написан на C

Open MPI — это очень большая и сложная кодовая база.

  • Стандарт MPI 2003 года — MPI-2.0, определяет более 300 интерфейсов API.
  • Предыдущие 4 проекта, каждый из которых был огромным. Например, LAM/MPI состоит из более чем 1900 исходных файлов с более чем 30W строк кода.
  • Надеемся, что Open MPI будет поддерживать как можно больше функций, сред и типов сетей.

Поэтому Open MPI потратил много времени на разработку архитектуры, сосредоточившись на трех вещах:

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

Abstraction Layer Architecture

Open MPi можно разделить на три основных уровня абстракции сверху вниз:

  • OMPI (Open MPI) (pronounced: oom-pee):

    • Определяется стандартом MPI
    • API, доступный для приложений верхнего уровня, вызываемый внешними приложениями
  • ORTE (Open MPI Run-Time Environment) (pronounced "or-tay"):

    • Система времени выполнения MPI
      • launch, monitor, kill individual processes
      • Сгруппируйте отдельные процессы в «работы»
    • Перенаправить стандартный ввод, стандартный вывод, стандартный вывод
    • Метод управления процессами ORTE: в простой среде, черезrshилиsshдля запуска процесса. В сложной среде (только для HPC) будут компоненты управления, такие как планировщик и диспетчер ресурсов, для выполнения справедливого планирования и распределения ресурсов для нескольких пользователей.ORTE поддерживает различные среды управления, такие как orque/PBS Pro, SLURM, Oracle Grid Двигатель и LSF.

    Обратите внимание, что ORTE был удален в версии 5.x, а модуль управления процессами был заменен на [prrte](openpmix/prrte: PMIx Reference RunTime Environment (PRRTE) (github.com))

  • OPAL (Open, Portable Access Layer)(произносится: o-pull): OPAL — это нижний слой xOmpi.

    • Работает только в одном процессе
    • Отвечает за переносимость в разных средах
    • Содержит некоторые общие функции (такие как связанный список, работа со строками, управление отладкой и т. д.)
img

Вышеуказанные абстрактные слои существуют в виде библиотек, и зависимости между ними могут быть только сверху вниз, то есть нижние слои не могут зависеть от верхних слоев.

image-20210515092155899

Он существует в виде проекта в каталоге кода, т.е.

ompi/
├── ompi
├── opal
└── orte

Следует отметить, что с учетом факторов производительности Open MPI имеет механизм «обхода» (bypass), уровни ORTE и OMPI, которые могут обходить OPAL и напрямую взаимодействовать с операционной системой (или даже аппаратным обеспечением). Например, OMPI будет напрямую взаимодействовать с сетевой картой для достижения максимальной производительности сети.

Plugin Architecture

Чтобы использовать похожие, но разные эффекты в Open MPI, Open MPI разработала архитектуру под названием **Modular Component Architecture (MCA)**.

В архитектуре MCA для каждого уровня абстракции (то есть OMPI, ORTE, OPAL) определено несколько фреймворков. Здесь фреймворк аналогичен интерфейсу в других языковых контекстах. Фреймворк абстрагирует функцию, а плагин — это другая реализация. каркаса. Каждый плагин существует в виде динамической библиотеки ссылок (DSO, динамический общий объект). Таким образом, во время выполнения можно динамически загружать различные плагины.

Например, btl на рисунке ниже — это фреймворк, предназначенный для передачи байтов, который принадлежит уровню OMPI. В фреймворк btl также входят реализации для разных типов сетей, таких как tcp, openib (InfiniBand), sm (общая память), sm-cuda (общая память) память для CUDA)

В Open MPI 2.x и выше модуль btl перемещен в OPAL.

image-20210515121838974

Зачем использовать архитектуру плагинов:

  • лучшая разработка программного обеспечения
    • Строгая абстракция
  • Сделайте блоки кода меньше и независимы друг от друга
    • Дружелюбен к обучению и новым разработчикам
    • Легче поддерживать и расширять
  • Применить пользователя к разделению серверной библиотеки
    • Приложения MPI компилируются независимо от того, какая конкретная библиотека используется, например, libibverbs.so / libportals.so / libpbs.a

Дизайн МСА

МКА:

  • Top-level architecture for component services
  • Find, load, unload components

Фреймворки:

  • Содержит ряд функций
  • определить интерфейс
  • Важно: группировка типов плагинов
  • Пример: двухточечный MPI, таймеры высокого разрешения.

Компоненты (плагины):

  • Code that exports a specific interface
  • Loaded / unloaded at run-time (usually)

Модули:

  • Привязать к ресурсу
  • Например: при загрузке компонента «btl_tcp» обнаруживаются две сетевые карты (eth0, eth1), и компонент btl_tcp создаст два модуля TCP.

Структура кода МСА

Фреймворки:

  • Имеет уникальное имя (строковое имя)

Компоненты:

  • Belong to exactly one framework
  • Have unique string names
  • Namespace is per framework

Все имена доступны имена переменных C

Структура каталога:

  • Иерархия: /mca//

    • Project = opal, orte, ompi
    • Framework = имя фреймворка или "база"
    • Component = component name, or "base"
  • Directory names must match

    • Framework name
    • Component name
  • пример:

    • ompi/mca/btl/tcp, ompi/mca/btl/sm
./ompi/mca
├── allocator
│   ├── Makefile.am
│   ├── allocator.h
│   ├── base
│   ├── basic
│   └── bucket
├── bcol
│   ├── Makefile.am
│   ├── base
│   ├── basesmuma
│   ├── bcol.h
│   └── ptpcoll
├── bml
│   ├── Makefile.am
│   ├── base
│   ├── bml.h
│   └── r2

Реализация кода MCA

  • Абстракция с использованием указателей на функции
  • Обычно компилируется как динамическая библиотека (DSO, поэтому файл)
  • Его также можно упаковать в libmpi как статическую библиотеку.
  • Используя инструмент GNU libltdl, можно загружать DSO на разных платформах.
Components struct

Структура определяется какompi/mca/btl/btl.h

struct mca_base_component_2_0_0_t {
    /* Component struct version number */
    int mca_major_version, mca_minor_version, mca_release_version;

    /* The string name of the framework that this component belongs to,
       and the framework's API version that this component adheres to */
    char mca_type_name[MCA_BASE_MAX_TYPE_NAME_LEN + 1];
    int mca_type_major_version, mca_type_minor_version,  
        mca_type_release_version;

    /* This component's name and version number */
    char mca_component_name[MCA_BASE_MAX_COMPONENT_NAME_LEN + 1];
    int mca_component_major_version, mca_component_minor_version,
        mca_component_release_version;

    /* Function pointers */  
    mca_base_open_component_1_0_0_fn_t mca_open_component;
    mca_base_close_component_1_0_0_fn_t mca_close_component;
    mca_base_query_component_2_0_0_fn_t mca_query_component;
    mca_base_register_component_params_2_0_0_fn_t 
        mca_register_component_params;
};

typedef struct mca_base_component_2_0_0_t mca_base_component_t;

typedef struct mca_base_component_2_0_0_t mca_base_component_2_0_0_t;

Несколько ключевых указателей функций:

  • open
  • close
  • query
  • register
Framework Interface

Возьмем, к примеру, btl, расположенный по адресуompi/mca/btl/btl.h

struct mca_btl_base_component_2_0_0_t {
  mca_base_component_t btl_version;
  mca_base_component_data_t btl_data;
  mca_btl_base_component_init_fn_t btl_init;
  mca_btl_base_component_progress_fn_t btl_progress;
};
typedef struct mca_btl_base_component_2_0_0_t mca_btl_base_component_2_0_0_t;
typedef struct mca_btl_base_component_2_0_0_t mca_btl_base_component_t;
Plugin

Возьмите btl_tcp в качестве примера:

struct mca_btl_tcp_component_t {
    /* btl framework-specific component struct */ 
    mca_btl_base_component_2_0_0_t super;

    /* Some of the TCP BTL component's specific data members */
    /* Number of TCP interfaces on this server */
    uint32_t tcp_addr_count;
    
    /* IPv4 listening socket descriptor */
    int tcp_listen_sd;

    /* ...and many more not shown here */
};
Module

Подобно плагину, существуют базовые классы и классы реализации.

базовый модуль btl:

struct mca_btl_base_module_t {
// ......
}

TCP-модуль:

struct mca_btl_tcp_module_t {
    mca_btl_base_module_t  super;
    // ......
}

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

img

Component / Module Lifecycle

image-20210515163520778

Run-Time Parameters

Также известный как параметры MCA, предоставляет параметры компонента MCA, а также базовые параметры.

дизайн фона

  • Старайтесь избегать использования констант и вместо этого используйте параметры времени выполнения.
    • избегать перекомпиляции
  • Изменение поведения программы во время выполнения
    • Найдите параметры для оптимальной производительности в конкретной среде

как пользоваться

Встроенные параметры
  • Имя каждого фреймворка является параметром mca.
  • Возможность указать, какой плагин использовать
  • Можно указать поведение включения или исключения, например, btl=tcp,self,sm или btl = ^openib
Как изменить параметры
  • В приложении используйте интерфейс API MPI для переопределения параметров по умолчанию.
  • Использование инструментов командной строки
    • Например:mpirun -mca <name> <value>
  • Используйте переменные среды
    • setenv OMPI_MCA_<name> <value>
  • изменение в файле
    • $HOME/.openmpi/mca-params.conf
    • $prefix/etc/openmpi-mca-params.conf

Характеристики параметра mca:

  • Обычно состоит из строк и чисел
  • Некоторые параметры доступны только для чтения, некоторые доступны для чтения и записи.
  • Некоторые параметры являются частными, некоторые общедоступными

правила имени параметра mca:

<framework>_<component>_<param_name>

Несколько примеров параметров mca:

  • btl_udverbs_version: доступная только для чтения строковая версия библиотеки Verbs, для которой был скомпилирован udverbs BTL.
  • btl_tcp_if_include: Read-write, string list of IP interfaces to use
  • btl: Read-write, list of BTL components to use
  • orte_base_singleton: Private, whether this process is a singleton

Кроме того, вы можете увидеть, какие параметры доступны с помощью инструмента командной строки ompi_info.

Как добиться

mca_base отвечает за разбор параметров MCA.