Санкт-Петербургский государственный университет
Опубликован: 11.10.2012 | Доступ: свободный | Студентов: 955 / 173 | Длительность: 05:14:00
Лекция 4:

Неблокирующие обмены

< Лекция 3 || Лекция 4: 12 || Лекция 5 >

Примеры использования неблокирующих двухточечных обменов

Пример

program main_mpi
include 'mpif.h'
integer rank, tag, cnt, ierr, status(MPI_STATUS_SIZE)
integer request
real sndbuf(5) /1., 2., 3., 4., 5./
real rcvbuf(5)
cnt = 5
tag = 0
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
…
if(rank.eq.0) then
call MPI_Isend(sndbuf(1), cnt, MPI_REAL, 1, tag, MPI_COMM_WORLD, request, ierr)
print *, "process ", rank, " send before Wait", sndbuf
call MPI_Wait(request, status, ierr)
print *, "process ", rank, " send after Wait", sndbuf
else
call MPI_Irecv(rcvbuf(1), cnt, MPI_REAL, 0, tag, MPI_COMM_WORLD, request, ierr)
print *, "process ", rank, " received before Wait", rcvbuf
call MPI_Wait(request, status, ierr)
print *, "process ", rank, " received after Wait", rcvbuf
end if
call MPI_Finalize(ierr)
stop
end

Пример

program main_mpi
include 'mpif.h'
integer rank, tag1, tag2, cnt, ierr, status(MPI_STATUS_SIZE)
integer request
real sndbuf1, sndbuf2, rcvbuf1, rcvbuf2
cnt = 1
tag = 0
sndbuf1 = 3.14159
sndbuf2 = 2.71828
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
…
if (rank.eq.0) then
call MPI_Send(sndbuf1, cnt, MPI_REAL, 1, tag1, MPI_COMM_WORLD, ierr)
print *, "process ", rank, " send ", sndbuf1
call MPI_Send(sndbuf2, cnt, MPI_REAL, 1, tag2, MPI_COMM_WORLD, ierr)
print *, "process ", rank, " send ", sndbuf2
else
call MPI_Irecv(rcvbuf1, cnt, MPI_REAL, 0, tag1, MPI_COMM_WORLD, request, ierr)
call MPI_Recv(rcvbuf2, cnt, MPI_REAL, 0, tag2, MPI_COMM_WORLD, status, ierr)
print *, "process ", rank, " received before Wait", rcvbuf1
print *, "process ", rank, " received before Wait", rcvbuf2
call MPI_Wait(request, status, ierr)
print *, "process ", rank, " received after Wait", rcvbuf1
print *, "process ", rank, " received after Wait", rcvbuf2
end if
call MPI_Finalize(ierr)
end

Подпрограммы-пробники

Неблокирующая проверка сообщения

Неблокирующая проверка сообщения выполняется подпрограммой:

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 - статус.

Если сообщение уже поступило и может быть принято, возвращается значение флага "истина".

Размер полученного сообщения (count) можно определить с помощью вызова подпрограммы

int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count)

MPI_Get_count(status, datatype, count, ierr)

Параметры

  • count -  количество элементов в буфере передачи;
  • datatype - тип каждого пересылаемого элемента;
  • status - статус обмена;
  • ierr - код завершения

Аргумент datatype должен соответствовать типу данных, указанному в операции обмена.

Пример

program main_mpi
include 'mpif.h'
integer rank, i, k, ierr, tag, dest, status(MPI_status_size)
real x
tag = 0
dest = 2
call MPI_Init(ierr)
call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
if (rank.eq.0) then
 i = 2002
 call MPI_Send(i, 1, MPI_INTEGER, dest, tag, MPI_COMM_WORLD, ierr)
else if(rank.eq.1) then
x = 3.14159
call MPI_Send(x, 1, MPI_REAL, dest, tag, MPI_COMM_WORLD, ierr)
…
do k = 1, 2
 call MPI_Probe(MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, status, ierr)
 if (status(MPI_source).eq.0) then
 call MPI_Recv(i, 1, MPI_INTEGER, 0, tag, MPI_COMM_WORLD, status, ierr)
 print *, "received ", i, " from 0"
else
 call MPI_Recv(x, 1, MPI_REAL, 1, tag, MPI_COMM_WORLD, status, ierr)
 print *, "received ", x, " from 1"
 end if
end do
end if
call MPI_Finalize(ierr)
stop
end
< Лекция 3 || Лекция 4: 12 || Лекция 5 >