Семантика неблокирующих коммуникаций определена подходящим расширением определений в разделе 3.5.
Очередность. Операции неблокирующих коммуникаций упорядочены согласно порядку исполнения вызовов, которые инициируют обмен. Требование отсутствия обгона раздела 3.5 расширено на неблокирующий обмен.
Пример 3.13 Установление очереди для неблокирующих операций.
CALL MPI_COMM_RANK(comm, rank, ierr)
IF (RANK.EQ.0) THEN
CALL MPI_ISEND(a, 1, MPI_REAL, 1, 0, comm, r1, ierr)
CALL MPI_ISEND(b, 1, MPI_REAL, 1, 0, comm, r2, ierr)
ELSE ! rank.EQ.1
CALL MPI_IRECV(a, 1, MPI_REAL, 0, MPI_ANY_TAG, comm, r1, ierr)
CALL MPI_IRECV(b, 1, MPI_REAL, 0, 0, comm, r2, ierr)
END IF
CALL MPI_WAIT(r1,status)
CALL MPI_WAIT(r2,status)
Первая посылка процесса нуль будет соответствовать первому приему процесса один, даже если оба сообщения посланы до того, как процесс один выполнит тот или другой прием.
Продвижение обмена. Вызов MPI_WAIT, который завершает прием, будет в конечном итоге заканчиваться, если соответствующая посылка была начата и не закрыта другим приемом. В частности, если соответствующая посылка неблокирующая, тогда прием должен завершиться, даже если отправитель не выполняет никакого вызова, чтобы завершить передачу. Аналогично, обращение к MPI_WAIT, которое завершает посылку, будет в конечном итоге заканчиваться, если соответствующий прием инициирован (если прием не закрыт другой передачей, и даже если никакого обращения не выполняется, чтобы закрыть прием).
Пример 3.14 Илюстрация семантики продвижения.
CALL MPI_COMM_RANK(comm, rank, ierr)
IF (RANK.EQ.0) THEN
CALL MPI_SSEND(a, 1, MPI_REAL, 1, 0, comm, ierr)
CALL MPI_SEND(b, 1, MPI_REAL, 1, 1, comm, ierr)
ELSE ! rank.EQ.1
CALL MPI_IRECV(a, 1, MPI_REAL, 0, 0, comm, r, ierr)
CALL MPI_RECV(b, 1, MPI_REAL, 0, 1, comm, ierr)
CALL MPI_WAIT(r, status, ierr)
END IF
Этот код не имеет дедлока при правильной реализации MPI. Первая синхронная посылка процесса нуль обязана завершиться после того, как процесс один установит соответствующий (неблокирующий) прием , даже если процесс один не достиг еще завершения вызова wait. Поэтому процесс ноль будет продолжаться и выполнит вторую посылку, позволяя процессу один завершить передачу.
Если MPI_TEST, который завершает прием, вызывается повторно с тем же самым аргументом и соответствующая посылка стартовала, тогда вызов рано или поздно возвратит flag = true, если посылка не закрыта другим приемом. Если MPI_TEST, который завершает посылку, повторяется с тем же самым аргументом и соответствующий прием стартовал, тогда вызов рано или поздно возвратит flag = true, если не будет закрыт другой посылкой.