main(int argc, char **argv)
{
int me, count, count2;
void *send_buf, *recv_buf, *send_buf2,
*recv_buf2;
MPI_Group MPI_GROUP_WORLD, grprem;
MPI_Comm commslave;
static int ranks[] = {0};
...
MPI_Init(&argc, &argv);
MPI_Comm_group(MPI_COMM_WORLD, &MPI_GROUP_WORLD);
MPI_Comm_rank(MPI_COMM_WORLD, &me); /* локально */
MPI_Group_excl(MPI_GROUP_WORLD, 1, ranks,
&grprem);/* локально */
MPI_Comm_create(MPI_COMM_WORLD, grprem, &commslave);
if(me != 0)
{
/* вычисления на подчиненном процессе */
...
MPI_Reduce(send_buf,recv_buff,count, MPI_INT,
MPI_SUM, 1, commslave);
...
}
/* процесс нуль останавливается немедленно после выполнения этого
reduce, другие процессы - позже... */
MPI_Reduce(send_buf2, recv_buff2, count2,
MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Comm_free(&commslave);
MPI_Group_free(&MPI_GROUP_WORLD);
MPI_Group_free(&grprem);
MPI_Finalize();
}
Этот пример иллюстрирует, как из исходной группы создается группа, содержащая все процессы, кроме процесса нуль, и затем, как формируется коммуникатор (commslave) для этой новой группы. Новый коммуникатор используется в коллективном обращении и все процессы выполняются в контексте MPI_COMM_WORLD. Пример иллюстрирует, как эти два коммуникатора (которые обязательно обладают различными контекстами) защищают обмен. Это означает, что обмен в MPI_COMM_WORLD изолирован от обмена в commslave и наоборот.
В общем, ``безопасность группы'' достигается через коммуникаторы, потому что различные контексты в пределах коммуникаторов являются уникальными на любом процессе.