Yet Another eXchange Tool  DO_NOT_EDIT_HERE
xt_redist.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 <limits.h>
51 #include <stdbool.h>
52 #include <stdlib.h>
53 
54 #include "core/core.h"
55 #include "xt/xt_core.h"
56 #include "xt/xt_redist.h"
57 #include "xt/xt_mpi.h"
58 #include "core/ppm_xfuncs.h"
59 #include "xt_redist_internal.h"
60 
62 
63  return redist->vtable->copy(redist);
64 }
65 
67 
68  redist->vtable->delete(redist);
69 }
70 
71 void xt_redist_s_exchange(Xt_redist redist, int num_arrays,
72  const void **src_data, void **dst_data) {
73 
74  redist->vtable->s_exchange(redist, num_arrays, src_data, dst_data);
75 }
76 
77 void xt_redist_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data) {
78 
79  redist->vtable->s_exchange1(redist, src_data, dst_data);
80 }
81 
82 MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank) {
83 
84  return redist->vtable->get_send_MPI_Datatype(redist, rank);
85 }
86 
87 MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank) {
88 
89  return redist->vtable->get_recv_MPI_Datatype(redist, rank);
90 }
91 
93 
94  return redist->vtable->get_MPI_Comm(redist);
95 }
96 
98  int **ranks)
99 {
100  return redist->vtable->get_msg_ranks(redist, direction, ranks);
101 }
102 
103 
104 void
106  struct Xt_redist_msg *restrict src,
107  size_t src_stride,
108  struct Xt_redist_msg *restrict dst,
109  size_t dst_stride,
110  MPI_Comm comm) {
111 
112 
113  unsigned char *restrict src_store = (unsigned char *)src,
114  *restrict dst_store = (unsigned char *)dst;
115  for (size_t i = 0; i < n; ++i) {
116  struct Xt_redist_msg *restrict src_msg
117  = (struct Xt_redist_msg *)(void *)(src_store + i * src_stride),
118  *dst_msg = (struct Xt_redist_msg *)(void *)(dst_store + i * dst_stride);
119  dst_msg->rank = src_msg->rank;
120  xt_mpi_call(MPI_Type_dup(src_msg->datatype, &(dst_msg->datatype)), comm);
121  }
122 }
123 
124 void xt_redist_msgs_strided_destruct(size_t n, struct Xt_redist_msg *msgs,
125  MPI_Comm comm, size_t ofs_stride) {
126 
127  unsigned char *restrict msgs_store = (unsigned char *)msgs;
128  for (size_t i = 0; i < n; ++i) {
129  MPI_Datatype *dt
130  = &(((struct Xt_redist_msg *)(void *)(msgs_store + i * ofs_stride))->datatype);
131  if (*dt != MPI_DATATYPE_NULL)
132  xt_mpi_call(MPI_Type_free(dt), comm);
133  }
134 }
135 
136 void
137 xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm) {
138  int result;
139 
140  for (int i = 0; i < num_redists; ++i) {
141 
142  xt_mpi_call(MPI_Comm_compare(xt_redist_get_MPI_Comm(redists[i]),
143  comm, &result), comm);
144 
145  if ((result != MPI_IDENT) && (result != MPI_CONGRUENT))
146  Xt_abort(comm, "ERROR: MPI communicators do not match; cannot build "
147  "redist_collection_static\n", __FILE__, __LINE__);
148  }
149 }
150 
151 size_t
152 xt_ranks_uniq_count(size_t num_rank_sets,
153  size_t *restrict num_ranks,
154  const int *ranks[num_rank_sets])
155 {
156  size_t rank_pos[num_rank_sets];
157  for (size_t j = 0; j < num_rank_sets; ++j)
158  rank_pos[j] = 0;
159  bool ranks_left;
160  size_t num_messages = 0;
161  do {
162  int min_rank = INT_MAX;
163  /* find minimal rank in list, guaranteed to be smaller than comm_size */
164  for (size_t j = 0; j < num_rank_sets; ++j)
165  if (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] < min_rank)
166  min_rank = ranks[j][rank_pos[j]];
167  ranks_left = false;
168  /* increment list index for all redists matching minimal rank and
169  * see if any ranks are left */
170  for (size_t j = 0; j < num_rank_sets; ++j) {
171  rank_pos[j]
172  += (rank_pos[j] < num_ranks[j] && ranks[j][rank_pos[j]] == min_rank);
173  ranks_left |= (rank_pos[j] < num_ranks[j]);
174  }
175  ++num_messages;
176  } while (ranks_left);
177  return num_messages;
178 }
179 
180 MPI_Datatype
181 xt_create_compound_datatype(size_t num_redists,
182  const MPI_Aint displacements[num_redists],
183  const MPI_Datatype datatypes[num_redists],
184  const int block_lengths[num_redists],
185  MPI_Comm comm)
186 {
187  size_t num_datatypes = 0;
188  /* allocate more than max_auto_dt datatype items from heap */
189  enum { max_auto_dt = 8 };
190  for (size_t i = 0; i < num_redists; ++i)
191  num_datatypes += (datatypes[i] != MPI_DATATYPE_NULL);
192  MPI_Datatype *datatypes_, dt_auto[max_auto_dt];
193  MPI_Aint *displacements_, disp_auto[max_auto_dt];
194  int *block_lengths_, bl_auto[max_auto_dt];
195 
196  if (num_datatypes != num_redists) {
197  if (num_datatypes > max_auto_dt) {
198  datatypes_ = xmalloc(num_datatypes * sizeof(*datatypes_));
199  displacements_ = xmalloc(num_datatypes * sizeof(*displacements_));
200  block_lengths_ = xmalloc(num_datatypes * sizeof(*block_lengths_));
201  } else {
202  datatypes_ = dt_auto;
203  displacements_ = disp_auto;
204  block_lengths_ = bl_auto;
205  }
206  num_datatypes = 0;
207 
208  for (size_t i = 0; i < num_redists; ++i) {
209  if (datatypes[i] != MPI_DATATYPE_NULL) {
210 
211  datatypes_[num_datatypes] = datatypes[i];
212  displacements_[num_datatypes] = displacements[i];
213  block_lengths_[num_datatypes] = block_lengths[i];
214  ++num_datatypes;
215  }
216  }
217  } else {
218  datatypes_ = (MPI_Datatype *)datatypes;
219  displacements_ = (MPI_Aint *)displacements;
220  block_lengths_ = (int *)block_lengths;
221  }
222  MPI_Datatype datatype;
223  if (num_datatypes > 1)
224  xt_mpi_call(MPI_Type_create_struct((int)num_datatypes, block_lengths_,
225  displacements_, datatypes_, &datatype),
226  comm);
227  else if (displacements_[0] == 0)
228  xt_mpi_call(MPI_Type_dup(datatypes_[0], &datatype), comm);
229  else
230  xt_mpi_call(MPI_Type_create_hindexed(1, (int [1]){1}, displacements_,
231  datatypes_[0], &datatype), comm);
232 
233  xt_mpi_call(MPI_Type_commit(&datatype), comm);
234 
235  if (num_datatypes != num_redists && num_datatypes > max_auto_dt) {
236  free(datatypes_);
237  free(displacements_);
238  }
239 
240  return datatype;
241 }
242 
243 /*
244  * Local Variables:
245  * c-basic-offset: 2
246  * coding: utf-8
247  * indent-tabs-mode: nil
248  * show-trailing-whitespace: t
249  * require-trailing-newline: t
250  * End:
251  */
base definitions header file
xt_msg_direction
void xt_redist_check_comms(Xt_redist *redists, int num_redists, MPI_Comm comm)
Definition: xt_redist.c:137
redistribution of data, non-public declarations
Xt_redist(* copy)(Xt_redist)
MPI_Comm(* get_MPI_Comm)(Xt_redist)
add versions of standard API functions not returning on error
MPI_Datatype(* get_send_MPI_Datatype)(Xt_redist, int)
const struct xt_redist_vtable * vtable
MPI_Datatype(* get_recv_MPI_Datatype)(Xt_redist, int)
MPI_Datatype xt_create_compound_datatype(size_t num_redists, const MPI_Aint displacements[num_redists], const MPI_Datatype datatypes[num_redists], const int block_lengths[num_redists], MPI_Comm comm)
Definition: xt_redist.c:181
void(* s_exchange1)(Xt_redist, const void *, void *)
redistribution of data
void(* s_exchange)(Xt_redist, int, const void **, void **)
void xt_redist_s_exchange(Xt_redist redist, int num_arrays, const void **src_data, void **dst_data)
Definition: xt_redist.c:71
void xt_redist_s_exchange1(Xt_redist redist, const void *src_data, void *dst_data)
Definition: xt_redist.c:77
void xt_redist_delete(Xt_redist redist)
Definition: xt_redist.c:66
MPI_Comm xt_redist_get_MPI_Comm(Xt_redist redist)
Definition: xt_redist.c:92
MPI_Datatype datatype
void(* delete)(Xt_redist)
void xt_redist_msgs_strided_destruct(size_t n, struct Xt_redist_msg *msgs, MPI_Comm comm, size_t ofs_stride)
Definition: xt_redist.c:124
int xt_redist_get_msg_ranks(Xt_redist redist, enum xt_msg_direction direction, int **ranks)
Definition: xt_redist.c:97
#define xt_mpi_call(call, comm)
Definition: xt_mpi.h:68
MPI_Datatype xt_redist_get_send_MPI_Datatype(Xt_redist redist, int rank)
Definition: xt_redist.c:82
int(* get_msg_ranks)(Xt_redist, enum xt_msg_direction, int **)
void xt_redist_msgs_strided_copy(size_t n, struct Xt_redist_msg *restrict src, size_t src_stride, struct Xt_redist_msg *restrict dst, size_t dst_stride, MPI_Comm comm)
Definition: xt_redist.c:105
MPI_Datatype xt_redist_get_recv_MPI_Datatype(Xt_redist redist, int rank)
Definition: xt_redist.c:87
#define xmalloc(size)
Definition: ppm_xfuncs.h:66
size_t xt_ranks_uniq_count(size_t num_rank_sets, size_t *restrict num_ranks, const int *ranks[num_rank_sets])
Definition: xt_redist.c:152
int MPI_Comm
Definition: core.h:64
utility routines for MPI
Xt_redist xt_redist_copy(Xt_redist redist)
Definition: xt_redist.c:61