Yet Another eXchange Tool 0.11.1
Loading...
Searching...
No Matches
xt_redist_p2p.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 <stdlib.h>
51#include <stdio.h>
52#include <assert.h>
53
54#include <mpi.h>
55
56#include "xt/xt_mpi.h"
57#include "xt_mpi_internal.h"
58#include "xt/xt_redist_p2p.h"
59#include "xt_redist_internal.h"
61#include "xt/xt_xmap.h"
62#include "xt/xt_idxlist.h"
63#include "core/ppm_xfuncs.h"
64#include "core/core.h"
65#include "xt_config_internal.h"
66
67#include "xt_arithmetic_util.h"
68
69#include "xt_mpi_ddt_cache.h"
70
71/* the following two functions fullfil the same purpose as
72 * xt_disp2ext and xt_disp2ext_count but work with an indirection */
73static size_t
74xt_mdisp2ext_count(size_t disp_len, const int *disp, const int *pos)
75{
76 if (!disp_len) return 0;
77 size_t i = 0;
78 int cur_stride = 1, cur_size = 1;
79 int last_disp = disp[pos[0]];
80 for (size_t p = 1; p < disp_len; ++p) {
81 int new_disp = disp[pos[p]];
82 int new_stride = new_disp - last_disp;
83 if (cur_size == 1) {
84 cur_stride = new_stride;
85 cur_size = 2;
86 } else if (new_stride == cur_stride) {
87 // cur_size >= 2:
88 cur_size++;
89 } else if (cur_size > 2 || (cur_size == 2 && cur_stride == 1) ) {
90 // we accept small contiguous vectors (nstrides==2, stride==1)
91 i++;
92 cur_stride = 1;
93 cur_size = 1;
94 } else { // cur_size == 2, next offset doesn't match current stride
95 // break up trivial vec:
96 i++;
97 cur_size = 2;
98 cur_stride = new_stride;
99 }
100 last_disp = new_disp;
101 }
102 // tail cases:
103 if (cur_size > 2 || (cur_size == 2 && cur_stride == 1)) {
104 i++;
105 } else if (cur_size == 2) {
106 i+=2;
107 } else { // cur_size == 1
108 i++;
109 }
110
111 return i;
112}
113
114static size_t
115xt_mdisp2ext(size_t disp_len, const int *disp, const int *pos,
116 struct Xt_offset_ext *restrict v)
117{
118 if (disp_len<1) return 0;
119
120 int cur_start = disp[pos[0]], cur_stride = 1, cur_size = 1;
121 int last_disp = cur_start;
122 size_t i = 0;
123 for (size_t p = 1; p < disp_len; ++p) {
124 int new_disp = disp[pos[p]];
125 int new_stride = new_disp - last_disp;
126 if (cur_size == 1) {
127 cur_stride = new_stride;
128 cur_size = 2;
129 } else if (new_stride == cur_stride) {
130 // cur_size >= 2:
131 cur_size++;
132 } else if (cur_size > 2 || (cur_size == 2 && cur_stride == 1) ) {
133 // we accept small contiguous vectors (nstrides==2, stride==1)
134 v[i] = (struct Xt_offset_ext){ .start = cur_start, .stride = cur_stride,
135 .size = cur_size };
136 i++;
137 cur_start = new_disp;
138 cur_stride = 1;
139 cur_size = 1;
140 } else { // cur_size == 2, next offset doesn't match current stride
141 // break up trivial vec:
142 v[i].start = cur_start;
143 v[i].size = 1;
144 v[i].stride = 1;
145 i++;
146 cur_start += cur_stride;
147 cur_size = 2;
148 cur_stride = new_stride;
149 }
150 last_disp = new_disp;
151 }
152 // tail cases:
153 if (cur_size > 2 || (cur_size == 2 && cur_stride == 1)) {
154 v[i] = (struct Xt_offset_ext){ .start = cur_start, .stride = cur_stride,
155 .size = cur_size };
156 i++;
157 } else if (cur_size == 2) {
158 v[i].start = cur_start;
159 v[i].size = 1;
160 v[i].stride = 1;
161 i++;
162 v[i].start = cur_start + cur_stride;
163 v[i].size = 1;
164 v[i].stride = 1;
165 i++;
166 } else { // cur_size == 1
167 v[i].start = cur_start;
168 v[i].size = 1;
169 v[i].stride = 1;
170 i++;
171 }
172
173 return i;
174}
175
176
177static MPI_Datatype
178generate_datatype(const int *transfer_pos, int num_transfer_pos,
179 const int *offsets,
180 size_t *vsize, struct Xt_offset_ext **v,
181 struct Xt_mpi_strp_prs_params *params)
182{
183 struct Xt_offset_ext *v_ = *v;
184 size_t vlen;
185 if (offsets != NULL) {
186 vlen = xt_mdisp2ext_count((size_t)num_transfer_pos, offsets, transfer_pos);
187 if (vlen > *vsize) {
188 *v = v_ = xrealloc(v_, sizeof(*v_) * vlen);
189 *vsize = vlen;
190 }
191 xt_mdisp2ext((size_t)num_transfer_pos, offsets, transfer_pos, v_);
192 } else {
193 vlen = xt_disp2ext_count((size_t)num_transfer_pos, transfer_pos);
194 if (vlen > *vsize) {
195 *v = v_ = xrealloc(v_, sizeof(*v_) * vlen);
196 *vsize = vlen;
197 }
198 xt_disp2ext((size_t)num_transfer_pos, transfer_pos, v_);
199 }
200
201 MPI_Datatype type = xt_mpi_parse_stripe(vlen, v_, params);
202 return type;
203}
204
205static void
206generate_msg_infos(int num_msgs, Xt_xmap_iter iter, const int *offsets,
207 struct Xt_redist_msg *msgs,
208 struct Xt_mpi_strp_prs_params *params) {
209
210 if (num_msgs > 0) {
211 size_t vsize = 0;
212 struct Xt_offset_ext *v = NULL;
213 struct Xt_redist_msg *restrict curr_msg = msgs;
214 do {
215
216 const int *curr_transfer_pos = xt_xmap_iterator_get_transfer_pos(iter);
217 int curr_num_transfer_pos = xt_xmap_iterator_get_num_transfer_pos(iter);
218
219 curr_msg->datatype
220 = generate_datatype(curr_transfer_pos, curr_num_transfer_pos,
221 offsets, &vsize, &v, params);
222 curr_msg->rank = xt_xmap_iterator_get_rank(iter);
223
224 curr_msg++;
225 } while (xt_xmap_iterator_next(iter));
226 free(v);
227 }
228}
229
231xt_redist_p2p_off_new(Xt_xmap xmap, const int *src_offsets,
232 const int *dst_offsets, MPI_Datatype datatype)
233{
234 return xt_redist_p2p_off_custom_new(xmap, src_offsets, dst_offsets, datatype,
236}
237
239xt_redist_p2p_off_custom_new(Xt_xmap xmap, const int *src_offsets,
240 const int *dst_offsets, MPI_Datatype datatype,
241 Xt_config config) {
242 // ensure that yaxt is initialized
243 assert(xt_initialized());
244
245 int nsend = xt_xmap_get_num_destinations(xmap),
246 nrecv = xt_xmap_get_num_sources(xmap);
247 size_t nmsg = (size_t)nsend + (size_t)nrecv;
248 struct Xt_redist_msg *msgs = xmalloc(nmsg * sizeof (*msgs)),
249 *send_msgs = msgs, *recv_msgs = msgs + nsend;
250 int tag_offset;
251 MPI_Comm comm
253
254 struct Xt_mpi_strp_prs_params params;
255 xt_init_mpi_strp_prs_params(&params, datatype, comm);
256 Xt_xmap_iter dst_iter = xt_xmap_get_in_iterator(xmap);
257 generate_msg_infos(nrecv, dst_iter, dst_offsets, recv_msgs, &params);
258 if (dst_iter) xt_xmap_iterator_delete(dst_iter);
259
260 Xt_xmap_iter src_iter = xt_xmap_get_out_iterator(xmap);
261 generate_msg_infos(nsend, src_iter, src_offsets, send_msgs, &params);
262 if (src_iter) xt_xmap_iterator_delete(src_iter);
263 Xt_mpi_ddt_cache_check_retention(&params.ddt_list, nmsg, msgs);
265
266 struct Xt_config_ config_ = *config;
267 config_.flags |= exch_no_dt_dup;
268
270 nsend, nrecv, send_msgs, recv_msgs, comm, &config_);
271
272 free(msgs);
273 xt_mpi_comm_smart_dedup(&comm, tag_offset);
274 return result;
275}
276
277/* ====================================================================== */
278
279static inline int
280pos2disp(int pos, int num_ext, const int psum_ext_size[])
281{
282 int j = 0;
283 /* FIXME: use bsearch if linear search is too slow, i.e. num_ext >> 1000 */
284 /* what extent covers the pos'th position? */
285 while (j < num_ext && pos >= psum_ext_size[j + 1])
286 ++j;
287 return j;
288}
289
290static inline int
291pos2disp2(int pos, int num_ext,
292 const int psum_ext_size[], int start_ext)
293{
294 int j = start_ext;
295 if (pos < psum_ext_size[j + 1] && pos >= psum_ext_size[j])
296 ;
297 else if (pos < psum_ext_size[j + 1])
298 {
299 j = 0;
300 while (j < start_ext && pos >= psum_ext_size[j + 1])
301 ++j;
302 }
303 else
304 while (j < num_ext && pos >= psum_ext_size[j + 1])
305 ++j;
306 return j;
307}
308
309#define XT_EXT_TYPE struct Xt_offset_ext
310#define XT_EXT_TAG ext
311#define XT_MPI_PARSE_STRIPE xt_mpi_parse_stripe
312#define XT_EXT_STRIDE_MASK isign_mask_current_pos_ext_size
313#define XT_EXT_STRIDE_MASK_PREP
314#include "xt_redist_p2p_ext.h"
315#undef XT_EXT_TYPE
316#undef XT_EXT_TAG
317#undef XT_MPI_PARSE_STRIPE
318#undef XT_EXT_STRIDE_MASK
319#undef XT_EXT_STRIDE_MASK_PREP
320
321#define XT_EXT_TYPE struct Xt_aoffset_ext
322#define XT_EXT_TAG aext
323#define XT_MPI_PARSE_STRIPE xt_mpi_parse_astripe
324#define XT_EXT_STRIDE_MASK asign_mask_current_pos_ext_size
325#define XT_EXT_STRIDE_MASK_PREP MPI_Aint asign_mask_current_pos_ext_size \
326 = asign_mask(current_pos_ext.size)
327#include "xt_redist_p2p_ext.h"
328#undef XT_EXT_TYPE
329#undef XT_EXT_TAG
330#undef XT_MPI_PARSE_STRIPE
331#undef XT_EXT_STRIDE_MASK
332#undef XT_EXT_STRIDE_MASK_PREP
333
334
335/* ====================================================================== */
336
337static inline void
338aux_gen_simple_block_offsets(int block_offsets[], const int block_sizes[],
339 size_t num_blocks) {
340
341 if (num_blocks > 0) {
342 int accum = 0;
343 for (size_t i = 0; i < num_blocks; ++i) {
344 block_offsets[i] = accum;
345 accum += block_sizes[i];
346 }
347 }
348}
349
350static MPI_Datatype
351generate_block_datatype(const int *transfer_pos, int num_transfer_pos,
352 const int *block_offsets, const int *block_sizes,
353 struct Xt_mpi_strp_prs_params *params) {
354
355 assert(block_sizes && block_offsets);
356
357 int *bdispl_vec = xmalloc(2 * (size_t)num_transfer_pos * sizeof(*bdispl_vec)),
358 *blen_vec = bdispl_vec + num_transfer_pos;
359
360 for (int i = 0; i < num_transfer_pos; ++i) {
361 int j = transfer_pos[i];
362 bdispl_vec[i] = block_offsets[j];
363 blen_vec[i] = block_sizes[j];
364 }
365
366 MPI_Datatype type
367 = xt_mpi_ddt_block_gen(num_transfer_pos, bdispl_vec, blen_vec, params);
368
369 free(bdispl_vec);
370
371 return type;
372}
373
374static void
376 const int *block_offsets,
377 const int *block_sizes, int **aux_offsets,
378 size_t num_blocks,
379 struct Xt_mpi_strp_prs_params *params,
380 struct Xt_redist_msg *msgs) {
381
382 if (num_msgs > 0) {
383
384 const int *block_offsets_;
385 if (block_offsets)
386 block_offsets_ = block_offsets;
387 else {
388 block_offsets_ = *aux_offsets
389 = xrealloc(*aux_offsets, num_blocks * sizeof(*block_offsets_));
390 aux_gen_simple_block_offsets(*aux_offsets, block_sizes, num_blocks);
391 }
392
393 size_t ofs = 0;
394 do {
395 const int *curr_transfer_pos = xt_xmap_iterator_get_transfer_pos(iter);
396 int curr_num_transfer_pos = xt_xmap_iterator_get_num_transfer_pos(iter);
397 msgs[ofs].datatype
398 = generate_block_datatype(curr_transfer_pos, curr_num_transfer_pos,
399 block_offsets_, block_sizes, params);
400 msgs[ofs].rank = xt_xmap_iterator_get_rank(iter);
401
402 ofs++;
403 } while (xt_xmap_iterator_next(iter));
404
405 }
406}
407
410 const int *src_block_offsets,
411 const int *src_block_sizes,
412 int src_block_num,
413 const int *dst_block_offsets,
414 const int *dst_block_sizes,
415 int dst_block_num,
416 MPI_Datatype datatype)
417{
419 xmap, src_block_offsets, src_block_sizes, src_block_num, dst_block_offsets,
420 dst_block_sizes, dst_block_num, datatype, (Xt_config)&xt_default_config);
421}
422
423
426 const int *src_block_offsets,
427 const int *src_block_sizes,
428 int src_block_num,
429 const int *dst_block_offsets,
430 const int *dst_block_sizes,
431 int dst_block_num,
432 MPI_Datatype datatype,
433 Xt_config config)
434{
435 // ensure that yaxt is initialized
436 assert(xt_initialized() && src_block_sizes && dst_block_sizes);
437
438 int tag_offset;
439 MPI_Comm comm
441
442
443 int nsend = xt_xmap_get_num_destinations(xmap),
444 nrecv = xt_xmap_get_num_sources(xmap);
445
446 size_t nmsg = ((size_t)nsend + (size_t)nrecv);
447 struct Xt_redist_msg *msgs = xmalloc(nmsg * sizeof (*msgs));
448
449 int *aux_offsets = NULL;
450
451 Xt_xmap_iter dst_iter = xt_xmap_get_in_iterator(xmap),
452 src_iter = xt_xmap_get_out_iterator(xmap);
453
454 // dst part:
455#ifndef NDEBUG
456 int max_dst_pos = xt_xmap_get_max_dst_pos(xmap);
457 if (dst_block_num < max_dst_pos)
458 die("xt_redist_p2p_blocks_off_new: dst_block_num too small");
459#endif
460 struct Xt_mpi_strp_prs_params params;
461 xt_init_mpi_strp_prs_params(&params, datatype, comm);
462 generate_block_msg_infos(nrecv, dst_iter, dst_block_offsets, dst_block_sizes,
463 &aux_offsets, (size_t)dst_block_num,
464 &params, msgs);
465 if (dst_iter) xt_xmap_iterator_delete(dst_iter);
466
467 // src part:
468#ifndef NDEBUG
469 int max_src_pos = xt_xmap_get_max_src_pos(xmap);
470 if (src_block_num < max_src_pos)
471 die("xt_redist_p2p_blocks_off_new: src_block_num too small");
472#endif
473 generate_block_msg_infos(nsend, src_iter, src_block_offsets, src_block_sizes,
474 &aux_offsets, (size_t)src_block_num,
475 &params, msgs+nrecv);
477 free(aux_offsets);
478
479 if (src_iter) xt_xmap_iterator_delete(src_iter);
480
481 struct Xt_config_ config_ = *config;
482 config_.flags |= exch_no_dt_dup;
483
484 Xt_redist result
486 nsend, nrecv, msgs+nrecv, msgs, comm, &config_);
487
488 free(msgs);
489 xt_mpi_comm_smart_dedup(&comm, tag_offset);
490 return result;
491}
492
494 const int *src_block_sizes,
495 int src_block_num,
496 const int *dst_block_sizes,
497 int dst_block_num,
498 MPI_Datatype datatype)
499{
501 xmap, src_block_sizes, src_block_num, dst_block_sizes, dst_block_num,
502 datatype, (Xt_config)&xt_default_config);
503}
504
507 const int *src_block_sizes, int src_block_num,
508 const int *dst_block_sizes, int dst_block_num,
509 MPI_Datatype datatype,
510 Xt_config config)
511{
513 xmap, NULL, src_block_sizes, src_block_num,
514 NULL, dst_block_sizes, dst_block_num, datatype, config);
515}
516
517
518Xt_redist xt_redist_p2p_new(Xt_xmap xmap, MPI_Datatype datatype)
519{
520 return xt_redist_p2p_custom_new(xmap, datatype,
522}
523
525xt_redist_p2p_custom_new(Xt_xmap xmap, MPI_Datatype datatype, Xt_config config)
526{
527 return xt_redist_p2p_off_custom_new(xmap, NULL, NULL, datatype, config);
528}
529
530/*
531 * Local Variables:
532 * c-basic-offset: 2
533 * coding: utf-8
534 * indent-tabs-mode: nil
535 * show-trailing-whitespace: t
536 * require-trailing-newline: t
537 * End:
538 */
int MPI_Comm
Definition core.h:64
#define die(msg)
Definition core.h:131
add versions of standard API functions not returning on error
#define xrealloc(ptr, size)
Definition ppm_xfuncs.h:71
#define xmalloc(size)
Definition ppm_xfuncs.h:70
struct Xt_mpiddt_list ddt_list
MPI_Datatype datatype
Definition xt_redist.h:69
struct Xt_config_ xt_default_config
Definition xt_config.c:203
implementation of configuration object
@ exch_no_dt_dup
int xt_initialized(void)
index list declaration
MPI_Comm xt_mpi_comm_smart_dup(MPI_Comm comm, int *tag_offset)
Definition xt_mpi.c:333
size_t xt_disp2ext_count(size_t disp_len, const int *disp)
Definition xt_mpi.c:92
size_t xt_disp2ext(size_t disp_len, const int *disp, struct Xt_offset_ext *restrict v)
Definition xt_mpi.c:133
void xt_mpi_comm_smart_dedup(MPI_Comm *comm, int tag_offset)
Definition xt_mpi.c:386
utility routines for MPI
void Xt_mpi_ddt_cache_check_retention(struct Xt_mpiddt_list *ddt_list, size_t nmsg, struct Xt_redist_msg msgs[nmsg])
MPI_Datatype xt_mpi_ddt_block_gen(int count, const int *disp, const int *blocklengths, struct Xt_mpi_strp_prs_params *params)
static void xt_destroy_mpi_strp_prs_params(struct Xt_mpi_strp_prs_params *params)
static void xt_init_mpi_strp_prs_params(struct Xt_mpi_strp_prs_params *params, MPI_Datatype old_type, MPI_Comm comm)
PPM_DSO_INTERNAL MPI_Datatype xt_mpi_parse_stripe(size_t vlen, const struct Xt_offset_ext v[vlen], struct Xt_mpi_strp_prs_params *params)
redistribution of data, non-public declarations
static size_t xt_mdisp2ext_count(size_t disp_len, const int *disp, const int *pos)
static MPI_Datatype generate_datatype(const int *transfer_pos, int num_transfer_pos, const int *offsets, size_t *vsize, struct Xt_offset_ext **v, struct Xt_mpi_strp_prs_params *params)
static void generate_block_msg_infos(int num_msgs, Xt_xmap_iter iter, const int *block_offsets, const int *block_sizes, int **aux_offsets, size_t num_blocks, struct Xt_mpi_strp_prs_params *params, struct Xt_redist_msg *msgs)
static size_t xt_mdisp2ext(size_t disp_len, const int *disp, const int *pos, struct Xt_offset_ext *restrict v)
static MPI_Datatype generate_block_datatype(const int *transfer_pos, int num_transfer_pos, const int *block_offsets, const int *block_sizes, struct Xt_mpi_strp_prs_params *params)
static void generate_msg_infos(int num_msgs, Xt_xmap_iter iter, const int *offsets, struct Xt_redist_msg *msgs, struct Xt_mpi_strp_prs_params *params)
static int pos2disp2(int pos, int num_ext, const int psum_ext_size[], int start_ext)
static void aux_gen_simple_block_offsets(int block_offsets[], const int block_sizes[], size_t num_blocks)
static int pos2disp(int pos, int num_ext, const int psum_ext_size[])
Xt_redist xt_redist_p2p_custom_new(Xt_xmap xmap, MPI_Datatype datatype, Xt_config config)
Xt_redist xt_redist_p2p_off_new(Xt_xmap xmap, const int *src_offsets, const int *dst_offsets, MPI_Datatype datatype)
Xt_redist xt_redist_p2p_blocks_custom_new(Xt_xmap xmap, const int *src_block_sizes, int src_block_num, const int *dst_block_sizes, int dst_block_num, MPI_Datatype datatype, Xt_config config)
Xt_redist xt_redist_p2p_new(Xt_xmap xmap, MPI_Datatype datatype)
Xt_redist xt_redist_p2p_off_custom_new(Xt_xmap xmap, const int *src_offsets, const int *dst_offsets, MPI_Datatype datatype, Xt_config config)
Xt_redist xt_redist_p2p_blocks_off_custom_new(Xt_xmap xmap, const int *src_block_offsets, const int *src_block_sizes, int src_block_num, const int *dst_block_offsets, const int *dst_block_sizes, int dst_block_num, MPI_Datatype datatype, Xt_config config)
Xt_redist xt_redist_p2p_blocks_off_new(Xt_xmap xmap, const int *src_block_offsets, const int *src_block_sizes, int src_block_num, const int *dst_block_offsets, const int *dst_block_sizes, int dst_block_num, MPI_Datatype datatype)
Xt_redist xt_redist_p2p_blocks_new(Xt_xmap xmap, const int *src_block_sizes, int src_block_num, const int *dst_block_sizes, int dst_block_num, MPI_Datatype datatype)
Xt_redist xt_redist_single_array_base_custom_new(int nsend, int nrecv, const struct Xt_redist_msg send_msgs[], const struct Xt_redist_msg recv_msgs[], MPI_Comm comm, Xt_config config)
exchange map declarations
int xt_xmap_iterator_next(Xt_xmap_iter iter)
Definition xt_xmap.c:101
Xt_xmap_iter xt_xmap_get_out_iterator(Xt_xmap xmap)
Definition xt_xmap.c:96
void xt_xmap_iterator_delete(Xt_xmap_iter iter)
Definition xt_xmap.c:130
int xt_xmap_get_num_destinations(Xt_xmap xmap)
Definition xt_xmap.c:61
int xt_xmap_iterator_get_rank(Xt_xmap_iter iter)
Definition xt_xmap.c:106
int xt_xmap_get_max_dst_pos(Xt_xmap xmap)
Definition xt_xmap.c:139
int xt_xmap_get_num_sources(Xt_xmap xmap)
Definition xt_xmap.c:66
Xt_xmap_iter xt_xmap_get_in_iterator(Xt_xmap xmap)
Definition xt_xmap.c:91
MPI_Comm xt_xmap_get_communicator(Xt_xmap xmap)
Definition xt_xmap.c:56
int const * xt_xmap_iterator_get_transfer_pos(Xt_xmap_iter iter)
Definition xt_xmap.c:111
int xt_xmap_get_max_src_pos(Xt_xmap xmap)
Definition xt_xmap.c:135
int xt_xmap_iterator_get_num_transfer_pos(Xt_xmap_iter iter)
Definition xt_xmap.c:116