Reputation: 199
I was wondering if there was a smart way to do this. Let's say I have three nodes, 0, 1, 2. And let's say each node has an array, a0, a1, a2. If the contents of each node is something like
a0 = {0, 1, 2, 1}
a1 = {1, 2, 2, 0}
a2 = {0, 0, 1, 2}
Is there a clever communication pattern so to move each number to it's corresponding node, i.e.
a0 = {0, 0, 0, 0}
a1 = {1, 1, 1, 1}
a2 = {2, 2, 2, 2}
The approach I have in mind, would involve sorting and temporary buffers, but I was wondering if there was a smarter way?
Upvotes: 0
Views: 184
Reputation: 22660
You can use MPI_Alltoallv
for this in the following way:
local_data
(a
) by corresponding node of each element in increasing order.send_displacements
array such that send_displacements[r]
indicates the index of the first element in the local_data
that refers to node r
.send_counts
array such that send_counts[r]
equals the number of elements in local_data
that correspond to node r
. This can be computed send_counts[r] = send_displacements[r+1] - send_displacements[r]
except for the last rank.MPI_Alltoall(send_counts, 1, MPI_INT, recv_counts, 1, MPI_INT, comm)
recv_displacements
such that recv_displacements[r] = sum(recv_counts[r'] for all r' < r)
.recv_data
with sum(recv_counts) elements.MPI_Alltoallv(local_data, send_counts, send_displacements, MPI_INT, recv_data, recv_counts, recv_displacements, MPI_INT, comm)
Upvotes: 2