- •Федеральное агентство по атомной энергии
- •Национальный исследовательский ядерный университет «мифи»
- •Средства разработки параллельных приложений на общей и распределенной памяти в стандарте интерфейса передачи данных mpi и openmp c реализации курс лекций
- •Void main(int argc, char *argv[] ){
- •Int rank, size;
- •Int mpi_Send(void* buf, int count, mpi_Datatype datatype, int dest, int tag, mpi_Comm comm)
- •Int mpi_Get_count(mpi_Status *status, mpi_Datatype datatype, int *count)
- •Стандартный режим передачи
- •Буферизующий режим передачи
- •1. Барьерная синхронизация - mpi_Barrier (comm)
- •2. Широковещательная передача
- •3. Сбор данных
- •4. Рассылка данных
- •5. Операции редукции (обработки данных)
- •Непрерывный.
- •2. Вектор
- •Int mpi_Type_hvector(int count, int blocklength, int stride, mpi_Datatype oldtype,
- •4. Индексированные данные
- •6. Структурный
- •3. Mpi_Group_translate_ranks (mpi_Group group1, int n, int *ranks1, mpi_Group group2, int *ranks2)
- •4. Mpi_Group _compare(group1, group2, result)
- •6. Mpi_Group _excl(group, n, ranks, newgroup)
- •1. Mpi_Comm_size (comm, size)
- •2. Mpi_Comm_rank(comm, rank)
- •3. Mpi_Comm_compare(comm1, comm2, result)
- •1. Mpi_Comm_dup(comm, newcomm)
- •2. Mpi_Comm_create(comm, group, newcomm)
- •3. Mpi_Comm_split(comm, color, key, newcomm)
- •1. Mpi_Cart_create(mpi_Comm comm_old, int ndims, int *dims, int *periods, int reorder, mpi_Comm *comm_cart)
- •2. Mpi_Dims_create(int nnodes, int ndims, int *dims)
- •1. Mpi_Cartdim_get(mpi_Comm comm, int *ndims)
- •2. Mpi_Cart_get(mpi_Comm comm, int maxdims, int *dims, int *periods, int *coords)
- •3. Int mpi_Cart_rank(mpi_Comm comm, int *coords, int *rank)
- •4. Int mpi_Cart_coords(mpi_Comm comm, int rank, int maxdims, int *coords)
- •5. Координаты декартова сдвига
- •Int mpi_Graph_create(mpi_Comm comm_old, int nnodes, int *index, int *edges, int reorder, mpi_Comm *comm_graph)
- •Int mpi_Topo_test(mpi_Comm comm, int *status)
- •Default(shared | none)
- •Void main()
- •Void main()
- •Int a[10], b[10], c[10]; // целочисленные массивы
- •2. Оператор sections
- •3. Оператор single
- •Void main()
- •10. Функция omp_get_nested
- •Int omp_get_nested(void)
1. Барьерная синхронизация - mpi_Barrier (comm)
IN comm коммуникатор (дескриптор)
Функция MPI_Barrier блокирует вызывающий ее процесс, пока все процессы группы не вызовут ее. В каждом процессе управление возвращается только тогда, когда все процессы в группе вызовут эту процедуру.
2. Широковещательная передача
Функция MPI_Bcast посылает сообщение из одного процесса всем процессам группы, включая себя.
MPI_Bcast(buffer, count, datatype, root, comm )
IN/OUT buffer адрес начала буфера
IN count количество записей в буфере (целое)
IN datatype тип данных в буфере
IN root номер корневого процесса (целое)
IN comm коммуникатор
3. Сбор данных
MPI_Gather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, int root, comm);
IN sendbuf начальный адрес буфера передачи сообщения
IN sendcount количество элементов в отсылаемом сообщении (целое)
IN sendtype тип элементов в отсылаемом сообщении
OUT recvbuf начальный адрес буфера сборки данных (исп-ся только корневым проц.)
IN recvcount колич. элем-ов в принимаемом сообщении (исп-ся только корневым проц.)
IN recvtype тип элементов в получаемом сообщения на процессе-получателе
IN root номер процесса-получателя (целое)
IN comm коммуникатор (дескриптор)
При выполнении операции сборки данных MPI_Gather каждый процесс, включая корневой, посылает содержимое своего буфера в корневой процесс. Корневой процесс получает сообщения и располагает их в порядке возрастания номеров процессов.
Выполнение MPI_Gather будет давать такой же результат, как если бы каждый из n процессов группы (включая корневой процесс) выполнил вызов MPI_Send (sendbuf, sendcount, sendtype, root, …), а принимающий процесс выполнил n вызовов MPI_Recv(recvbuf + i * recvcount * extent(recvtype), recvcount, recvtype, i, …)
Количество посланных и полученных данных должно совпадать, т.е. sendcount== recvcount. Аргумент recvcount в главном процессе показывает количество элементов, которые он получил от каждого процесса, а не общее количество полученных элементов.
В корневом процессе используются все аргументы функции, на остальных процессах используются только аргументы sendbuf, sendcount, sendtype, root, comm. Аргументы comm и root должны иметь одинаковые значения во всех процессах.
MPI_Gatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm)
IN sendbuf начальный адрес буфера отправителя
IN sendcount количество элементов в отсылаемом сообщении (целое)
IN sendtype тип элементов в отсылаемом сообщении
OUT recvbuf адрес буфера процесса сборки данных (существ-но для корневого процесса)
IN recvcounts массив цел. чисел (gsize), содержит количество элементов, полученных от каждого процесса (используется корневым процессом)
IN displs массив целых чисел (gsize). Эл-нт i определяет смещение относит. recvbuf, в котором размещаются данные из процесса i (исп-ся корневым процессом)
IN recvtype тип данных элементов в буфере процесса-получателя
IN root номер процесса-получателя (целое)
IN comm коммуникатор
MPI_Gatherv имеет аналогичные параметры, за исключением int* recvcounts и int*displs – это массивы целых чисел, размеры которых равны размеру группы (числу процессов).
В отличие от MPI_Gather при использовании функции MPI_Gatherv разрешается принимать от каждого процесса переменное число элементов данных, поэтому в функции MPI_Gatherv аргумент recvcounts является массивом. Если Вы выполняете операцию вне ветки какого-либо процесса, значение sendcount будет одно для всех процессов в группе. Для того, чтобы процессы могли выполнить операцию с различным sendcount функцию надо вызывать в каждой ветке, определяющей код процесса, правильно определяя значения элементов массива recvcounts на корневом процессе.
Выполнение MPI_Gatherv будет давать такой же результат, как если бы каждый процесс, включая корневой, посылал корневому процессу сообщение: MPI_Send(sendbuf, sendcount, sendtype, root, …), а принимающий процесс выполнил n операций приема: MPI_Recv(recvbuf+displs[i]*extern(recvtype), recvcounts[i], recvtype, i, …).
Сообщения помещаются в буфер принимающего процесса в порядке возрастания номеров процессов, от которых они приходят, то есть данные, посланные процессом i, помещаются в i-ю часть принимающего буфера recvbuf на корневом процессе. i-я часть recvbuf начинается со смещения displs[i].
В принимающем процессе используются все аргументы функции MPI_Gatherv, а на всех других процессах используются только аргументы sendbuf, sendcount, sendtype, root, comm. Переменные comm и root должны иметь одинаковые значения во всех процессах.