Интерфейс передачи сообщений MPI
Управление коммуникаторами
Стандартный коммуникатор MPI_COMM_WORLD создается автоматически при запуске параллельной программы на выполнение. Напомним, что имеются также стандартные коммуникаторы:
- MPI_COMM_SELF - коммуникатор, содержащий только вызывающий процесс;
- MPI_COMM_NULL - пустой коммуникатор.
Получение доступа к группе group, связанной с коммуникатором comm
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group) MPI_COMM_GROUP(COMM, GROUP, IERR)
Выходной параметр - группа. Для выполнения операций с группой к ней сначала необходимо получить доступ.
Создание новой группы newgroup из n процессов, входящих в группу oldgroup
int MPI_Group_incl(MPI_Group oldgroup, int n, int *ranks, MPI_Group *newgroup) MPI_GROUP_INCL(OLDGROUP, N, RANKS, NEWGROUP, IERR)
Ранги процессов содержатся в массиве ranks. В новую группу войдут процессы с рангами ranks[0], ranks[n - 1],причем рангу i в новой группе соответствует ранг ranks[i] в старой группе. При n = 0 создается пустая группа MPI_GROUP_EMPTY. С помощью данной подпрограммы можно не только создать новую группу, но и изменить порядок процессов в старой группе.
Создание группы newgroup исключением из исходной группы (group) процессы с рангами ranks[0] ..., ranks[n - 1]
int MPI_Group_excl(MPI_Group oldgroup, int n, int *ranks, MPI_Group *newgroup) MPI_GROUP_EXCL(OLDGROUP, N, RANKS, NEWGROUP, IERR)
При n = 0 новая группа тождественна старой.
Создание группы newgroup из группы group добавлением в нее n процессов, ранг которых указан в массиве ranks
int MPI_Group_range_incl(MPI_Group oldgroup, int n, int ranks[][3], MPI_Group *newgroup) MPI_GROUP_RANGE_INCL(OLDGROUP, N, RANKS, NEWGROUP, IERR)
Массив ranks состоит из целочисленных триплетов вида (первый_1, последний_1, шаг_1), ..., (первый_n, последний_n, шаг_n). В новую группу войдут процессы с рангами (по первой группе) первый_1, первый_1 + шаг_1, ....
Создание группы newgroup из группы group исключением из нее n процессов, ранг которых указан в массиве ranks
int MPI_Group_range_excl(MPI_Group group, int n, int ranks[][3], MPI_Group *newgroup) MPI_GROUP_RANGE_EXCL(GROUP, N, RANKS, NEWGROUP, IERR)
Массив ranks устроен так же, как аналогичный массив в подпрограмме MPI_Group_range_incl.
Создание новой группы (newgroup) из разности двух групп (group1) и (group2)
int MPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group *newgroup) MPI_GROUP_DIFFERENCE(GROUP1, GROUP2, NEWGROUP, IERR)
Создание новой группы (newgroup) из пересечения групп group1 и group2
int MPI_Group_intersection(MPI_Group group1, MPI_Group group2, MPI_Group *newgroup) MPI_GROUP_INTERSECTION(GROUP1, GROUP2, NEWGROUP, IERR)
Создание группы (newgroup) объединением групп group1 и group2
Int MPI_Group_union(MPI_Group group1, MPI_Group group2, MPI_Group *newgroup) MPI_GROUP_UNION(GROUP1, GROUP2, NEWGROUP, IERR)
Имеются и другие подпрограммы-конструкторы новых групп.
Уничтожение группы group
int MPI_Group_free(MPI_Group *group) MPI_GROUP_FREE(GROUP, IERR)
Определение количества процессов (size) в группе (group)
MPI_GROUP_SIZE(GROUP, SIZE, IERR) int MPI_Group_size(MPI_Group group, int *size)
Определение ранга (rank) процесса в группе group
int MPI_Group_rank(MPI_Group group, int *rank) MPI_GROUP_RANK(GROUP, RANK, IERR)
Если процесс не входит в указанную группу, возвращается значение MPI_UNDEFINED.
Преобразование ранга процесса в одной группе в его ранг относительно другой группы
int MPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2) MPI_GROUP_TRANSLATE_RANKS(GROUP1, N, RANKS1, GROUP2, RANKS2, IERR)
Сравнение групп group1 и group2
int MPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result) MPI_GROUP_COMPARE(GROUP1, GROUP2, RESULT, IERR)
Если группы полностью совпадают, возвращается значение MPI_IDENT. Если члены обеих групп одинаковы, но их ранги отличаются, результатом будет значение MPI_SIMILAR. Если группы различны, результатом будет MPI_UNEQUAL.
Создание дубликата уже существующего коммуникатора oldcomm int
MPI_Comm_dup(MPI_Comm oldcomm, MPI_Comm *newcomm) MPI_COMM_DUP(OLDCOMM, NEWCOMM, IERR)
В результате вызова данной подпрограммы создается новый коммуникатор ( newcomm ) с той же группой процессов, с теми же атрибутами, но с другим контекстом. Подпрограмма может применяться как к интра-, так и к интеркоммуникаторам.
Создание нового коммуникатора (newcomm) из подмножества процессов (group) другого коммуникатора (oldcomm)
int MPI_Comm_create(MPI_Comm oldcomm, MPI_Group group, MPI_Comm *newcomm) MPI_COMM_CREATE(OLDCOMM, GROUP, NEWCOMM, IERR)
Вызов этой подпрограммы должны выполнить все процессы из старого коммуникатора, даже если они не входят в группу group, с одинаковыми аргументами. Если одновременно создаются несколько коммуникаторов, они должны создаваться в одной последовательности всеми процессами.
Создание нескольких коммуникаторов сразу методом расщепления
int MPI_Comm_split(MPI_Comm oldcomm, int split, int rank, MPI_Comm* newcomm) MPI_COMM_SPLIT(OLDCOMM, SPLIT, RANK, NEWCOMM, IERR)
Группа процессов, связанных с коммуникатором oldcomm, разбивается на непересекающиеся подгруппы, по одной для каждого значения аргумента split. Процессы с одинаковым значением split образуют новую группу. Ранг в новой группе определяется значением rank. Если процессы A и B вызывают MPI_Comm_split с одинаковым значением split, а аргумент rank, переданный процессом A, меньше, чем аргумент, переданный процессом B, ранг A в группе, соответствующей новому коммуникатору, будет меньше ранга процесса B. Если же в вызовах используется одинаковое значение rank, система присвоит ранги произвольно. Для каждой подгруппы создается собственный коммуникатор newcomm.
MPI_Comm_split должны вызвать все процессы из старого коммуникатора, даже если они не войдут в новый коммуникатор. Для этого в качестве аргумента split в подпрограмму передается предопределенная константа MPI_UNDEFINED. Соответствующие процессы вернут в качестве нового коммуникатора значение MPI_COMM_NULL. Новые коммуникаторы, созданные подпрограммой MPI_Comm_split, не пересекаются, однако с помощью повторных вызовов подпрограммы MPI_Comm_split можно создавать и перекрывающиеся коммуникаторы.
Пометить коммуникатор comm для удаления
int MPI_Comm_free(MPI_Comm *comm) MPI_COMM_FREE(COMM, IERR)
Обмены, связанные с этим коммуникатором, завершаются обычным образом, а сам коммуникатор удаляется только после того, как на него не будет активных ссылок. Данная операция может применяться к коммуникаторам интра- и интер-.
Сравнение двух коммуникаторов (comm1) и (comm2)
int MPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result) MPI_COMM_COMPARE(COMM1, COMM2, RESULT, IERR)
Выходной параметр:
- result - целое значение, которое равно MPI_IDENT, если контексты и группы коммуникаторов совпадают; MPI_CONGRUENT, если совпадают только группы; MPI_SIMILAR и MPI_UNEQUAL, если не совпадают ни группы, ни контексты.
В качестве аргументов нельзя использовать пустой коммуникатор MPI_COMM_NULL.
Присвоение коммуникатору comm строкового имени name
int MPI_Comm_set_name(MPI_Comm com, char *name) MPI_COMM_SET_NAME(COM, NAME, IERR)
Определение имени коммуникатора
int MPI_Comm_get_name(MPI_Comm comm, char *name, int *reslen) MPI_COMM_GET_NAME(COMM, NAME, RESLEN, IERR)
Выходной параметр:
- name - строковое имя коммуникатора comm.;
- reslen - длина имени.
Имя представляет собой массив символьных значений, длина которого должна быть не более MPI_MAX_NAME_STRING.
Проверка, является ли коммуникатор comm (входной параметр) интеркоммуникатором
int MPI_Comm_test_inter(MPI_Comm comm, int *flag) MPI_COMM_TEST_INTER(COMM, FLAG, IERR)
Выходной параметр:
- flag - значение флага "истина", если аргументом является интеркоммуникатор.
Создание интракоммуникатора newcomm из интеркоммуникатора oldcomm
int MPI_Intercomm_merge(MPI_Comm oldcomm, int high, MPI_Comm *newcomm) MPI_INTERCOMM_MERGE(OLDCOMM, HIGH, NEWCOMM, IERR)
Параметр high используется для упорядочения групп обоих интракоммуникаторов в comm при создании нового коммуникатора.
Получение доступа к удаленной группе, связанной с интеркоммуникатором comm int
MPI_Comm_remote_group(MPI_Comm comm, MPI_Group *group) MPI_COMM_REMOTE_GROUP(COMM, GROUP, IERR)
Выходной параметр:
- group - удаленная группа.
Определение размера удаленной группы, связанной с интеркоммуникатором comm int
MPI_Comm_remote_size(MPI_Comm comm, int *size) MPI_COMM_REMOTE_SIZE(COMM, SIZE, IERR)
Выходной параметр:
- size - количество процессов в области взаимодействия, связанной с коммуникатором comm.
Создание интеркоммуникатора
int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *new_intercomm) MPI_INTERCOMM_CREATE(LOCAL_COMM, LOCAL_LEADER, PEER_COMM, REMOTE_LEADER, TAG, NEW_INTERCOMM, IERR)
Входные параметры:
- local_comm - локальный интракоммуникатор;
- local_leader - ранг лидера в локальном коммуникаторе (обычно 0);
- peer_comm - удаленный коммуникатор;
- remote_leader - ранг лидера в удаленном коммуникаторе (обычно 0);
- tag - тег интеркоммуникатора, используемый лидерами обеих групп для обменов в контексте родительского коммуникатора.
Выходной параметр:
- new_intercomm - интеркоммуникатор.
"Джокеры" в качестве параметров использовать нельзя. Вызов этой подпрограммы должен выполняться в обеих группах процессов, которые должны быть связаны между собой. В каждом из этих вызовов используется локальный интракоммуникатор, соответствующий данной группе процессов. При работе с MPI_Intercomm_create локальная и удаленная группы процессов не должны пересекаться, иначе возможны "тупики".