68static const char filename[] =
"xt_exchanger_neigh_alltoall.c";
70#define MAX(a,b) ((a) >= (b) ? (a) : (b))
74 MPI_Comm newComm,
int new_tag_offset);
77 const void * src_data,
80 const void * src_data,
86 int *restrict *ranks);
106 team_share->
ranks = NULL;
108 team_share->
displs = NULL;
119 free(team_share->
ranks);
130 .team_share_default_init
148 void *exchanger_team_share)
150 size_t nmsg = nsend + nrecv;
151 bool need_team_share_alloc = exchanger_team_share == NULL;
154 + (need_team_share_alloc ?
sizeof (*exchanger->
team_share) : 0));
157 if (need_team_share_alloc) {
167 MPI_Datatype *restrict datatypes,
170 for (
size_t i = 0; i < n; ++i)
174 datatypes[i] = msgs[i].datatype;
181 for (
size_t i = 0; i < n; ++i)
182 ranks[i] = msgs[i].rank;
197 xt_mpi_call(MPI_Comm_test_inter(comm, &flag), comm);
199 Xt_abort(comm,
"ERROR(xt_exchanger_neigh_alltoall_new): "
200 "inter-communicator's are not defined for virtual topologies",
203 assert((nsend >= 0) & (nrecv >= 0));
209 copy_dt((
size_t)nrecv, recv_msgs, exchanger->
datatypes + nsend, comm, dt_dup);
213 size_t nmsg = (size_t)nsend + (
size_t)nrecv;
214 size_t max_msgs =
MAX((
size_t)nsend, (
size_t)nrecv);
223 for (
size_t i = 0; i < max_msgs; ++i) {
225 team_share->
displs[i] = 0;
227 enum { no_reorder = 0 };
228#if __GNUC__ >= 11 && __GNUC__ <= 13
231#pragma GCC diagnostic push
232#pragma GCC diagnostic ignored "-Wstringop-overread"
235 MPI_Dist_graph_create_adjacent(
236 comm, nrecv, team_share->
ranks + nsend, MPI_UNWEIGHTED, nsend,
237 team_share->
ranks, MPI_UNWEIGHTED, MPI_INFO_NULL, no_reorder,
239#if __GNUC__ >= 11 && __GNUC__ <= 13
240#pragma GCC diagnostic pop
248 MPI_Comm new_comm,
int new_tag_offset)
250 (void)new_tag_offset;
255 size_t nsend = (size_t)team_share->
nmsg[
SEND],
256 nrecv = (
size_t)team_share->
nmsg[
RECV];
262 *team_share_copy = exchanger_copy->
team_share;
263 size_t nmsg = nsend + nrecv;
264 size_t max_msgs =
MAX(nsend, nrecv);
265 team_share_copy->
nmsg[
SEND] = (int)nsend;
266 team_share_copy->
nmsg[
RECV] = (int)nrecv;
272 memcpy(team_share_copy->
ranks, team_share->
ranks,
274 for (
size_t i = 0; i < max_msgs; ++i) {
276 team_share_copy->
displs[i] = 0;
278#ifndef NEED_MPICH_UNWEIGHTED_COMM_DUP_WORKAROUND
284 enum { no_reorder = 0 };
285#if __GNUC__ >= 11 && __GNUC__ <= 13
288#pragma GCC diagnostic push
289#pragma GCC diagnostic ignored "-Wstringop-overread"
292 MPI_Dist_graph_create_adjacent(
293 new_comm, (
int)nrecv, team_share_copy->
ranks + nsend, MPI_UNWEIGHTED,
294 (
int)nsend, team_share_copy->
ranks, MPI_UNWEIGHTED, MPI_INFO_NULL,
295 no_reorder, &team_share_copy->
nb_comm), new_comm);
296#if __GNUC__ >= 11 && __GNUC__ <= 13
297#pragma GCC diagnostic pop
300 for (
size_t i = 0; i <
nmsg; ++i)
302 exchanger_copy->
datatypes + i), new_comm);
315 + (
size_t)team_share_na->
nmsg[
RECV];
317 for (
size_t i = 0; i <
nmsg; ++i)
327 const void * src_data,
336 MPI_Neighbor_alltoallw(src_data, team_share->
one_counts,
346 const void * src_data,
355#if defined OMPI_MAJOR_VERSION && OMPI_MAJOR_VERSION == 4 \
356 && OMPI_MINOR_VERSION == 0 && OMPI_RELEASE_VERSION == 2
369 size_t nmsg = (size_t)team_share->
nmsg[
SEND] + (
size_t)team_share->
nmsg[
RECV],
371 body_size =
sizeof (MPI_Datatype) * nmsg +
sizeof (int) * nmsg,
372 dt_size = nmsg *
sizeof (MPI_Datatype);
373 body_size = (body_size +
sizeof (MPI_Datatype) - 1)
374 /
sizeof (MPI_Datatype) *
sizeof (MPI_Datatype);
378 header_size + body_size + dt_size);
380 MPI_Datatype *dt_copy
381 = (MPI_Datatype *)(
void *)((
unsigned char *)request_ + header_size + body_size);
382 memcpy(dt_copy, exchanger_na->
datatypes, dt_size);
384 MPI_Ineighbor_alltoallw(src_data, team_share->
one_counts,
385 team_share->
displs, dt_copy,
387 team_share->
displs, dt_copy +
392 MPI_Request tmp_request;
394 MPI_Ineighbor_alltoallw(src_data, team_share->
one_counts,
399 team_share->
nb_comm, &tmp_request),
416 size_t nsend = (size_t)team_share->
nmsg[
SEND],
417 nmsg = (
size_t)team_share->
nmsg[direction],
418 ofs = direction ==
SEND ? 0 : nsend;
419 int *restrict
ranks = team_share->
ranks + ofs;
420 MPI_Datatype datatype_copy = MPI_DATATYPE_NULL;
421 for (
size_t i = 0; i <
nmsg; ++i) {
422 if (
ranks[i] == rank) {
425 &datatype_copy), team_share->
nb_comm);
427 datatype_copy = exchanger_na->
datatypes[i+ofs];
431 return datatype_copy;
437 int *restrict *
ranks)
443 size_t nsend = (size_t)team_share->
nmsg[
SEND],
444 nmsg = (
size_t)team_share->
nmsg[direction],
445 ofs = direction ==
SEND ? 0 : nsend;
446 int *ranks_ = *
ranks;
add versions of standard API functions not returning on error
#define xrealloc(ptr, size)
void * exchanger_team_share
struct xt_exchanger_neigh_alltoall_team_share * team_share
struct xt_exchanger_neigh_alltoall_team_share team_share_[]
const struct xt_exchanger_vtable * vtable
int MPI_Type_free(MPI_Datatype *datatype)
int MPI_Type_dup(MPI_Datatype oldtype, MPI_Datatype *newtype)
static const char filename[]
struct Xt_config_ * Xt_config
implementation of configuration object
exchanging of data based on information provided by redist's
struct Xt_exchanger_ * Xt_exchanger
static void copy_ranks(size_t n, const struct Xt_redist_msg *restrict msgs, int *restrict ranks)
static int xt_exchanger_neigh_alltoall_get_msg_ranks(Xt_exchanger exchanger, enum xt_msg_direction direction, int *restrict *ranks)
Xt_exchanger xt_exchanger_neigh_alltoall_new(int nsend, int nrecv, const struct Xt_redist_msg *send_msgs, const struct Xt_redist_msg *recv_msgs, MPI_Comm comm, int tag_offset, Xt_config config)
struct Xt_exchanger_neigh_alltoall_ * Xt_exchanger_neigh_alltoall
static void xt_exchanger_neigh_alltoall_a_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data, Xt_request *request)
static MPI_Datatype xt_exchanger_neigh_alltoall_get_MPI_Datatype(Xt_exchanger exchanger, int rank, enum xt_msg_direction direction, bool do_dup)
static void xt_exchanger_neigh_alltoall_delete(Xt_exchanger exchanger)
static void xt_exchanger_neigh_alltoall_team_share_destroy(void *share)
static Xt_exchanger xt_exchanger_neigh_alltoall_copy(Xt_exchanger exchanger, MPI_Comm newComm, int new_tag_offset)
static void xt_exchanger_neigh_alltoall_team_share_default_init(void *share)
static void copy_dt(size_t n, const struct Xt_redist_msg *restrict msgs, MPI_Datatype *restrict datatypes, MPI_Comm comm, bool dt_dup)
static void xt_exchanger_neigh_alltoall_s_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data)
const struct xt_exchanger_vtable xt_exchanger_neigh_alltoall_vtable
static Xt_exchanger_neigh_alltoall xt_exchanger_neigh_alltoall_alloc(size_t nsend, size_t nrecv, void *exchanger_team_share)
static struct xt_gpu_vtable vtable
#define xt_mpi_call(call, comm)
redistribution of data, non-public declarations
struct Xt_request_ * Xt_request
Xt_request xt_request_msgs_new(int n, const MPI_Request requests[n], MPI_Comm comm)
exchange map declarations