Синтаксис функции 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), если это более эффективно.[]