Санкт-Петербургский государственный университет
Опубликован: 11.02.2010 | Доступ: свободный | Студентов: 530 / 93 | Оценка: 4.41 / 4.44 | Длительность: 08:19:00
Специальности: Программист
Лекция 3:

Интерфейс передачи сообщений 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 локальная и удаленная группы процессов не должны пересекаться, иначе возможны "тупики".