74 const void **src_data,
void **dst_data) {
80 const void **src_data,
void **dst_data,
129 int *restrict *ranks)
144 const unsigned char *restrict src_store = (
const unsigned char *)src;
145 unsigned char *restrict dst_store = (
unsigned char *)dst;
146 for (
size_t i = 0; i < n; ++i) {
148 = (
const struct Xt_redist_msg *)(
const void *)(src_store + i * src_stride);
150 = (
struct Xt_redist_msg *)(
void *)(dst_store + i * dst_stride);
151 dst_msg->
rank = src_msg->rank;
159 unsigned char *restrict msgs_store = (
unsigned char *)msgs;
160 for (
size_t i = 0; i < n; ++i) {
162 = &(((
struct Xt_redist_msg *)(
void *)(msgs_store + i * ofs_stride))->datatype);
163 if (*dt != MPI_DATATYPE_NULL)
172 for (
int i = 0; i < num_redists; ++i) {
174 if (redists[i] == NULL)
175 Xt_abort(comm,
"ERROR: invalid redist; cannot build "
176 "redistribution collection\n", __FILE__, __LINE__);
179 comm, &result), comm);
181 if ((result != MPI_IDENT) && (result != MPI_CONGRUENT))
182 Xt_abort(comm,
"ERROR: MPI communicators do not match; cannot build "
183 "redistribution collection\n", __FILE__, __LINE__);
189 const size_t *restrict num_ranks,
190 const int *
const ranks[num_rank_sets])
192 size_t rank_pos[num_rank_sets];
193 for (
size_t j = 0; j < num_rank_sets; ++j)
196 size_t num_messages = 0;
198 int min_rank = INT_MAX;
200 for (
size_t j = 0; j < num_rank_sets; ++j)
201 if (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] < min_rank)
202 min_rank = ranks[j][rank_pos[j]];
206 for (
size_t j = 0; j < num_rank_sets; ++j) {
208 += (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank);
209 ranks_left |= (rank_pos[j] < num_ranks[j]);
212 }
while (ranks_left);
219 size_t num_ranks[num_redists],
220 int *restrict ranks[num_redists])
222 bool ranks_left =
false;
224 for (
size_t j = 0; j < num_redists; ++j) {
225 size_t nranks = num_ranks[j]
227 ranks_left |= (nranks > 0);
232 size_t num_messages = ranks_left
235 return (
unsigned)num_messages;
240 const MPI_Aint displacements[count],
241 const MPI_Datatype datatypes[count],
242 const int block_lengths[count],
245 size_t num_datatypes = 0;
247 enum { max_auto_dt = 8 };
248 for (
size_t i = 0; i < count; ++i)
249 num_datatypes += (datatypes[i] != MPI_DATATYPE_NULL);
250 MPI_Datatype *datatypes_, dt_auto[max_auto_dt];
251 MPI_Aint *displacements_, disp_auto[max_auto_dt];
252 int *block_lengths_, bl_auto[max_auto_dt];
254 if (num_datatypes != count) {
255 if (num_datatypes > max_auto_dt) {
256 datatypes_ =
xmalloc(num_datatypes *
sizeof(*datatypes_));
257 displacements_ =
xmalloc(num_datatypes *
sizeof(*displacements_));
258 block_lengths_ =
xmalloc(num_datatypes *
sizeof(*block_lengths_));
260 datatypes_ = dt_auto;
261 displacements_ = disp_auto;
262 block_lengths_ = bl_auto;
266 for (
size_t i = 0; i < count; ++i) {
267 if (datatypes[i] != MPI_DATATYPE_NULL) {
269 datatypes_[num_datatypes] = datatypes[i];
270 displacements_[num_datatypes] = displacements[i];
271 block_lengths_[num_datatypes] = block_lengths[i];
276 datatypes_ = (MPI_Datatype *)datatypes;
277 displacements_ = (MPI_Aint *)displacements;
278 block_lengths_ = (
int *)block_lengths;
281 if (num_datatypes > 1)
282 xt_mpi_call(MPI_Type_create_struct((
int)num_datatypes, block_lengths_,
283 displacements_, datatypes_, &
datatype),
285 else if (displacements_[0] == 0)
288 xt_mpi_call(MPI_Type_create_hindexed(1, (
int [1]){1}, displacements_,
293 if (num_datatypes != count && num_datatypes > max_auto_dt) {
295 free(displacements_);
add versions of standard API functions not returning on error
const struct xt_redist_vtable * vtable
Xt_redist(* copy)(Xt_redist)
void(* a_exchange)(Xt_redist, int, const void **, void **, Xt_request *)
void(* s_exchange1)(Xt_redist, const void *, void *)
MPI_Datatype(* get_msg_MPI_Datatype)(Xt_redist, int, enum xt_msg_direction)
void(* a_exchange1)(Xt_redist, const void *, void *, Xt_request *)
int(* get_num_msg)(Xt_redist, enum xt_msg_direction)
int(* get_msg_ranks)(Xt_redist, enum xt_msg_direction, int *restrict *)
void(* s_exchange)(Xt_redist, int, const void **, void **)
void(* delete)(Xt_redist)
MPI_Comm(* get_MPI_Comm)(Xt_redist)
base definitions header file
#define xt_mpi_call(call, comm)
MPI_Datatype xt_redist_get_MPI_Datatype(Xt_redist redist, int rank, enum xt_msg_direction direction)
int xt_redist_get_msg_ranks(Xt_redist redist, enum xt_msg_direction direction, int *restrict *ranks)
MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank)
void xt_redist_delete(Xt_redist redist)
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)
int xt_redist_get_num_recv_msg(Xt_redist redist)
static size_t xt_ranks_uniq_count(size_t num_rank_sets, const size_t *restrict num_ranks, const int *const ranks[num_rank_sets])
unsigned xt_redist_agg_msg_count(size_t num_redists, enum xt_msg_direction direction, const Xt_redist redists[num_redists], size_t num_ranks[num_redists], int *restrict ranks[num_redists])
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
int xt_redist_get_num_send_msg(Xt_redist redist)
MPI_Datatype xt_create_compound_datatype(size_t count, const MPI_Aint displacements[count], const MPI_Datatype datatypes[count], const int block_lengths[count], MPI_Comm comm)
void xt_redist_a_exchange1(Xt_redist redist, const void *src_data, void *dst_data, Xt_request *request)
Xt_redist xt_redist_copy(Xt_redist redist)
void xt_redist_msgs_strided_destruct(size_t n, struct Xt_redist_msg *msgs, MPI_Comm comm, size_t ofs_stride)
MPI_Comm xt_redist_get_MPI_Comm(Xt_redist redist)
MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank)
void xt_redist_a_exchange(Xt_redist redist, int num_arrays, const void **src_data, void **dst_data, Xt_request *request)
void xt_redist_s_exchange(Xt_redist redist, int num_arrays, const void **src_data, void **dst_data)
void xt_redist_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data)
redistribution of data, non-public declarations
void(* xt_sort_int)(int *a, size_t n)