72 const void **src_data,
void **dst_data) {
113 unsigned char *restrict src_store = (
unsigned char *)src,
114 *restrict dst_store = (
unsigned char *)dst;
115 for (
size_t i = 0; i < n; ++i) {
117 = (
struct Xt_redist_msg *)(
void *)(src_store + i * src_stride),
118 *dst_msg = (
struct Xt_redist_msg *)(
void *)(dst_store + i * dst_stride);
119 dst_msg->
rank = src_msg->rank;
120 xt_mpi_call(MPI_Type_dup(src_msg->datatype, &(dst_msg->datatype)), comm);
127 unsigned char *restrict msgs_store = (
unsigned char *)msgs;
128 for (
size_t i = 0; i < n; ++i) {
130 = &(((
struct Xt_redist_msg *)(
void *)(msgs_store + i * ofs_stride))->datatype);
131 if (*dt != MPI_DATATYPE_NULL)
140 for (
int i = 0; i < num_redists; ++i) {
143 comm, &result), comm);
145 if ((result != MPI_IDENT) && (result != MPI_CONGRUENT))
146 Xt_abort(comm,
"ERROR: MPI communicators do not match; cannot build " 147 "redist_collection_static\n", __FILE__, __LINE__);
153 size_t *restrict num_ranks,
154 const int *ranks[num_rank_sets])
156 size_t rank_pos[num_rank_sets];
157 for (
size_t j = 0; j < num_rank_sets; ++j)
160 size_t num_messages = 0;
162 int min_rank = INT_MAX;
164 for (
size_t j = 0; j < num_rank_sets; ++j)
165 if (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] < min_rank)
166 min_rank = ranks[j][rank_pos[j]];
170 for (
size_t j = 0; j < num_rank_sets; ++j) {
172 += (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank);
173 ranks_left |= (rank_pos[j] < num_ranks[j]);
176 }
while (ranks_left);
182 const MPI_Aint displacements[num_redists],
183 const MPI_Datatype datatypes[num_redists],
184 const int block_lengths[num_redists],
187 size_t num_datatypes = 0;
189 enum { max_auto_dt = 8 };
190 for (
size_t i = 0; i < num_redists; ++i)
191 num_datatypes += (datatypes[i] != MPI_DATATYPE_NULL);
192 MPI_Datatype *datatypes_, dt_auto[max_auto_dt];
193 MPI_Aint *displacements_, disp_auto[max_auto_dt];
194 int *block_lengths_, bl_auto[max_auto_dt];
196 if (num_datatypes != num_redists) {
197 if (num_datatypes > max_auto_dt) {
198 datatypes_ =
xmalloc(num_datatypes *
sizeof(*datatypes_));
199 displacements_ =
xmalloc(num_datatypes *
sizeof(*displacements_));
200 block_lengths_ =
xmalloc(num_datatypes *
sizeof(*block_lengths_));
202 datatypes_ = dt_auto;
203 displacements_ = disp_auto;
204 block_lengths_ = bl_auto;
208 for (
size_t i = 0; i < num_redists; ++i) {
209 if (datatypes[i] != MPI_DATATYPE_NULL) {
211 datatypes_[num_datatypes] = datatypes[i];
212 displacements_[num_datatypes] = displacements[i];
213 block_lengths_[num_datatypes] = block_lengths[i];
218 datatypes_ = (MPI_Datatype *)datatypes;
219 displacements_ = (MPI_Aint *)displacements;
220 block_lengths_ = (
int *)block_lengths;
223 if (num_datatypes > 1)
224 xt_mpi_call(MPI_Type_create_struct((
int)num_datatypes, block_lengths_,
225 displacements_, datatypes_, &datatype),
227 else if (displacements_[0] == 0)
228 xt_mpi_call(MPI_Type_dup(datatypes_[0], &datatype), comm);
230 xt_mpi_call(MPI_Type_create_hindexed(1, (
int [1]){1}, displacements_,
235 if (num_datatypes != num_redists && num_datatypes > max_auto_dt) {
237 free(displacements_);
base definitions header file
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
redistribution of data, non-public declarations
Xt_redist(* copy)(Xt_redist)
MPI_Comm(* get_MPI_Comm)(Xt_redist)
add versions of standard API functions not returning on error
MPI_Datatype(* get_send_MPI_Datatype)(Xt_redist, int)
const struct xt_redist_vtable * vtable
MPI_Datatype(* get_recv_MPI_Datatype)(Xt_redist, int)
MPI_Datatype xt_create_compound_datatype(size_t num_redists, const MPI_Aint displacements[num_redists], const MPI_Datatype datatypes[num_redists], const int block_lengths[num_redists], MPI_Comm comm)
void(* s_exchange1)(Xt_redist, const void *, void *)
void(* s_exchange)(Xt_redist, int, const void **, void **)
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)
void xt_redist_delete(Xt_redist redist)
MPI_Comm xt_redist_get_MPI_Comm(Xt_redist redist)
void(* delete)(Xt_redist)
void xt_redist_msgs_strided_destruct(size_t n, struct Xt_redist_msg *msgs, MPI_Comm comm, size_t ofs_stride)
int xt_redist_get_msg_ranks(Xt_redist redist, enum xt_msg_direction direction, int **ranks)
#define xt_mpi_call(call, comm)
MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank)
int(* get_msg_ranks)(Xt_redist, enum xt_msg_direction, int **)
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)
MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank)
size_t xt_ranks_uniq_count(size_t num_rank_sets, size_t *restrict num_ranks, const int *ranks[num_rank_sets])
Xt_redist xt_redist_copy(Xt_redist redist)