Синтаксис функции сборки данных 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 количества, типы данных и смещения не должны приводить к тому, чтобы любая область корневого процесса записывалась бы более одного раза. Такой вызов является неверным.