Yet Another eXchange Tool 0.11.1
Loading...
Searching...
No Matches
xt_redist.c
Go to the documentation of this file.
1
12/*
13 * Keywords:
14 * Maintainer: Jörg Behrens <behrens@dkrz.de>
15 * Moritz Hanke <hanke@dkrz.de>
16 * Thomas Jahns <jahns@dkrz.de>
17 * URL: https://dkrz-sw.gitlab-pages.dkrz.de/yaxt/
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met:
22 *
23 * Redistributions of source code must retain the above copyright notice,
24 * this list of conditions and the following disclaimer.
25 *
26 * Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 *
30 * Neither the name of the DKRZ GmbH nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
37 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
38 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 */
46#ifdef HAVE_CONFIG_H
47#include <config.h>
48#endif
49
50#include <limits.h>
51#include <stdbool.h>
52#include <stdlib.h>
53
54#include "core/core.h"
55#include "xt/xt_core.h"
56#include "xt/xt_redist.h"
57#include "xt/xt_mpi.h"
58#include "xt/xt_request.h"
59#include "core/ppm_xfuncs.h"
60#include "xt_redist_internal.h"
61#include "xt_mpi_ddt_cache.h"
62#include "xt_config_internal.h"
63
64
65
66static const char filename[] = "xt_redist.c";
67
69
70 return redist->vtable->copy(redist);
71}
72
74
75 redist->vtable->delete(redist);
76}
77
78void xt_redist_s_exchange(Xt_redist redist, int num_arrays,
79 const void **src_data, void **dst_data) {
80
81 redist->vtable->s_exchange(redist, num_arrays, src_data, dst_data);
82}
83
84void xt_redist_a_exchange(Xt_redist redist, int num_arrays,
85 const void **src_data, void **dst_data,
86 Xt_request *request) {
87
88 redist->vtable->a_exchange(redist, num_arrays, src_data, dst_data, request);
89}
90
91void xt_redist_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data) {
92
93 redist->vtable->s_exchange1(redist, src_data, dst_data);
94}
95
96void xt_redist_a_exchange1(Xt_redist redist, const void *src_data,
97 void *dst_data, Xt_request *request) {
98
99 redist->vtable->a_exchange1(redist, src_data, dst_data, request);
100}
101
103
104 return redist->vtable->get_num_msg(redist, SEND);
105}
106
108
109 return redist->vtable->get_num_msg(redist, RECV);
110}
111
112MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank) {
113
114 return redist->vtable->get_msg_MPI_Datatype(redist, rank, SEND, true);
115}
116
117MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank) {
118
119 return redist->vtable->get_msg_MPI_Datatype(redist, rank, RECV, true);
120}
121
122MPI_Datatype xt_redist_get_MPI_Datatype(Xt_redist redist, int rank,
123 enum xt_msg_direction direction,
124 bool do_dup)
125{
126 return redist->vtable->get_msg_MPI_Datatype(redist, rank, direction, do_dup);
127}
128
130
131 return redist->vtable->get_MPI_Comm(redist);
132}
133
135 int *restrict *ranks)
136{
137 return redist->vtable->get_msg_ranks(redist, direction, ranks);
138}
139
140
141void
142xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm) {
143 int result;
144
145 for (int i = 0; i < num_redists; ++i) {
146
147 if (redists[i] == NULL)
148 Xt_abort(comm, "ERROR: invalid redist; cannot build "
149 "redistribution collection\n", filename, __LINE__);
150
151 xt_mpi_call(MPI_Comm_compare(xt_redist_get_MPI_Comm(redists[i]),
152 comm, &result), comm);
153
154 if ((result != MPI_IDENT) && (result != MPI_CONGRUENT))
155 Xt_abort(comm, "ERROR: MPI communicators do not match; cannot build "
156 "redistribution collection\n", filename, __LINE__);
157 }
158}
159
160static size_t
161xt_ranks_uniq_count(size_t num_rank_sets,
162 const size_t *restrict num_ranks,
163 const int *const ranks[num_rank_sets])
164{
165 size_t rank_pos[num_rank_sets];
166 for (size_t j = 0; j < num_rank_sets; ++j)
167 rank_pos[j] = 0;
168 bool ranks_left;
169 size_t num_messages = 0;
170 do {
171 int min_rank = INT_MAX;
172 /* find minimal rank in list, guaranteed to be smaller than comm_size */
173 for (size_t j = 0; j < num_rank_sets; ++j)
174 if (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] < min_rank)
175 min_rank = ranks[j][rank_pos[j]];
176 ranks_left = false;
177 /* increment list index for all redists matching minimal rank and
178 * see if any ranks are left */
179 for (size_t j = 0; j < num_rank_sets; ++j) {
180 rank_pos[j]
181 += (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank);
182 ranks_left |= (rank_pos[j] < num_ranks[j]);
183 }
184 ++num_messages;
185 } while (ranks_left);
186 return num_messages;
187}
188
189unsigned
190xt_redist_agg_msg_count(size_t num_redists, enum xt_msg_direction direction,
191 const Xt_redist redists[num_redists],
192 size_t num_ranks[num_redists],
193 int *restrict ranks[num_redists],
194 Xt_config config)
195{
196 bool ranks_left = false;
197 /* get lists of ranks to send/receive message to/from */
198 size_t num_ranks_total = 0;
199 for (size_t j = 0; j < num_redists; ++j) {
200 size_t redist_num_ranks
201 = (size_t)(redists[j]->vtable->get_num_msg(redists[j], direction));
202 num_ranks[j] = redist_num_ranks;
203 num_ranks_total += redist_num_ranks;
204 }
205 if (num_ranks_total) {
206 int *ranks_buf = xmalloc(num_ranks_total * sizeof (*ranks_buf));
207 void (*sort_int)(int a[], size_t n) = config->sort_funcs->sort_int;
208 size_t ofs = 0;
209 for (size_t j = 0; j < num_redists; ++j) {
210 ranks[j] = ranks_buf + ofs;
211 size_t nranks
212 = (size_t)xt_redist_get_msg_ranks(redists[j], direction, ranks + j);
213 ranks_left |= (nranks > 0);
214 /* sort list */
215 sort_int(ranks[j], nranks);
216 ofs += nranks;
217 }
218 } else
219 for (size_t j = 0; j < num_redists; ++j)
220 ranks[j] = NULL;
221 /* count number of different ranks to send/receive message to/from */
222 size_t num_messages = ranks_left
223 ? xt_ranks_uniq_count(num_redists, num_ranks, (const int *const *)ranks)
224 : 0;
225 return (unsigned)num_messages;
226}
227
228MPI_Datatype
230 const MPI_Aint displacements[count],
231 const MPI_Datatype datatypes[count],
232 const int block_lengths[count],
233 struct Xt_mpiddt_list *ddt_list,
234 MPI_Comm comm)
235{
236 size_t num_datatypes = 0;
237 /* allocate more than max_auto_dt datatype items from heap */
238 enum { max_auto_dt = 8 };
239 for (size_t i = 0; i < count; ++i)
240 num_datatypes += (datatypes[i] != MPI_DATATYPE_NULL);
241 MPI_Datatype *datatypes_, dt_auto[max_auto_dt];
242 MPI_Aint *displacements_, disp_auto[max_auto_dt];
243 int *block_lengths_, bl_auto[max_auto_dt];
244
245 if (num_datatypes != count) {
246 if (num_datatypes > max_auto_dt) {
247 size_t buf_size = num_datatypes * sizeof(*datatypes_)
248 + num_datatypes * sizeof(*displacements_)
249 + num_datatypes * sizeof(*block_lengths_);
250 displacements_ = xmalloc(buf_size);
251 datatypes_ = (MPI_Datatype *)(displacements_ + num_datatypes);
252 block_lengths_ = (int *)(datatypes_ + num_datatypes);
253 } else {
254 datatypes_ = dt_auto;
255 displacements_ = disp_auto;
256 block_lengths_ = bl_auto;
257 }
258 num_datatypes = 0;
259
260 for (size_t i = 0; i < count; ++i) {
261 if (datatypes[i] != MPI_DATATYPE_NULL) {
262
263 datatypes_[num_datatypes] = datatypes[i];
264 displacements_[num_datatypes] = displacements[i];
265 block_lengths_[num_datatypes] = block_lengths[i];
266 ++num_datatypes;
267 }
268 }
269 } else {
270 datatypes_ = (MPI_Datatype *)datatypes;
271 displacements_ = (MPI_Aint *)displacements;
272 block_lengths_ = (int *)block_lengths;
273 }
274 MPI_Datatype datatype;
275 if (num_datatypes > 1)
277 ddt_list, (int)num_datatypes, block_lengths_,
278 displacements_, datatypes_, comm);
279 else if (displacements_[0] == 0)
280 xt_mpi_call(MPI_Type_dup(datatypes_[0], &datatype), comm);
281 else
283 ddt_list, 1, (int [1]){1}, displacements_, datatypes_[0], comm);
284 xt_mpi_call(MPI_Type_commit(&datatype), comm);
285
286 if (num_datatypes != count && num_datatypes > max_auto_dt)
287 free(displacements_);
288
289 return datatype;
290}
291
292/*
293 * Local Variables:
294 * c-basic-offset: 2
295 * coding: utf-8
296 * indent-tabs-mode: nil
297 * show-trailing-whitespace: t
298 * require-trailing-newline: t
299 * End:
300 */
int MPI_Comm
Definition core.h:64
add versions of standard API functions not returning on error
#define xmalloc(size)
Definition ppm_xfuncs.h:70
const struct Xt_sort_algo_funcptr * sort_funcs
const struct xt_redist_vtable * vtable
void(* sort_int)(int *a, size_t n)
MPI_Datatype(* get_msg_MPI_Datatype)(Xt_redist, int, enum xt_msg_direction, bool need_dup)
Xt_redist(* copy)(Xt_redist)
void(* a_exchange)(Xt_redist, int, const void **, void **, Xt_request *)
void(* s_exchange1)(Xt_redist, const void *, void *)
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)
int MPI_Type_dup(MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_commit(MPI_Datatype *datatype)
implementation of configuration object
base definitions header file
static struct xt_gpu_vtable vtable
Definition xt_gpu.c:75
utility routines for MPI
#define xt_mpi_call(call, comm)
Definition xt_mpi.h:68
MPI_Datatype Xt_mpi_ddt_cache_acquire_hindexed(struct Xt_mpiddt_list *ddt_list, int count, int blocklength[count], MPI_Aint disp[count], MPI_Datatype oldtype, MPI_Comm comm)
MPI_Datatype Xt_mpi_ddt_cache_acquire_struct(struct Xt_mpiddt_list *ddt_list, int count, int blocklength[count], MPI_Aint disp[count], MPI_Datatype oldtype[count], MPI_Comm comm)
MPI_Datatype xt_redist_get_MPI_Datatype(Xt_redist redist, int rank, enum xt_msg_direction direction, bool do_dup)
Definition xt_redist.c:122
MPI_Datatype xt_create_compound_datatype(size_t count, const MPI_Aint displacements[count], const MPI_Datatype datatypes[count], const int block_lengths[count], struct Xt_mpiddt_list *ddt_list, MPI_Comm comm)
Definition xt_redist.c:229
static const char filename[]
Definition xt_redist.c:66
int xt_redist_get_msg_ranks(Xt_redist redist, enum xt_msg_direction direction, int *restrict *ranks)
Definition xt_redist.c:134
MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank)
Definition xt_redist.c:117
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])
Definition xt_redist.c:161
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
Definition xt_redist.c:142
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], Xt_config config)
Definition xt_redist.c:190
MPI_Comm xt_redist_get_MPI_Comm(Xt_redist redist)
Definition xt_redist.c:129
MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank)
Definition xt_redist.c:112
redistribution of data
void xt_redist_delete(Xt_redist redist)
Definition xt_redist.c:73
int xt_redist_get_num_recv_msg(Xt_redist redist)
Definition xt_redist.c:107
int xt_redist_get_num_send_msg(Xt_redist redist)
Definition xt_redist.c:102
void xt_redist_a_exchange1(Xt_redist redist, const void *src_data, void *dst_data, Xt_request *request)
Definition xt_redist.c:96
Xt_redist xt_redist_copy(Xt_redist redist)
Definition xt_redist.c:68
void xt_redist_a_exchange(Xt_redist redist, int num_arrays, const void **src_data, void **dst_data, Xt_request *request)
Definition xt_redist.c:84
void xt_redist_s_exchange(Xt_redist redist, int num_arrays, const void **src_data, void **dst_data)
Definition xt_redist.c:78
void xt_redist_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data)
Definition xt_redist.c:91
redistribution of data, non-public declarations
xt_msg_direction