Главная страница

Программирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В.. Программирование для многопроцессорных систем в стандарте MPI -. Организация вычислений в многопроцессорных системах


Скачать 1.61 Mb.
НазваниеОрганизация вычислений в многопроцессорных системах
АнкорПрограммирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В..pdf
Дата15.03.2018
Размер1.61 Mb.
Формат файлаpdf
Имя файлаПрограммирование для многопроцессорных систем в стандарте MPI - .pdf
ТипКонтрольные вопросы
#16702
КатегорияИнформатика. Вычислительная техника
страница7 из 26
1   2   3   4   5   6   7   8   9   10   ...   26
i
, и в последнем случае уста- навливается в
MPI_UNDEFINED
MPI_TESTANY
с массивом, со- держащим один активный элемент, эквивалентен
MPI_TEST
MPI_TESTANY (count, array_of_requests, index, flag, status)
IN count длина списка (целое)
INOUT
array_of_requests массив запросов (массив дескрипторов)
OUT index индекс дескриптора для завершенной операции (целое)
OUT flag true, если одна из операций завершена (логический тип)
OUT status статусный объект (статус) int MPI_Testany (int count, MPI_Request *array_of_requests, int *index, int *flag,
MPI_Status *status)
MPI_TESTANY(COUNT, ARRAY_OF_REQUESTS, INDEX, FLAG, STATUS,
IERROR)
LOGICAL FLAG

73
INTEGER COUNT, ARRAY_OF_REQUESTS(*), INDEX,
STATUS(MPI_STATUS_SIZE), IERROR static bool MPI::Request::Testany (int count, MPI::Request array_of_requests[], int& index, MPI::Status& status)
Функция
MPI_WAITALL
блокирует работу, пока все операции обмена, связанные с активными дескрипторами в списке, не завершат- ся, и возвращает статус всех операций. Оба массива имеют то же са- мое количество элементов. Элемент с номером
i
в
array_of_statuses
устанавливается в возвращаемый статус
i
-й операции. Запросы, соз- данные операцией неблокирующего обмена, удаляются, и соответст- вующие дескрипторы устанавливаются в
MPI_REQUEST_NULL
Список может содержать нуль или неактивные дескрипторы. Вызов устанавливает статус каждого такого элемента в состояние
empty
Когда один или более обменов, завершенных обращением к
MPI_WAITALL
, оказались неудачны, желательно возвратить специ- альную информацию по каждому обмену. Функция
MPI_WAITALL
возвращает в таком случае код
MPI_ERR_IN_STATUS
и устанавли- вает в поля ошибки каждого статуса специфический код ошибки. Этот код будет
MPI_SUCCESS
, если обмен завершен, или другой код, если обмен не состоялся; или он может быть
MPI_ERR_PENDING
, если код не завершен и не в состоянии отказа. Функция
MPI_WAITALL
будет возвращать
MPI
_
SUCCESS
, если никакой из запросов не имеет ошибки, или будет возвращать другой код ошибки, если не выполнил- ся по другим причинам (таким как неверный аргумент). В таком слу- чае он не будет корректировать поле ошибки в статусе.
MPI_WAITALL ( count, array_of_requests, array_of_statuses)
IN count длина списков (целое)
INOUT array_of_requests массив запросов (массив дескрипторов)
OUT array_of_statuses массив статусных объектов (массив статусов) int MPI_Waitall (int count, MPI_Request *array_of_requests,
MPI_Status *array_of_statuses)
MPI_WAITALL(COUNT, ARRAY_OF_REQUESTS, ARRAY_OF_STATUSES,
IERROR)
INTEGER COUNT, ARRAY_OF_REQUESTS(*)
INTEGER ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*), IERROR static void MPI::Request::Waitall (int count, MPI::Request array_of_requests[],
MPI::Status array_of_statuses[])

74
Функция
MPI_TESTALL
возвращает
flag=true
, если обмены, свя- занные с активными дескрипторами в массиве, завершены. В этом случае каждый статусный элемент, который соответствует активному дескриптору, устанавливается в статус соответствующего обмена; ес- ли запрос был размещен вызовом неблокирующего обмена, то он уда- ляется, и дескриптор устанавливается в
MPI_REQUEST_NULL
. Ка- ждый статусный элемент, который соответствует нулю или неактив- ному дескриптору, устанавливается в состояние
empty
. В противном случае возвращается
flag=false
, никакие запросы не модифицируются, и значения статусных элементов неопределенные. Это локальная опе- рация.
MPI_TESTALL (count, array_of_requests, flag, array_of_statuses)
IN count длина списка (целое)
INOUT array_of_requests массив запросов (массив дескрипторов)
OUT flag
(логический тип)
OUT array_of_statuses массив статусных объектов(массив статусов) int MPI_Testall(int count, MPI_Request *array_of_requests, int *flag,
MPI_Status *array_of_statuses)
MPI_TESTALL(COUNT, ARRAY_OF_REQUESTS, FLAG,
ARRAY_OF_STATUSES, IERROR)
LOGICAL FLAG
INTEGER COUNT, ARRAY_OF_REQUESTS(*),
ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*), IERROR static bool MPI::Request::Testall (int count, MPI::Request array_of_requests[],
MPI::Status array_of_statuses[])
Функция
MPI_WAITSOME
ожидает, пока, по крайней мере, одна операция, связанная с активным дескриптором в списке, не завершит- ся. Возвращает в
outcount
число запросов из списка
array_of_indices
, которые завершены. Возвращает в первую
outcount
ячейку массива
array_of_indices
индексы этих операций (индекс внутри
ar-
ray_of_requests
). Возвращает в первую ячейку
outcount
массива
ar-
ray_of_status
статус этих завершенных операций. Если завершенный запрос был создан вызовом неблокирующего обмена, то он удаляется, и связанный дескриптор устанавливается в
MPI_REQUEST_NULL
Если список не содержит активных дескрипторов, то вызов закан- чивается немедленно со значением
outcount = MPI_UNDEFINED

75
MPI_WAITSOME (incount, array_of_requests, outcount,
array_of_indices, array_of_statuses)
IN incount длина массива запросов (целое)
INOUT array_of_requests массив запросов (массив дескрипторов)
OUT outcount число завершенных запросов (целое)
OUT array_of_indices массив индексов операций, которые завершены
(массив целых)
OUT array_of_statuses массив статусных операций для завершенных операций (массив статусов) int MPI_Waitsome (int incount, MPI_Request *array_of_requests, int *outcount, int *array_of_indices, MPI_Status *array_of_statuses)
MPI_WAITSOME (INCOUNT, ARRAY_OF_REQUESTS, OUTCOUNT,
ARRAY_OF_INDICES, ARRAY_OF_STATUSES, IERROR)
INTEGER INCOUNT, ARRAY_OF_REQUESTS(*), OUTCOUNT,
ARRAY_OF_INDICES(*), ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*),
IERROR static int MPI::Request::Waitsome(int incount, MPI::Request array_of_requests[], int array_of_indices[], MPI::Status array_of_statuses[])
Если один или более обменов, завершенных
MPI_WAITSOME
, не могут быть выполнены, надо возвращать по каждому обмену специ- фическую информацию.
Аргументы
outcount,
array_of_indices
и
array_of_statuses
будут индицировать завершение всех обменов, успешных или неуспешных.
Вызов будет возвращать код ошибки
MPI_ERR_IN_STATUS
и устанавливать поле ошибки каждого возвращенного статуса, чтобы указать на успешное завершение или возвратить специфический код ошибки.
Вызов будет возвращать
MPI_SUCCESS
, если ни один запрос не содержал ошибки, и будет возвращен другой код ошибки, если запрос не может быть выполнен по какой-то причине. В таких случаях поля ошибок статуса не будут корректироваться.
Функция
MPI_TESTSOME
ведет себя подобно
MPI_WAITSOME
за исключением того, что заканчивается немед- ленно. Если ни одной операции не завершено, она возвращает
outcount = 0
. Если не имеется активных дескрипторов в списке, она возвращает
outcount = MPI_UNDEFINED

76
MPI_TESTSOME (incount, array_of_requests, outcount, array_of_indices,
array_of_statuses)
IN incount длина массива запросов (целое)
IN OUT array_of_requests массив запросов (массив дескрипторов)
OUT outcount число завершенных запросов (целое)
OUT array_of_indices массив индексов завершенных операций (массив целых)
OUT array_of_statuses массив статусных объектов завершенных операций
(массив статусов) int MPI_Testsome (int incount, MPI_Request *array_of_requests, int *outcount, int *array_of_indices, MPI_Status *array_of_statuses)
MPI_TESTSOME (INCOUNT, ARRAY_OF_REQUESTS, OUTCOUNT,
ARRAY_OF_INDICES, ARRAY_OF_STATUSES, IERROR)
INTEGER INCOUNT, ARRAY_OF_REQUESTS(*), OUTCOUNT,
ARRAY_OF_INDICES(*), ARRAY_OF_STATUSES(MPI_STATUS_SIZE,*),
IERROR static int MPI::Request::Testsome(int incount, MPI::Request array_of_requests[], int array_of_indices[], MPI::Status array_of_statuses[])
MPI_TESTSOME
является локальной операцией, которая закан- чивается немедленно, тогда как
MPI_WAITSOME
будет блокиро- ваться до завершения обменов, если в списке содержится хотя бы один активный дескриптор. Оба вызова выполняют требование одно- значности: если запрос на прием повторно появляется в списке запро- сов, передаваемых
MPI_WAITSOME
или
MPI_TESTSOME
, и соот- ветствующая посылка была инициирована, тогда прием будет завер- шен успешно, если передача не закрыта другим приемом.
Пример 3.13.
Код клиент – сервер (невозможность обмена).
CALL MPI_COMM_SIZE(comm, size, ierr)
CALL MPI_COMM_RANK(comm, rank, ierr)
! код клиента
IF(rank > 0) THEN
DO WHILE(.TRUE.)
CALL MPI_ISEND(a, n, MPI_REAL, 0, tag, comm, request, ierr)
CALL MPI_WAIT(request, status, ierr)
END DO
ELSE
! rank=0 – код сервера
DO i=1, size-1
CALL MPI_IRECV(a(1,i),n,MPI_REAL,i tag,comm,request_list(i),ierr)
END DO

77
DO WHILE(.TRUE.)
CALL MPI_WAITANY(size-1, request_list, index, status, ierr)
CALL DO_SERVICE(a(1,index)) ! дескриптор одного сообщения
CALL MPI_IRECV(a(1,index),n,MPI_REAL,index,tag,comm, request_list(index), ierr)
END DO
END IF
Пример 3.14.
Код с использованием MPI_WAITSOME.
CALL MPI_COMM_SIZE(comm, size, ierr)
CALL MPI_COMM_RANK(comm, rank, ierr)
! код клиента
IF(rank > 0) THEN
DO WHILE(.TRUE.)
CALL MPI_ISEND(a, n, MPI_REAL, 0, tag, comm, request, ierr)
CALL MPI_WAIT(request, status, ierr)
END DO
ELSE
! rank=0 – код сервера
DO i=1, size-1
CALL MPI_IRECV(a(1,i), n, MPI_REAL,i,tag,comm, requests(i), ierr)
END DO
DO WHILE(.TRUE.)
CALL MPI_WAITSOME(size,request_list,numdone,indices,statuses, ierr)
DO i=1, numdone
CALL DO_SERVICE(a(1, indices(i)))
CALL MPI_IRECV(a(1, indices(i)), n, MPI_REAL, 0, tag, comm, requests(indices(i)), ierr)
END DO
END DO
END IF
3.8. ПРОБА И ОТМЕНА
Операции
MPI_PROBE
и
MPI_IPROBE
позволяют проверить входные сообщения без реального их приема. Пользователь затем мо- жет решить, как ему принимать эти сообщения, основываясь на ин- формации, возвращенной при пробе (преимущественно на информа- ции, возвращенной аргументом
status
). В частности, пользователь может выделить память для приемного буфера согласно длине опро- бованного сообщения.
Операция
MPI_CANCEL
позволяет отменить ждущие сообщения.
Это необходимо для очистки. Инициация операций получения или от- правки связывает пользовательские ресурсы, и может оказаться необ- ходимой отмена, чтобы освободить эти ресурсы.

78
MPI_IPROBE (source, tag, comm, flag, status)
IN source номер процесса-отправителя или MPI_ANY_SOURCE (целое)
IN tag значение тэга или MPI_ANY_TAG (целое)
IN comm коммуникатор (дескриптор)
OUT flag
(логическое значение)
OUT status статус (статус) int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status)
MPI_IPROBE(SOURCE, TAG, COMM, FLAG, STATUS, IERROR)
LOGICAL FLAG
INTEGER SOURCE, TAG, COMM, STATUS(MPI_STATUS_SIZE), IERROR bool MPI::Comm::Iprobe(int source, int tag, MPI::Status& status) const
MPI_IPROBE
(
source, tag, comm, flag, status
)
возвращает
flag =
true
, если имеется сообщение, которое может быть получено и кото- рое соответствует образцу, описанному аргументами
source
,
tag
, и
comm
. Вызов соответствует тому же сообщению, которое было бы получено с помощью вызова
MPI_RECV
(..., source, tag, comm,
status
), выполненного на той же точке программы, и возвращает ста- тус с теми же значениями, которые были бы возвращены
MPI_RECV()
. Другими словами, вызов возвращает
flag = false
и ос- тавляет статус неопределенным. Если
MPI_IPROBE
возвращает
flag
= true
, тогда содержание статусного объекта может быть впоследст- вии получено, как описано в параграфе 3.2.5, чтобы определить ис- точник, тэг и длину опробованного сообщения. Последующий прием, выполненный с тем же самым контекстом и тэгом, возвращенным в
status
вызовом
MPI_IPROBE
, будет получать сообщение, которое соответствует пробе, если после пробы не вмешается какое-либо дру- гое сообщение. Если принимающий процесс многопоточный, ответст- венность за выполнение условия возлагается на пользователя.
MPI_PROBE (source, tag, comm, status)
IN source номер источника или MPI_ANY_SOURCE (целое)
IN tag значение тэга или MPI_ANY_TAG (целое)
IN comm коммуникатор (дескриптор)
OUT status статус (статус) int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status)
MPI_PROBE(SOURCE, TAG, COMM, STATUS, IERROR)
INTEGER SOURCE, TAG, COMM, STATUS(MPI_STATUS_SIZE), IERROR void MPI::Comm::Probe(int source, int tag, MPI::Status& status) const

79
MPI_PROBE
ведет себя подобно
MPI_IPROBE
, исключая то, что функция
MPI_PROBE
является блокирующей и заканчивается после того, как соответствующее сообщение было найдено.
Аргумент
source
функции
MPI_PROBE
может быть
MPI_ANY_SOURCE
, это позволяет опробовать сообщения из произ- вольного источника и/или с произвольным тэгом. Однако специфиче- ский контекст обмена обязан создаваться только при помощи аргу- мента
comm
. Сообщение не обязательно должно быть получено сразу после опробования, оно может опробоваться несколько раз перед его получением.
MPI–реализация
MPI_PROBE
и
MPI
_
IPROBE
нуждается в га- рантии продвижения: если обращение к
MPI_PROBE
уже было за- пущено процессом и посылка, которая соответствует пробе, уже ини- циирована тем же процессом, то вызов
MPI_PROBE
будет завершен, если сообщение не получено другой конкурирующей операцией приема (которая выполняется другой ветвью опробуемого процесса).
Аналогично, если процесс ожидает выполнения
MPI_IPROBE
и соответствующее сообщение было запущено, то обращение к
MPI_IPROBE
возвратит
flag = true
, если сообщение не получено другой конкурирующей приемной операцией.
Пример 3.15.
Использование блокируемой пробы для ожидания входного сообщения.
CALL MPI_COMM_RANK(comm, rank, ierr)
IF (rank.EQ.0) THEN
CALL MPI_SEND(i, 1, MPI_INTEGER, 2, 0, comm, ierr)
ELSE
IF(rank.EQ.1) THEN
CALL MPI_SEND(x, 1, MPI_REAL, 2, 0, comm, ierr)
ELSE
! rank.EQ.2
DO i=1, 2
CALL MPI_PROBE(MPI_ANY_SOURCE, 0, comm, status, ierr)
IF (status(MPI_SOURCE) = 0) THEN
100 CALL MPI_RECV(i,1,MPI_INTEGER,0,0,comm, status, ierr)
ELSE
200 CALL MPI_RECV(x,1,MPI_REAL,1,0,comm, status, ierr)
END IF
END DO
END IF
Каждое сообщение принимается с правильным типом.

80
Пример 3.16.
Некорректная программа с использованием блокируе- мой пробы для ожидания входного сообщения.
CALL MPI_COMM_RANK(comm, rank, ierr)
IF (rank.EQ.0) THEN
CALL MPI_SEND(i, 1, MPI_INTEGER, 2, 0, comm, ierr)
ELSE
IF(rank.EQ.1) THEN
CALL MPI_SEND(x, 1, MPI_REAL, 2, 0, comm, ierr)
ELSE
DO i=1, 2
CALL MPI_PROBE(MPI_ANY_SOURCE, 0,comm, status, ierr)
IF (status(MPI_SOURCE) = 0) THEN
100
CALL MPI_RECV(i,1,MPI_INTEGER,MPI_ANY_SOURCE,
0,comm,status, ierr)
ELSE
200
CALL MPI_RECV(x,1,MPI_REAL,MPI_ANY_SOURCE,0, comm,status,ierr)
END IF
END DO
END IF
Модифицируем пример 3.15, используя
MPI_ANY_SOURCE
, как аргумент
sourse
в двух вызовах приема, обозначенных метками 100 и
200. Теперь программа некорректна: операция приема может получать сообщение, которое отличается от сообщения, опробованного преды- дущим обращением к
MPI_PROBE
MPI_CANCEL (request)
IN request коммуникационный запрос (дескриптор) int MPI_Cancel(MPI_Request *request)
MPI_CANCEL(REQUEST, IERROR)
INTEGER REQUEST, IERROR void MPI::Request::Cancel () const
Обращение к
MPI_CANCEL
маркирует для отмены ждущие не- блокирующие операции обмена (передача или прием). Вызов cancel является локальным. Он заканчивается немедленно, возможно перед действительной отменой обмена. После маркировки необходимо за- вершить эту операцию обмена, используя вызов
MPI_WAIT
или
MPI_TEST
(или любые производные операции). Если обмен отмечен для отмены, то вызов
MPI_WAIT
для этой операции гарантирует за-

81
вершение, не глядя на активность других процессов (то есть
MPI_WAIT
ведет себя как локальная функция); аналогично, если
MPI_TEST
вызывается повторно в цикле занятого ожидания для от- мены обмена, тогда
MPI_TEST
будет неизбежно успешно закончен.
Успешная отмена буферизованной передачи освобождает буферное пространство, занятое ждущим сообщением.
Должно выполняться следующее условие: либо отмена имеет ус- пех, либо имеет успех обмен, но не обе ситуации вместе. Если переда- ча маркирована для отмены, то обязательно должна быть ситуация, что когда-либо передача завершается нормально (посланное сообще- ние принято процессом назначения) или передача отменена успешно
(никакая часть сообщения не принята по адресу назначения). Тогда любой соответствующий прием закрывается другой передачей. Если прием маркирован для отмены, то обязан быть случай, когда прием завершился нормально или этот прием успешно отменен (никакая часть приемного буфера не изменена). Тогда любая соответствующая передача должна быть удовлетворена другим приемом. Если операция была отменена, тогда информация об этом будет возвращена в аргу- мент статуса операции, которая завершает обмен.
1   2   3   4   5   6   7   8   9   10   ...   26


написать администратору сайта