Yet Another eXchange Tool 0.11.3
Loading...
Searching...
No Matches
xt_redist_collection.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 <assert.h>
51#include <limits.h>
52#include <stdbool.h>
53#include <stdlib.h>
54#include <string.h>
55
56#include <mpi.h>
57
58#include "core/core.h"
59#include "core/ppm_xfuncs.h"
60#include "xt/xt_mpi.h"
61#include "xt_mpi_internal.h"
63#include "ensure_array_size.h"
64#include "xt/xt_redist.h"
65#include "xt/xt_request.h"
66#include "xt_redist_internal.h"
67#include "xt_exchanger.h"
68#include "xt_config_internal.h"
69
70
71
72static const char filename[] = "xt_redist_collection.c";
73
75
76static void
78
79static Xt_redist
81
82static void
83redist_collection_s_exchange(Xt_redist redist, int num_src_arrays,
84 const void *const *src_data,
85 void *const *dst_data);
86
87static void
88redist_collection_a_exchange(Xt_redist redist, int num_src_arrays,
89 const void *const *src_data,
90 void *const *dst_data,
91 Xt_request *request);
92
93static void
95 const void *src_data, void *dst_data);
96
97static void
99 const void *src_data, void *dst_data,
100 Xt_request *request);
101
103 enum xt_msg_direction direction);
104
105static MPI_Datatype
107 enum xt_msg_direction direction, bool do_dup);
108
109static int
111 enum xt_msg_direction direction,
112 int *restrict *ranks);
113
114static MPI_Comm
116
119 .delete = redist_collection_delete,
120 .s_exchange = redist_collection_s_exchange,
121 .a_exchange = redist_collection_a_exchange,
122 .s_exchange1 = redist_collection_s_exchange1,
123 .a_exchange1 = redist_collection_a_exchange1,
124 .get_num_msg = redist_collection_get_num_msg,
125 .get_msg_MPI_Datatype = redist_collection_get_MPI_Datatype,
126 .get_msg_ranks = redist_collection_get_msg_ranks,
127 .get_MPI_Comm = redist_collection_get_MPI_Comm
128};
129
131{
132 size_t token;
133 /* array structure: [cache_size][2][num_redists] */
134 MPI_Aint *displacements;
136};
137
139
141
143
145
147
148 unsigned nmsg[2];
150
154
155 MPI_Datatype all_component_dt[];
156};
157
158static void align_component_dt(unsigned num_redists, unsigned nmsgs,
159 const Xt_redist *redists,
160 int *restrict in_ranks[num_redists],
161 const size_t num_ranks[num_redists],
162 int *out_ranks,
163 MPI_Datatype *component_dt,
164 enum xt_msg_direction direction)
165{
166 size_t rank_pos[num_redists];
167 for (size_t j = 0; j < num_redists; ++j)
168 rank_pos[j] = 0;
169 if (nmsgs) {
170 /* find ranks and corresponding component datatypes */
171 for (size_t i = 0; i < nmsgs; ++i) {
172 int min_rank = INT_MAX;
173 for (size_t j = 0; j < num_redists; ++j)
174 if (rank_pos[j] < num_ranks[j] && in_ranks[j][rank_pos[j]] < min_rank)
175 min_rank = in_ranks[j][rank_pos[j]];
176
177 for (size_t j = 0; j < num_redists; ++j)
178 component_dt[i * num_redists + j] =
179 (rank_pos[j] < num_ranks[j] && in_ranks[j][rank_pos[j]] == min_rank)
180 ? xt_redist_get_MPI_Datatype(redists[j], min_rank, direction, true)
181 : MPI_DATATYPE_NULL;
182
183 out_ranks[i] = min_rank;
184 for (size_t j = 0; j < num_redists; ++j)
185 rank_pos[j]
186 += (rank_pos[j] < num_ranks[j] && in_ranks[j][rank_pos[j]] == min_rank);
187 }
188 }
189 free(in_ranks[0]);
190}
191
192/* not yet used cache entries are marked with -1 as first displacement,
193 * which becomes 0 later on through use */
194static inline void
195init_cache(struct exchanger_cache *cache, size_t cache_size,
196 unsigned num_redists)
197{
198 cache->exchangers = xcalloc(cache_size, sizeof(*(cache->exchangers)));
199 size_t num_displ = cache_size * num_redists;
200 MPI_Aint *restrict q = cache->displacements
201 = xmalloc(2 * num_displ * sizeof (*q));
202 for (size_t i = 0; i < 2 * num_displ; i += num_redists)
203 q[i] = (MPI_Aint)-1;
204 cache->token = 0;
205}
206
207static inline void
209 size_t cache_size)
210{
211 for (size_t i = 0; i < cache_size; ++i)
212 if (cache->exchangers[i] != NULL)
214 free(cache->exchangers);
215 free(cache->displacements);
216}
217
219 int cache_size, MPI_Comm comm)
220{
221 return xt_redist_collection_custom_new(redists, num_redists, cache_size,
223}
224
226alloc_redist_coll(size_t num_redists, size_t nmsg_send, size_t nmsg_recv,
227 Xt_config config, MPI_Comm comm)
228{
229 size_t nmsg = nmsg_recv + nmsg_send,
230 header_size = sizeof (struct Xt_redist_collection_),
231 all_component_dt_size = sizeof (MPI_Datatype) * num_redists * nmsg,
232 ranks_size = nmsg * sizeof (int),
233 team_data_size,
234 own_size = header_size + all_component_dt_size + ranks_size;
235 Xt_exchanger_new exchanger_new = (Xt_exchanger_new)0;
237 exchanger_new
238 = xt_config_get_exchange_new_by_comm(config, comm);
239 team_data_size
240 = xt_exchanger_new_team_get_share_size(exchanger_new);
241 /* round up own size to align beginning of team_data */
242 own_size = ((own_size + team_share_align - 1)
243 / team_share_align) * team_share_align;
244 } else
245 team_data_size = 0;
246 Xt_redist_collection redist_coll
247 = xmalloc(own_size + team_data_size);
248 redist_coll->vtable = &redist_collection_vtable;
249 redist_coll->num_redists = (unsigned)num_redists;
250 redist_coll->nmsg[SEND] = (unsigned)nmsg_send;
251 redist_coll->nmsg[RECV] = (unsigned)nmsg_recv;
252 redist_coll->msg_ranks
253 = (int *)(redist_coll->all_component_dt + nmsg * num_redists);
254 redist_coll->config = *config;
255 /* all mpi datatypes are created for the exclusive use by the
256 * underlying exchanger, no need for dup'ing them */
257 redist_coll->config.flags |= exch_no_dt_dup;
259 redist_coll->config.exchanger_team_share
260 = (unsigned char *)redist_coll + own_size;
261 xt_exchanger_new_team_share_default_init(
262 exchanger_new, redist_coll->config.exchanger_team_share);
263 }
264 return redist_coll;
265}
266
270{
271 // ensure that yaxt is initialized
272 assert(xt_initialized());
273#ifndef NDEBUG
274 if (num_redists > 0) ; else
275 Xt_abort(comm, "ERROR: invalid number of redists passed",
276 "xt_redist_collection_custom_new", __LINE__);
277 if (cache_size >= -1) ; else
278 Xt_abort(comm, "ERROR: invalid cache size in xt_redist_collection_new",
279 filename, __LINE__);
280#endif
281 unsigned num_redists_ = (unsigned)num_redists;
282 size_t num_ranks[2][num_redists_];
283 int *restrict ranks[2][num_redists_];
284 unsigned nmsg_send = xt_redist_agg_msg_count(
285 num_redists_, SEND, redists, num_ranks[SEND], ranks[SEND], config),
286 nmsg_recv = xt_redist_agg_msg_count(
287 num_redists_, RECV, redists, num_ranks[RECV], ranks[RECV], config);
288 int tag_offset;
290 Xt_redist_collection redist_coll
291 = alloc_redist_coll(num_redists_, nmsg_send, nmsg_recv, config, new_comm);
292 redist_coll->cache_size
293 = (cache_size == -1)
294 ?((unsigned)DEFFAULT_DATATYPE_CACHE_SIZE):(unsigned)cache_size;
295
296 redist_coll->comm = new_comm;
297 redist_coll->tag_offset = tag_offset;
298
300
301 MPI_Datatype *all_component_dt = redist_coll->all_component_dt;
302 align_component_dt(num_redists_, nmsg_send, redists,
303 ranks[SEND], num_ranks[SEND], redist_coll->msg_ranks,
305 align_component_dt(num_redists_, nmsg_recv, redists,
306 ranks[RECV], num_ranks[RECV],
307 redist_coll->msg_ranks+nmsg_send,
308 all_component_dt + nmsg_send * num_redists_, RECV);
309 init_cache(&redist_coll->cache, redist_coll->cache_size, num_redists_);
310
311 return (Xt_redist)redist_coll;
312}
313
314
315static void
317 unsigned num_messages, size_t num_redists,
318 const int ranks[num_messages],
319 const MPI_Datatype *component_dt,
320 const MPI_Aint displacements[num_redists],
321 struct Xt_redist_msg redist_msgs[num_messages],
322 struct Xt_mpiddt_list *ddt_list,
324{
325 int block_lengths[num_redists];
326
327 for (size_t i = 0; i < num_redists; ++i)
328 block_lengths[i] = 1;
329 for (size_t i = 0; i < num_messages; ++i) {
330 redist_msgs[i].datatype
332 component_dt + i * num_redists,
333 block_lengths, ddt_list, comm);
334 redist_msgs[i].rank = ranks[i];
335 }
336}
337
338static void
339compute_displ(const void *const *data, unsigned num_redists,
340 MPI_Aint displacements[num_redists])
341{
342 if (num_redists) {
343 MPI_Aint base_addr, offset;
344 base_addr = (MPI_Aint)(intptr_t)(const void *)data[0];
345 displacements[0] = 0;
346 for (size_t i = 1; i < num_redists; ++i) {
347 offset = (MPI_Aint)(intptr_t)(const void *)data[i];
348 displacements[i] = offset - base_addr;
349 }
350 }
351}
352
353static size_t
355 const MPI_Aint displacements[2][num_redists],
356 const MPI_Aint (*cached_displacements)[2][num_redists],
357 size_t cache_size)
358{
359 for (size_t i = 0; i < cache_size &&
360 cached_displacements[i][SEND][0] == (MPI_Aint)0 &&
361 cached_displacements[i][RECV][0] == (MPI_Aint)0; ++i) {
362 bool mismatch = false;
363 for (size_t d = 0; d < 2; ++d)
364 for (size_t j = 0; j < num_redists; ++j)
365 mismatch |= (displacements[d][j] != cached_displacements[i][d][j]);
366 if (!mismatch) return i;
367 }
368 return cache_size;
369}
370
372
373static Xt_exchanger
375 size_t num_redists,
376 MPI_Aint displacements[2][num_redists],
377 struct Xt_redist_msg *msgs)
378{
379 unsigned nmsg_send = redist_coll->nmsg[SEND],
380 nmsg_recv = redist_coll->nmsg[RECV];
381 const MPI_Datatype *all_component_dt = redist_coll->all_component_dt;
382 struct Xt_mpiddt_list ddt_list = Xt_mpiddt_empty_list;
383 MPI_Comm comm = redist_coll->comm;
384 create_all_dt_for_dir(nmsg_send, num_redists,
385 redist_coll->msg_ranks, all_component_dt,
386 displacements[SEND], msgs, &ddt_list, comm);
387 create_all_dt_for_dir(nmsg_recv, num_redists,
388 redist_coll->msg_ranks+nmsg_send,
389 all_component_dt + nmsg_send * num_redists,
390 displacements[RECV],
391 msgs + nmsg_send, &ddt_list, comm);
392 Xt_mpi_ddt_cache_free(&ddt_list, comm);
393 Xt_exchanger_new exchanger_new
394 = xt_config_get_exchange_new_by_comm(&redist_coll->config, comm);
395 return exchanger_new((int)nmsg_send, (int)nmsg_recv,
396 msgs, msgs + nmsg_send, comm, redist_coll->tag_offset,
397 &redist_coll->config);
398}
399
400
401static Xt_exchanger
403 const void *const * src_data, const void *const * dst_data,
404 unsigned num_redists)
405{
406 MPI_Aint displacements[2][num_redists];
407 unsigned nmsg_send = redist_coll->nmsg[SEND],
408 nmsg_recv = redist_coll->nmsg[RECV];
409 compute_displ(src_data, num_redists, displacements[SEND]);
410 compute_displ(dst_data, num_redists, displacements[RECV]);
411
412 Xt_exchanger exchanger;
413
414 struct exchanger_cache *restrict cache = &redist_coll->cache;
415 size_t cache_size = redist_coll->cache_size,
416 cache_index = 0;
417 if (cache_size > 0)
418 {
419 cache_index
420 = lookup_cache_index(num_redists,
421 (const MPI_Aint (*)[num_redists])displacements,
422 (const MPI_Aint (*)[2][num_redists])
423 cache->displacements,
424 cache_size);
425
426 if (cache_index != cache_size)
427 return cache->exchangers[cache_index];
428
429 cache_index = cache->token;
430 cache->token = (cache_index + 1) % cache_size;
431 memcpy(cache->displacements + cache_index * 2 * num_redists,
432 displacements, sizeof (displacements));
433
434 if (cache->exchangers[cache_index] != NULL)
435 xt_exchanger_delete(cache->exchangers[cache_index]);
436 }
437 size_t nmsg = (size_t)nmsg_send + nmsg_recv;
438 struct Xt_redist_msg *restrict p = xmalloc(nmsg * sizeof (*p));
439
440 exchanger =
441 create_exchanger(redist_coll, num_redists, displacements, p);
442 free(p);
443 if (cache_size > 0)
444 cache->exchangers[cache_index] = exchanger;
445 return exchanger;
446}
447
448static inline Xt_redist_collection
449xrc(void *redist)
450{
451 return (Xt_redist_collection)redist;
452}
453
454static void
456 const void *const *src_data,
457 void *const *dst_data)
458{
459 Xt_redist_collection redist_coll = xrc(redist);
460
461 if (num_arrays != (int)redist_coll->num_redists)
462 Xt_abort(redist_coll->comm, "ERROR: wrong number of arrays in "
463 "redist_collection_s_exchange", filename, __LINE__);
464
465
466 Xt_exchanger exchanger = get_exchanger(redist_coll,
467 src_data,
468 (const void *const (*))dst_data,
469 redist_coll->num_redists);
470
471 xt_exchanger_s_exchange(exchanger, src_data[0], dst_data[0]);
472
473 if (redist_coll->cache_size == 0)
474 xt_exchanger_delete(exchanger);
475}
476
477static void
479 const void *const *src_data, void *const *dst_data,
480 Xt_request *request) {
481
482 Xt_redist_collection redist_coll = xrc(redist);
483
484 if (num_arrays != (int)redist_coll->num_redists)
485 Xt_abort(redist_coll->comm, "ERROR: wrong number of arrays in "
486 "redist_collection_a_exchange", filename, __LINE__);
487
488
489 Xt_exchanger exchanger = get_exchanger(redist_coll,
490 src_data,
491 (const void *const (*))dst_data,
492 redist_coll->num_redists);
493
494 xt_exchanger_a_exchange(exchanger, src_data[0], dst_data[0], request);
495
496 if (redist_coll->cache_size == 0)
497 xt_exchanger_delete(exchanger);
498
499}
500
501static void
502copy_component_dt(size_t num_component_dt,
503 const MPI_Datatype *component_dt_orig,
504 MPI_Datatype *component_dt_copy,
505 MPI_Comm comm)
506{
507 for (size_t i = 0; i < num_component_dt; ++i)
508 {
509 MPI_Datatype orig_dt = component_dt_orig[i];
510 if (orig_dt != MPI_DATATYPE_NULL)
511 xt_mpi_call(MPI_Type_dup(orig_dt, component_dt_copy + i), comm);
512 else
513 component_dt_copy[i] = orig_dt;
514 }
515}
516
517static Xt_redist
519
520static Xt_redist
522{
523 Xt_redist_collection redist_coll = xrc(redist);
524 unsigned nmsg_send = redist_coll->nmsg[SEND],
525 nmsg_recv = redist_coll->nmsg[RECV];
526 size_t nmsg = (size_t)nmsg_recv + nmsg_send;
527 struct Xt_config_ config = redist_coll->config;
528 /* if redist comes with an integrated team share, cause creation of
529 * a new one */
530 void *team_share = config.exchanger_team_share;
531 if ((unsigned char *)team_share > (unsigned char *)redist_coll
532 && (unsigned char *)team_share <
533 (unsigned char *)(redist_coll->msg_ranks + nmsg) + team_share_align)
534 config.exchanger_team_share = NULL;
535 return redist_collection_custom_copy(redist, &config);
536}
537
538static Xt_redist
540{
541 Xt_redist_collection redist_coll = xrc(redist);
542 unsigned num_redists = redist_coll->num_redists,
543 nmsg_send = redist_coll->nmsg[SEND],
544 nmsg_recv = redist_coll->nmsg[RECV];
545 size_t nmsg = (size_t)nmsg_recv + nmsg_send;
546 int tag_offset;
547 MPI_Comm copy_comm
548 = xt_mpi_comm_smart_dup(redist_coll->comm, &tag_offset);
549 Xt_redist_collection redist_copy
550 = alloc_redist_coll(num_redists, nmsg_send, nmsg_recv, config, copy_comm);
551 redist_copy->comm = copy_comm;
552 redist_copy->tag_offset = tag_offset;
553
554 memcpy(redist_copy->msg_ranks, redist_coll->msg_ranks,
555 sizeof (*redist_copy->msg_ranks) * nmsg);
556 copy_component_dt(num_redists * nmsg,
557 redist_coll->all_component_dt,
558 redist_copy->all_component_dt, copy_comm);
559 unsigned cache_size = redist_coll->cache_size;
560 redist_copy->cache_size = cache_size;
561 init_cache(&redist_copy->cache, cache_size, num_redists);
562 return (Xt_redist)redist_copy;
563}
564
565static void
566free_component_dt(size_t num_dt, MPI_Datatype *all_component_dt, MPI_Comm comm)
567{
568 for (size_t i = 0; i < num_dt; ++i)
569 if (all_component_dt[i] != MPI_DATATYPE_NULL)
570 xt_mpi_call(MPI_Type_free(all_component_dt + i), comm);
571}
572
573static void
575
576 Xt_redist_collection redist_coll = xrc(redist);
577
578 unsigned num_redists = redist_coll->num_redists;
579 size_t nmsg = (size_t)redist_coll->nmsg[RECV] + redist_coll->nmsg[SEND];
580 free_component_dt(nmsg * num_redists, redist_coll->all_component_dt,
581 redist_coll->comm);
582
583 destruct_cache(&redist_coll->cache, redist_coll->cache_size);
584
585 void *team_share = redist_coll->config.exchanger_team_share;
586 if ((unsigned char *)team_share > (unsigned char *)redist_coll
587 && (unsigned char *)team_share
588 < (unsigned char *)(redist_coll->msg_ranks + nmsg) + team_share_align) {
591 redist_coll->comm);
593 }
594 xt_mpi_comm_smart_dedup(&(redist_coll->comm), redist_coll->tag_offset);
595
596 free(redist_coll);
597}
598
600 enum xt_msg_direction direction)
601{
602 return (int)(xrc(redist)->nmsg[direction]);
603}
604
605static MPI_Datatype
607 enum xt_msg_direction XT_UNUSED(direction),
608 bool XT_UNUSED(do_dup))
609{
610 Xt_redist_collection redist_coll = xrc(redist);
611
612 Xt_abort(redist_coll->comm, "ERROR: datatype retrieval is not"
613 " supported for this xt_redist type (Xt_redist_collection)",
614 filename, __LINE__);
615
616 return MPI_DATATYPE_NULL;
617}
618
619static void
621 const void *src_data, void *dst_data)
622{
623
624 Xt_redist_collection redist_coll = xrc(redist);
625 if (redist_coll->num_redists == 1)
626 redist_collection_s_exchange(redist, 1, &src_data, &dst_data);
627 else
628 Xt_abort(redist_coll->comm, "ERROR: s_exchange1 is not implemented for"
629 " this xt_redist type (Xt_redist_collection)", filename, __LINE__);
630}
631
632static void
634 const void *src_data, void *dst_data,
635 Xt_request *request)
636{
637
638 Xt_redist_collection redist_coll = xrc(redist);
639 if (redist_coll->num_redists == 1)
640 redist_collection_a_exchange(redist, 1, &src_data, &dst_data, request);
641 else
642 Xt_abort(redist_coll->comm, "ERROR: a_exchange1 is not implemented for"
643 " this xt_redist type (Xt_redist_collection)", filename, __LINE__);
644}
645
646static int
648 enum xt_msg_direction direction,
649 int *restrict *ranks)
650{
651 Xt_redist_collection redist_coll = xrc(redist);
652 unsigned nmsg_direction = redist_coll->nmsg[direction],
653 nmsg_send = redist_coll->nmsg[SEND];
654 size_t nmsg = (size_t)nmsg_direction + redist_coll->nmsg[!direction];
655 int *ranks_orig
656 = (int *)(redist_coll->all_component_dt + nmsg * redist_coll->num_redists)
657 + (((unsigned)direction-1) & nmsg_send);
658 if (nmsg_direction > 0) {
659 int *ranks_ = *ranks;
660 if (!ranks_)
661 ranks_ = *ranks = xmalloc(nmsg_direction * sizeof (*ranks_));
662 memcpy(ranks_, ranks_orig, nmsg_direction * sizeof (*ranks));
663 }
664 return (int)nmsg_direction;
665}
666
667
668static MPI_Comm
670
671 Xt_redist_collection redist_coll = xrc(redist);
672
673 return redist_coll->comm;
674}
675
676/*
677 * Local Variables:
678 * c-basic-offset: 2
679 * coding: utf-8
680 * indent-tabs-mode: nil
681 * show-trailing-whitespace: t
682 * require-trailing-newline: t
683 * End:
684 */
int MPI_Comm
Definition core.h:64
#define XT_UNUSED(x)
Definition core.h:84
add versions of standard API functions not returning on error
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:68
#define xmalloc(size)
Definition ppm_xfuncs.h:70
Xt_exchanger_new exchanger_new
void * exchanger_team_share
const struct xt_redist_vtable * vtable
struct exchanger_cache cache
Xt_exchanger * exchangers
int MPI_Type_free(MPI_Datatype *datatype)
int MPI_Type_dup(MPI_Datatype oldtype, MPI_Datatype *newtype)
static const char filename[]
Definition xt_config.c:76
Xt_exchanger_new xt_config_get_exchange_new_by_comm(Xt_config config, MPI_Comm comm)
Definition xt_config.c:158
struct Xt_config_ xt_default_config
Definition xt_config.c:204
struct Xt_config_ * Xt_config
Definition xt_config.h:58
implementation of configuration object
@ exch_no_dt_dup
int xt_initialized(void)
struct Xt_redist_ * Xt_redist
Definition xt_core.h:86
void xt_exchanger_s_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data)
void xt_exchanger_a_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data, Xt_request *request)
void xt_exchanger_delete(Xt_exchanger exchanger)
exchanging of data based on information provided by redist's
@ team_share_align
struct Xt_exchanger_ * Xt_exchanger
PPM_DSO_INTERNAL void xt_exchanger_new_team_share_destroy(Xt_exchanger_new exchanger_new, void *share)
Xt_exchanger(* Xt_exchanger_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_config config)
MPI_Comm xt_mpi_comm_smart_dup(MPI_Comm comm, int *tag_offset)
Definition xt_mpi.c:333
void xt_mpi_comm_smart_dedup(MPI_Comm *comm, int tag_offset)
Definition xt_mpi.c:386
utility routines for MPI
#define xt_mpi_call(call, comm)
Definition xt_mpi.h:68
void Xt_mpi_ddt_cache_free(struct Xt_mpiddt_list *ddt_list, MPI_Comm comm)
#define Xt_mpiddt_empty_list
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
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
Definition xt_redist.c:143
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
redistribution of data
static void init_cache(struct exchanger_cache *cache, size_t cache_size, unsigned num_redists)
static size_t lookup_cache_index(unsigned num_redists, const MPI_Aint displacements[2][num_redists], const MPI_Aint(*cached_displacements)[2][num_redists], size_t cache_size)
static void copy_component_dt(size_t num_component_dt, const MPI_Datatype *component_dt_orig, MPI_Datatype *component_dt_copy, MPI_Comm comm)
Xt_redist xt_redist_collection_new(Xt_redist *redists, int num_redists, int cache_size, MPI_Comm comm)
static Xt_exchanger create_exchanger(struct Xt_redist_collection_ *redist_coll, size_t num_redists, MPI_Aint displacements[2][num_redists], struct Xt_redist_msg *msgs)
static MPI_Comm redist_collection_get_MPI_Comm(Xt_redist redist)
static const struct xt_redist_vtable redist_collection_vtable
struct Xt_redist_collection_ * Xt_redist_collection
static void compute_displ(const void *const *data, unsigned num_redists, MPI_Aint displacements[num_redists])
static Xt_redist_collection alloc_redist_coll(size_t num_redists, size_t nmsg_send, size_t nmsg_recv, Xt_config config, MPI_Comm comm)
static void redist_collection_a_exchange1(Xt_redist redist, const void *src_data, void *dst_data, Xt_request *request)
static Xt_exchanger get_exchanger(struct Xt_redist_collection_ *redist_coll, const void *const *src_data, const void *const *dst_data, unsigned num_redists)
static void redist_collection_a_exchange(Xt_redist redist, int num_src_arrays, const void *const *src_data, void *const *dst_data, Xt_request *request)
static void align_component_dt(unsigned num_redists, unsigned nmsgs, const Xt_redist *redists, int *restrict in_ranks[num_redists], const size_t num_ranks[num_redists], int *out_ranks, MPI_Datatype *component_dt, enum xt_msg_direction direction)
static Xt_redist redist_collection_copy(Xt_redist redist)
static void redist_collection_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data)
static void redist_collection_delete(Xt_redist redist)
static int redist_collection_get_msg_ranks(Xt_redist redist, enum xt_msg_direction direction, int *restrict *ranks)
static void destruct_cache(struct exchanger_cache *cache, size_t cache_size)
static Xt_redist redist_collection_custom_copy(Xt_redist redist, Xt_config config)
static void redist_collection_s_exchange(Xt_redist redist, int num_src_arrays, const void *const *src_data, void *const *dst_data)
@ DEFFAULT_DATATYPE_CACHE_SIZE
static int redist_collection_get_num_msg(Xt_redist redist, enum xt_msg_direction direction)
static void free_component_dt(size_t num_dt, MPI_Datatype *all_component_dt, MPI_Comm comm)
static Xt_redist_collection xrc(void *redist)
Xt_redist xt_redist_collection_custom_new(Xt_redist *redists, int num_redists, int cache_size, MPI_Comm comm, Xt_config config)
static void create_all_dt_for_dir(unsigned num_messages, size_t num_redists, const int ranks[num_messages], const MPI_Datatype *component_dt, const MPI_Aint displacements[num_redists], struct Xt_redist_msg redist_msgs[num_messages], struct Xt_mpiddt_list *ddt_list, MPI_Comm comm)
@ redist_msg_stack_alloc_lim
static MPI_Datatype redist_collection_get_MPI_Datatype(Xt_redist redist, int rank, enum xt_msg_direction direction, bool do_dup)
redistribution of data, non-public declarations
xt_msg_direction
struct Xt_request_ * Xt_request
Definition xt_request.h:51