Класс функций стандартного двухточечного обмена сообщениями. Предопределенные константы типов
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 – структура, используемая для хранения параметров сообщений. Она содержит три обязательных поля:
- MPI_Source (номер процесса отправителя).
- MPI_Tag (идентификатор сообщения).
- 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);