§23. Работа с группами и коммуникаторами

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

Группа представляет собой упорядоченное множество процессов. Каждый процесс идентифицируется переменной целого типа. Идентификаторы процессов образуют непрерывный ряд, начинающийся с 0. В MPI вводится специальный тип данных MPI_Group и набор функций для работы с переменными и константами этого типа. Существует две предопределенных группы:

MPI_GROUP_EMPTY

-

группа, не содержащая ни одного процесса;

MPI_GROUP_NULL

-

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

Созданная группа не может быть модифицирована - расширена или усечена, может быть только создана новая группа. Интересно отметить, что при инициализации MPI не создается группы, соответствующей коммуникатору MPI_COMM_WORLD. Она должна создаваться специальной функцией явным образом.

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

В MPI существует два типа коммуникаторов:

intracommunicator

-

описывает область связи некоторой группы процессов;

intercommunicator

-

служит для связи между процессами двух различных групп.

Тип коммуникатора можно определить с помощью специальной функции MPI_Comm_test_inter.

FORTRAN:

INTEGER COMM, IERR

LOGICAL FLAG

MPI_COMM_TEST_INTER(COMM, FLAG, IERR)

С:

MPI_Comm_test_inter(MPI_Comm comm, int *flag)

Входные параметры:

comm

-

коммуникатор.

Выходные параметры:

flag

-

возвращает true, если comm - intercommunicator.

Функция возвращает значение "истина", если коммуникатор является интеркоммуникатором.

При инициализации MPI создается два предопределенных коммуникатора:

MPI_COMM_WORLD

-

описывает область связи, содержащую все процессы;

MPI_COMM_SELF

-

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

Функции работы с коммуникаторами

В данном подразделе рассматриваются функции работы с коммуникаторами. Они разделяются на функции доступа к коммуникаторам и функции создания коммуникаторов. Функции доступа являются локальными и не требуют коммуникаций, в отличие от функций создания, которые являются коллективными и могут потребовать межпроцессорных коммуникаций. Две основных функции доступа к коммуникатору: MPI_Comm_size - опрос числа процессов в области связи и MPI_Comm_rank - опрос идентификатора (номера) процесса в области связи, были рассмотрены в самом начале среди базовых функций MPI. Кроме них, имеется функция сравнения двух коммуникаторов MPI_Comm_compare.

FORTRAN:

INTEGER COMM1, COMM2, RESULT, IERR

MPI_COMM_COMPARE(COMM1, COMM2, RESULT, IERR)

С:

MPI_Comm_compare(MPI_Comm comm1,MPI_Comm comm2, int *result)

Входные параметры:

comm1

-

первый коммуникатор;

comm1

-

второй коммуникатор.

Выходные параметры:

result

-

результат сравнения.

Возможные значения результата сравнения:

MPI_IDENT

-

коммуникаторы идентичны, представляют один и тот же объект;

MPI_CONGRUENT

-

коммуникаторы конгруэнтны, две области связи с одними и теми же атрибутами группы;

MPI_SIMILAR

-

коммуникаторы подобны, группы содержат одни и те же процессы, но другое упорядочивание;

MPI_UNEQUAL

-

во всех других случаях.

Создание нового коммуникатора возможно с помощью одной из трех функций: MPI_Comm_dup, MPI_Comm_create, MPI_Comm_split.

Функция дублирования коммуникатора MPI_Comm_dup.

FORTRAN:

INTEGER COMM, NEWCOMM, IERR

MPI_COMM_DUP(COMM, NEWCOMM, IERR)

С:

MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm)

Входные параметры:

comm

-

коммуникатор.

Выходные параметры:

newcomm

-

копия коммуникатора.

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

Функция создания коммуникатора MPI_Comm_create.

FORTRAN:

INTEGER COMM, GROUP, NEWCOMM, IERR

MPI_COMM_CREATE(COMM, GROUP, NEWCOMM, IERR)

С:

MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm)

Входные параметры:

comm

-

родительский коммуникатор;

group

-

группа, для которой создается коммуникатор.

Выходные параметры:

newcomm

-

новый коммуникатор.

Эта функция создает коммуникатор для группы group. Для процессов, которые не являются членами группы, возвращается значение MPI_COMM_NULL. Функция возвращает код ошибки, если группа group не является подгруппой родительского коммуникатора.

Функция расщепления коммуникатора MPI_Comm_split.

FORTRAN:

INTEGER COMM, COLOR, KEY, NEWCOMM, IERR

MPI_COMM_SPLIT(COMM, COLOR, KEY, NEWCOMM, IERR)

С:

MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)

Входные параметры:

comm

-

родительский коммуникатор;

color

-

признак подгруппы;

key

-

управление упорядочиванием.

Выходные параметры:

newcomm

-

>новый коммуникатор.

Функция расщепляет группу, связанную с родительским коммуникатором, на непересекающиеся подгруппы по одной на каждое значение признака подгруппы color. Значение color должно быть неотрицательным. Каждая подгруппа содержит процессы с одним и тем же значением color. Параметр key управляет упорядочиванием внутри новых групп: меньшему значению key соответствует меньшее значение идентификатора процесса. В случае равенства параметра key для нескольких процессов упорядочивание выполняется в соответствии с порядком в родительской группе.

Приведем алгоритм расщепления группы из восьми процессов на три подгруппы и его графическую интерпретацию (рис.52).

INTEGER comm, newcomm;

INTEGER myid, color, ierr;

 . . . . . .

CALL MPI_Comm_rank(comm, myid, ierr);

color = myid%3;

CALL MPI_Comm_split(comm, color, myid, newcomm, ierr);

Рис. 52. Разбиение группы из восьми процессов на три подгруппы

В данном примере первую подгруппу образовали процессы, номера которых делятся на 3 без остатка, вторую - для которых остаток равен 1 и третью - для которых остаток равен 2. Отметим, что после выполнения функции MPI_Comm_split значения коммуникатора newcomm в процессах разных подгрупп будут отличаться.

Функция уничтожения коммуникатораа MPI_Comm_free.

FORTRAN:

INTEGER COMM, IERR

MPI_COMM_FREE(COMM, IERR)

С:

MPI_Comm_free(MPI_Comm *comm)

Входные параметры:

comm

-

уничтожаемый коммуникатор.