Функция передачи сообщения с блокировкой и функции для передачи сообщения без блокировки

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

MPI поддерживает четыре разновидности двухточечного обмена сообщениями между параллельными процессами:

1) стандартный;

2) синхронный;

3) буферизованный;

4) по готовности.

Каждый из перечисленных способов обмена может быть реализован как в блокирующем, так и в неблокирующем вариантах.

В данном курсе лекций будут рассмотрены функции только стандартного двухточечного обмена (блокирующий и в неблокирующий варианты).

int MPI_Send(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);

где:

buf – адрес начала расположения пересылаемых данных;

count – число пересылаемых элементов;

datatype – тип посылаемых элементов (см. п.3.3);

dest – номер процесса-получателя в группе с идентификатором comm;

tag – числовой идентификатор сообщения;

comm – идентификатор группы.

Функция выполняет посылку count элементов типа datatype сообщения с числовым идентификатором tag процессу с номером dest в группе с идентификатором comm. Переменная buf – это, как правило, адрес скалярной переменной, значение которой нужно переслать или адрес первого элемента массива. В последнем случае, все передаваемые элементы сообщения должны быть расположены подряд в буфере buf.

Значение count может быть нулем. Тип передаваемых элементов datatype должен указываться с помощью предопределенных констант типа (см. п.3.3). Разрешается передавать сообщение самому себе.

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

Пример №1 (в качестве практического занятия дописать).

Дано: процессу №1 (значение переменной «int NP;») необходимо передать значение одной переменную «double a;» на процесс № 0. Прием в данном примере не рассматривается.

if(_ _ _ _ _ _)

{

MPI_Send(_ _ _ _

}

(конец примера №1)

Пример №2 (в качестве практического занятия дописать).

Дано: процессу №0 (значение переменной «int NP;») необходимо передать весь вектор «double A[100];» на процесс № 1. Прием в данном примере не рассматривается.

if(_ _ _ _ _ _)

{

MPI_Send(_ _ _ _

}

(конец примера №2)

Функция передачи сообщения без блокировки:

int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request);

где:

buf – адрес начала буфера посылки сообщения;

count – число передаваемых элементов в сообщении;

datatype – тип передаваемых элементов (см. п.3.3);

dest – номер процесса-получателя;

tag – числовой идентификатор сообщения;

comm – идентификатор группы;

OUT request – значение, используемое при завершении операции посылки.

Возврат из функции происходит немедленно (immediate), без ожидания окончания передачи данных. Этим объясняется префикс I в именах функций. Поэтому переменную buf повторно использовать нельзя без получения дополнительной информации о завершении данной посылки.

Окончание процесса передачи (т.е. того момента, когда можно повторно использовать буфер buf без опасения испортить передаваемое сообщение) можно определить с помощью параметра request и функций MPI_Wait (и ей подобных) и MPI_Test (и ей подобных).

Ожидание завершения операции обмена, инициированной функциями MPI_Isend или MPI_Irecv (о ней в п.3.2), которые вернули значение по адресу request типа MPI_Request, или, что то же, ожидание завершения операции, ассоциированной с указанным значением типа MPI_Request, производится следующей функцией:

int MPI_Wait(MPI_Request *request, MPI_Status *status);

где:

request – адрес, куда записано значение типа MPI_Request;

OUT status – параметры сообщения.

MPI_Status – структура, используемая для хранения параметров сообщений. Она содержит три обязательных поля:

  1. MPI_Source (номер процесса отправителя).
  2. MPI_Tag (идентификатор сообщения).
  3. MPI_Error (код ошибки).

Блокировка выполнения операций на процессе до тех пор, пока все операции обмена, ассоциированные с указанными значениями типа MPI_Request, не будут завершены:

int MPI_Waitall(int count, MPI_Request *requests, MPI_Status *statuses);

где:

count – число значений типа MPI_Request;

requests – массив значений типа MPI_Request;

OUT statuses – параметры сообщений.

Если во время одной или нескольких операций обмена возникли ошибки, то поле ошибки в элементах массива statuses будет установлено в соответствующее значение.

Блокировка выполнения операций на процессе до тех пор, пока какая-либо операция обмена, ассоциированные с указанными значениями типа MPI_Request, не будет завершена:

int MPI_Waitany(int count, MPI_Request *requests, int *index, MPI_Status *status);

где:

count – число значений типа MPI_Request;

requests – массив значений типа MPI_Request;

OUT index – номер в массиве завершенной операции обмена;

OUT status – параметры сообщений.

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

Блокировка выполнения операций на процессе до тех пор, пока крайней мере одна из операций обмена, ассоциированных с указанными значениями типа MPI_Request, не будет завершена:

int MPI_Waitsome(int incount, MPI_Request *requests, int *outcount, int *indexes, MPI_Status *statuses);

где:

incount – число идентификаторов;

requests – массив значений типа MPI_Request;

OUT outcount – число переменных типа MPI_Status завершившихся операций обмена;

OUT indexes – массив номеров завершившихся операции обмена;

OUT statuses - параметры завершившихся сообщений.

Параметр outcount содержит число завершенных операций, а первые outcount элементов массива indexes содержат номера элементов массива requests. Первые outcount элементов массива statuses содержат параметры завершенных операций.

Функции проверки завершения семейства TEST имеют практически такие же прототипы, как и функции ожидания завершения семейства WAIT, только добавляется дополнительный параметр «flag» типа int* (кроме функции MPI_Testsome, для которой такой параметр не нужен):

int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status);

int MPI_Testall(int count, MPI_Request *requests, int *flag, MPI_Status *statuses);

int MPI_Testany(int count, MPI_Request *requests, int *index, int *flag, MPI_Status *status);

int MPI_Testsome(int incount, MPI_Request *requests, int *outcount, int *indexes, MPI_Status *statuses);

Функция прерывания коммуникационной операции:

int MPI_Cancel(MPI_Request *request);


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: