if (my_rank == 0)
{
for (i = 0; i < 50; i++)
vector[i] = 0.0;
for (i = 50; i < 100; i++)
vector[i] = 1.0;
MPI_Send(vector+50, 50, MPI_FLOAT, 1, 0,
MPI_COMM_WORLD);
}
else
{ /* my_rank == 1 */
MPI_Recv(vector+50, 50, MPI_FLOAT, 0, 0,
MPI_COMM_WORLD, &status);
for (i = 50; i < 100; i++)
printf("%3.1f ",vector[i]);
printf("\n");
}
MPI_Finalize();
} /* main */
Размер полученного сообщения (count) можно определить с помощью вызова подпрограммы MPI_Get_count:
int MPI_Get_count(MPI_Status *status,
MPI_Datatype datatype, int *count)
Аргумент datatype должен соответствовать типу данных, указанному в операции обмена.
Подпрограмма MPI_Recv может принимать сообщения, отправленные в любом режиме. Имеется некоторая асимметрия между операциями приема и передачи. Она состоит в том, что прием может выполняться от произвольного процесса, а в операции передачи должен быть указан вполне определенный адрес. Приемник может использовать джокеры для источника и для тега. Процесс может отправить сообщение и самому себе, но следует учитывать, что в этом случае блокирующие операции могут привести к тупику.
Программа, в которой используется двухточечный обмен, схематически представлена на рис. 5.2. Перед завершением программы и выполнением MPI_Finalize следует убедиться, что приняты все сообщения, отправленные ранее.
Процесс_0 |
Процесс_1 |
|
MPI_Init(); MPI_Send(dest=1); MPI_Finalize(); |
¾¾¾® |
MPI_Init(); MPI_Recv(source=0); MPI_Finalize(); |
Рис. 5.2.Схема простейшей программы с двухточечным обменом
Если во втором процессе не предусмотрен прием отправленного ему сообщения, программу следует считать ошибочной (рис. 5.3).
Процесс_0 |
Процесс_1 |
|
MPI_Init(); MPI_Send(dest=1); MPI_Finalize(); |
¾¾¾® ? |
MPI_Init(); MPI_Finalize(); |
Рис. 5.3.Схема ошибочной программы с двухточечным обменом
Простой пример законченной MPI-программы с двухточечным обменом приведен в тексте 5.1.
#include "mpi.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
int myid, numprocs;
char message[24];
int myrank;
MPI_Status status;
int tag = 0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
if (myrank == 0)
{
strcpy(message, "Hi, Parallel Programmer!");
MPI_Send(&message, 25, MPI_CHAR, 1, tag,
MPI_COMM_WORLD);
}
else
{
MPI_Recv(&message, 25, MPI_CHAR, 0, tag,
MPI_COMM_WORLD, &status);
printf("received: %s\n", message);
}
MPI_Finalize();
return 0;
}
В этом примере процесс с рангом 0 передает сообщение процессу с рангом 1, используя для этого подпрограмму MPI_Send. При выполнении этой операции в памяти процесса-отправителя выделяется буфер передачи с именем message. В буфере размещается 24 символа сообщения (Hi, Parallel Programmer!). Процесс с рангом 1 принимает сообщение с помощью подпрограммы MPI_Recv. Сообщение сохраняется на приемной стороне в буфере с аналогичным идентификатором message. Следующие два аргумента подпрограммы приема определяют размер и тип данных, помещаемых в буфер приема. Результат выполнения этой программы:
mpiexec –hostHM1, HM2 -n 2 -- myprogr
received: Hi, Parallel Programmer!
В первой строке приведена командная строка запуска программы c именем myprogr на двух (-n 2) главных машинах: HM1 – хозяине (ранг 0) и HM2 – клиенте (ранг 1, согласно порядку перечисления названий главных машин). Здесь и далее будем полагать, что имя исполняемой программы –myprogr.
Пример программы, в котором сообщениями обмениваются процессы с четными и нечетными рангами, дан в тексте 5.2. Предполагается, что значение size четно.
#include "mpi.h"
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.