63 MPI_Comm newComm,
int new_tag_offset);
66 const void * src_data,
102 static Xt_exchanger_mix_isend_irecv
105 Xt_exchanger_mix_isend_irecv exchanger;
106 size_t header_size =
sizeof (*exchanger),
107 body_size =
sizeof (
struct mix_msg) * nmsg;
108 exchanger =
xmalloc(header_size + body_size);
109 exchanger->
n = (int)nmsg;
120 assert((nsend >= 0) & (nrecv >= 0));
121 size_t nmsg = (size_t)nsend + (
size_t)nrecv;
122 Xt_exchanger_mix_isend_irecv exchanger
127 &(msgs[0].
data),
sizeof (msgs[0]), comm);
128 for (
size_t i = 0; i < (size_t)nsend; ++i)
131 &(msgs[nsend].data),
sizeof (msgs[0]), comm);
132 for (
size_t i = 0; i < (size_t)nrecv; ++i)
133 msgs[i + (
size_t)nsend].type =
RECV;
137 for (
size_t i = 1; i < nmsg; ++i) {
139 if ((msgs[i-1].data.rank == msgs[i].data.rank) && (msgs[i].type ==
SEND)) {
141 struct mix_msg temp = msgs[i-1];
153 MPI_Comm new_comm,
int new_tag_offset)
155 Xt_exchanger_mix_isend_irecv exchanger_msr =
157 size_t nmsg = (size_t)exchanger_msr->
n;
158 Xt_exchanger_mix_isend_irecv exchanger_copy
160 exchanger_copy->
comm = new_comm;
161 exchanger_copy->tag_offset = new_tag_offset;
162 struct mix_msg *restrict new_msgs = exchanger_copy->msgs,
163 *restrict orig_msgs = exchanger_msr->
msgs;
165 &new_msgs->data, sizeof (*new_msgs),
167 for (
size_t i = 0; i < nmsg; ++i)
168 new_msgs[i].
type = orig_msgs[i].
type;
175 Xt_exchanger_mix_isend_irecv exchanger_msr =
178 size_t nmsg = (size_t)exchanger_msr->
n;
179 struct mix_msg *restrict msgs = exchanger_msr->
msgs;
187 const void * src_data,
190 Xt_exchanger_mix_isend_irecv exchanger_msr =
193 if (exchanger_msr->
n > 0) {
194 size_t nmsg = (size_t)exchanger_msr->
n;
196 struct mix_msg *restrict msgs = exchanger_msr->
msgs;
198 MPI_Request *requests =
xmalloc(nmsg *
sizeof (*requests));
199 for (
size_t i = 0; i < nmsg; ++i) {
200 typedef int (*ifp)(
void *buf,
int count, MPI_Datatype datatype,
int dest,
201 int tag,
MPI_Comm comm, MPI_Request *request);
202 ifp op = msgs[i].
type ==
SEND ? (ifp)MPI_Isend : (ifp)MPI_Irecv;
203 void *
data = msgs[i].
type ==
SEND ? (
void *)src_data : dst_data;
207 comm, requests+i), comm);
209 xt_mpi_call(MPI_Waitall((
int)nmsg, requests, MPI_STATUSES_IGNORE), comm);
219 Xt_exchanger_mix_isend_irecv exchanger_msr =
221 size_t nmsg = 0, nmsg_all = (size_t)exchanger_msr->
n;
222 const struct mix_msg *restrict msgs = exchanger_msr->
msgs;
223 for (
size_t i = 0; i < nmsg_all; ++i)
224 nmsg += msgs[i].
type == direction;
225 int *restrict ranks_ = *ranks =
xmalloc(nmsg *
sizeof (*ranks_));
226 for (
size_t i = 0, j = (
size_t)-1; i < nmsg_all; ++i)
227 if (msgs[i].
type == direction)
237 Xt_exchanger_mix_isend_irecv exchanger_msr =
239 size_t nmsg = (size_t)exchanger_msr->
n;
240 struct mix_msg *restrict msgs = exchanger_msr->
msgs;
241 MPI_Datatype datatype_copy = MPI_DATATYPE_NULL;
242 for (
size_t i = 0; i < nmsg; ++i)
243 if (msgs[i].
type == direction && msgs[i].
data.
rank == rank) {
245 exchanger_msr->
comm);
248 return datatype_copy;
enum xt_msg_direction type
redistribution of data, non-public declarations
Xt_exchanger xt_exchanger_mix_isend_irecv_new(int nsend, int nrecv, struct Xt_redist_msg *send_msgs, struct Xt_redist_msg *recv_msgs, MPI_Comm comm, int tag_offset)
add versions of standard API functions not returning on error
static const struct xt_exchanger_vtable exchanger_mix_isend_irecv_vtable
static int xt_exchanger_mix_isend_irecv_get_msg_ranks(Xt_exchanger exchanger, enum xt_msg_direction direction, int **ranks)
static Xt_exchanger_mix_isend_irecv xt_exchanger_mix_isend_irecv_alloc(size_t nmsg)
Xt_exchanger(* copy)(Xt_exchanger, MPI_Comm, int)
static Xt_exchanger xt_exchanger_mix_isend_irecv_copy(Xt_exchanger exchanger, MPI_Comm newComm, int new_tag_offset)
static void xt_exchanger_mix_isend_irecv_delete(Xt_exchanger exchanger)
const struct xt_exchanger_vtable * vtable
struct Xt_redist_msg data
void xt_exchanger_internal_optimize(size_t n, void *msgs, size_t msg_type_size, MPI_Comm comm)
void xt_redist_msgs_strided_destruct(size_t n, struct Xt_redist_msg *msgs, MPI_Comm comm, size_t ofs_stride)
static MPI_Datatype xt_exchanger_mix_isend_irecv_get_MPI_Datatype(Xt_exchanger exchanger, int rank, enum xt_msg_direction direction)
struct Xt_exchanger_mix_isend_irecv_ * Xt_exchanger_mix_isend_irecv
exchanging of data based on information provided by redist's
#define xt_mpi_call(call, comm)
void xt_redist_msgs_strided_copy(size_t n, struct Xt_redist_msg *restrict src, size_t src_stride, struct Xt_redist_msg *restrict dst, size_t dst_stride, MPI_Comm comm)
static void xt_exchanger_mix_isend_irecv_s_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data)