}
printf("\n");
/* открываем доступ к группе, указав ее адрес */
MPI_Comm_group(MPI_COMM_WORLD, &MPI_GROUP_WORLD);
/* создаем группу сq процессами, ранги которых в process_ranks*/
MPI_Group_incl(MPI_GROUP_WORLD, q,
process_ranks, &group);
/* создаем для группы group коммуникатор с именем fcomm */
MPI_Comm_create(MPI_COMM_WORLD, group, &fcomm);
if (fcomm != MPI_COMM_NULL) /* если fcomm не пуст, то */
{ /* открываем доступ к группе и определяем ранг процесса в группе */
MPI_Comm_group(fcomm, &group);
MPI_Comm_rank(fcomm, &rank_in_group);
if (rank_in_group ==0)
{ /* печать и рассылка сообщения процессом с рангом 0 */
strcpy(message, "Hi, Parallel Programmer!");
MPI_Bcast(&message, 25, MPI_BYTE, 0, fcomm);
printf("0 send: %s\n", message);
}
else
{ /* принимаем сообщение от корневого процесса с рангом 0 */
MPI_Bcast(&message, 25, MPI_BYTE, 0, fcomm);
printf("%i received: %s\n",
rank_in_group, message);
}
/* вызываем деструкторы, уничтожающие коммуникатор и группу */
MPI_Comm_free(&fcomm);
MPI_Group_free(&group);
} /* заканчиваем выполнение MPI-программы */
MPI_Finalize();
return 0; /* возвращаем код нормального завершения */
}
С коммуникатором MPI_COMM_WORLD может быть связано несколько процессов, например, p, которые должны быть размещены, к примеру, на 5 процессорах. Область взаимодействия организуем для q процессов. В параллельной программе сначала создается список процессов, которые будут входить в область взаимодействия нового коммуникатора. Затем создается группа, состоящая из этих процессов. Для этого требуются две операции. Первая определяет группу, связанную с коммуникатором MPI_COMM_WORLD. Новая группа создается вызовом подпрограммы MPI_Group_incl. Затем создается новый коммуникатор. Для этого используется подпрограмма MPI_Comm_create. Новому коммуникатору дается имя fcomm. В результате всех этих действий все процессы, входящие в коммуникатор fcomm, смогут выполнять операции коллективного обмена, но только между собой. Результат ее выполнения:
mpiexec –host -machinefile -n 5 – myprogr
New group contains processes:0 1 2 3
0 send: Hi, Parallel Programmer!
New group contains processes:0 1 2 3
1 received: Hi, Parallel Programmer!
New group contains processes:0 1 2 3
3 received: Hi, Parallel Programmer!
New group contains processes:0 1 2 3
2 received: Hi, Parallel Programmer!
Подпрограмма MPI_Comm_split позволяет создать несколько коммуникаторов сразу:
int MPI_Comm_split(MPI_Comm oldcomm, int split,
int rank, MPI_Comm* newcomm)
Группа процессов, связанных с коммуникатором oldcomm, разбивается на непересекающиеся подгруппы, по одной для каждого значения аргумента split. Процессы с одинаковым значением split образуют новую группу. Ранг в новой группе определяется значением rank. Если процессы А и В вызывают MPI_Comm_split с одинаковым значением split, а аргумент rank, переданный процессом А, меньше, чем аргумент, переданный процессом В, то ранг процесса А в группе, соответствующей новому коммуникатору, будет меньше ранга процесса В. Если же в вызовах используется одинаковое значение rank, то система присвоит ранги произвольно. Для каждой подгруппы создается собственный коммуникатор newcomm.
MPI_Comm_split — коллективная подпрограмма, ее должны вызвать все процессы из старого коммуникатора, даже если они и не войдут в новый коммуникатор. Для этого в качестве аргумента split в подпрограмму передается предопределенная константа MPI_UNDEFINED. Соответствующие процессы вернут в качестве нового коммуникатора значение MPI_COMM_NULL. Новые коммуникаторы, созданные подпрограммой MPI_Comm_split, не пересекаются, однако с помощью повторных вызовов подпрограммы MPI_Comm_split можно создавать и перекрывающиеся коммуникаторы.
Пример расщепления коммуникатора:
MPI_Comm_rank(MPI_Commcomm, intrank)
MPI_Comm_size(MPI_Comm comm, int size)
split = 2*rank/size
key = size - rank - 1
MPI_Comm_split(MPI_Comm comm, int split,
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.