Операция send-receive комбинирует в одном обращении посылку сообщения одному получателю и прием сообщения от другого отправителя. Получателем и отправителем может быть тот же самый процесс. Эта операция весьма полезна для выполнения сдвига по цепи процессов. Если для такого сдвига были использованы блокирующие приемы и передачи, тогда нужно корректно упорядочить эти приемы и передачи (например, четные процессы передают, затем принимают, нечетные процессы сначала принимают, затем передают) так, чтобы предупредить циклические зависимости, которые могут привести к дедлоку. Когда используется операция send-receive, коммуникационная система решает эти проблемы. Операция send-receive может быть использована в сочетании с функциями, описанными в главе 6, для выполнения сдвигов на различных топологиях. К тому же операция send-receive полезна для реализации удаленных процедурных вызовов.
Сообщение, посланное операцией send-receive, может быть получено обычной операцией приема или опробовано операцией probe; send-receive может также получать сообщения, посланные обычной операцией передачи.
Синтаксис функции MPI_SENDRECV представлен ниже.
MPI_SENDRECV(sendbuf, sendcount, sendtype, dest, sendtag,
recvbuf, recvcount, recvtype, source, recvtag, comm, status)
IN | sendbuf | начальный адрес буфера отправителя (альтернатива) | |
IN | sendcount | число элементов в буфере отправителя (целое) | |
IN | sendtype | тип элементов в буфере отправителя (дескриптор) | |
IN | dest | номер процесса-получателя (целое) | |
IN | sendtag | тэг процесса-отправителя (целое) | |
OUT | recvbuf | начальный адрес приемного буфера (альтернатива) | |
IN | recvcount | число элементов в в приемном буфере (целое) | |
IN | recvtype | тип элементов в приемном буфере (дескриптор) | |
IN | source | номер процесса-отправителя (целое) | |
IN | recvtag | тэг процесса-получателя (целое) | |
IN | comm | коммуникатор (дескриптор) | |
OUT | status | статус (статус) |
int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
int dest, int sendtag, void *recvbuf, int recvcount,
MPI_Datatype recvtype, int source, MPI_Datatype recvtag,
MPI_Comm comm, MPI_Status *status)
MPI_SENDRECV(SENDBUF, SENDCOUNT, SENDTYPE, DEST, SENDTAG, RECVBUF,
RECVCOUNT, RECVTYPE, SOURCE, RECVTAG, COMM, STATUS, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE, DEST, SENDTAG, RECVCOUNT, RECVTYPE,
SOURCE, RECVTAG, COMM, STATUS(MPI_STATUS_SIZE), IERROR
void MPI::Comm::Sendrecv(const void *sendbuf, int sendcount,
const MPI::Datatype& sendtype, int dest, int sendtag,
void *recvbuf, int recvcount, const MPI::Datatype& recvtype,
int source, int recvtag, MPI::Status& status) const
void MPI::Comm::Sendrecv(const void *sendbuf, int sendcount,
const MPI::Datatype& sendtype, int dest, int sendtag,
void *recvbuf, int recvcount, const MPI::Datatype& recvtype,
int source, int recvtag) const
Функция MPI_SENDRECV выполняет операции блокирующей передачи и приема. Передача и прием используют тот же самый коммуникатор, но возможно различные тэги. Буфера отправителя и получателя должны быть разделены и могут иметь различную длину и типы данных.
Синтаксис функции MPI_SENDRECV_REPLACE представлен ниже.
MPI_SENDRECV_REPLACE(buf, count, datatype, dest,
sendtag, source, recvtag, comm, status)
INOUT | buf | начальный адрес буфера отправителя и получателя (альтернатива) | |
IN | count | число элементов в буфере отправителя и получателя (целое) | |
IN | datatype | тип элементов в буфере отправителя и получателя (дескриптор) | |
IN | dest | номер процесса-получателя (целое) | |
IN | sendtag | тэг процесса-отправителя (целое) | |
IN | source | номер процесса-отправителя (целое) | |
IN | recvtag | тэг процесса-получателя (целое) | |
IN | comm | коммуникатор (дескриптор) | |
OUT | 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, IERROR)
<type> BUF(*)
INTEGER COUNT, DATATYPE, DEST, SENDTAG, SOURCE, RECVTAG,
COMM, STATUS(MPI_STATUS_SIZE), IERROR
void MPI::Comm::Sendrecv_replace (void* buf, int count,
const MPI::Datatype& datatype, int dest, int sendtag,
int source, int recvtag, MPI::Status& status) const
void MPI::Comm::Sendrecv_replace(void* buf, int count,
const MPI::Datatype& datatype, int dest, int sendtag,
int source, int recvtag) const
Функция MPI_SENDRECV_REPLACE выполняет блокирующие передачи и приемы. Тот же самый буфер используется для отправки и получения, так что посланное сообщение замещается полученным. Семантика операции send-receive похожа на запуск двух конкурирующих потоков, когда один выполняет передачу, а другой - прием, с последующим объединением этих потоков.
Совет разработчикам: Для варианта "замещения" необходима дополнительная промежуточная буферизация.[]