1 1 Коллективные операции

Набор операций типа точка-точка является достаточным для программирования любых алгоритмов, однако MPI вряд ли бы завоевал такую популярность, если бы ограничивался только этим набором коммуникационных операций. Одной из наиболее привлекательных сторон MPI является наличие широкого набора коллективных операций, которые берут на себя выполнение наиболее часто встречающихся при программировании действий. Например, часто возникает потребность разослать некоторую переменную или массив из одного процессора всем остальным. Каждый программист может написать такую процедуру с использованием операций Send/Recv, однако гораздо удобнее воспользоваться коллективной операцией MPI_Bcast. Причем гарантировано, что эта операция будет выполняться гораздо эффективнее, поскольку MPI-функция реализована с использованием внутренних возможностей коммуникационной среды.

Главное отличие коллективных операций от операций типа точка-точка состоит в том, что в них всегда участвуют все процессы, связанные с некоторым коммуникатором. Несоблюдение этого правила приводит либо к аварийному завершению задачи, либо к еще более неприятному зависанию задачи.

Рассмотрим основные функции, определенные для коллективных операций.

Функция синхронизации процессов MPI_Barrier блокирует работу вызвавшего ее процесса до тех пор, пока все другие процессы группы также не вызовут эту функцию. Завершение работы этой функции возможно только всеми процессами одновременно (все процессы "преодолевают барьер" одновременно).

    MPI_BARRIER(COMM, IERROR)
    INTEGER COMM, IERROR
	    
    IN comm - коммуникатор.

Синхронизация с помощью барьеров используется, например, для завершения всеми процессами некоторого этапа решения задачи, результаты которого будут использоваться на следующем этапе. Использование барьера гарантирует, что ни один из процессов не приступит раньше времени к выполнению следующего этапа, пока результат работы предыдущего не будет окончательно сформирован. Неявную синхронизацию процессов выполняет любая коллективная функция.

Широковещательная рассылка данных выполняется с помощью функции MPI_Bcast. Процесс с номером root рассылает сообщение из своего буфера передачи всем процессам области связи коммуникатора comm.

    MPI_BCAST(BUFFER, COUNT, DATATYPE, ROOT, COMM, IERROR)
    <type> BUFFER(*)
    INTEGER COUNT, DATATYPE, ROOT, COMM, IERROR
ТипПараметрОписание
INOUTbufferадрес начала расположения в памяти рассылаемых данных
INcountчисло посылаемых элементов
INdatatypeтип посылаемых элементов
INrootномер процесса-отправителя
INcommкоммуникатор

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

Пример использования функции MPI_Bcast.

   ...
   IF ( MYID .EQ. 0 ) THEN
   PRINT *, 'ВВЕДИТЕ ПАРАМЕТР N : '
   READ *, N
   END IF
   CALL MPI_BCAST(N, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, IERR)

Функция MPI_Gather производит сборку блоков данных, посылаемых всеми процессами группы, в один массив процесса с номером root. Длина блоков предполагается одинаковой. Объединение происходит в порядке увеличения номеров процессов-отправителей. То есть данные, посланные процессом i из своего буфера sendbuf, помещаются в i-ю порцию буфера recvbuf процесса root. Длина массива, в который собираются данные, должна быть достаточной для их размещения.

    MPI_GATHER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF,
  	       RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR)
    <type> SENDBUF(*), RECVBUF(*)
    INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR
ТипПараметрОписание
INsendbufадрес начала размещения посылаемых данных
INsendcountчисло посылаемых элементов
INsendtypeтип посылаемых элементов
OUTrecvbufадрес начала буфера приема (используется только в процессе-получателе root)
INrecvcountчисло элементов, получаемых от каждого процесса (используется только в процессе-получателе root)
INrecvtypeтип получаемых элементов
INrootномер процесса-получателя
INcommкоммуникатор

Тип посылаемых элементов sendtype должен совпадать с типом recvtype получаемых элементов, а число sendcount должно равняться числу recvcount. То есть, recvcount в вызове из процесса root - это число собираемых от каждого процесса элементов, а не общее количество собранных элементов.

Графическая интерпретация операции Gather представлена на следующем рисунке:

MPI_Gather

Функция MPI_Allgather выполняется так же, как MPI_Gather, но получателями являются все процессы группы. Данные, посланные процессом i из своего буфера sendbuf, помещаются в i-ю порцию буфера recvbuf каждого процесса. После завершения операции содержимое буферов приема recvbuf у всех процессов одинаково.

    MPI_ALLGATHER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF,
 	          RECVCOUNT, RECVTYPE, COMM, IERROR)
    <type> SENDBUF(*), RECVBUF(*)
    INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, COMM, IERROR
ТипПараметрОписание
INsendbufадрес начала буфера посылки
INsendcountчисло посылаемых элементов
INsendtypeтип посылаемых элементов
OUTrecvbufадрес начала буфера приема
INrecvcountчисло элементов, получаемых от каждого процесса
INrecvtypeтип получаемых элементов
INcommкоммуникатор

Графическая интерпретация операции Allgater представлена на следующем рисунке. На этой схеме ось Y образуют процессы группы, а ось X блоки данных.

MPI_Allgather

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

    MPI_REDUCE(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, ROOT,
	        COMM, IERROR)
    <type> SENDBUF(*), RECVBUF(*)
    INTEGER COUNT, DATATYPE, OP, ROOT, COMM, IERROR
ТипПараметрОписание
INsendbufадрес начала входного буфера
OUTrecvbufадрес начала буфера результатов (используется только в процессе-получателе root)
INcountчисло элементов во входном буфере
INdatatypeтип элементов во входном буфере
INopоперация, по которой выполняется редукция
INrootномер процесса-получателя результата операции
INcommкоммуникатор

Ниже на рисунке представлена графическая интерпретация операции Reduce. На данной схеме операция "+" означает любую допустимую операцию редукции.

MPI_Reduce

Copyright © 1998-2011 Юрий Сбитнев