Yet Another eXchange Tool  0.9.0
xt_redist_collection_static.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 
55 #include <mpi.h>
56 
57 #include "core/core.h"
58 #include "core/ppm_xfuncs.h"
59 #include "xt/xt_mpi.h"
60 #include "xt_mpi_internal.h"
63 #include "ensure_array_size.h"
64 #include "xt/xt_redist.h"
65 #include "xt_redist_internal.h"
66 #include "xt_config_internal.h"
67 
68 
69 static size_t
71  const MPI_Aint *displacements,
72  const Xt_redist *redists,
73  size_t num_redists, MPI_Comm comm,
74  enum xt_msg_direction direction)
75 {
76  size_t num_ranks[num_redists];
77  int *restrict ranks[num_redists];
78 
79  size_t num_messages = xt_redist_agg_msg_count(num_redists, direction,
80  redists, num_ranks, ranks);
81  /* get lists of ranks to send/receive message to/from */
82  size_t rank_pos[num_redists];
83  for (size_t j = 0; j < num_redists; ++j)
84  rank_pos[j] = 0;
85  struct Xt_redist_msg *p = NULL;
86  if (num_messages) {
87  MPI_Datatype datatypes[num_redists];
88  int block_lengths[num_redists];
89  for (size_t i = 0; i < num_redists; ++i)
90  block_lengths[i] = 1;
91  p = xmalloc(sizeof (*p) * num_messages);
92  for (size_t i = 0; i < num_messages; ++i) {
93  int min_rank = INT_MAX;
94  for (size_t j = 0; j < num_redists; ++j)
95  if (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] < min_rank)
96  min_rank = ranks[j][rank_pos[j]];
97 
98  for (size_t j = 0; j < num_redists; ++j)
99  datatypes[j] =
100  (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank)
101  ? xt_redist_get_MPI_Datatype(redists[j], min_rank, direction)
102  : MPI_DATATYPE_NULL;
103 
104  p[i].rank = min_rank;
105  p[i].datatype
106  = xt_create_compound_datatype(num_redists, displacements, datatypes,
107  block_lengths, comm);
108  for (size_t j = 0; j < num_redists; ++j) {
109  if (datatypes[j] != MPI_DATATYPE_NULL)
110  xt_mpi_call(MPI_Type_free(datatypes+j), comm);
111  rank_pos[j]
112  += (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank);
113  }
114  }
115  }
116  for (size_t j = 0; j < num_redists; ++j)
117  free(ranks[j]);
118  *msgs = p;
119  return num_messages;
120 }
121 
122 Xt_redist
123 xt_redist_collection_static_new(Xt_redist *redists, int num_redists,
124  const MPI_Aint src_displacements[num_redists],
125  const MPI_Aint dst_displacements[num_redists],
126  MPI_Comm comm)
127 {
129  redists, num_redists, src_displacements, dst_displacements, comm,
131 }
132 
133 Xt_redist
135  Xt_redist * redists, int num_redists,
136  const MPI_Aint src_displacements[num_redists],
137  const MPI_Aint dst_displacements[num_redists],
138  MPI_Comm comm, Xt_config config) {
139  // ensure that yaxt is initialized
140  assert(xt_initialized());
141 
142  struct Xt_redist_msg *send_msgs, *recv_msgs;
143 
144  int tag_offset;
145  MPI_Comm new_comm = xt_mpi_comm_smart_dup(comm, &tag_offset);
146 
147  xt_redist_check_comms(redists, num_redists, comm);
148 
149  size_t num_redists_ = num_redists >= 0 ? (size_t)num_redists : 0;
150  size_t nsend
151  = generate_msg_infos(&send_msgs, src_displacements, redists, num_redists_,
152  new_comm, SEND);
153 
154  size_t nrecv
155  = generate_msg_infos(&recv_msgs, dst_displacements, redists, num_redists_,
156  new_comm, RECV);
157 
158  Xt_redist redist_collection =
160  (int)nsend, (int)nrecv, send_msgs, recv_msgs, new_comm, config);
161 
162  xt_redist_msgs_free(nsend, send_msgs, new_comm);
163  xt_redist_msgs_free(nrecv, recv_msgs, new_comm);
164  xt_mpi_comm_smart_dedup(&new_comm, tag_offset);
165  return redist_collection;
166 }
167 
168 /*
169  * Local Variables:
170  * c-basic-offset: 2
171  * coding: utf-8
172  * indent-tabs-mode: nil
173  * show-trailing-whitespace: t
174  * require-trailing-newline: t
175  * End:
176  */
int MPI_Comm
Definition: core.h:64
add versions of standard API functions not returning on error
#define xmalloc(size)
Definition: ppm_xfuncs.h:70
MPI_Datatype datatype
Definition: xt_redist.h:69
struct Xt_config_ xt_default_config
Definition: xt_config.c:65
implementation of configuration object
int xt_initialized(void)
Definition: xt_init.c:107
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
Xt_redist xt_redist_collection_static_new(Xt_redist *redists, int num_redists, const MPI_Aint src_displacements[num_redists], const MPI_Aint dst_displacements[num_redists], MPI_Comm comm)
static size_t generate_msg_infos(struct Xt_redist_msg **msgs, const MPI_Aint *displacements, const Xt_redist *redists, size_t num_redists, MPI_Comm comm, enum xt_msg_direction direction)
Xt_redist xt_redist_collection_static_custom_new(Xt_redist *redists, int num_redists, const MPI_Aint src_displacements[num_redists], const MPI_Aint dst_displacements[num_redists], MPI_Comm comm, Xt_config config)
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
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)