Функции завершения неблокированных операций

 

Чтобы завершить неблокированные посылку и получение данных, используются завершающие функции MPI_Wait и MPI_Test. Завершение посылающего процесса указывает, что он теперь свободен к доступу посылающего буфера. Завершение получающего процесса указывает, что буфер приема данных содержит сообщение, приемник свободен к его доступу и что объект состояния урегулирован.

 

 

int MPI_Wait (MPI_Request *request,MPI_Status *status)

request имя запроса

status статус объекта

 

Запрос к MPI_Wait возвращает управление после того, как операция, идентифицированная request, выполнилась, т.е. это блокированная функция. Если объект системы, указанный request, был первоначально создан неблокированными попосылающей или получающей функциями, то этот объект освобождается функцией MPI_Wait и request устанавливается в MPI_Request_null. Статус объекта содержит информацию относительно выполненной операции. MPI_Wait имеет не местную семантику завершения.

 

 

Удобней и эффективней завершить в одном запросе список многократно отложенных операций связи, чем завершение только одной операции. Функции MPI_Waitany или MPI_Testany используются, чтобы завершить несколько операций, MPI_Waitall или MPI_Testall – чтобы завершить все операции в списке, MPI_Waitsome или MPI_Testsome – чтобы завершить некоторые операции в списке.


int MPI_Waitany (int count,MPI_Request *array_of_requests,int *index,MPI_Status *status)

count длина списка

array_of_requests массив имен запросов

index индекс в массиве имени запроса, который завершился

status статус принятого пакета данных


MPI_Waitany блокирована, пока одна из операций обмена, связанных с запросами, заголовки которых записаны в массиве array_of_requests, не завершились. Если к этому времени будет завершена более чем одна операция, MPI_Waitany произвольно выбирает одну из них и завершает ее. MPI_Waitany возвращает в index порядковый номер в массиве, где записан заголовок завершенного запроса, и возвращает в status состояние завершенной связи. Объект запроса освобождается и имени запроса присваивается величина MPI_Request_null. MPI_Waitany имеет не локальную семантику завершения.

 

MPI_Waitall (count,&array_of_requests,&array_of_statuses)

count длина списка

array_of_requests массив имен запросов

array_of_statuses массив статусов объектов

MPI_Waitall блокирован до выполнения всех операций, связанных с запросами, записанными в массиве array_of_requests. В массиве array_of_statuses в строке с индексом 1 возвращается статус 1-й операции. Все объекты запросов освобождаются, и соответствующим именам запросов присваивается величина MPI_Request_null. MPI_Waitall имеет не локальную семантику завершения.

Выполнение MPI_Waitall имеет тот же самый эффект, что и выполнение MPI_Wait для i = 0… , count-1 в некотором произвольном порядке.

Когда один или большее количество обменов, законченных запросом к MPI_Waitall терпят неудачу, MPI_Waitall возвратит ошибку, обозначенную константой MPI_Err_in_status и запишет в поле ошибки каждого состояния код ошибки. Этот код будет MPI_Success, если обмен завершился; это будет другой определенный код, если обмен потерпел неудачу; или это будет MPI_Pending, если обмен еще происходит. Функция MPI_Waitall возвратит MPI_Success, если обмен всех операций завершился успешно, или возвратит другой код ошибки, если обмен потерпел неудачу. MPI_Waitall модернизирует поля ошибки объектов состояния только, когда она возвращает MPI_Err_in_status


int MPI_Waitsome (int incount,MPI_Request *array_of_requests, int *outcount, int *array_of_indices, MPI_Status *array_of_statuses)

 

MPI_Waitsome ждет до завершения по крайней мере одной из операций, связанной с запросами в массиве array_of_requests, и возвращает в outcount количество завершенных запросов. В первые outcount элеметнов массива array_of_statuses записаны статусы для этих завершенных операций. Каждый запрос,который окончился, освобождается, и имени запроса присваивается константа MPI_Request_null. MPI_Request имеет не локальную семантику завершения.

Если одна или больше операций, завершенных MPI_Waitsome, не выполнились, то аргументам outcount, array_of_indices, array_of_statuses будут присвоены значения, указывающие на завершение или не завершение операций.

 

 

int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status)

 

request имя запроса

flag если операция выполнилась, то true, иначе false

status статус объекта

 

запрос к MPI_Test возвращает flag = true, если операция, идентифицированная request, выполнилась. В этом случае статус состояния содержит информацию относительно законченной операции. Если объект системы, указанный request, был первоначально создан неблокированными посылающей или получающей функциями, то он освобождается функцией MPI_Test и request устанавливается в MPI_Request_null. Запрос возвращает flag = false, если операция не выполнилась. В этом случае значение статуса состояния неопределенно, т.е. это неблокированная функция. MPI_Test имеет локальную семантику завершения.

 

int MPI_Iprobe (int source, int tag, MPI_Comm comm,int *flag, MPI_Status *status)

int MPI_Probe (int source, int tag, MPI_Comm comm, MPI_Status *status)


Функции MPI_Iprobe и MPI_Probe позволяют опрашивать поступающие сообщения без их фактического получения. Прикладная программа может затем решать, как получить их, основываясь на информации, возвращенной зондом(в переменной status). Например, распределять память для буфера приема согласно длине исследованного сообщения.

MPI_Iprobe – операция неблокированная, возвращает true, если имеется сообщение, к-рое может быть получено и соответствует оболочке сообщения с аргументами source, tag и comm. Запрос соответствует тому же самому сообщению, которое было бы получено запросом к MPI_Recv(с этими аргументами), выполненному в той же самой точке программы, и возвратил бы в статусе объекта(пакета данных) то же самое значение. Иначе запрос возвращает flag = false и неопределенное состояние аргументов.

MPI_Probe – операция блокированная, и возвращается только после того, как соответствующее сообщение было найдено.

 

MPI_Barrier (comm)

 

Синхронизирует все процессы группы

 

MPI_Bcast (&buffer,count,datatype,root,comm)

 

Broadcasts (sends) a message from the process with rank "root" to all other processes in the group.

Передает данные от одного процесса группы с рангом "root" ко всем остальным процессам группы, включая "root"

 

 

MPI_Gather (&sendbuf, sendcnt, sendtype, &recvbuf, recvcount, recvtype, root, comm)

 

Сбор данных от всех процессов группы, включая "root" к одному процессу группы

Каждый процесс(включая процесс корня) посылает содержимое его буфера к процессу корня. Процесс корня получает сообщения и хранит их в порядке рангов посылающих процессов. Результат выглядит так, как будто каждый из n процессов в группе( включая процесс корня ) выполнил запрос к MPI_Send и корень выполнил n запросов к MPI_Recv

 

MPI_Scatter (&sendbuf, sendcnt, sendtype, &recvbuf, recvcnt, recvtype, root, comm)

 

Разброс данных от одного процесса группы ко всем процессам группы, включая "root"

Обратная операция к MPI_Gather. Результат выглядит так, как будто корень выполнил n посылающих операций MPI_Send. И каждый принимающий процесс выполнил функцию MPI_Recv

 

 

int MPI_Allgather (void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount,MPI_Datatype recvtype, MPI_Comm comm)

 

Сбор данных в цикле по всем процессам группы; все элементы группы получают результат от всех

MPI_Allgather аналогична MPI_Gather за исключением того,что все процессы получают результат от всех процессов, а не только от одного корня. j-й блок данных, посланных из каждого процесса, получен каждым процессом и размещается в j-м блоке буфера recvbuf.

Аргументы sendcount и sedntype в процессе должны быть равны во всех процессах. Результат запроса к MPI_Allgather выглядит так, как будто все процессы выполнили n запросов к MPI_Gather

 

int MPI_Alltoall (void *sendbuf, int sendcount,MPI_Datatype sendtype, void *recvbuf, int recvcnt, MPI_Datatype recvtype, MPI_Comm comm)


MPI_Alltoall – это расширение MPI_Allgather для случая, когда каждый процесс посылает различные данные на каждый из приемников. j-й блок, посланный из процесса

Каждый процесс связывается с каждым процессом

 

int MPI_Reduce (void *sendbuf,void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op,int root, MPI_Comm comm)

 

MPI_Reduce объединяет элементы, находящиеся в передаваемом буфере каждого процесса в группе, используя операцию op, и возвращает объединенное значение в буфере приема в процессе с рангом root. Передаваемый и приемный буфер имеют то же самое число элементов с тем же самым типом.

 

 

MPI_Allreduce (&sendbuf,&recvbuf,count,datatype,op,comm)

 

Операция такая же как и MPI_Reduce, исключая то, что результат появляется в буфере приема у всех процессов группы comm.

 

MPI_Reduce_scatter (&sendbuf,&recvbuf,recvcount,datatype,
...... op,comm)

 

MPI_Reduce_scatter действует, как будто она сначала делает поэлементно редукцию на векторе из count = Σi recvcounts[i] элементов в посылающемся буфере, определенном sendbuf, count и datatype. Вектор результатов – это n непересекающихся сегментов, где n – число процессов в группе comm. Сегмент i содержит recvcounts[i] элементов. i-й сегмент посылается процессу i и записывается в буфере приема, определенном recvbuf, recvcount, datatype.

First does an element-wise reduction on a vector across all tasks in the group. Next, the result vector is split into disjoint segments and distributed across the tasks. This is equivalent to an MPI_Reduce followed by an MPI_Scatter operation.

 

 

int MPI_Scan (void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)

 

MPI_Scan используется, чтобы делать префиксное сокращение на данных, распределенных по всей группе. В результате операции в буфере приема процесса с рангом i сокращаение значений в посылающихся буферах процессов с рангами 0, … , i(включительно). Тип поддержанных операций, их семантики и ограничений посылаемого буфера и буфера приема, как в операции MPI_Reduce.

Предопределенные редуцированные операции для MPI_Reduce, MPI_Allreduce, MPI_Reduce_scatter, MPI_Scan. Эти операции вызываются, размещая указанные имена вместо аргумента op.

MPI_MAX максимум

MPI_MIN минимум

MPI_SUM сумма

MPI_PROD произведение

MPI_LAND логическое И

MPI_BAND поразрядное И

MPI_LOR логическое ИЛИ

MPI_BOR поразрядное ИЛИ

MPI_LXOR логическое ИЛИ-НЕ

MPI_BXOR поразрядное ИЛИ-НЕ

MPI_MAXLOC значение максимума и локализация

MPI_MINLOC значение минимума и локализация

Возникновение ошибкиSEEK_SET

ОшибкаSEEK_SETвозникает из-за дублирования #defineSEEK_SETв файлеstdio.hиmpi.h. Для устранения необходимо добавить код:

#undef SEEK_SET

#undef SEEK_CUR

#undef SEEK_END

#include "mpi.h"

 

При этом обьязательно что бы блок #undef следовал строго перед директивой #include "mpi.h", учитывая что #include "mpi.h" является последним из присоеденяемых файлов

Использованная литература

1. Корнеев В.Д. Параллельное программирование в MPI. Новосибирск, 2002, 209 с.

2. Гергель В.П. Теория и практика параллельных вычислений.
БИНОМ. Лаборатория знаний, Интернет-университет информационных технологий - ИНТУИТ.ру, 2007.

3. Воеводин В.В. Курс лекций "Параллельная обработка данных".

4. https://computing.llnl.gov/tutorials/mpi/ High Performance Computing Training. Livermore Computing. Message Passing Interface (MPI)








Дата добавления: 2015-02-03; просмотров: 1043;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.026 сек.