Int MPI_Probe(int source, int msgtag, MPI_Comm comm, MPI_Status status)




MPI_Init 2

MPI_Finalize 2

MPI_Comm_size 2

MPI_Comm_rank 2

MPI_Wtime 3

MPI_Send 3

MPI_Bsend 3

MPI_Ssend 4

MPI_Rsend 4

MPI_Recv 4

MPI_Get_count 6

MPI_Probe 6

MPI_Isend 6

MPI_Irecv 7

MPI_Wait 7

MPI_Waitall 7

MPI_Waitany 8

MPI_Waitsome 8

MPI_Test 9

MPI_Testall 9

MPI_Testany 9

MPI_Testsome 10

MPI_Iprobe 10

MPI_Send_init 11

MPI_Recv_init 11

MPI_Startall 11

MPI_Sendrecv 12

MPI_Bcast 12

MPI_Gather 13

MPI_Scatter 13

MPI_Allreduce 14

MPI_Reduce 15

MPI_Barrier 15

MPI_Comm_split 15

MPI_Comm_free 16

Список соответствия типов данных для языка С и MPI 16


MPI_Init

int MPI_Init (int *argc, char ***argv)

Инициализация параллельной части программы. Все другие функции MPI могут быть вызваны только после вызова MPI_Init. Необычный тип аргументов MPI_Init предусмотрен для того, чтобы иметь возможность передать всем процессам аргументы функции main. Инициализация параллельной части для каждого приложения должна выполняться только один раз.

MPI_Finalize

Int MPI_Finalize(void)

Завершение параллельной части приложения. Все последующие обращения к любым MPI-функциям, в том числе к MPI_Init, запрещены. К моменту вызова MPI_Finalize каждым процессом программы все действия, требующие его участия в обмене сообщениями, должны быть завершены.

 

Общая схема MPI-программы выглядит так:

main(int argc, char **argv) {

MPI_Init(&argc, &argv);

MPI_Finalize();

}

MPI_Comm_size

int MPI_Comm_size(MPI_Comm comm, int *size)

comm — идентификатор коммуникатора,

size — число процессов в коммуникаторе comm.

Определение общего числа параллельных процессов в коммуникаторе comm. Результат возвращается через параметр size, для чего функции передается адрес этой переменной. Поскольку коммуникатор является сложной структурой, перед ним стоит имя предопределенного типа MPI_Comm, определенного в файле mpi.h.

MPI_Comm_rank

int MPI_Comm_rank (MPI_Comm comm, int *rank)

comm — идентификатор коммуникатора,

out rank — номер процесса в коммуникаторе comm.

Определение номера процесса в коммуникаторе comm. Если функция MPI_Comm_size для того же коммуникатора comm вернула значение size, то значение, возвращаемое функцией MPI_Comm_rank через переменную rank, лежит в диапазоне от 0 до size-1.

MPI_Wtime

Double MPI_Wtime(void)

Эта функция возвращает астрономическое время в секундах (вещественное число), прошедшее с некоторого момента в прошлом. Если некоторый участок программы окружить вызовами данной функции, то разность возвращаемых значений покажет время работы данного участка. Гарантируется, что момент времени, используемый в качестве точки отсчета, не будет изменен за время существования процесса. Заметим, что эта функция возвращает результат своей работы не через параметры, а явным образом.

MPI_Send

int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm)

buf — адрес начала буфера с посылаемым сообщением;

count — число передаваемых элементов в сообщении;

datatype — тип передаваемых элементов;

dest — номер процесса-получателя;

msgtag — идентификатор сообщения;

comm — идентификатор коммуникатора.

 

Блокирующая посылка сообщения с идентификатором msgtag, состоящего из count элементов типа datatype, процессу с номером dest. Все элементы посылаемого сообщения расположены подряд в буфере buf. Значение count может быть нулем. Разрешается передавать сообщение самому себе. Тип передаваемых элементов datatype должен указываться с помощью предопределенных констант типа, например, MPI_INT, MPI_LONG, MPI_SHORT, MPI_LONG_DOUBLE, MPI_CHAR, MPI_UNSIGNED_CHAR, MPI_FLOAT и т.п. для каждого типа данных языков Фортран и Си есть своя константа. Полный список предопределенных имен типов можно найти в файле mpi.h.

MPI_Bsend— передача сообщения с буферизацией. Если прием посылаемого сообщения еще не был инициализирован процессом получателем, то сообщение будет записано в буфер, и произойдет немедленный возврат из функции. Выполнение данной функции никак не зависит от соответствующего вызова функции приема сообщения. Тем не менее, функция может вернуть код ошибки, если места под буфер недостаточно.

MPI_Ssend— передача сообщения с синхронизацией. Выход из данной функции произойдет только тогда, когда прием посылаемого сообщения будет инициализирован процессом-получателем. Таким образом, завершение передачи с синхронизацией говорит не только о возможности повторного использования буфера, но и о гарантированном достижении процессом-получателем точки приема сообщения в программе. Если прием сообщения так же выполняется с блокировкой, то функция MPI_Ssend сохраняет семантику блокирующих вызовов.

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

MPI_Recv

int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int msgtag, MPI_Comm comm, MPI_Status *status)

out buf — адрес начала буфера для приема сообщения;

count — максимальное число элементов в принимаемом сообщении;

datatype — тип элементов принимаемого сообщения;

source — номер процесса-отправителя;

msgtag — идентификатор принимаемого сообщения;

comm — идентификатор коммуникатора;

out status — параметры принятого сообщения.

Прием сообщения с идентификатором msgtag от процесса source с блокировкой. Число элементов в принимаемом сообщении не должно превосходить значения count. Если число принятых элементов меньше значения count, то гарантируется, что в буфере buf изменятся только элементы, соответствующие элементам принятого сообщения. Если нужно узнать точное число элементов в принимаемом сообщении, то можно воспользоваться функцией MPI_Get_count. Блокировка гарантирует, что после возврата из функции все элементы сообщения уже будут приняты и расположены в буфере buf.

Ниже приведен пример программы, в которой нулевой процесс посылает сообщение процессу с номером один и ждет от него ответа. Если программа будет запущена с большим числом процессов, то реально выполнять пересылки все равно станут только нулевой и первый процессы. Остальные процессы после их порождения функцией MPI_Init сразу завершатся, выполнив функцию МРI_Finalize.

#include "mpi.h"

#include <stdio.h>

int main(int argc, char **argv)

{

int numtasks, rank, dest, src, re, tag=l;

char inmsg, outmsg='x';

MPI_Status Stat;

MPI_Init(&argc,&argv);

MPI_Comm_size(MPI_COMM_WORLD,&numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (rank == 0) {

dest = 1;

src = 1;

rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD);

rc = MPI_Recv(&inmsg, 1, MPI_CHAR, src, tag, MPI_COMM_WORLD, &Stat);

}

Else

if (rank == 1) {

dest = 0;

src = 0;

rc = MPI_Recv(&inmsg, 1, MPI_CHAR, src, tag, MPI_COMM_WORLD, &Stat);

rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD);

}

MPI_Finalize();

}

В следующем примере каждый процесс с четным номером посылает сообщение своему соседу с номером на единицу большим. Дополнительно поставлена проверка для процесса с максимальным номером, чтобы он не послал сообщение несуществующему процессу. Показана только схема программы.

#include "mpi.h"

#include <stdio.h> main(int argc, char**argv) {

int me, size;

int SOME_TAG=0;

MPI_Status status;

MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &me); MPI_Comm_size (MPI_COMM_WORLD, &size);

if ((me % 2) == 0) {

if ((me+1) < size) /* посылают все процессы, кроме последнего */

MPI_Send (..., me+1, SOME_TAG, MPI_COMM_WORLD);

}

Else

MPI_Recv (..., me-1, SOME_TAG, MPI_COMM_WORLD, &status);

MPI_Finalize();

}

MPI_Get_count

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

status — параметры принятого сообщения;

datatype — тип элементов принятого сообщения;

out count — число элементов сообщения.

По значению параметра status данная функция определяет число уже принятых (после обращения к MPI_Recv) или принимаемых (после обращения к МРI_Prоbе или MPI_Iprobe) элементов сообщения типа datatype. Данная функция, в частности, необходима для определения размера области памяти, выделяемой для хранения принимаемого сообщения.

MPI_Probe

int MPI_Probe(int source, int msgtag, MPI_Comm comm, MPI_Status status)

source — номер процесса-отправителя или MPIANYSOURCE;

msgtag — идентификатор ожидаемого сообщения или MPI_ANY_TAG;

comm — идентификатор коммуникатора;

out status — параметры найденного подходящего сообщения.

Получение информации о структуре ожидаемого сообщения с блокировкой. Возврата из функции не произойдет до тех пор, пока сообщение с подходящим идентификатором и номером процесса отправителя не будет доступно для получения. Атрибуты доступного сообщения можно определить обычным образом с помощью параметра status. Следует особо обратить внимание на то, что функция определяет только факт прихода сообщения, но реально его не принимает.

MPI_Isend

int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm, MPI_Request *request)

buf — адрес начала буфера c посылаемым сообщением;

count — число передаваемых элементов в сообщении;

datatype — тип передаваемых элементов;

dest — номер процесса-получателя;

msgtag — идентификатор сообщения;

comm — идентификатор коммуникатора,

out request — идентификатор асинхронной операции передачи.

MPI_Irecv

int MPI_Irecv (void *buf, int count, MPI_Datatype datatype, int source, int msgtag, MPI_Comm comm, MPI_Request *request)

OUT buf — адрес начала буфера для приема сообщения.

count — максимальное число элементов в принимаемом сообщении;

datatype — тип элементов принимаемого сообщения;

source — номер процесса-отправителя;

msgtag — идентификатор принимаемого сообщения;

comm — идентификатор коммуникатора;

out request — идентификатор операции асинхронного приема.

MPI_Wait

int MPI_Wait(MPI_Request *request, MPI_Status *status)

Ожидание завершения асинхронной операции, ассоциированной с идентификатором request и запущенной вызовом процедуры MPI_Isend или MPI_Irecv. Пока асинхронная операция не будет завершена, процесс, выполнивший процедуру MPI_Wait, будет заблокирован. Для операции не блокирующего приема определяется параметр status. После выполнения

процедуры идентификатор не блокирующей операции request устанавливается в значение MPI_REQUEST_NULL.

MPI_Waitall

int MPI_Waitall(int count, MPI_Request *requests, MPI_Status *statuses)

count — число идентификаторов асинхронных операций;

requests — идентификаторы операций асинхронного приема или передачи;

out statuses — параметры сообщений.

Выполнение процесса блокируется до тех пор, пока все операции обмена, ассоциированные с указанными идентификаторами, не будут завершены. Если во время одной или нескольких операций обмена возникли ошибки, то поле ошибки в элементах массива statuses будет установлено в соответствующее значение.

Ниже показан пример программы, в которой все процессы обмениваются сообщениями с ближайшими соседями в соответствии с топологией кольца.

#include "mpi.h"

#include <stdio.h>

int main(int argc, char **argv)

{

int numtasks, rank, next, prev, buf[2], tagl=l, tag2=2;

MPI_Request reqs[4];

MPI_Status stats[4];

MPI_Init(&argc,&argv);

MPI_Comm_size(MPI_COMM_WORLD, &numtasks);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

prev = rank - 1;

next = rank + 1;

if (rank == 0) prev = numtasks - 1;

if (rank == (numtasks - 1)) next = 0;

MPI_Irecv(&buf[0], 1, MPI_INT, prev, tagl, MPI_COMM_WORLD, &reqs[0]);

MPI_Irecv(&buf[1], 1, MPI_INT, next, tag2, MPI_COMM_WORLD, &reqs[1]);

MPI_Isend(&rank, 1, MPI_INT, prev, tag2, MPI_COMM_WORLD, &reqs[2]);

MPI_Isend(&rank, 1, MPI_INT, next, tagl, MPI_COMM_WORLD, &reqs[3]);

MPI_Waitall(4, reqs, stats); MPI_Finalize(); }

MPI_Waitany

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

count — число идентификаторов асинхронных операций;

requests — идентификаторы операций асинхронного приема или передачи;

out index — номер завершенной операции обмена;

out status — параметры сообщений.

Выполнение процесса блокируется до тех пор, пока какая-либо асинхронная операция обмена, ассоциированная с указанными идентификаторами, не будет завершена. Если завершились несколько операций, то случайным образом будет выбрана одна из них. Параметр index содержит номер элемента в массиве requests, содержащего идентификатор завершенной операции.

MPI_Waitsome

int MPI_Waitsome(int incount, MPI_Request *requests, int *outcount, int *indexes, MPI_Status *statuses)

incount — число идентификаторов асинхронных операций;

requests — идентификаторы операций асинхронного приема или передачи;

out outcount — число идентификаторов завершившихся операций обмена;

out indexes — массив номеров завершившихся операции обмена;

out statuses — параметры завершившихся сообщений.

Выполнение процесса блокируется до тех пор, пока хотя бы одна из операций обмена, ассоциированных с указанными идентификаторами, не будет завершена. Параметр outcount содержит число завершенных операций, а первые outcount элементов массива indexes содержат номера элементов массива requests с их идентификаторами. Первые outcount элементов массива statuses содержат параметры завершенных операций.

MPI_Test

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

request — идентификатор операции асинхронного приема или передачи;

out flag — признак завершенности операции обмена;

out status — параметры сообщения.

Проверка завершенности асинхронных функций MPI_Isend или MPI_Irecv, ассоциированных с идентификатором request. В параметре flag функция MPI_Test возвращает значение 1, если соответствующая операция завершена, и значение 0 в противном случае. Если завершена процедура приема, то атрибуты и длину полученного сообщения можно определить обычным образом с помощью параметра status.

MPI_Testall

int MPI_Testall(int count, MPI_Request *requests, int *flag, MPI_Status *statuses)

count — число идентификаторов асинхронных операций;

requests — идентификаторы операций асинхронного приема или передачи;

out flag — признак завершенности операций обмена;

out statuses — параметры сообщений.

В параметре flag функция возвращает значение 1, если все операции, ассоциированные с указанными идентификаторами, завершены. В этом случае параметры сообщений будут указаны в массиве statuses. Если какая-либо из операций не завершилась, то возвращается о, и определенность элементов массива statuses не гарантируется.

MPI_Testany

int MPI_Testany(int count, MPI_Request *requests, int *index, int *flag, MPI_Status *status)

count — число идентификаторов асинхронных операций;

requests — идентификаторы операций асинхронного приема или передачи;

out index — номер завершенной операции обмена;

out flag — признак завершенности операции обмена;

out status — параметры сообщения.

Если к моменту вызова функции MPi_Testany хотя бы одна из операций асинхронного обмена завершилась, то в параметре flag возвращается значение 1, index содержит номер соответствующего элемента в массиве requests, *status — параметры сообщения. В противном случае в параметре flag будет возвращено значение 0.

MPI_Testsome

int MPI_Testsome(int incount, MPI_Request *requests, int *outcount, int *indexes, MPI_Status *statuses)

incount — число идентификаторов асинхронных операций;

requests — идентификаторы операций асинхронного приема или передачи;

out outcount — число идентификаторов завершившихся операций обмена;

out indexes —массив номеров завершившихся операции обмена;

out statuses — параметры завершившихся операций.

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

MPI_Iprobe

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

source — номер процесса-отправителя или mpianysource;

msgtag — идентификатор ожидаемого сообщения или MPI_ANY_TAG;

comm — идентификатор коммуникатора;

out flag —признак завершенности операции обмена;

out status — параметры подходящего сообщения.

Получение информации о поступлении и структуре ожидаемого сообщения без блокировки. В параметре flag возвращается значение 1, если сообщение с подходящими атрибутами уже может быть принято (в этом случае ее действие полностью аналогично MPI_Probe), и значение 0, если сообщения с указанными атрибутами еще нет.

MPI_Send_init

int MPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dest, int msgtag, MPI_Comm comm, MPI_Request *request)

buf — адрес начала буфера с посылаемым сообщением;

count — число передаваемых элементов в сообщении;

datatype — тип передаваемых элементов;

dest — номер процесса-получателя;

msgtag — идентификатор сообщения;

comm — идентификатор коммуникатора;

out request — идентификатор асинхронной передачи.

Формирование запроса на выполнение пересылки данных. Все параметры точно такие же, как и у подпрограммы MPI_Isend, однако в отличие от нее пересылка не начинается до вызова подпрограммы MPI_Startall. Как и прежде, дополнительно предусмотрены варианты и для трех модификаций посылки сообщений: MPI_Bsend_init, MPI_Ssend_init, MPI_Rsend_init.

MPI_Recv_init

int MPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int source, int msgtag, MPI_Comm comm, MPI_Request *request)

out buf — адрес начала буфера приема сообщения;

count — число принимаемых элементов в сообщении;

datatype — тип принимаемых элементов;

source — номер процесса-отправителя;

msgtag — идентификатор сообщения;

comm — идентификатор коммуникатора;

out request — идентификатор асинхронного приема.

Формирование запроса на выполнение приема сообщения. Все параметры точно такие же, как и у функции MPI_Irecv, однако в отличие от нее реальный прием не начинается до вызова функции MPI_Startall.

MPI_Startall

int MPI_Startall(int count, MPI_Request *requests)

count — число запросов на взаимодействие;

out requests — массив идентификаторов приема/передачи

Запуск всех отложенных операций передачи и приема, ассоциированных с элементами массива запросов requests и инициированных функциями MPI_Recv_init, MPI_Send_init или ее тремя модификациями. Все отложенные взаимодействия запускаются в режиме без блокировки, а их завершение можно определить обычным образом с помощью функций семейств MPI_Wait и MPI_Test.

MPI_Sendrecv

int MPI_Sendrecv(void *sbuf, int scount, MPI_Datatype stype, int dest, int stag, void *rbuf, int rcount, MPI_Datatype rtype, int source, MPI_Datatype rtag, MPI_Comm comm, MPI_Status *status)

sbuf — адрес начала буфера с посылаемым сообщением;

scount — число передаваемых элементов в сообщении;

stype — тип передаваемых элементов;

dest — номер процесса-получателя;

stag — идентификатор посылаемого сообщения;

out rbuf — адрес начала буфера приема сообщения;

rcount — число принимаемых элементов сообщения;

rtype — тип принимаемых элементов;

source — номер процесса-отправителя;

rtag — идентификатор принимаемого сообщения;

comm — идентификатор коммуникатора;

out status — параметры принятого сообщения.

MPI_Bcast

int MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int source, MPI_Comm comm)

out buf — адрес начала буфера посылки сообщения;

count — число передаваемых элементов в сообщении;

datatype — тип передаваемых элементов;

source — номер рассылающего процесса;

comm — идентификатор коммуникатора.

Рассылка сообщения от процесса source всем процессам данного коммуникатора, включая рассылающий процесс. При возврате из процедуры содержимое буфера buf процесса source будет скопировано в локальный буфер каждого процесса коммуникатора comm. Значения параметров count, datatype, source и comm должны быть одинаковыми у всех процессов. В результате выполнения следующего оператора всеми процессами коммуникатора comm:

MPI_Bcast(&array, 100, MPI_INT, 0, comm);

первые сто целых чисел из массива array нулевого процесса будут скопированы в локальные буфера array каждого процесса коммуникатора comm.

MPI_Gather

int MPI_Gather(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, int dest, MPI_Comm comm)

sbuf — адрес начала буфера посылки;

scount — число элементов в посылаемом сообщении;

stype — тип элементов отсылаемого сообщения;

out rbuf — адрес начала буфера сборки данных;

rcount — число элементов в принимаемом сообщении;

rtype — тип элементов принимаемого сообщения;

dest — номер процесса, на котором происходит сборка данных;

comm — идентификатор коммуникатора.

Сборка данных со всех процессов в буфере rbuf процесса dest. Каждый процесс, включая dest, посылает содержимое своего буфера sbuf процессу dest. Собирающий процесс сохраняет данные в буфере rbuf, располагая их в порядке возрастания номеров процессов. На процессе dest существенными являются значения всех параметров, а на всех остальных процессах — только значения параметров sbuf, scount, stype, dest и comm. Значения параметров dest и comm должны быть одинаковыми у всех процессов. Параметр rcount у процесса dest обозначает число элементов типа rtype, принимаемых не от всех процессов в сумме, а от каждого процесса. С помощью похожей функции MPI_Gatherv можно принимать от процессов массивы данных различной длины.

MPI_Scatter

int MPI_Scatter(void *sbuf, int scount, MPI_Datatype stype, void *rbuf, int rcount, MPI_Datatype rtype, int source, MPI_Comm comm)

sbuf — адрес начала буфера посылки;

scount — число элементов в посылаемом сообщении;

stype — тип элементов отсылаемого сообщения;

out rbuf — адрес начала буфера сборки данных;

rcount — число элементов в принимаемом сообщении;

rtype — тип элементов принимаемого сообщения;

source — номер процесса, на котором происходит сборка данных;

comm — идентификатор коммуникатора.

Функция MPi_Scatter по своему действию является обратной к MPi_Gather. Процесс source рассылает порции данных из массива sbuf всем п процессам приложения. Можно считать, что массив sbuf делится на п равных частей, состоящих из scount элементов типа stype, после чего i -я часть посылается i -му процессу. На процессе source существенными являются значения всех параметров, а на всех остальных процессах — только значения параметров rbuf, rcount, rtype, source и comm. Значения параметров source и comm должны быть одинаковыми у всех процессов. Аналогично функции MPI_Gatherv, с помощью функции MPI_Scatterv процессам можно отослать порции данных различной длины.

В следующем примере показано использование функции MPI_Scatter для рассылки строк массива. Напомним, что в языке Си, в отличие от Фортрана, массивы хранятся в памяти по строкам.

#include "mpi.h"

#include <stdio.h>

#define SIZE 4

int main(int argc, char **argv)

{

int numtasks, rank, sendcount, recvcount, source; float sendbuf[SIZE][SIZE] = { {l.0, 2.0, 3.0, 4.0}, {5.0, 6.0, 7.0, 8.0}, {9.0, 10.0, 11.0, 12.0}, {13.0, 14.0, 15.0, 16.0} };

float recvbuf[SIZE];

MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &numtasks);

if (numtasks == SIZE) { source = 1; sendcount = SIZE;

recvcount = SIZE;



Поделиться:




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

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-06-12 Нарушение авторских прав и Нарушение персональных данных


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