Yet Another eXchange Tool  0.9.0
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://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 <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 
71 
72 static void
74 
75 static Xt_redist
77 
78 static void
79 redist_collection_s_exchange(Xt_redist redist, int num_src_arrays,
80  const void **src_data, void **dst_data);
81 
82 static void
83 redist_collection_a_exchange(Xt_redist redist, int num_src_arrays,
84  const void **src_data, void **dst_data,
85  Xt_request *request);
86 
87 static void
89  const void *src_data, void *dst_data);
90 
91 static void
93  const void *src_data, void *dst_data,
94  Xt_request *request);
95 
97  enum xt_msg_direction direction);
98 
99 static MPI_Datatype
101  enum xt_msg_direction direction);
102 
103 static int
105  enum xt_msg_direction direction,
106  int *restrict *ranks);
107 
108 static MPI_Comm
110 
111 static const struct xt_redist_vtable redist_collection_vtable = {
113  .delete = redist_collection_delete,
114  .s_exchange = redist_collection_s_exchange,
115  .a_exchange = redist_collection_a_exchange,
116  .s_exchange1 = redist_collection_s_exchange1,
117  .a_exchange1 = redist_collection_a_exchange1,
118  .get_num_msg = redist_collection_get_num_msg,
119  .get_msg_MPI_Datatype = redist_collection_get_MPI_Datatype,
120  .get_msg_ranks = redist_collection_get_msg_ranks,
121  .get_MPI_Comm = redist_collection_get_MPI_Comm
122 };
123 
125 {
126  size_t token;
129  struct Xt_redist_msg * msgs;
130 };
131 
133 
135 
136  const struct xt_redist_vtable *vtable;
137 
138  unsigned num_redists;
139 
140  struct exchanger_cache cache;
141 
142  unsigned nmsg[2];
144 
145  size_t cache_size;
146 
150 
151  MPI_Datatype all_component_dt[];
152 };
153 
154 static void align_component_dt(unsigned num_redists, unsigned nmsgs,
155  const Xt_redist *redists,
156  int *restrict in_ranks[num_redists],
157  size_t num_ranks[num_redists],
158  int *out_ranks,
159  MPI_Datatype *component_dt,
160  enum xt_msg_direction direction)
161 {
162  size_t rank_pos[num_redists];
163  for (size_t j = 0; j < num_redists; ++j)
164  rank_pos[j] = 0;
165  if (nmsgs) {
166  /* find ranks and corresponding component datatypes */
167  for (size_t i = 0; i < nmsgs; ++i) {
168  int min_rank = INT_MAX;
169  for (size_t j = 0; j < num_redists; ++j)
170  if (rank_pos[j] < num_ranks[j] && in_ranks[j][rank_pos[j]] < min_rank)
171  min_rank = in_ranks[j][rank_pos[j]];
172 
173  for (size_t j = 0; j < num_redists; ++j)
174  component_dt[i * num_redists + j] =
175  (rank_pos[j] < num_ranks[j] && in_ranks[j][rank_pos[j]] == min_rank)
176  ? xt_redist_get_MPI_Datatype(redists[j], min_rank, direction)
177  : MPI_DATATYPE_NULL;
178 
179  out_ranks[i] = min_rank;
180  for (size_t j = 0; j < num_redists; ++j)
181  rank_pos[j]
182  += (rank_pos[j] < num_ranks[j] && in_ranks[j][rank_pos[j]] == min_rank);
183  }
184  }
185  for (size_t j = 0; j < num_redists; ++j)
186  free(in_ranks[j]);
187 }
188 
189 /* not yet used cache entries are marked with -1 as first displacement,
190  * which becomes 0 later on through use */
191 static inline void
192 init_cache(struct exchanger_cache *cache, size_t cache_size, size_t ntx,
193  unsigned num_redists)
194 {
195  cache->exchangers = xcalloc(cache_size, sizeof(*(cache->exchangers)));
196  size_t num_displ = cache_size * num_redists;
197  struct Xt_redist_msg *msgs = cache->msgs = xmalloc(ntx * sizeof (*msgs));
198  for (size_t i = 0; i < ntx; ++i) msgs[i].datatype = MPI_DATATYPE_NULL;
199  MPI_Aint *restrict q = cache->src_displacements
200  = xmalloc(2 * num_displ * sizeof (*q));
201  cache->dst_displacements = q + num_displ;
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 
207 static inline void
209  size_t cache_size, size_t ntx, MPI_Comm comm)
210 {
211  for (size_t i = 0; i < cache_size; ++i)
212  if (cache->exchangers[i] != NULL)
213  xt_exchanger_delete(cache->exchangers[i]);
214  free(cache->exchangers);
215 
216  xt_redist_msgs_free(ntx, cache->msgs, comm);
217  free(cache->src_displacements);
218 }
219 
220 Xt_redist xt_redist_collection_new(Xt_redist *redists, int num_redists,
221  int cache_size, MPI_Comm comm)
222 {
223  return xt_redist_collection_custom_new(redists, num_redists, cache_size,
224  comm, (Xt_config)&xt_default_config);
225 }
226 
228  int cache_size, MPI_Comm comm,
229  Xt_config config)
230 {
231  // ensure that yaxt is initialized
232  assert(xt_initialized());
233 
234  unsigned num_redists_ = num_redists >= 0 ? (unsigned)num_redists : 0;
235  size_t num_ranks[2][num_redists_];
236  int *restrict ranks[2][num_redists_];
237  unsigned nmsg_send = xt_redist_agg_msg_count(num_redists_, SEND, redists,
238  num_ranks[SEND], ranks[SEND]),
239  nmsg_recv = xt_redist_agg_msg_count(num_redists_, RECV, redists,
240  num_ranks[RECV], ranks[RECV]);
241  size_t nmsg = (size_t)nmsg_send + nmsg_recv;
242  size_t size_all_component_dt = sizeof (MPI_Datatype) * num_redists_ * nmsg;
243  Xt_redist_collection redist_coll
244  = xmalloc(sizeof (*redist_coll)
245  + size_all_component_dt + nmsg * sizeof (int));
246  redist_coll->exchanger_new = config->exchanger_new;
247  redist_coll->nmsg[RECV] = nmsg_recv;
248  redist_coll->nmsg[SEND] = nmsg_send;
249  redist_coll->send_ranks
250  = (int *)(redist_coll->all_component_dt + nmsg * num_redists_);
251  redist_coll->recv_ranks = redist_coll->send_ranks + nmsg_send;
252  redist_coll->vtable = &redist_collection_vtable;
253  redist_coll->num_redists = num_redists_;
254  if (cache_size < -1)
255  Xt_abort(comm, "ERROR: invalid cache size in xt_redist_collection_new",
256  __FILE__, __LINE__);
257  redist_coll->cache_size
258  = (cache_size == -1)?(DEFFAULT_DATATYPE_CACHE_SIZE):(size_t)cache_size;
259 
260  redist_coll->comm = xt_mpi_comm_smart_dup(comm, &redist_coll->tag_offset);
261 
262  xt_redist_check_comms(redists, num_redists, comm);
263 
264  MPI_Datatype *all_component_dt = redist_coll->all_component_dt;
265  align_component_dt(num_redists_, nmsg_send, redists,
266  ranks[SEND], num_ranks[SEND], redist_coll->send_ranks,
267  all_component_dt, SEND);
268  align_component_dt(num_redists_, nmsg_recv, redists,
269  ranks[RECV], num_ranks[RECV], redist_coll->recv_ranks,
270  all_component_dt + nmsg_send * num_redists_, RECV);
271  init_cache(&redist_coll->cache, redist_coll->cache_size, nmsg,
272  num_redists_);
273 
274  return (Xt_redist)redist_coll;
275 }
276 
277 
278 static void
280  unsigned num_messages, unsigned num_redists,
281  const int ranks[num_messages],
282  const MPI_Datatype *component_dt,
283  const MPI_Aint displacements[num_redists],
284  struct Xt_redist_msg redist_msgs[num_messages],
285  MPI_Comm comm)
286 {
287  int block_lengths[num_redists];
288 
289  for (size_t i = 0; i < num_redists; ++i)
290  block_lengths[i] = 1;
291  for (size_t i = 0; i < num_messages; ++i) {
292  if (redist_msgs[i].datatype != MPI_DATATYPE_NULL)
293  xt_mpi_call(MPI_Type_free(&(redist_msgs[i].datatype)), comm);
294  redist_msgs[i].datatype
295  = xt_create_compound_datatype(num_redists, displacements,
296  component_dt + i * num_redists,
297  block_lengths, comm);
298  redist_msgs[i].rank = ranks[i];
299  }
300 }
301 
302 static void
303 compute_displ(const void *const *data, unsigned num_redists,
304  MPI_Aint displacements[num_redists])
305 {
306  if (num_redists) {
307  MPI_Aint base_addr, offset;
308  base_addr = (MPI_Aint)(intptr_t)(const void *)data[0];
309  displacements[0] = 0;
310  for (size_t i = 1; i < num_redists; ++i) {
311  offset = (MPI_Aint)(intptr_t)(const void *)data[i];
312  displacements[i] = offset - base_addr;
313  }
314  }
315 }
316 
317 static size_t
318 lookup_cache_index(unsigned num_redists,
319  const MPI_Aint src_displacements[num_redists],
320  const MPI_Aint dst_displacements[num_redists],
321  const MPI_Aint (*cached_src_displacements)[num_redists],
322  const MPI_Aint (*cached_dst_displacements)[num_redists],
323  size_t cache_size)
324 {
325  for (size_t i = 0; i < cache_size &&
326  cached_src_displacements[i][0] == (MPI_Aint)0 &&
327  cached_dst_displacements[i][0] == (MPI_Aint)0; ++i) {
328  bool mismatch = false;
329  for (size_t j = 0; j < num_redists; ++j)
330  mismatch |= (src_displacements[j] != cached_src_displacements[i][j]) ||
331  (dst_displacements[j] != cached_dst_displacements[i][j]);
332  if (!mismatch) return i;
333  }
334  return cache_size;
335 }
336 
337 static Xt_exchanger
339  const void *const * src_data, void *const * dst_data,
340  unsigned num_redists)
341 {
342  MPI_Aint displacements[2][num_redists];
343  unsigned num_send_messages = redist_coll->nmsg[SEND],
344  num_recv_messages = redist_coll->nmsg[RECV];
345  compute_displ(src_data, num_redists, displacements[0]);
346  compute_displ((const void *const *)dst_data, num_redists, displacements[1]);
347 
348  Xt_exchanger exchanger;
349 
350  const MPI_Datatype *all_component_dt = redist_coll->all_component_dt;
351  struct exchanger_cache *restrict cache = &redist_coll->cache;
352  size_t cache_size = redist_coll->cache_size;
353  MPI_Comm comm = redist_coll->comm;
354  int tag_offset = redist_coll->tag_offset;
355  if (cache_size > 0)
356  {
357  size_t cache_index
358  = lookup_cache_index(num_redists, displacements[0], displacements[1],
359  (const MPI_Aint (*)[num_redists])cache->src_displacements,
360  (const MPI_Aint (*)[num_redists])cache->dst_displacements,
361  cache_size);
362 
363  if (cache_index == cache_size)
364  {
365  cache_index = cache->token;
366  create_all_dt_for_dir(num_send_messages, num_redists,
367  redist_coll->send_ranks, all_component_dt,
368  displacements[SEND], cache->msgs, comm);
369  create_all_dt_for_dir(num_recv_messages, num_redists,
370  redist_coll->recv_ranks,
371  all_component_dt + num_send_messages * num_redists,
372  displacements[RECV],
373  cache->msgs + num_send_messages, comm);
374  memcpy(cache->src_displacements + cache_index * num_redists,
375  displacements[0], sizeof (displacements[0]));
376  memcpy(cache->dst_displacements + cache_index * num_redists,
377  displacements[1], sizeof (displacements[1]));
378 
379  if (cache->exchangers[cache_index] != NULL)
380  xt_exchanger_delete(cache->exchangers[cache_index]);
381 
382  exchanger = cache->exchangers[cache_index] =
383  redist_coll->exchanger_new((int)num_send_messages,
384  (int)num_recv_messages,
385  cache->msgs, cache->msgs
386  + (size_t)num_send_messages,
387  comm, tag_offset);
388  cache->token = (cache->token + 1) % cache_size;
389  }
390  else
391  exchanger = cache->exchangers[cache_index];
392  }
393  else
394  {
395  size_t nmsg = (size_t)num_send_messages + (size_t)num_recv_messages;
396  struct Xt_redist_msg *restrict p = xmalloc(nmsg * sizeof (*p));
397  for (size_t i = 0; i < nmsg; ++i)
398  p[i].datatype = MPI_DATATYPE_NULL;
399 
400  create_all_dt_for_dir(num_send_messages, num_redists,
401  redist_coll->send_ranks,
402  all_component_dt, displacements[0], p, comm);
403  create_all_dt_for_dir(num_recv_messages, num_redists,
404  redist_coll->recv_ranks,
405  all_component_dt + num_send_messages * num_redists,
406  displacements[1], p + num_send_messages, comm);
407 
408  exchanger =
409  redist_coll->exchanger_new((int)num_send_messages, (int)num_recv_messages,
410  p, p + (size_t)num_send_messages, comm,
411  tag_offset);
412 
413  xt_redist_msgs_free(nmsg, p, comm);
414  }
415 
416  return exchanger;
417 }
418 
419 static inline Xt_redist_collection
420 xrc(void *redist)
421 {
422  return (Xt_redist_collection)redist;
423 }
424 
425 static void
427  const void **src_data, void **dst_data) {
428 
429  Xt_redist_collection redist_coll = xrc(redist);
430 
431  if (num_arrays != (int)redist_coll->num_redists)
432  Xt_abort(redist_coll->comm, "ERROR: wrong number of arrays in "
433  "redist_collection_s_exchange", __FILE__, __LINE__);
434 
435 
436  Xt_exchanger exchanger = get_exchanger(redist_coll,
437  src_data, dst_data,
438  redist_coll->num_redists);
439 
440  xt_exchanger_s_exchange(exchanger, src_data[0], dst_data[0]);
441 
442  if (redist_coll->cache_size == 0)
443  xt_exchanger_delete(exchanger);
444 }
445 
446 static void
448  const void **src_data, void **dst_data,
449  Xt_request *request) {
450 
451  Xt_redist_collection redist_coll = xrc(redist);
452 
453  if (num_arrays != (int)redist_coll->num_redists)
454  Xt_abort(redist_coll->comm, "ERROR: wrong number of arrays in "
455  "redist_collection_a_exchange", __FILE__, __LINE__);
456 
457 
458  Xt_exchanger exchanger = get_exchanger(redist_coll,
459  src_data, dst_data,
460  redist_coll->num_redists);
461 
462  xt_exchanger_a_exchange(exchanger, src_data[0], dst_data[0], request);
463 
464  if (redist_coll->cache_size == 0)
465  xt_exchanger_delete(exchanger);
466 
467 }
468 
469 static void
470 copy_component_dt(size_t num_component_dt,
471  const MPI_Datatype *component_dt_orig,
472  MPI_Datatype *component_dt_copy,
473  MPI_Comm comm)
474 {
475  for (size_t i = 0; i < num_component_dt; ++i)
476  {
477  MPI_Datatype orig_dt = component_dt_orig[i];
478  if (orig_dt != MPI_DATATYPE_NULL)
479  xt_mpi_call(MPI_Type_dup(orig_dt, component_dt_copy + i), comm);
480  else
481  component_dt_copy[i] = orig_dt;
482  }
483 }
484 
485 static Xt_redist
487 {
488  Xt_redist_collection redist_coll = xrc(redist);
489  unsigned num_redists = redist_coll->num_redists,
490  nmsg_send = redist_coll->nmsg[SEND],
491  nmsg_recv = redist_coll->nmsg[RECV];
492  size_t nmsg = (size_t)nmsg_recv + nmsg_send,
493  size_all_component_dt = sizeof (MPI_Datatype) * num_redists * nmsg;
494  Xt_redist_collection redist_copy
495  = xmalloc(sizeof (*redist_copy)
496  + size_all_component_dt + nmsg * sizeof (int));
497  redist_copy->vtable = redist_coll->vtable;
498  redist_copy->num_redists = num_redists;
499  redist_copy->exchanger_new = redist_coll->exchanger_new;
500  redist_copy->nmsg[SEND] = nmsg_send;
501  redist_copy->nmsg[RECV] = nmsg_recv;
502  redist_copy->send_ranks
503  = (int *)(redist_copy->all_component_dt + nmsg * num_redists);
504  redist_copy->recv_ranks = redist_copy->send_ranks + nmsg_send;
505 
506  MPI_Comm copy_comm = redist_copy->comm
507  = xt_mpi_comm_smart_dup(redist_coll->comm, &redist_copy->tag_offset);
508 
509  memcpy(redist_copy->send_ranks, redist_coll->send_ranks,
510  sizeof (*redist_copy->send_ranks) * nmsg);
511  copy_component_dt(num_redists * nmsg,
512  redist_coll->all_component_dt,
513  redist_copy->all_component_dt, copy_comm);
514  size_t cache_size = redist_coll->cache_size;
515  redist_copy->cache_size = cache_size;
516  init_cache(&redist_copy->cache, cache_size, nmsg, num_redists);
517  return (Xt_redist)redist_copy;
518 }
519 
520 static void
521 free_component_dt(size_t num_dt, MPI_Datatype *all_component_dt, MPI_Comm comm)
522 {
523  for (size_t i = 0; i < num_dt; ++i)
524  if (all_component_dt[i] != MPI_DATATYPE_NULL)
525  xt_mpi_call(MPI_Type_free(all_component_dt + i), comm);
526 }
527 
528 static void
530 
531  Xt_redist_collection redist_coll = xrc(redist);
532 
533  unsigned num_redists = redist_coll->num_redists;
534  size_t nmsg = (size_t)redist_coll->nmsg[RECV] + redist_coll->nmsg[SEND];
535  free_component_dt(nmsg * num_redists, redist_coll->all_component_dt,
536  redist_coll->comm);
537 
538  destruct_cache(&redist_coll->cache, redist_coll->cache_size,
539  nmsg, redist_coll->comm);
540 
541  xt_mpi_comm_smart_dedup(&(redist_coll->comm), redist_coll->tag_offset);
542 
543  free(redist_coll);
544 }
545 
547  enum xt_msg_direction direction)
548 {
549  return (int)(xrc(redist)->nmsg[direction]);
550 }
551 
552 static MPI_Datatype
554  enum xt_msg_direction XT_UNUSED(direction))
555 {
556  Xt_redist_collection redist_coll = xrc(redist);
557 
558  Xt_abort(redist_coll->comm, "ERROR: datatype retrieval is not"
559  " supported for this xt_redist type (Xt_redist_collection)",
560  __FILE__, __LINE__);
561 
562  return MPI_DATATYPE_NULL;
563 }
564 
565 static void
567  const void *src_data, void *dst_data)
568 {
569 
570  Xt_redist_collection redist_coll = xrc(redist);
571  if (redist_coll->num_redists == 1)
572  redist_collection_s_exchange(redist, 1, &src_data, &dst_data);
573  else
574  Xt_abort(redist_coll->comm, "ERROR: s_exchange1 is not implemented for"
575  " this xt_redist type (Xt_redist_collection)", __FILE__, __LINE__);
576 }
577 
578 static void
580  const void *src_data, void *dst_data,
581  Xt_request *request)
582 {
583 
584  Xt_redist_collection redist_coll = xrc(redist);
585  if (redist_coll->num_redists == 1)
586  redist_collection_a_exchange(redist, 1, &src_data, &dst_data, request);
587  else
588  Xt_abort(redist_coll->comm, "ERROR: a_exchange1 is not implemented for"
589  " this xt_redist type (Xt_redist_collection)", __FILE__, __LINE__);
590 }
591 
592 static int
594  enum xt_msg_direction direction,
595  int *restrict *ranks)
596 {
597  Xt_redist_collection redist_coll = xrc(redist);
598  unsigned nmsg_direction = redist_coll->nmsg[direction],
599  nmsg_send = redist_coll->nmsg[SEND];
600  size_t nmsg = (size_t)nmsg_direction + redist_coll->nmsg[!direction];
601  int *ranks_orig
602  = (int *)(redist_coll->all_component_dt + nmsg * redist_coll->num_redists)
603  + (((unsigned)direction-1) & nmsg_send);
604  int *ranks_ = *ranks = xmalloc(nmsg_direction * sizeof (*ranks_));
605  memcpy(ranks_, ranks_orig, nmsg_direction * sizeof (*ranks));
606  return (int)nmsg_direction;
607 }
608 
609 
610 static MPI_Comm
612 
613  Xt_redist_collection redist_coll = xrc(redist);
614 
615  return redist_coll->comm;
616 }
617 
618 /*
619  * Local Variables:
620  * c-basic-offset: 2
621  * coding: utf-8
622  * indent-tabs-mode: nil
623  * show-trailing-whitespace: t
624  * require-trailing-newline: t
625  * End:
626  */
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
const struct xt_redist_vtable * vtable
struct exchanger_cache cache
Xt_exchanger_new exchanger_new
MPI_Datatype datatype
Definition: xt_redist.h:69
struct Xt_redist_msg * msgs
Xt_exchanger * exchangers
MPI_Aint * src_displacements
MPI_Aint * dst_displacements
Xt_redist(* copy)(Xt_redist)
struct Xt_config_ xt_default_config
Definition: xt_config.c:65
implementation of configuration object
int xt_initialized(void)
Definition: xt_init.c:107
void xt_exchanger_s_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data)
Definition: xt_exchanger.c:71
void xt_exchanger_a_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data, Xt_request *request)
Definition: xt_exchanger.c:76
void xt_exchanger_delete(Xt_exchanger exchanger)
Definition: xt_exchanger.c:66
exchanging of data based on information provided by redist's
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)
Definition: xt_exchanger.h:155
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
#define xt_mpi_call(call, comm)
Definition: xt_mpi.h:68
MPI_Datatype xt_redist_get_MPI_Datatype(Xt_redist redist, int rank, enum xt_msg_direction direction)
Definition: xt_redist.c:117
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])
Definition: xt_redist.c:217
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
Definition: xt_redist.c:169
MPI_Datatype xt_create_compound_datatype(size_t count, const MPI_Aint displacements[count], const MPI_Datatype datatypes[count], const int block_lengths[count], MPI_Comm comm)
Definition: xt_redist.c:239
redistribution of data
static void redist_collection_a_exchange(Xt_redist redist, int num_src_arrays, const void **src_data, void **dst_data, Xt_request *request)
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 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
@ DEFFAULT_DATATYPE_CACHE_SIZE
static size_t lookup_cache_index(unsigned num_redists, const MPI_Aint src_displacements[num_redists], const MPI_Aint dst_displacements[num_redists], const MPI_Aint(*cached_src_displacements)[num_redists], const MPI_Aint(*cached_dst_displacements)[num_redists], size_t cache_size)
static void compute_displ(const void *const *data, unsigned num_redists, MPI_Aint displacements[num_redists])
static void redist_collection_a_exchange1(Xt_redist redist, const void *src_data, void *dst_data, Xt_request *request)
static void init_cache(struct exchanger_cache *cache, size_t cache_size, size_t ntx, unsigned num_redists)
static Xt_redist redist_collection_copy(Xt_redist redist)
static void destruct_cache(struct exchanger_cache *cache, size_t cache_size, size_t ntx, MPI_Comm comm)
static Xt_exchanger get_exchanger(struct Xt_redist_collection_ *redist_coll, const void *const *src_data, void *const *dst_data, unsigned num_redists)
static void redist_collection_s_exchange(Xt_redist redist, int num_src_arrays, const void **src_data, void **dst_data)
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 MPI_Datatype redist_collection_get_MPI_Datatype(Xt_redist redist, int rank, enum xt_msg_direction direction)
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 align_component_dt(unsigned num_redists, unsigned nmsgs, const Xt_redist *redists, int *restrict in_ranks[num_redists], size_t num_ranks[num_redists], int *out_ranks, MPI_Datatype *component_dt, enum xt_msg_direction direction)
static void create_all_dt_for_dir(unsigned num_messages, unsigned 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], MPI_Comm comm)
redistribution of data, non-public declarations
static void xt_redist_msgs_free(size_t n, struct Xt_redist_msg *msgs, MPI_Comm comm)
xt_msg_direction
@ RECV
@ SEND