Параллельное программирование: Учебное пособие, страница 89

Код ошибочного завершения подпрограммы в MPI выводится в виде идентификатора, в который мнемонически заложено указание на причину возникновения ошибки, например:

·  MPI_ERR_COMM — неправильно указан коммуникатор, например, был использован "пустой" коммуникатор;

·  MPI_ERR_COUNT — неправильно задано значение аргумента (count), определяющего количество пересылаемых данных;

·  MPI_ERR_TYPE — неправильное значение аргумента, задающего тип пересылаемых данных;

·  MPI_ERR_TAG — неправильно указан тег сообщения;

·  MPI_ERR_RANK — неправильно указан ранг источника или ранг адресата  сообщения;

·  MPI_ERR_ARG — неправильный аргумент, ошибочное задание которого не попадает ни в один класс ошибок;

·  MPI_ERR_REQUEST — неправильный запрос на выполнение операции.

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

Сообщение может быть скопировано прямо в буфер приема, а может быть помещено во временный системный буфер, где и будет дожидаться момента, когда в выполняемом процессе-адресате будет вызвана подпрограмма приема. Буферизация сообщения требует выполнения дополнительных операций копирования из памяти в память, а также выделения памяти для промежуточного буфера. В стандартном режиме MPI самостоятельно решает, надо ли буферизовать исходящие сообщения.

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

Подпрограмма стандартного блокирующего приема объявляется так:

int MPI_Recv(void *buf, int count,

MPI_Datatype datatype, int source, int tag,

MPI_Comm comm, MPI_Status *status)

Входными параметрами этой подпрограммы являются:

·  count — максимальное количество элементов в буфере приема, которое можно определить с помощью подпрограммы MPI_Get_count;

·  datatype — тип принимаемых данных;

·  source — ранг источника, в качестве которого можно использовать и специальную константу MPI_ANY_SOURCE, задающую произвольное значение ранга, процесс которого может выполнять роль ведущего процесса (“джокера”);

·  tag — метка сообщения или константа MPI_ANY_TAG (joker – джокер, шутник), соответствующий произвольному значению тега;

·  comm — идентификатор конкретного коммуникатора.

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

Выходными параметрами являются:

·  buf — начальный адрес буфера приема с размером, достаточным для размещения принимаемого сообщение, иначе при приеме произойдет сбой — ошибка переполнения;

·  status — статус обмена.

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

Ниже приведена программа, которая через переменную с именем vector осуществляет передачу половины содержимого в другой процессор.

/* Посылка блока вектора от процессора 0 в процессор 1

#include <stdio.h>

#include "mpi.h"

main(int argc, char* argv[])

{

    float vector[100];

    MPI_Status status;

    int p;

    int my_rank;

    int i;

    MPI_Init(&argc, &argv);

    MPI_Comm_size(MPI_COMM_WORLD, &p);

    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

/* Инициализация вектора и передача */