Украина, г. Киев |
Опубликован: 11.10.2012 | Уровень: для всех | Доступ: платный | ВУЗ: Санкт-Петербургский государственный университет
Лекция 4:
Неблокирующие обмены
Примеры использования неблокирующих двухточечных обменов
Пример
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