Yet Another eXchange Tool  DO_NOT_EDIT_HERE
xt_exchanger_simple_base.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 <mpi.h>
52 
53 #include "core/core.h"
54 #include "core/ppm_xfuncs.h"
55 #include "xt/xt_mpi.h"
56 #include "xt_mpi_internal.h"
57 #include "xt_redist_internal.h"
58 #include "xt_exchanger.h"
60 
61 static Xt_exchanger
63  MPI_Comm newComm, int new_tag_offset);
64 static void xt_exchanger_simple_base_delete(Xt_exchanger exchanger);
66  const void * src_data,
67  void * dst_data);
68 static int
70  enum xt_msg_direction direction,
71  int **ranks);
72 
73 static MPI_Datatype
75  int rank,
76  enum xt_msg_direction direction);
77 
78 
85 };
86 
88 
90 
91  const struct xt_exchanger_vtable * vtable;
92 
93  int nsend, nrecv;
97  struct Xt_redist_msg msgs[];
98 };
99 
100 static Xt_exchanger_simple_base
102 {
103  Xt_exchanger_simple_base exchanger;
104  size_t header_size = sizeof(*exchanger),
105  body_size = nmsg * sizeof (exchanger->msgs[0]);
106  exchanger = xmalloc(header_size + body_size);
107  exchanger->vtable = &exchanger_simple_base_vtable;
108  return exchanger;
109 }
110 
113  struct Xt_redist_msg * send_msgs,
114  struct Xt_redist_msg * recv_msgs,
115  MPI_Comm comm, int tag_offset,
117 
118  if (func == NULL)
119  Xt_abort(comm, "ERROR(xt_exchanger_simple_base_new): invalid exchange "
120  "function pointer", __FILE__, __LINE__);
121 
122  assert((nsend >= 0) & (nrecv >= 0));
123  size_t nmsg = (size_t)nsend + (size_t)nrecv;
124  Xt_exchanger_simple_base exchanger
126  exchanger->comm = comm, exchanger->tag_offset = tag_offset;
127  exchanger->nsend = nsend;
128  xt_redist_msgs_strided_copy((size_t)nsend, send_msgs, sizeof (send_msgs[0]),
129  exchanger->msgs, sizeof (exchanger->msgs[0]),
130  comm);
131  exchanger->nrecv = nrecv;
132  xt_redist_msgs_strided_copy((size_t)nrecv, recv_msgs, sizeof (recv_msgs[0]),
133  exchanger->msgs + nsend,
134  sizeof (exchanger->msgs[0]),
135  comm);
136  exchanger->func = func;
137 
138  xt_exchanger_internal_optimize((size_t)nsend, exchanger->msgs,
139  sizeof(exchanger->msgs[0]),
140  comm);
141 
142  xt_exchanger_internal_optimize((size_t)nrecv, exchanger->msgs + nsend,
143  sizeof(exchanger->msgs[0]),
144  comm);
145 
146  return (Xt_exchanger)exchanger;
147 }
148 
149 static Xt_exchanger
151  MPI_Comm new_comm, int new_tag_offset)
152 {
153  Xt_exchanger_simple_base exchanger_sb =
154  (Xt_exchanger_simple_base)exchanger;
155  int nsend = exchanger_sb->nsend,
156  nrecv = exchanger_sb->nrecv;
157  size_t nmsg = (size_t)nsend + (size_t)nrecv;
158  Xt_exchanger_simple_base exchanger_copy
160  exchanger_copy->nsend = nsend;
161  exchanger_copy->nrecv = nrecv;
162  exchanger_copy->func = exchanger_sb->func;
163  struct Xt_redist_msg *restrict new_msgs = exchanger_copy->msgs,
164  *restrict orig_msgs = exchanger_sb->msgs;
165  xt_redist_msgs_strided_copy(nmsg, orig_msgs, sizeof (*orig_msgs),
166  new_msgs, sizeof (*new_msgs),
167  new_comm);
168  exchanger_copy->comm = new_comm;
169  exchanger_copy->tag_offset = new_tag_offset;
170  return (Xt_exchanger)exchanger_copy;
171 }
172 
173 
175 
176  Xt_exchanger_simple_base exchanger_sb =
177  (Xt_exchanger_simple_base)exchanger;
178 
179  size_t nmsg = (size_t)exchanger_sb->nsend + (size_t)exchanger_sb->nrecv;
180  struct Xt_redist_msg *restrict msgs = exchanger_sb->msgs;
181  xt_redist_msgs_strided_destruct(nmsg, msgs, exchanger_sb->comm,
182  sizeof (msgs[0]));
183  free(exchanger_sb);
184 }
185 
187  const void * src_data,
188  void * dst_data) {
189 
190  Xt_exchanger_simple_base exchanger_sb =
191  (Xt_exchanger_simple_base)exchanger;
192 
193  int nsend = exchanger_sb->nsend;
194  exchanger_sb->func(src_data, dst_data, nsend,
195  exchanger_sb->nrecv, exchanger_sb->msgs,
196  exchanger_sb->msgs + (size_t)nsend,
197  exchanger_sb->tag_offset, exchanger_sb->comm);
198 }
199 
200 static MPI_Datatype
202  int rank,
203  enum xt_msg_direction direction)
204 {
205  Xt_exchanger_simple_base exchanger_sb =
206  (Xt_exchanger_simple_base)exchanger;
207  size_t nsend = (size_t)exchanger_sb->nsend,
208  nrecv = (size_t)exchanger_sb->nrecv,
209  nmsg = direction == SEND ? nsend : nrecv,
210  ofs = direction == SEND ? 0 : nsend;
211  struct Xt_redist_msg *restrict msgs = exchanger_sb->msgs + ofs;
212  MPI_Datatype datatype_copy = MPI_DATATYPE_NULL;
213  for (size_t i = 0; i < nmsg; ++i)
214  if (msgs[i].rank == rank) {
215  xt_mpi_call(MPI_Type_dup(msgs[i].datatype, &datatype_copy),
216  exchanger_sb->comm);
217  break;
218  }
219  return datatype_copy;
220 }
221 
222 static int
224  enum xt_msg_direction direction,
225  int **ranks)
226 {
227  Xt_exchanger_simple_base exchanger_sb = (Xt_exchanger_simple_base)exchanger;
228  size_t nmsg;
229  struct Xt_redist_msg *restrict msgs;
230  if (direction == SEND) {
231  nmsg = (size_t)exchanger_sb->nsend;
232  msgs = exchanger_sb->msgs;
233  } else {
234  nmsg = (size_t)exchanger_sb->nrecv;
235  msgs = exchanger_sb->msgs + (size_t)exchanger_sb->nsend;
236  }
237  int *restrict ranks_ = *ranks = xmalloc(nmsg * sizeof (*ranks_));
238  for (size_t i = 0; i < nmsg; ++i)
239  ranks_[i] = msgs[i].rank;
240  return (int)nmsg;
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  */
xt_simple_exchange_func func
static void xt_exchanger_simple_base_s_exchange(Xt_exchanger exchanger, const void *src_data, void *dst_data)
const struct xt_exchanger_vtable * vtable
static int xt_exchanger_simple_base_get_msg_ranks(Xt_exchanger exchanger, enum xt_msg_direction direction, int **ranks)
xt_msg_direction
redistribution of data, non-public declarations
Xt_exchanger xt_exchanger_simple_base_new(int nsend, int nrecv, struct Xt_redist_msg *send_msgs, struct Xt_redist_msg *recv_msgs, MPI_Comm comm, int tag_offset, xt_simple_exchange_func func)
add versions of standard API functions not returning on error
static MPI_Datatype xt_exchanger_simple_base_get_MPI_Datatype(Xt_exchanger exchanger, int rank, enum xt_msg_direction direction)
void(* xt_simple_exchange_func)(const void *src_data, void *dst_data, int nsend, int nrecv, struct Xt_redist_msg *send_msgs, struct Xt_redist_msg *recv_msgs, int tag_offset, MPI_Comm comm)
static Xt_exchanger xt_exchanger_simple_base_copy(Xt_exchanger exchanger, MPI_Comm newComm, int new_tag_offset)
Xt_exchanger(* copy)(Xt_exchanger, MPI_Comm, int)
Definition: xt_exchanger.h:65
static void xt_exchanger_simple_base_delete(Xt_exchanger exchanger)
static Xt_exchanger_simple_base xt_exchanger_simple_base_alloc(size_t nmsg)
MPI_Datatype datatype
static const struct xt_exchanger_vtable exchanger_simple_base_vtable
void xt_exchanger_internal_optimize(size_t n, void *msgs, size_t msg_type_size, MPI_Comm comm)
Definition: xt_exchanger.c:87
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
struct Xt_exchanger_simple_base_ * Xt_exchanger_simple_base
exchanging of data based on information provided by redist&#39;s
#define xt_mpi_call(call, comm)
Definition: xt_mpi.h:68
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
#define xmalloc(size)
Definition: ppm_xfuncs.h:66
int MPI_Comm
Definition: core.h:64
utility routines for MPI