Yet Another eXchange Tool  0.9.0
xt_request_msgs_packed.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 <stdlib.h>
52 #include <string.h>
53 
54 #include "core/ppm_xfuncs.h"
55 #include "xt/xt_mpi.h"
56 
58 #include "xt_mpi_internal.h"
59 #include "xt_request_internal.h"
60 
61 static void xt_request_msgs_wait_packed(Xt_request request);
63 
64 static const struct Xt_request_vtable request_msgs_packed_vtable = {
65 
68 };
69 
71 
73 
74  const struct Xt_request_vtable * vtable;
75  MPI_Request * requests;
80  MPI_Datatype * datatypes;
81  void ** buffers;
82  void * unpacked_data;
83 };
84 
86  const MPI_Request *requests,
87  MPI_Comm comm, int n_packed,
88  int n_tmp_buffers,
89  const MPI_Datatype * datatypes,
90  void ** packed_data,
91  void ** tmp_buffers,
92  void * unpacked_data) {
93 
94  assert(n_requests >= 0 && n_packed >= 0 && n_tmp_buffers >= 0);
95  Xt_request_msgs_packed request = xmalloc(1 * sizeof(*request));
96 
98  request->n_requests = n_requests;
99  request->requests = xmalloc((size_t)n_requests * sizeof(*request->requests) +
100  (size_t)n_requests *
101  sizeof(*request->ops_completed_buffer));
102  request->ops_completed_buffer =
103  (int *)(request->requests + (size_t)n_requests);
104  memcpy(request->requests, requests,
105  (size_t)n_requests * sizeof(*request->requests));
106  request->comm = comm;
107  request->n_packed = n_packed;
108  request->n_tmp_buffers = n_tmp_buffers;
109  request->datatypes = xmalloc((size_t)n_packed * sizeof(*request->datatypes));
110  for (int i = 0; i < n_packed; ++i)
111  xt_mpi_call(MPI_Type_dup(datatypes[i], request->datatypes + i), comm);
112  request->buffers =
113  xmalloc(((size_t)n_packed + (size_t)n_tmp_buffers)
114  * sizeof(*request->buffers));
115  memcpy(request->buffers, packed_data,
116  (size_t)n_packed * sizeof(*request->buffers));
117  memcpy(request->buffers + n_packed, tmp_buffers,
118  (size_t)n_tmp_buffers * sizeof(*request->buffers));
119  request->unpacked_data = unpacked_data;
120 
121  return (Xt_request)request;
122 }
123 
124 static void unpack_data(Xt_request_msgs_packed request_msgs_packed) {
125 
126  for (int i = 0; i < request_msgs_packed->n_packed; ++i) {
127  int position = 0, buffer_size;
128  xt_mpi_call(MPI_Pack_size(1, request_msgs_packed->datatypes[i],
129  request_msgs_packed->comm, &buffer_size),
130  request_msgs_packed->comm);
131  xt_mpi_call(MPI_Unpack(request_msgs_packed->buffers[i], buffer_size,
132  &position, request_msgs_packed->unpacked_data,
133  1, request_msgs_packed->datatypes[i],
134  request_msgs_packed->comm),
135  request_msgs_packed->comm);
136  }
137 }
138 
139 static void free_request(Xt_request_msgs_packed request_msgs_packed) {
140 
141  for (int i = 0; i < request_msgs_packed->n_packed +
142  request_msgs_packed->n_tmp_buffers; ++i)
143  free(request_msgs_packed->buffers[i]);
144  free(request_msgs_packed->buffers);
145  for (int i = 0; i < request_msgs_packed->n_packed; ++i)
146  xt_mpi_call(MPI_Type_free(request_msgs_packed->datatypes+i),
147  request_msgs_packed->comm);
148  free(request_msgs_packed->datatypes);
149  free(request_msgs_packed->requests);
150  free(request_msgs_packed);
151 }
152 
154 
155  Xt_request_msgs_packed request_msgs_packed = (Xt_request_msgs_packed)request;
156 
157  xt_mpi_call(MPI_Waitall(request_msgs_packed->n_requests,
158  request_msgs_packed->requests, MPI_STATUSES_IGNORE),
159  request_msgs_packed->comm);
160 
161  unpack_data(request_msgs_packed);
162  free_request(request_msgs_packed);
163 }
164 
166 
167  Xt_request_msgs_packed request_msgs_packed = (Xt_request_msgs_packed)request;
168 
169  int flag =
170  xt_mpi_test_some(&(request_msgs_packed->n_requests),
171  request_msgs_packed->requests,
172  request_msgs_packed->ops_completed_buffer,
173  request_msgs_packed->comm);
174 
175  if (flag) {
176  unpack_data(request_msgs_packed);
177  free_request(request_msgs_packed);
178  }
179 
180  return flag;
181 }
182 
183 /*
184  * Local Variables:
185  * c-basic-offset: 2
186  * coding: utf-8
187  * indent-tabs-mode: nil
188  * show-trailing-whitespace: t
189  * require-trailing-newline: t
190  * End:
191  */
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
const struct Xt_request_vtable * vtable
void(* wait)(Xt_request request)
bool xt_mpi_test_some(int *restrict num_req, MPI_Request *restrict req, int *restrict ops_completed, MPI_Comm comm)
Definition: xt_mpi.c:892
utility routines for MPI
#define xt_mpi_call(call, comm)
Definition: xt_mpi.h:68
Provide non-public declarations common to all requests.
static void xt_request_msgs_wait_packed(Xt_request request)
Xt_request xt_request_msgs_packed_new(int n_requests, const MPI_Request *requests, MPI_Comm comm, int n_packed, int n_tmp_buffers, const MPI_Datatype *datatypes, void **packed_data, void **tmp_buffers, void *unpacked_data)
struct Xt_request_msgs_packed_ * Xt_request_msgs_packed
static void free_request(Xt_request_msgs_packed request_msgs_packed)
static int xt_request_msgs_test_packed(Xt_request request)
static void unpack_data(Xt_request_msgs_packed request_msgs_packed)
static const struct Xt_request_vtable request_msgs_packed_vtable