next up previous contents
Next: Примеры использования функций MPI_GATHER, Up: Коллективные взаимодействия процессов Previous: Пример использования MPI_BCAST   Contents

Сборка данных

Синтаксис функции сборки данных MPI_GATHER приводится ниже.

MPI_GATHER(sendbuf,sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm)

IN sendbuf начальный адрес буфера процесса-отправителя (альтернатива)
IN sendcount количество элементов в отсылаемом сообщении (целое)
IN sendtype тип элементов в отсылаемом сообщении (дескриптор)
OUT recvbuf начальный адрес буфера процесса сборки данных (альтернатива, существенно только для корневого процесса)
IN recvcount количество элементов в принимаемом сообщении (целое, имеет значение только для корневого процесса)
IN recvtype тип данных элементов в буфере процесса-получателя (дескриптор)
IN root номер процесса-получателя (целое)
IN comm коммуникатор (дескриптор)

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

MPI_GATHER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, RECVTYPE,
ROOT, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT,
SENDTYPE, RECVCOUNT, RECVTYPE, ROOT, COMM, IERROR

void MPI::Intracomm::Gather(const void* sendbuf, int sendcount,
const Datatype& sendtype, void* recvbuf, int recvcount,
const Datatype& recvtype, int root) const

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

MPI_Send(sendbuf, sendcount, sendtype, root, ...), и корневой процесс выполнил n вызовов

MPI_Recv(recvbuf + i * recvcount * extent(recvtype), recvcount, recvtype, i, ...), где extent (recvtype) - размер типа данных, получаемый с помощью MPI_Type_extent().

В общем случае как для sendtype, так и для recvtype разрешены производные типы данных. Сигнатура типа данных sendcount, sendtype у процесса i должна быть такой же, как сигнатура recvcount, recvtype корневого процессе. Это требует, чтобы количество посланных и полученных данных совпадало попарно для корневого и каждого другого процессов. Однако по-прежнему разрешается различие в картах типов между отправителями и получателями.

В корневом процессе используются все аргументы функции, в то время как у остальных процессов используются только аргументы sendbuf, sendcount, sendtype, root, comm. Аргументы comm и root должны иметь одинаковые значения во всех процессах.

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

Отметим, что аргумент recvcount в главном процессе показывает количество элементов, которые он получил от каждого процесса, а не общее количество полученных элементов.

Ниже приводится синтаксис функции MPI_GATHERV, обеспечивающей переменное число посылаемых данных.

MPI_GATHERV(sendbuf,sendcount, sendtype, recvbuf,
recvcounts, displs, recvtype, root, comm)

IN sendbuf начальный адрес буфера процесса-отправителя (альтернатива)
IN sendcount количество элементов в отсылаемом сообщении (целое)
IN sendtype тип элементов в отсылаемом сообщении (дескриптор)
OUT recvbuf начальный адрес буфера процесса сборки данных (альтернатива, существенно только для корневого процесса)
IN recvcounts массив целых чисел (по размеру группы), содержащий количества элементов, которые получены от каждого из процессов (используется только корневым процессом)
IN displs массив целых чисел (по размеру группы). Элемент i определяет смещение относительно recvbuf, в котором размещаются данные из процесса i (используется только корневым процессом)
IN recvtype тип данных элементов в буфере процесса-получателя (дескриптор)
IN root номер процесса-получателя (целое)
IN comm коммуникатор (дескриптор)

int MPI_Gatherv(void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype,
int root, MPI_Comm comm)

MPI_GATHERV(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF,
RECVCOUNTS, DISPLS, RECVTYPE, ROOT, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE,
RECVCOUNTS(*), DISPLS(*), RECVTYPE, ROOT, COMM, IERROR

void MPI::Intracomm::Gatherv(const void* sendbuf, int sendcount,
const Datatype& sendtype, void* recvbuf, const int recvcounts[],
const int displs[], const Datatype& recvtype, int root) const

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

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

MPI_Send(sendbuf, sendcount, sendtype, root, ...), и корневой процесс выполнил бы n операций приема MPI_Recv(recvbuf + displs[i] * extern(recvtype), recvcounts[i], recvtype, i, ...).

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

Сигнатура типа, используемая sendcount, sendtype в процессе i должна быть такой же, как и сигнатура, используемая recvcounts[i], recvtype в корневом процессе. Необходимо, чтобы количество посланных и полученных данных совпадало попарно для корневого и каждого другого процессов. Однако по-прежнему разрешается различие в картах типов между отправителями и получателями, как показано в примере 4.6.

В корневом процессе используются все аргументы функции MPI_GATHERV, а на всех других процессах используются только аргументы sendbuf, sendcount, sendtype, root, comm . Переменные comm и root должны иметь одинаковые значения во всех процессах.

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



Subsections
next up previous contents
Next: Примеры использования функций MPI_GATHER, Up: Коллективные взаимодействия процессов Previous: Пример использования MPI_BCAST   Contents
Alex Otwagin 2002-12-10