Yet Another eXchange Tool  0.9.0
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://doc.redmine.dkrz.de/yaxt/html/
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 static MPI_Datatype
70 generate_datatype(const int *transfer_pos, int num_transfer_pos,
71  const int *offsets, MPI_Datatype base_datatype, MPI_Comm comm)
72 {
73  int const * displ;
74  int * tmp_displ = NULL;
75 
76  if (offsets != NULL) {
77 
78  tmp_displ = xmalloc((size_t)num_transfer_pos * sizeof(int));
79 
80  for (int i = 0; i < num_transfer_pos; ++i)
81  tmp_displ[i] = offsets[transfer_pos[i]];
82 
83  displ = tmp_displ;
84 
85  } else
86  displ = transfer_pos;
87 
88 
89  MPI_Datatype type
90  = xt_mpi_generate_datatype(displ, num_transfer_pos, base_datatype, comm);
91 
92  free(tmp_displ);
93 
94  return type;
95 }
96 
97 static void
98 generate_msg_infos(int num_msgs, Xt_xmap_iter iter, const int *offsets,
99  MPI_Datatype base_datatype, struct Xt_redist_msg *msgs,
100  MPI_Comm comm) {
101 
102  if (num_msgs > 0) {
103  struct Xt_redist_msg *restrict curr_msg = msgs;
104 
105  do {
106 
107  const int *curr_transfer_pos = xt_xmap_iterator_get_transfer_pos(iter);
108  int curr_num_transfer_pos = xt_xmap_iterator_get_num_transfer_pos(iter);
109 
110  curr_msg->datatype
111  = generate_datatype(curr_transfer_pos, curr_num_transfer_pos,
112  offsets, base_datatype, comm);
113  curr_msg->rank = xt_xmap_iterator_get_rank(iter);
114 
115  curr_msg++;
116  } while (xt_xmap_iterator_next(iter));
117  }
118 }
119 
120 Xt_redist
121 xt_redist_p2p_off_new(Xt_xmap xmap, const int *src_offsets,
122  const int *dst_offsets, MPI_Datatype datatype)
123 {
124  return xt_redist_p2p_off_custom_new(xmap, src_offsets, dst_offsets, datatype,
126 }
127 
128 Xt_redist
129 xt_redist_p2p_off_custom_new(Xt_xmap xmap, const int *src_offsets,
130  const int *dst_offsets, MPI_Datatype datatype,
131  Xt_config config) {
132  // ensure that yaxt is initialized
133  assert(xt_initialized());
134 
135  int nsend = xt_xmap_get_num_destinations(xmap),
136  nrecv = xt_xmap_get_num_sources(xmap);
137  size_t nmsg = (size_t)nsend + (size_t)nrecv;
138  struct Xt_redist_msg *msgs = xmalloc(nmsg * sizeof (*msgs)),
139  *send_msgs = msgs, *recv_msgs = msgs + nsend;
140  int tag_offset;
141  MPI_Comm comm
142  = xt_mpi_comm_smart_dup(xt_xmap_get_communicator(xmap), &tag_offset);
143 
144  Xt_xmap_iter dst_iter = xt_xmap_get_in_iterator(xmap);
145  generate_msg_infos(nrecv, dst_iter, dst_offsets, datatype, recv_msgs,
146  comm);
147  if (dst_iter) xt_xmap_iterator_delete(dst_iter);
148 
149  Xt_xmap_iter src_iter = xt_xmap_get_out_iterator(xmap);
150  generate_msg_infos(nsend, src_iter, src_offsets, datatype, send_msgs,
151  comm);
152  if (src_iter) xt_xmap_iterator_delete(src_iter);
153 
155  nsend, nrecv, send_msgs, recv_msgs, comm, config);
156 
157  xt_redist_msgs_free(nmsg, msgs, comm);
158  xt_mpi_comm_smart_dedup(&comm, tag_offset);
159  return result;
160 }
161 
162 /* ====================================================================== */
163 
164 struct ext_disp
165 {
166  int disp, ext_idx;
167 };
168 
169 static inline struct ext_disp
170 pos2disp(int pos, int num_ext, const struct Xt_offset_ext extents[],
171  const int psum_ext_size[])
172 {
173  int j = 0;
174  /* FIXME: use bsearch if linear search is too slow, i.e. num_ext >> 1000 */
175  /* what extent covers the pos'th position? */
176  while (j < num_ext && pos >= psum_ext_size[j + 1])
177  ++j;
178  int disp = extents[j].start + (pos - psum_ext_size[j]) * extents[j].stride;
179  return (struct ext_disp){ .disp = disp, .ext_idx = j };
180 }
181 
182 static inline struct ext_disp
183 pos2disp2(int pos, int num_ext, const struct Xt_offset_ext extents[],
184  const int psum_ext_size[], int start_ext)
185 {
186  int j = start_ext;
187  if (pos < psum_ext_size[j + 1] && pos >= psum_ext_size[j])
188  ;
189  else if (pos < psum_ext_size[j + 1])
190  {
191  j = 0;
192  while (j < start_ext && pos >= psum_ext_size[j + 1])
193  ++j;
194  }
195  else
196  while (j < num_ext && pos >= psum_ext_size[j + 1])
197  ++j;
198  int disp = extents[j].start + (pos - psum_ext_size[j]) * extents[j].stride;
199  return (struct ext_disp){ .disp = disp, .ext_idx = j };
200 }
201 
202 static MPI_Datatype
203 generate_ext_datatype(int num_transfer_pos_ext,
204  const struct Xt_pos_ext transfer_pos_ext[],
205  int num_ext, const struct Xt_offset_ext extents[],
206  const int psum_ext_size[],
207  MPI_Datatype base_datatype, MPI_Comm comm)
208 {
209  if (num_transfer_pos_ext > 0)
210  {
211  size_t size_dt_stripes = 8, num_dt_stripes = 0;
212  struct Xt_offset_ext *dt_stripes
213  = xmalloc(size_dt_stripes * sizeof (*dt_stripes));
214  int i = 0,
215  search_start_ext
216  = pos2disp(transfer_pos_ext[0].start,
217  num_ext, extents, psum_ext_size).ext_idx;
218  do
219  {
220  struct Xt_pos_ext current_pos_ext = transfer_pos_ext[i];
221  if (num_dt_stripes >= size_dt_stripes)
222  {
223  more_stripes:
224  size_dt_stripes *= 2;
225  dt_stripes = xrealloc(dt_stripes,
226  size_dt_stripes * sizeof (*dt_stripes));
227  }
228  do {
229  /* find extent containing start position of current range */
230  struct ext_disp pos = pos2disp2(current_pos_ext.start,
231  num_ext, extents, psum_ext_size,
232  search_start_ext);
233  search_start_ext = pos.ext_idx;
234  struct Xt_offset_ext base_ext = extents[pos.ext_idx],
235  derived_ext;
236  int preceding = psum_ext_size[pos.ext_idx];
237  derived_ext.start
238  = base_ext.start + ((current_pos_ext.start - preceding)
239  * base_ext.stride);
240  int isign_mask_current_pos_ext_size = isign_mask(current_pos_ext.size);
241  /* find number of positions in containing extent,
242  * which precede current_pos_ext.start
243  * if (current_pos_ext.size < 0)
244  * or follow current_pos_ext.start
245  * if (current_pos_ext.size > 0) */
246  derived_ext.size = imin(abs(current_pos_ext.size),
247  (~isign_mask_current_pos_ext_size
248  & (base_ext.size
249  - (current_pos_ext.start - preceding)))
250  | (isign_mask_current_pos_ext_size
251  & (current_pos_ext.start - preceding + 1)));
252  derived_ext.stride
253  = (~isign_mask_current_pos_ext_size & base_ext.stride)
254  | (isign_mask_current_pos_ext_size & -base_ext.stride);
255  dt_stripes[num_dt_stripes++] = derived_ext;
256  current_pos_ext.size
257  += (~isign_mask_current_pos_ext_size & -derived_ext.size)
258  | (isign_mask_current_pos_ext_size & derived_ext.size);
259  current_pos_ext.start += derived_ext.size;
260  } while ((abs(current_pos_ext.size) > 0)
261  & (num_dt_stripes < size_dt_stripes));
262  /* current_pos_ext hasn't been mapped completely, get more
263  * stripe memory */
264  if (abs(current_pos_ext.size) > 0)
265  goto more_stripes;
266  /* only advance current_pos_ext after it has been mapped completely */
267  } while (++i < num_transfer_pos_ext);
268  MPI_Datatype type
269  = xt_mpi_generate_datatype_stripe(dt_stripes, (int)num_dt_stripes,
270  base_datatype, comm);
271  free(dt_stripes);
272  return type;
273  }
274  else
275  return MPI_DATATYPE_NULL;
276 }
277 
278 static void
280  int num_ext,
281  const struct Xt_offset_ext extents[],
282  MPI_Datatype base_datatype,
283  struct Xt_redist_msg *msgs,
284  MPI_Comm comm)
285 {
286  if (num_msgs > 0) {
287  /* partial sums of ext sizes */
288  int *psum_ext_size
289  = xmalloc(((size_t)num_ext + 1) * sizeof (psum_ext_size[0]));
290  psum_ext_size[0] = 0;
291  for (size_t i = 0; i < (size_t)num_ext; ++i)
292  psum_ext_size[i + 1] = psum_ext_size[i] + extents[i].size;
293 
294  struct Xt_redist_msg *curr_msg = msgs;
295  do {
296 
297  const struct Xt_pos_ext *curr_transfer_pos_ext
299  int curr_num_transfer_pos_ext
301 
302  curr_msg->datatype
303  = generate_ext_datatype(curr_num_transfer_pos_ext,
304  curr_transfer_pos_ext,
305  num_ext, extents, psum_ext_size,
306  base_datatype, comm);
307  curr_msg->rank = xt_xmap_iterator_get_rank(iter);
308 
309  curr_msg++;
310 
311  } while (xt_xmap_iterator_next(iter));
312  free(psum_ext_size);
313  }
314 }
315 
316 Xt_redist
318  int num_src_ext,
319  const struct Xt_offset_ext src_extents[],
320  int num_dst_ext,
321  const struct Xt_offset_ext dst_extents[],
322  MPI_Datatype datatype)
323 {
324  return xt_redist_p2p_ext_custom_new(xmap, num_src_ext, src_extents,
325  num_dst_ext, dst_extents, datatype,
327 }
328 
329 Xt_redist
331  int num_src_ext,
332  const struct Xt_offset_ext src_extents[],
333  int num_dst_ext,
334  const struct Xt_offset_ext dst_extents[],
335  MPI_Datatype datatype,
336  Xt_config config)
337 {
338  // ensure that yaxt is initialized
339  assert(xt_initialized());
340  int tag_offset;
341  MPI_Comm comm
342  = xt_mpi_comm_smart_dup(xt_xmap_get_communicator(xmap), &tag_offset);
343 
344  int nrecv = xt_xmap_get_num_sources(xmap),
345  nsend = xt_xmap_get_num_destinations(xmap);
346  size_t nmsg = (size_t)nrecv + (size_t)nsend;
347  struct Xt_redist_msg *msgs = xmalloc(nmsg * sizeof (*msgs)),
348  *send_msgs = msgs, *recv_msgs = msgs + nsend;
349  Xt_xmap_iter dst_iter = xt_xmap_get_in_iterator(xmap);
350  generate_ext_msg_infos(nrecv, dst_iter, num_dst_ext, dst_extents,
351  datatype, recv_msgs, comm);
352  if (dst_iter) xt_xmap_iterator_delete(dst_iter);
353 
354  Xt_xmap_iter src_iter = xt_xmap_get_out_iterator(xmap);
355  generate_ext_msg_infos(nsend, src_iter, num_src_ext, src_extents,
356  datatype, send_msgs, comm);
357  if (src_iter) xt_xmap_iterator_delete(src_iter);
358 
360  nsend, nrecv, send_msgs, recv_msgs, comm, config);
361 
362  xt_redist_msgs_free(nmsg, msgs, comm);
363  xt_mpi_comm_smart_dedup(&comm, tag_offset);
364  return result;
365 }
366 
367 /* ====================================================================== */
368 
369 static inline void
370 aux_gen_simple_block_offsets(int block_offsets[], const int block_sizes[],
371  size_t num_blocks) {
372 
373  if (num_blocks > 0) {
374  int accum = 0;
375  for (size_t i = 0; i < num_blocks; ++i) {
376  block_offsets[i] = accum;
377  accum += block_sizes[i];
378  }
379  }
380 }
381 
382 static MPI_Datatype
383 generate_block_datatype(const int *transfer_pos, int num_transfer_pos,
384  const int *block_offsets, const int *block_sizes,
385  MPI_Datatype base_datatype, MPI_Comm comm) {
386 
387  assert(block_sizes && block_offsets);
388 
389  int *bdispl_vec = xmalloc(2 * (size_t)num_transfer_pos * sizeof(*bdispl_vec)),
390  *blen_vec = bdispl_vec + num_transfer_pos;
391 
392  for (int i = 0; i < num_transfer_pos; ++i) {
393  int j = transfer_pos[i];
394  bdispl_vec[i] = block_offsets[j];
395  blen_vec[i] = block_sizes[j];
396  }
397 
398  MPI_Datatype type
399  = xt_mpi_generate_datatype_block(bdispl_vec, blen_vec,
400  num_transfer_pos, base_datatype, comm);
401 
402  free(bdispl_vec);
403 
404  return type;
405 }
406 
407 static void
409  const int *block_offsets,
410  const int *block_sizes, int **aux_offsets,
411  size_t num_blocks,
412  MPI_Datatype base_datatype,
413  struct Xt_redist_msg **msgs, MPI_Comm comm) {
414 
415  if (num_msgs > 0) {
416 
417  const int *block_offsets_;
418  if (block_offsets)
419  block_offsets_ = block_offsets;
420  else {
421  block_offsets_ = *aux_offsets
422  = xrealloc(*aux_offsets, num_blocks * sizeof(*block_offsets_));
423  aux_gen_simple_block_offsets(*aux_offsets, block_sizes, num_blocks);
424  }
425 
426  struct Xt_redist_msg *curr_msg
427  = *msgs = xmalloc((size_t)num_msgs * sizeof(**msgs));
428 
429  do {
430  const int *curr_transfer_pos = xt_xmap_iterator_get_transfer_pos(iter);
431  int curr_num_transfer_pos = xt_xmap_iterator_get_num_transfer_pos(iter);
432  curr_msg->datatype
433  = generate_block_datatype(curr_transfer_pos, curr_num_transfer_pos,
434  block_offsets_, block_sizes, base_datatype,
435  comm);
436  curr_msg->rank = xt_xmap_iterator_get_rank(iter);
437 
438  curr_msg++;
439  } while (xt_xmap_iterator_next(iter));
440 
441  } else
442  *msgs = NULL;
443 }
444 
445 Xt_redist
447  const int *src_block_offsets,
448  const int *src_block_sizes,
449  int src_block_num,
450  const int *dst_block_offsets,
451  const int *dst_block_sizes,
452  int dst_block_num,
453  MPI_Datatype datatype)
454 {
456  xmap, src_block_offsets, src_block_sizes, src_block_num, dst_block_offsets,
457  dst_block_sizes, dst_block_num, datatype, (Xt_config)&xt_default_config);
458 }
459 
460 
461 Xt_redist
463  const int *src_block_offsets,
464  const int *src_block_sizes,
465  int src_block_num,
466  const int *dst_block_offsets,
467  const int *dst_block_sizes,
468  int dst_block_num,
469  MPI_Datatype datatype,
470  Xt_config config)
471 {
472  // ensure that yaxt is initialized
473  assert(xt_initialized());
474 
475  struct Xt_redist_msg * send_msgs = NULL;
476  struct Xt_redist_msg * recv_msgs = NULL;
477 
478  assert(src_block_sizes && dst_block_sizes);
479 
480  int tag_offset;
481  MPI_Comm comm
482  = xt_mpi_comm_smart_dup(xt_xmap_get_communicator(xmap), &tag_offset);
483 
484 
485  int nsend = xt_xmap_get_num_destinations(xmap),
486  nrecv = xt_xmap_get_num_sources(xmap);
487 
488  int *aux_offsets = NULL;
489 
490  Xt_xmap_iter dst_iter = xt_xmap_get_in_iterator(xmap),
491  src_iter = xt_xmap_get_out_iterator(xmap);
492 
493  // dst part:
494 #ifndef NDEBUG
495  int max_dst_pos = xt_xmap_get_max_dst_pos(xmap);
496  if (dst_block_num < max_dst_pos)
497  die("xt_redist_p2p_blocks_off_new: dst_block_num too small");
498 #endif
499  generate_block_msg_infos(nrecv, dst_iter, dst_block_offsets, dst_block_sizes,
500  &aux_offsets, (size_t)dst_block_num,
501  datatype, &recv_msgs, comm);
502  if (dst_iter) xt_xmap_iterator_delete(dst_iter);
503 
504  // src part:
505 #ifndef NDEBUG
506  int max_src_pos = xt_xmap_get_max_src_pos(xmap);
507  if (src_block_num < max_src_pos)
508  die("xt_redist_p2p_blocks_off_new: src_block_num too small");
509 #endif
510  generate_block_msg_infos(nsend, src_iter, src_block_offsets, src_block_sizes,
511  &aux_offsets, (size_t)src_block_num,
512  datatype, &send_msgs, comm);
513  free(aux_offsets);
514 
515  if (src_iter) xt_xmap_iterator_delete(src_iter);
516 
517  Xt_redist result
519  nsend, nrecv, send_msgs, recv_msgs, comm, config);
520 
521  xt_redist_msgs_free((size_t)nsend, send_msgs, comm);
522  xt_redist_msgs_free((size_t)nrecv, recv_msgs, comm);
523  xt_mpi_comm_smart_dedup(&comm, tag_offset);
524  return result;
525 }
526 
528  const int *src_block_sizes,
529  int src_block_num,
530  const int *dst_block_sizes,
531  int dst_block_num,
532  MPI_Datatype datatype)
533 {
535  xmap, src_block_sizes, src_block_num, dst_block_sizes, dst_block_num,
537 }
538 
539 Xt_redist
541  const int *src_block_sizes, int src_block_num,
542  const int *dst_block_sizes, int dst_block_num,
543  MPI_Datatype datatype,
544  Xt_config config)
545 {
547  xmap, NULL, src_block_sizes, src_block_num,
548  NULL, dst_block_sizes, dst_block_num, datatype, config);
549 }
550 
551 
553 {
554  return xt_redist_p2p_custom_new(xmap, datatype,
556 }
557 
558 Xt_redist
560 {
561  return xt_redist_p2p_off_custom_new(xmap, NULL, NULL, datatype, config);
562 }
563 
564 /*
565  * Local Variables:
566  * c-basic-offset: 2
567  * coding: utf-8
568  * indent-tabs-mode: nil
569  * show-trailing-whitespace: t
570  * require-trailing-newline: t
571  * End:
572  */
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
int size
Definition: xt_core.h:93
int start
Definition: xt_core.h:93
MPI_Datatype datatype
Definition: xt_redist.h:69
static int isign_mask(int x)
static int imin(int a, int b)
struct Xt_config_ xt_default_config
Definition: xt_config.c:65
implementation of configuration object
int xt_initialized(void)
Definition: xt_init.c:107
index list declaration
MPI_Comm xt_mpi_comm_smart_dup(MPI_Comm comm, int *tag_offset)
Definition: xt_mpi.c:813
void xt_mpi_comm_smart_dedup(MPI_Comm *comm, int tag_offset)
Definition: xt_mpi.c:864
utility routines for MPI
MPI_Datatype xt_mpi_generate_datatype(int const *displacements, int count, MPI_Datatype old_type, MPI_Comm comm)
Definition: xt_mpi.c:264
MPI_Datatype xt_mpi_generate_datatype_stripe(const struct Xt_offset_ext *v, int count, MPI_Datatype old_type, MPI_Comm comm)
MPI_Datatype xt_mpi_generate_datatype_block(const int *displacements, const int *blocklengths, int count, MPI_Datatype old_type, MPI_Comm comm)
Definition: xt_mpi.c:227
redistribution of data, non-public declarations
static void xt_redist_msgs_free(size_t n, struct Xt_redist_msg *msgs, MPI_Comm comm)
static void generate_msg_infos(int num_msgs, Xt_xmap_iter iter, const int *offsets, MPI_Datatype base_datatype, struct Xt_redist_msg *msgs, MPI_Comm comm)
Definition: xt_redist_p2p.c:98
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)
static struct ext_disp pos2disp2(int pos, int num_ext, const struct Xt_offset_ext extents[], const int psum_ext_size[], int start_ext)
static MPI_Datatype generate_ext_datatype(int num_transfer_pos_ext, const struct Xt_pos_ext transfer_pos_ext[], int num_ext, const struct Xt_offset_ext extents[], const int psum_ext_size[], MPI_Datatype base_datatype, MPI_Comm comm)
static struct ext_disp pos2disp(int pos, int num_ext, const struct Xt_offset_ext extents[], const int psum_ext_size[])
Xt_redist xt_redist_p2p_ext_new(Xt_xmap xmap, int num_src_ext, const struct Xt_offset_ext src_extents[], int num_dst_ext, const struct Xt_offset_ext dst_extents[], MPI_Datatype datatype)
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)
static MPI_Datatype generate_datatype(const int *transfer_pos, int num_transfer_pos, const int *offsets, MPI_Datatype base_datatype, MPI_Comm comm)
Definition: xt_redist_p2p.c:70
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)
static void generate_ext_msg_infos(int num_msgs, Xt_xmap_iter iter, int num_ext, const struct Xt_offset_ext extents[], MPI_Datatype base_datatype, struct Xt_redist_msg *msgs, MPI_Comm comm)
static void aux_gen_simple_block_offsets(int block_offsets[], const int block_sizes[], size_t num_blocks)
static MPI_Datatype generate_block_datatype(const int *transfer_pos, int num_transfer_pos, const int *block_offsets, const int *block_sizes, MPI_Datatype base_datatype, MPI_Comm comm)
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, MPI_Datatype base_datatype, struct Xt_redist_msg **msgs, MPI_Comm comm)
Xt_redist xt_redist_p2p_ext_custom_new(Xt_xmap xmap, int num_src_ext, const struct Xt_offset_ext src_extents[], int num_dst_ext, const struct Xt_offset_ext dst_extents[], MPI_Datatype datatype, Xt_config config)
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:100
Xt_xmap_iter xt_xmap_get_out_iterator(Xt_xmap xmap)
Definition: xt_xmap.c:95
int xt_xmap_iterator_get_num_transfer_pos_ext(Xt_xmap_iter iter)
Definition: xt_xmap.c:125
int const * xt_xmap_iterator_get_transfer_pos(Xt_xmap_iter iter)
Definition: xt_xmap.c:110
void xt_xmap_iterator_delete(Xt_xmap_iter iter)
Definition: xt_xmap.c:129
int xt_xmap_get_num_destinations(Xt_xmap xmap)
Definition: xt_xmap.c:60
int xt_xmap_iterator_get_rank(Xt_xmap_iter iter)
Definition: xt_xmap.c:105
int xt_xmap_get_max_dst_pos(Xt_xmap xmap)
Definition: xt_xmap.c:138
int xt_xmap_get_num_sources(Xt_xmap xmap)
Definition: xt_xmap.c:65
const struct Xt_pos_ext * xt_xmap_iterator_get_transfer_pos_ext(Xt_xmap_iter iter)
Definition: xt_xmap.c:121
Xt_xmap_iter xt_xmap_get_in_iterator(Xt_xmap xmap)
Definition: xt_xmap.c:90
MPI_Comm xt_xmap_get_communicator(Xt_xmap xmap)
Definition: xt_xmap.c:55
int xt_xmap_get_max_src_pos(Xt_xmap xmap)
Definition: xt_xmap.c:134
int xt_xmap_iterator_get_num_transfer_pos(Xt_xmap_iter iter)
Definition: xt_xmap.c:115