Санкт-Петербургский государственный университет
Опубликован: 11.10.2012 | Доступ: свободный | Студентов: 955 / 173 | Длительность: 05:14:00
Лекция 6:

Группы процессов и коммуникаторы

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >

Операции обмена между группами процессов

Интеробмены

При выполнении интеробмена процессу-источнику сообщения указывается ранг адресата относительно удаленной группы, а процессу-получателю — ранг источника (также относительно удаленной по отношению к получателю группы).

Обмен выполняется между лидерами обеих групп. Предполагается, что в обеих группах есть, по крайней мере, по одному процессу, который может обмениваться сообщениями со своим партнером.

Интеробмен возможен, только если создан соответствующий интеркоммуникатор, а это можно сделать с помощью подпрограммы:

int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, 
int remote_leader, int tag, MPI_Comm *new_intercomm)
MPI_Intercomm_create(local_comm, local_leader, peer_comm, 
remote_leader, tag, new_intercomm, ierr)
    

Входные параметры этой подпрограммы:

  • local_comm - локальный интракоммуникатор;
  • local_leader - ранг лидера в локальном коммуникаторе (обычно 0);
  • peer_comm - удаленный коммуникатор;
  • remote_leader - ранг лидера в удаленном коммуникаторе (обычно 0);
  • tag - тег интеркоммуникатора, используемый лидерами обеих групп для обменов в контексте родительского коммуникатора.

Выходной параметр - интеркоммуникатор (new_intercomm).

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

При работе с MPI_Intercomm_create локальная и удаленная группы процессов не должны пересекаться, иначе возможны "тупики".

Пример

#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, 1, MPI_INT,  0, 0, inter_comm);
 printf("Process rank %i send %i\n", myid, counter);
}
 MPI_Comm_free(&inter_comm );
 MPI_Finalize();
} 
    

В примере процессы делятся на две группы: первая состоит из одного процесса (процесс с максимальным рангом в исходном коммуникаторе MPI_COMM_WORLD), это - "сервер", а во вторую входят все остальные процессы.

Между этими группами создается интеркоммуникатор inter_comm.

Процессы-клиенты передают серверу сообщения.

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

"Ненужные" коммуникаторы удаляются.

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >