63static const char filename[] =
"xt_exchanger_simple_base.c";
67 MPI_Comm newComm,
int new_tag_offset);
70 const void * src_data,
73 const void * src_data,
79 int *restrict *ranks);
120 size_t header_size =
sizeof(*exchanger),
121 body_size = nmsg *
sizeof (exchanger->
msgs[0]);
122 exchanger =
xmalloc(header_size + body_size);
130 return r + (r <= comm_rank ? comm_size : 0);
133#define XT_SORTFUNC_DECL static
134#define SORT_TYPE struct Xt_redist_msg
135#define SORT_TYPE_SUFFIX redist_msg
136#define SORT_TYPE_CMP_LT(u,v,i,j) \
137 (adjusted_rank((u).rank, comm_rank, comm_size) \
138 < adjusted_rank((v).rank, comm_rank, comm_size))
139#define SORT_TYPE_CMP_LE(u,v,i,j) \
140 (adjusted_rank((u).rank, comm_rank, comm_size) \
141 <= adjusted_rank((v).rank, comm_rank, comm_size))
142#define SORT_TYPE_CMP_EQ(u,v,i,j) (((u).rank) == ((v).rank))
143#define XT_SORT_EXTRA_ARGS_DECL , int comm_rank, int comm_size
144#define XT_SORT_EXTRA_ARGS_PASS , comm_rank, comm_size
145#define XT_SORT_VECSWAP_EXTRA_ARGS_DECL
146#define XT_SORT_VECSWAP_EXTRA_ARGS_PASS
152 int nsend,
int nrecv,
167 Xt_abort(comm,
"ERROR(xt_exchanger_simple_base_new): invalid synchronous "
168 "exchange function pointer",
filename, __LINE__);
170 assert((nsend >= 0) & (nrecv >= 0));
171 size_t nmsg = (size_t)nsend + (
size_t)nrecv;
174 exchanger->
comm = comm;
180 exchanger->
msgs, sizeof (exchanger->
msgs[0]),
183 exchanger->
msgs + nsend,
184 sizeof (exchanger->
msgs[0]),
186 exchanger->
s_func = s_func;
187 exchanger->
a_func = a_func;
191 int comm_size, comm_rank, is_inter;
192 xt_mpi_call(MPI_Comm_rank(comm, &comm_rank), comm);
193 xt_mpi_call(MPI_Comm_test_inter(comm, &is_inter), comm);
194 int (*get_comm_size)(
MPI_Comm,
int *)
195 = is_inter ? MPI_Comm_remote_size : MPI_Comm_size;
196 xt_mpi_call(get_comm_size(comm, &comm_size), comm);
209 xt_quicksort_redist_msg(exchanger->
msgs, (
size_t)nsend,
210 comm_rank, comm_size);
211 xt_quicksort_redist_msg(exchanger->
msgs + (
size_t)nsend, (
size_t)nrecv,
212 comm_rank, comm_size);
220 MPI_Comm new_comm,
int new_tag_offset)
224 int nsend = exchanger_sb->
nmsg[
SEND],
226 size_t nmsg = (size_t)nsend + (
size_t)nrecv;
235 *restrict orig_msgs = exchanger_sb->
msgs;
237 new_msgs,
sizeof (*new_msgs),
239 exchanger_copy->
comm = new_comm;
250 size_t nmsg = (size_t)exchanger_sb->
nmsg[
SEND] + (
size_t)exchanger_sb->
nmsg[
RECV];
258 const void * src_data,
264 int nsend = exchanger_sb->
nmsg[
SEND];
265 exchanger_sb->
s_func(src_data, dst_data, nsend,
267 exchanger_sb->
msgs + (
size_t)nsend,
272 const void * src_data,
279 if (exchanger_sb->
a_func == NULL)
280 Xt_abort(exchanger_sb->
comm,
"ERROR(xt_exchanger_simple_base_a_exchange): "
281 "asynchronous exchange function not defined for current exchanger",
284 int nsend = exchanger_sb->
nmsg[
SEND];
285 exchanger_sb->
a_func(src_data, dst_data, nsend,
287 exchanger_sb->
msgs + (
size_t)nsend,
299 size_t nsend = (size_t)exchanger_sb->
nmsg[
SEND],
300 nmsg = (
size_t)exchanger_sb->
nmsg[direction],
301 ofs = direction ==
SEND ? 0 : nsend;
303 MPI_Datatype datatype_copy = MPI_DATATYPE_NULL;
304 for (
size_t i = 0; i < nmsg; ++i)
310 datatype_copy = msgs[i].datatype;
313 return datatype_copy;
319 int *restrict *ranks)
322 size_t nmsg = (size_t)exchanger_sb->
nmsg[direction];
324 + (direction ==
RECV ? (size_t)exchanger_sb->
nmsg[
SEND] : 0);
325 int *restrict ranks_ = *ranks;
327 ranks_ = *ranks =
xmalloc(nmsg *
sizeof (*ranks_));
328 for (
size_t i = 0; i < nmsg; ++i)
329 ranks_[i] = msgs[i].
rank;
338 int nsend = exchanger_sb->
nmsg[
SEND];
341 exchanger_sb->
msgs, exchanger_sb->
msgs + nsend, exchanger_sb->
comm);
add versions of standard API functions not returning on error
xt_simple_a_exchange_func a_func
xt_simple_s_exchange_func s_func
xt_simple_create_omp_share_func create_omp_share_func
struct Xt_redist_msg msgs[]
const struct xt_exchanger_vtable * vtable
int MPI_Type_dup(MPI_Datatype oldtype, MPI_Datatype *newtype)
implementation of configuration object
exchanging of data based on information provided by redist's
struct Xt_exchanger_omp_share_ * Xt_exchanger_omp_share
const struct xt_exchanger_vtable xt_exchanger_simple_base_vtable
static void xt_exchanger_simple_base_a_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data, Xt_request *request)
static int adjusted_rank(int r, int comm_rank, int comm_size)
static const char filename[]
Xt_exchanger xt_exchanger_simple_base_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_simple_s_exchange_func s_func, xt_simple_a_exchange_func a_func, xt_simple_create_omp_share_func create_omp_share_func, Xt_config config)
static Xt_exchanger_simple_base xt_exchanger_simple_base_alloc(size_t nmsg)
static int xt_exchanger_simple_base_get_msg_ranks(Xt_exchanger exchanger, enum xt_msg_direction direction, int *restrict *ranks)
static void xt_exchanger_simple_base_delete(Xt_exchanger exchanger)
static Xt_exchanger xt_exchanger_simple_base_copy(Xt_exchanger exchanger, MPI_Comm newComm, int new_tag_offset)
static void xt_exchanger_simple_base_s_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data)
struct Xt_exchanger_simple_base_ * Xt_exchanger_simple_base
static Xt_exchanger_omp_share xt_exchanger_simple_base_create_omp_share(Xt_exchanger exchanger)
static MPI_Datatype xt_exchanger_simple_base_get_MPI_Datatype(Xt_exchanger exchanger, int rank, enum xt_msg_direction direction, bool do_dup)
void(* xt_simple_s_exchange_func)(const void *src_data, void *dst_data, int nsend, int nrecv, const struct Xt_redist_msg *send_msgs, const struct Xt_redist_msg *recv_msgs, int tag_offset, MPI_Comm comm)
void(* xt_simple_a_exchange_func)(const void *src_data, void *dst_data, int nsend, int nrecv, const struct Xt_redist_msg *send_msgs, const struct Xt_redist_msg *recv_msgs, int tag_offset, MPI_Comm comm, Xt_request *request)
Xt_exchanger_omp_share(* xt_simple_create_omp_share_func)(int nsend, int nrecv, const struct Xt_redist_msg *send_msgs, const struct Xt_redist_msg *recv_msgs, MPI_Comm comm)
#define xt_mpi_call(call, comm)
macros to create quicksort implementations
redistribution of data, non-public declarations
PPM_DSO_INTERNAL void xt_redist_msgs_strided_copy(size_t n, const struct Xt_redist_msg *restrict src, size_t src_stride, struct Xt_redist_msg *restrict dst, size_t dst_stride, MPI_Comm comm, bool dt_dup)
PPM_DSO_INTERNAL void xt_redist_msgs_strided_destruct(size_t n, struct Xt_redist_msg *msgs, MPI_Comm comm, size_t ofs_stride)