- •Двухточечный обмен
- •Int mpi_Testall(int count, mpi_Request requests[], int *flag, mpi_Status statuses[])
- •Коллективный обмен
- •Int mpi_Scatterv(void *sendbuf, int *sendcounts, int *displs,
- •Int mpi_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls,
- •Int mpi_Reduce(void *buf, void *result, int count,
- •Int mpi_Op_create(mpi_User_function *function, int commute, mpi_Op *op)
- •Int mpi_Allreduce(void *sendbuf, void *rcvbuf, int count,
- •Int mpi_Scan(void *sendbuf, void *rcvbuf, int count, mpi_Datatype datatype, mpi_Op op, mpi_Comm comm)
- •Int mpi_Intercomm_create(mpi_Comm local_comm, int local_leader,
- •Топологии
- •Int mpi_Cart_coords(mpi_Comm comm, int rank, int maxdims, int *coords)
- •Int mpi_Cart_map(mpi_Comm comm_old, int ndims, int *dims, int *periods, int *newrank)
- •Производные типы
- •Атрибуты
- •Void *extra_state, void *attribute_val_in, void *attribute_val_out, int *flag)
- •Int mpi_Keyval_free(int *keyval)
- •Int mpi_Attr_put(mpi_Comm comm, int keyval, void* attribute)
- •Int mpi_Attr_get(mpi_Comm comm, int keyval, void *attribute, int *flag)
- •Int mpi_Attr_delete(mpi_Comm comm, int keyval)
- •Задание 3
Двухточечный обмен
Участниками двухточечного обмена являются два процесса: процесс-отправитель и процесс-получатель (рис. 3.3).
Рис. 3.3. Двухточечный обмен
Далее приводится описание интерфейса подпрограмм, реализующих разные виды двухточечного обмена.
Стандартная блокирующая передача
int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
MPI_SEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR)
Входные параметры:
buf - адрес первого элемента в буфере передачи;
count - количество элементов в буфере передачи;
datatype - тип MPI каждого пересылаемого элемента;
dest - ранг процесса-получателя сообщения (целое число от 0 до n - 1, где n - число процессов в области взаимодействия);
tag - тег сообщения;
comm - коммуникатор;
ierr - код завершения.
Стандартный блокирующий прием
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source,
int tag, MPI_Comm comm, MPI_Status *status)
MPI_RECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, STATUS, IERR)
Входные параметры:
count - максимальное количество элементов в буфере приема. Фактическое их количество можно определить с помощью подпрограммы MPI_Get_count ;
datatype - тип принимаемых данных. Напомним о необходимости соблюдения соответствия типов аргументов подпрограмм приема и передачи;
source - ранг источника. Можно использовать специальное значение MPI_ANY_SOURCE, соответствующее произвольному значению ранга. В программировании идентификатор, отвечающий произвольному значению параметра, часто называют "джокером". Этот термин будем использовать и мы;
tag - тег сообщения или "джокер" MPI_ANY_TAG, соответствующий произвольному значению тега;
comm - коммуникатор. При указании коммуникатора "джокеры" использовать нельзя.
Выходные параметры:
buf - начальный адрес буфера приема. Его размер должен быть достаточным, чтобы разместить принимаемое сообщение, иначе при выполнении приема произойдет сбой - возникнет ошибка переполнения;
status - статус обмена.
Если сообщение меньше, чем буфер приема, изменяется содержимое лишь тех ячеек памяти буфера, которые относятся к сообщению.
Определение размера полученного сообщения (count)
int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count)
MPI_GET_COUNT(STATUS, DATATYPE, COUNT, IERR)
Аргумент datatype должен соответствовать типу данных, указанному в операции передачи сообщения.
Синхронная передача
int MPI_Ssend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
MPI_SSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR)
Параметры этой подпрограммы совпадают с параметрами подпрограммы MPI_Send.
Буферизованный обмен
int MPI_Bsend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
MPI_BSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR)
Параметры совпадают с параметрами подпрограммы MPI_Send.
Создание буфера
int MPI_Buffer_attach(void *buf, size)
MPI_BUFFER_ATTACH(BUF, SIZE, IERR)
Выходной параметр:
buf - буфер размером size байтов.
В программах на языке Fortran роль буфера может играть массив. Этот массив должен быть описан в программе, его не следует использовать для других целей (например, в качестве первого аргумента подпрограммы MPI_Bsend ). За один раз к процессу может быть подключен только один буфер.
Отключение буфера
int MPI_Buffer_detach(void *buf, int *size)
MPI_BUFFER_DETACH(BUF, SIZE, IERR)
Выходные параметры:
buf - адрес;
size - размер отключаемого буфера.
Вызов данной подпрограммы блокирует работу процесса до тех пор, пока все сообщения, находящиеся в буфере, не будут обработаны. В языке C данный вызов не освобождает автоматически память, отведенную для буфера.
Передача по готовности
int MPI_Rsend(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm)
MPI_RSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR)
Параметры совпадают с параметрами подпрограммы MPI_Send.
Блокирующая проверка доставки сообщения
int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status)
MPI_PROBE(SOURCE, TAG, COMM, STATUS, IERR)
Входные параметры:
source - ранг источника или " джокер";
tag - значение тега или "джокер";
comm - коммуникатор.
Выходной параметр:
status - статус.
Неблокирующая проверка сообщения
int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status)
MPI_IPROBE(SOURCE, TAG, COMM, FLAG, STATUS, IERR)
Входные параметры этой подпрограммы те же, что и у подпрограммы MPI_Probe
Выходные параметры:
flag - флаг;
status - статус.
Если сообщение уже поступило и может быть принято, возвращается значение флага "истина".
Прием и передача данных с блокировкой
int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype,
int source, int recvtag, MPI_Comm comm, MPI_Status *status)
MPI_SENDRECV(SENDBUF, SENDCOUNT, SENDTYPE, DEST, SENDTAG,
RECVBUF, RECVCOUNT, RECVTYPE, SOURCE, RECVTAG, COMM, STATUS, IERR)
Входные параметры:
sendbuf - начальный адрес буфера передачи;
sendcount - количество передаваемых элементов;
sendtype - тип передаваемых элементов;
dest - ранг адресата;
sendtag - тег передаваемого сообщения;
recvbuf - начальный адрес буфера приема;
recvcount - количество элементов в буфере приема;
recvtype - тип элементов в буфере приема;
source - ранг источника;
recvtag - тег принимаемого сообщения;
comm - коммуникатор.
Выходные параметры:
recvbuf - начальный адрес буфера приема;
status - статус операции приема.
Прием, и передача используют один и тот же коммуникатор. Буферы передачи и приема не должны пересекаться, у них может быть разный размер, типы пересылаемых и принимаемых данных также могут различаться.
Отправка и прием сообщения в блокирующем режиме с общим буфером для передачи и для приема
int MPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,
int dest, int sendtag, int source, int recvtag, MPI_Comm comm, MPI_Status *status)
MPI_SENDRECV_REPLACE(BUF, COUNT, DATATYPE, DEST, SENDTAG, SOURCE, RECVTAG, COMM, STATUS, IERR)
Входные параметры:
count - количество отправляемых данных и емкость буфера приема;
datatype - тип данных в буфере приема и передачи;
dest - ранг адресата;
sendtag - тег передаваемого сообщения;
source - ранг источника;
recvtag - тег принимаемого сообщения;
comm - коммуникатор.
Выходные параметры:
buf - начальный адрес буфера приема и передачи;
status - статус.
Принимаемое сообщение не должно превышать по размеру отправляемое сообщение, а передаваемые и принимаемые данные должны быть одного типа. Последовательность приема и передачи выбирается системой автоматически.
Инициализация неблокирующей стандартной передачи
int MPI_Isend(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm, MPI_Request *request)
MPI_ISEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR)
Входные параметры этой подпрограммы аналогичны аргументам подпрограммы MPI_Send.
Выходной параметр:
request - идентификатор операции.
Инициализация неблокирующей синхронной передачи данных
int MPI_Issend(void *buf, int count, MPI_Datatype datatype,
int dest, int tag, MPI_Comm comm, MPI_Request *request)
MPI_ISSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR)
Параметры этой подпрограммы совпадают с параметрами подпрограммы MPI_Send.
Неблокирующая буферизованная передача сообщения
int MPI_Ibsend(void *buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm, MPI_Request *request)
MPI_IBSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR)
Неблокирующая передача "по готовности"
int MPI_Irsend(void* buf, int count, MPI_Datatype datatype, int dest,
int tag, MPI_Comm comm, MPI_Request *request)
MPI_IRSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR)
Параметры всех подпрограмм неблокирующей передачи совпадают.
Инициализация неблокирующего приема
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source,
int tag, MPI_Comm comm, MPI_Request *request)
MPI_IRECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST, IERR)
Назначение аргументов здесь такое же, как и в предыдущих подпрограммах, за исключением того, что указывается ранг не адресата, а источника сообщения (source ).
Блокировка работы процесса до завершения приема или передачи сообщения
int MPI_Wait(MPI_Request *request, MPI_Status *status)
MPI_WAIT(REQUEST, STATUS, IERR)
Входной параметр:
request - идентификатор операции обмена.
Выходной параметр:
status - статус выполненной операции.
Значение статуса для операции передачи сообщения можно получить вызовом подпрограммы MPI_Test_cancelled. Можно вызвать MPI_Wait с пустым или неактивным аргументом request. В этом случае операция завершается сразу же с пустым статусом.
Успешное выполнение подпрограммы MPI_Wait после вызова MPI_Ibsend подразумевает, что буфер передачи можно использовать вновь, то есть пересылаемые данные отправлены или скопированы в буфер, выделенный при вызове подпрограммы MPI_Buffer_attach. В этот момент уже нельзя отменить передачу. Если не будет зарегистрирован соответствующий прием, буфер нельзя будет освободить. В этом случае можно применить подпрограмму MPI_Cancel, которая освобождает память, выделенную подсистеме коммуникаций.
Неблокирующая проверка завершения приема или передачи сообщения
int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)
MPI_TEST(REQUEST, FLAG, STATUS, IERR)
Входной параметр:
request - идентификатор операции обмена.
Выходные параметры:
flag - "истина", если операция, заданная идентификатором request, выполнена;
status - статус выполненной операции.
Если при вызове MPI_Test используется пустой или неактивный аргумент request, операция возвращает значение флага "истина" и пустой статус.
Проверка завершения всех обменов
int MPI_Waitall(int count, MPI_Request requests[], MPI_Status statuses [ ])
MPI_WAITALL(COUNT, REQUESTS, STATUSES, IERR)
Выполнение процесса блокируется до тех пор, пока все операции обмена, связанные с активными запросами в массиве requests, не будут выполнены. Возвращается статус этих операций. Статус обменов содержится в массиве statuses. count - количество запросов на обмен (размер массивов requests иstatuses ).
В результате выполнения подпрограммы MPI_Waitall запросы, сформированные неблокирующими операциями обмена, аннулируются, а соответствующим элементам массива присваивается значение MPI_REQUEST_NULL. Список может содержать пустые или неактивные запросы. Для каждого из них устанавливается пустое значение статуса.
В случае неуспешного выполнения одной или более операций обмена подпрограмма MPI_Waitall возвращает код ошибки MPI_ERR_IN_STATUS и присваивает полю ошибки статуса значение кода ошибки соответствующей операции. Если операция выполнена успешно, полю присваивается значение MPI_SUCCESS, а если не выполнена, но и не было ошибки - значение MPI_ERR_PENDING. Последний случай соответствует наличию запросов на выполнение операции обмена, ожидающих обработки.
Неблокирующая проверка завершения обменов