Параллельное программирование: Учебное пособие, страница 107

int MPI_Group_difference(MPI_Group group1,

MPI_Group group2, MPI_Group *newgroup)

Подпрограмма MPI_Group_intersection создает новую группу newgroup из пересечения групп group1 и group2, то есть в новую группу войдут те процессы, которые являются одновременно элементами обоих групп:

int MPI_Group_intersection(MPI_Group group1,

MPI_Group group2, MPI_Group *newgroup)

Новая группа newgroup с множеством процессов, равном объединению множеств процессов из групп group1 и group2 можно создать с помощью подпрограммы MPI_Group_union:

int MPI_Group_union(MPI_Group group1,

MPI_Group group2, MPI_Group *newgroup)

Перечисленными подпрограммами не исчерпывается все разнообразие уже существующих подпрограмм-конструкторов новых групп. Есть и подпрограмма-деструктор MPI_Group_fгее, вызов которой уничтожает группу с именем group:

int MPI_Group_free(MPI_Group *group)

5.3.6  Получение информации о группе

Для определения количества процессов (size) в группе с именем group используется подпрограмма MPI_Group_size:

int MPI_Group_size(MPI_Group group, int *size)

Ранг (rank) процесса в группе group получают вызовом подпрограммы  MPI_Group_rank:

int MPI_Group_rank(MPI_Group group, int *rank)

Если процесс не входит в указанную группу, то возвращается значение MPI_UNDEFINED.

Иногда процесс может входить в несколько групп. В этом случае необходимо определить относительную нумерацию одних и тех же процессов в двух разных группах. Такое преобразование выполняет подпрограмма MPI_Group_translate_ranks:

intMPI_Group_translate_ranks(MPI_Groupgroup1, intn,

int *ranks1, MPI_Group group2, int *ranks2)

Для сравнения групп group1 и group2 используется подпрограмма MPI_Group_compare:

int MPI_Group_compare(MPI_Group group1,

MPI_Group group2, int *result)

При полном совпадении групп, возвращается значение MPI_IDENT. Если члены обеих групп одинаковы, но их ранги отличаются, то переменная result будет иметь значение MPI_SIMILAR. Если группы различны, то будет получено значение MPI_UNEQUAL.

5.3.7  Управление коммуникаторами

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

Подпрограмма MPI_Comm_dup дублирует уже существующий коммуникатор с именем oldcomm, создавая новый коммуникатор с новым именем newcomm, с той же группой процессов, с теми же атрибутами, но с другим контекстом:

int MPI_Comm_dup (MPI_Comm oldcomm, MPI_Comm *newcomm)

Эта подпрограмма может применяться как к интракоммуникаторам, так и к интеркоммуникаторам.

Подпрограмма MPI_Comm_create создает новый коммуникатор newcomm из подмножества процессов group другого коммуникатора oldcomm:

int MPI_Comm_create(MPI_Comm oldcomm,

MPI_Group group, MPI_Comm *newcomm)

Вызов этой подпрограммы должны выполнить все процессы из старого коммуникатораoldcomm, даже если они не входят в группу group, с одинаковыми аргументами. Данная операция применяется только к интракоммуникаторам. Она позволяет выделять подмножества процессов со своими областями взаимодействия, если, например, требуется уменьшить "зернистость" параллельной программы. Побочным эффектом применения подпрограммы MPI_Comm_create является синхронизация процессов. Если одновременно создаются несколько коммуникаторов, то они должны создаваться в одной и той же последовательности всеми процессами, например, так как показано в тексте 5.14.

Текст 5.14. Пример создания коммуникатора

#include "mpi.h"

#include <stdio.h>

int main(int argc, char *argv[])

{

char message[24];

MPI_Group MPI_GROUP_WORLD;

MPI_Group group;

MPI_Comm fcomm;

int size, q, proc;

int* process_ranks;

int rank, rank_in_group;

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &size);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

printf("New group contains processes:");

q = size — 1;

process_ranks = (int*) malloc(q*sizeof(int));

for (proc = 0; proc < q; proc++)

{

process_ranks[proc] = proc;

printf("%i ", process_ranks[proc]);