Интеробмен возможен, только если создан соответствующий интеркоммуникатор, а это можно сделать с помощью подпрограммы MPI_Intercomm_create:
int MPI_Intercomm_create(MPI_Comm local_comm,
int local_leader, MPI_Comm peer_comm,
int remote_leader, int tag,
MPI_Comm *new_intercomm)
Входные параметры этой подпрограммы:
· local_comm — локальный интракоммуникатор;
· local_leader — ранг лидера в локальном коммуникаторе (обычно процесс с рангом 0);
· рееr_соmm — удаленный коммуникатор;
· remote_leader — ранг лидера в удаленном коммуникаторе (обычно процесс с рангом 0);
· tag — тег интеркоммуникатора, используемый лидерами обеих групп для обменов в контексте родительского коммуникатора.
Выходной параметр — интеркоммуникатор (new_intercomm). "Джокеры" в качестве параметров использовать нельзя. Вызов этой подпрограммы должен выполняться в обеих группах процессов, которые должны быть связаны между собой. При этом в каждом из этих вызовов используется локальный интракоммуникатор, соответствующий данной группе процессов. При работе с MPI_Intercomm_create локальная и удаленная группы процессов не должны пересекаться, иначе возможны "тупики".
Пример организации обмена между разными группами с помощью интеркоммуникатора приведен в тексте 5.15.
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[]}
{
int counter, message, myid, numprocs, server;
int color, remote_leader_rank, i, ICTAG = 0;
MPI_Status status;
MPI_Comm oldcommdup, splitcomm, oldcomm, inter_comm;
MPI_Init(&argc, &argv);
oldcomm = MPI_COMM_WORLD;
MPI_Comm_dup(oldcomm, &oldcommdup);
MPI_Comm_size(oldcommdup, &numprocs);
MPI_Comm_rank(oldcommdup, &myid);
server = numprocs — 1;
color = (myid == server);
MPI_Comm_split(oldcomm, color, myid, &splitcomm);
if(!color)
{
remote_leader_rank = server;
}
else
{
remote_leader_rank = 0;
}
MPI_Intercomm_create(splitcomm, 0, oldcommdup,
remote_leader_rank, ICTAG, &inter_comm);
MPI_Comm_free (&oldcommdup) ;
if (myid == server)
{
for(i = 0; i<server; i++)
{
MPI_Recv(&message, 1, MPI_INT, i,
MPI_ANY_TAG, inter_comm, &status);
printf("Process rank %i received %i from %i\n",
myid, message, status.MPI_SOURCE);
}
}
else
{
counter = myid;
MPI_Send(&counter, I, MPI_INT, 0, 0, inter_comm);
printf("Process rank %i send %i\n", counter);
}
MPI_Comm_free(&inter_comm);
MPI_Finalize();
return 0;
}
В этой программе процессы делятся на две группы: первая состоит из одного процесса (процесс с максимальным рангом в исходном коммуникаторе MPI_Comm_world), это — "сервер", а во вторую входят все остальные процессы. Между этими группами и создается интеркоммуникатор intercomm. Процессы-клиенты передают серверу сообщения. Сервер принимает эти сообщения с помощью подпрограммы стандартного блокирующего двухточечного приема и выводит их на экран. "Ненужные" коммуникаторы удаляются. Распечатка вывода этой программы выглядит следующим образом:
mpiexec –host -machinefile -n 10 – myprogr
Process rank 4 send 4
Process rank 8 send 8
Process rank 2 send 2
Process rank 6 send 6
Process rank 3 send 3
Process rank 1 send 1
Process rank 9 received 0 from 0
Process rank 9 received 1 from 1
Process rank 9 received 2 from 2
Process rank 9 received 3 from 3
Process rank 9 received 4 from 4
Process rank 9 received 5 from 5
Process rank 9 received 6 from 6
Process rank 9 received 7 from 7
Process rank 9 received 8 from 8
Process rank 5 send 5
Process rank 7 send 7
Process rank 0 send 0
Разберите работу программы и прокомментируйте результат ее выполнения.
1. Какие фактические параметры и в каком порядке необходимо перечислять в списке параметров процедур двухточечного обмена?
2. Перечислите множество вариантов посылки сообщений от одного процесса к другому в процедуре двухточечного обмена.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.