Yet Another eXchange Tool 0.11.4
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 <stdint.h>
53#include <stdlib.h>
54
55#include "core/core.h"
56#include "xt/xt_core.h"
57#include "xt/xt_redist.h"
58#include "xt/xt_mpi.h"
59#include "xt/xt_request.h"
60#include "core/ppm_xfuncs.h"
61#include "xt_redist_internal.h"
62#include "xt_mpi_ddt_cache.h"
63#include "xt_config_internal.h"
64
65
66
67static const char filename[] = "xt_redist.c";
68
70
71 return redist->vtable->copy(redist);
72}
73
75
76 redist->vtable->delete(redist);
77}
78
79void xt_redist_s_exchange(Xt_redist redist, int num_arrays,
80 const void *const src_data[], void *const dst_data[]) {
81
82 redist->vtable->s_exchange(redist, num_arrays, src_data, dst_data);
83}
84
85void xt_redist_a_exchange(Xt_redist redist, int num_arrays,
86 const void *const *src_data, void *const *dst_data,
87 Xt_request *request) {
88
89 redist->vtable->a_exchange(redist, num_arrays, src_data, dst_data, request);
90}
91
92void xt_redist_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data) {
93
94 redist->vtable->s_exchange1(redist, src_data, dst_data);
95}
96
97void xt_redist_a_exchange1(Xt_redist redist, const void *src_data,
98 void *dst_data, Xt_request *request) {
99
100 redist->vtable->a_exchange1(redist, src_data, dst_data, request);
101}
102
104
105 return redist->vtable->get_num_msg(redist, SEND);
106}
107
109
110 return redist->vtable->get_num_msg(redist, RECV);
111}
112
113MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank) {
114
115 return redist->vtable->get_msg_MPI_Datatype(redist, rank, SEND, true);
116}
117
118MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank) {
119
120 return redist->vtable->get_msg_MPI_Datatype(redist, rank, RECV, true);
121}
122
123MPI_Datatype xt_redist_get_MPI_Datatype(Xt_redist redist, int rank,
124 enum xt_msg_direction direction,
125 bool do_dup)
126{
127 return redist->vtable->get_msg_MPI_Datatype(redist, rank, direction, do_dup);
128}
129
131
132 return redist->vtable->get_MPI_Comm(redist);
133}
134
136 int *restrict *ranks)
137{
138 return redist->vtable->get_msg_ranks(redist, direction, ranks);
139}
140
141
142void
143xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm) {
144 int result;
145
146 for (int i = 0; i < num_redists; ++i) {
147
148 if (redists[i] == NULL)
149 Xt_abort(comm, "ERROR: invalid redist; cannot build "
150 "redistribution collection\n", filename, __LINE__);
151
152 xt_mpi_call(MPI_Comm_compare(xt_redist_get_MPI_Comm(redists[i]),
153 comm, &result), comm);
154
155 if ((result != MPI_IDENT) && (result != MPI_CONGRUENT))
156 Xt_abort(comm, "ERROR: MPI communicators do not match; cannot build "
157 "redistribution collection\n", filename, __LINE__);
158 }
159}
160
161static size_t
162xt_ranks_uniq_count(size_t num_rank_sets,
163 const size_t *restrict num_ranks,
164 const int *const ranks[num_rank_sets])
165{
166 size_t rank_pos[num_rank_sets];
167 for (size_t j = 0; j < num_rank_sets; ++j)
168 rank_pos[j] = 0;
169 bool ranks_left;
170 size_t num_messages = 0;
171 do {
172 int min_rank = INT_MAX;
173 /* find minimal rank in list, guaranteed to be smaller than comm_size */
174 for (size_t j = 0; j < num_rank_sets; ++j)
175 if (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] < min_rank)
176 min_rank = ranks[j][rank_pos[j]];
177 ranks_left = false;
178 /* increment list index for all redists matching minimal rank and
179 * see if any ranks are left */
180 for (size_t j = 0; j < num_rank_sets; ++j) {
181 rank_pos[j]
182 += (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank);
183 ranks_left |= (rank_pos[j] < num_ranks[j]);
184 }
185 ++num_messages;
186 } while (ranks_left);
187 return num_messages;
188}
189
190unsigned
191xt_redist_agg_msg_count(size_t num_redists, enum xt_msg_direction direction,
192 const Xt_redist redists[num_redists],
193 size_t num_ranks[num_redists],
194 int *restrict ranks[num_redists],
195 Xt_config config)
196{
197 bool ranks_left = false;
198 /* get lists of ranks to send/receive message to/from */
199 size_t num_ranks_total = 0;
200 for (size_t j = 0; j < num_redists; ++j) {
201 size_t redist_num_ranks
202 = (size_t)(redists[j]->vtable->get_num_msg(redists[j], direction));
203 num_ranks[j] = redist_num_ranks;
204 num_ranks_total += redist_num_ranks;
205 }
206 if (num_ranks_total) {
207 int *ranks_buf = xmalloc(num_ranks_total * sizeof (*ranks_buf));
208 void (*sort_int)(int a[], size_t n) = config->sort_funcs->sort_int;
209 size_t ofs = 0;
210 for (size_t j = 0; j < num_redists; ++j) {
211 ranks[j] = ranks_buf + ofs;
212 size_t nranks
213 = (size_t)xt_redist_get_msg_ranks(redists[j], direction, ranks + j);
214 ranks_left |= (nranks > 0);
215 /* sort list */
216 sort_int(ranks[j], nranks);
217 ofs += nranks;
218 }
219 } else
220 for (size_t j = 0; j < num_redists; ++j)
221 ranks[j] = NULL;
222 /* count number of different ranks to send/receive message to/from */
223 size_t num_messages = ranks_left
224 ? xt_ranks_uniq_count(num_redists, num_ranks,
225 (const int *const *)(intptr_t)ranks)
226 : 0;
227 return (unsigned)num_messages;
228}
229
230MPI_Datatype
232 const MPI_Aint displacements[count],
233 const MPI_Datatype datatypes[count],
234 const int block_lengths[count],
235 struct Xt_mpiddt_list *ddt_list,
236 MPI_Comm comm)
237{
238 size_t num_datatypes = 0;
239 /* allocate more than max_auto_dt datatype items from heap */
240 enum { max_auto_dt = 8 };
241 for (size_t i = 0; i < count; ++i)
242 num_datatypes += (datatypes[i] != MPI_DATATYPE_NULL);
243 MPI_Datatype *datatypes_, dt_auto[max_auto_dt];
244 MPI_Aint *displacements_ = NULL, disp_auto[max_auto_dt];
245 int *block_lengths_, bl_auto[max_auto_dt];
246
247 if (num_datatypes != count) {
248 if (num_datatypes > max_auto_dt) {
249 size_t buf_size = num_datatypes * sizeof(*datatypes_)
250 + num_datatypes * sizeof(*displacements_)
251 + num_datatypes * sizeof(*block_lengths_);
252 displacements_ = xmalloc(buf_size);
253 datatypes_ = (MPI_Datatype *)(displacements_ + num_datatypes);
254 block_lengths_ = (int *)(datatypes_ + num_datatypes);
255 } else {
256 datatypes_ = dt_auto;
257 displacements_ = disp_auto;
258 block_lengths_ = bl_auto;
259 }
260 num_datatypes = 0;
261
262 for (size_t i = 0; i < count; ++i) {
263 if (datatypes[i] != MPI_DATATYPE_NULL) {
264
265 datatypes_[num_datatypes] = datatypes[i];
266 displacements_[num_datatypes] = displacements[i];
267 block_lengths_[num_datatypes] = block_lengths[i];
268 ++num_datatypes;
269 }
270 }
271 datatypes = datatypes_;
272 displacements = displacements_;
273 block_lengths = block_lengths_;
274 }
275 MPI_Datatype datatype;
276 if (num_datatypes > 1)
278 ddt_list, (int)num_datatypes, block_lengths,
279 displacements, datatypes, comm);
280 else if (displacements[0] == 0)
281 xt_mpi_call(MPI_Type_dup(datatypes[0], &datatype), comm);
282 else
284 ddt_list, 1, (int [1]){1}, displacements, datatypes[0], comm);
285 xt_mpi_call(MPI_Type_commit(&datatype), comm);
286
287 if (num_datatypes != count && num_datatypes > max_auto_dt)
288 free(displacements_);
289
290 return datatype;
291}
292
293/*
294 * Local Variables:
295 * c-basic-offset: 2
296 * coding: utf-8
297 * indent-tabs-mode: nil
298 * show-trailing-whitespace: t
299 * require-trailing-newline: t
300 * End:
301 */
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(* s_exchange1)(Xt_redist, const void *, void *)
void(* a_exchange)(Xt_redist, int, const void *const *, void *const *, Xt_request *)
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(* delete)(Xt_redist)
MPI_Comm(* get_MPI_Comm)(Xt_redist)
void(* s_exchange)(Xt_redist, int, const void *const *, void *const *)
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, const int blocklength[count], const 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, const int blocklength[count], const MPI_Aint disp[count], const 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:123
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:231
static const char filename[]
Definition xt_redist.c:67
int xt_redist_get_msg_ranks(Xt_redist redist, enum xt_msg_direction direction, int *restrict *ranks)
Definition xt_redist.c:135
MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank)
Definition xt_redist.c:118
void xt_redist_delete(Xt_redist redist)
Definition xt_redist.c:74
int xt_redist_get_num_recv_msg(Xt_redist redist)
Definition xt_redist.c:108
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:162
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
Definition xt_redist.c:143
int xt_redist_get_num_send_msg(Xt_redist redist)
Definition xt_redist.c:103
void xt_redist_a_exchange1(Xt_redist redist, const void *src_data, void *dst_data, Xt_request *request)
Definition xt_redist.c:97
void xt_redist_a_exchange(Xt_redist redist, int num_arrays, const void *const *src_data, void *const *dst_data, Xt_request *request)
Definition xt_redist.c:85
Xt_redist xt_redist_copy(Xt_redist redist)
Definition xt_redist.c:69
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:191
void xt_redist_s_exchange(Xt_redist redist, int num_arrays, const void *const src_data[], void *const dst_data[])
Definition xt_redist.c:79
MPI_Comm xt_redist_get_MPI_Comm(Xt_redist redist)
Definition xt_redist.c:130
MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank)
Definition xt_redist.c:113
void xt_redist_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data)
Definition xt_redist.c:92
redistribution of data
redistribution of data, non-public declarations
xt_msg_direction