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

Функция all-to-all Scatter/Gather

Синтаксис функции All-to-all Scatter/Gather представлен ниже.

MPI_ALLTOALL(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm)

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

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

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

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

MPI_ALLTOALL - это расширение функции MPI_ALLGATHER для случая, когда каждый процесс посылает различные данные каждому получателю. j-й блок, посланный процессом i, принимается процессом j и помещается в i-й блок буфера recvbuf.

Сигнатура типа, связанная с sendcount, sendtype в каждом процессе должна быть такой же, как и в любом другом процессе. Необходимо, чтобы количество посланных данных было равно количеству полученных данных между каждой парой процессов. Как обычно, карты типа могут отличаться.

Результат выполнения функции MPI_ALLTOALL такой же, как если бы каждый процесс выполнил посылку данных каждому процессу (включая себя) вызовом

MPI_Send(sendbuf + i * sendcount * extent(sendtype), sendcount, sendtype, i, ...), и принял данные от всех остальных процессов путем вызова

MPI_Recv(recvbuf + i* recvcount* extent(recvtype), recvcount, i, ...).

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

Синтаксис функции MPI_ALLTOALLV представлен ниже.

MPI_ALLTOALLV(sendbuf,sendcounts,sdispls,sendtype, recvbuf,recvcounts,rdispls,recvtype,comm)

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

int MPI_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls,
MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *rdispls,
MPI_Datatype recvtype, MPI_Comm comm)

MPI_ALLTOALLV(SENDBUF, SENDCOUNTS, SDISPLS, SENDTYPE, RECVBUF, RECVCOUNTS,
RDISPLS, RECVTYPE, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNTS(*), SDISPLS(*), SENDTYPE, RECVCOUNTS(*),
RDISPLS(*), RECVTYPE, COMM, IERROR

void MPI::Intracomm::Alltoallv(const void* sendbuf, const int sendcounts[],
const int sdispls[], const Datatype& sendtype, void* recvbuf,
const int recvcounts[], const int rdispls[], const Datatype& recvtype) const

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

j-й блок, посланный процессом i, принимается процессом j и помещается в i-й блок recvbuf. Эти блоки не обязаны быть одного размера.

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

Результат выполнения MPI_ALLTOALLV такой же, как если бы процесс посылал сообщение всем остальным процессам с помощью функции MPI_Send(sendbuf + displs[i] * extent(sendtype), sendcounts[i], sendtype, i, ...), и принимал сообщение от всех остальных процессов, вызывая

MPI_Recv(recvbuf + displs[i] * extent(recvtype), recvcounts[i], recvtype, i, ...).

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

Объяснение: Определения функций MPI_ALLTOALL и MPI_ALLTOALLV дают столько же гибкости, сколько можно было бы получить, используя n независимых парных межпроцессных обменов, но с двумя исключениями: все сообщения используют один и тот же тип данных, и сообщения разосланы из (или собраны от) непрерывной памяти.[]

Совет разработчикам: Хотя обсуждение коллективных операций с помощью парных обменов подразумевает, что каждое сообщение перемещено непосредственно от процесса-отправителя процессу-получателю, реализации могут использовать древовидную схему связи. Сообщения могут быть посланы промежуточными узлами, где они разделяются (для scatter) или объединяются (для gather), если это более эффективно.[]


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