Для иллюстрации основ работы с коммуникаторами создается коммуникатор, основная группа которого состоит из процессов в первой строке виртуальной сетки. Пусть MPI_COMM_WORLD состоит из процессов, где . Пусть также . При этом первая строка процессов состоит из процессов с рангами (Ранги указаны относительно MPI_COMM_WORLD). Чтобы создать группу для нового коммуникатора, следует выполнить следующий код:
MPI_Group first_row_group;
MPI_Comm first_row_comm;
int row_size;
int* process_ranks;
/* Создает список процессов нового */
* коммуникатора */
process_ranks = (int*) malloc(q*sizeof(int));
for (proc = 0; proc < q; proc++)
process_ranks[proc] = proc;
/* Получить группу, относящуюся к MPI_COMM_WORLD */
MPI_Comm_group(MPI_COMM_WORLD, &MPI_GROUP_WORLD);
/* Создать новую группу */
MPI_Group_incl(MPI_GROUP_WORLD, q, process_ranks,
&first_row_group);
/* Создать новый коммуникатор */
MPI_Comm_create(MPI_COMM_WORLD, first_row_group,
&first_row_comm);
float* A_00;
/* my_rank определяет ранг процесса в MPI_GROUP_WORLD */
if (my_rank < q) {
MPI_Comm_rank(first_row_comm, &my_rank_in_first_row);
/* Выделить память для A_00, order = n_bar */
A_00 = (float*) malloc (n_bar*n_bar*sizeof(float));
if (my_rank_in_first_row == 0) {
/* Инициализация A_00 */
. . .
}
MPI_Bcast(A_00, n_bar*n_bar, MPI_FLOAT, 0,
first_row_comm);
}
Контексты явно не используются ни в одной из функций MPI. Они неявно связываются с группами при создании коммуникаторов. Операция
int new_group_size, int* ranks_in_old_group,
MPI_Group* new_group)
MPI_Group new_group, MPI_Comm* new_comm)
Существует важное различие между первыми двумя и третьей функциями. Вызовы MPI_Comm_group() и MPI_Group_incl() являются локальными действиями. Это значит, что нет никакого взаимодействия между процессами, участвующими в их выполнении. Операция MPI_Comm_create() - коллективное действие. Процессы в old_comm должны вызывать MPI_Comm_create() с теми же самыми аргументами.
Если создаются несколько коммуникаторов, они должны создаваться в одном и том же порядке во всех процессах.