Yet Another eXchange Tool 0.11.4
Loading...
Searching...
No Matches
xt_mpi_ddt_gen.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://dkrz-sw.gitlab-pages.dkrz.de/yaxt/
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
53#include <mpi.h>
54#include "core/ppm_xfuncs.h"
55#include "xt/xt_mpi.h"
56#include "xt_mpi_internal.h"
57#include "xt_mpi_ddt_cache.h"
58
64#define COMPACT_DT
65
66#ifndef COMPACT_DT
67static MPI_Datatype copy_mpi_datatype(MPI_Datatype old_type, MPI_Comm comm) {
68
69 MPI_Datatype datatype;
70
71 xt_mpi_call(MPI_Type_dup(old_type, &datatype), comm);
72
73 return datatype;
74}
75
76static MPI_Datatype
77gen_mpi_datatype_simple(int displacement, MPI_Datatype old_type, MPI_Comm comm)
78{
79 MPI_Datatype datatype;
80
81 xt_mpi_call(MPI_Type_create_indexed_block(1, 1, &displacement, old_type,
82 &datatype), comm);
83 xt_mpi_call(MPI_Type_commit(&datatype), comm);
84
85 return datatype;
86}
87
88static MPI_Datatype
89gen_mpi_datatype_contiguous(int displacement, int blocklength,
90 MPI_Datatype old_type, MPI_Comm comm) {
91
92 MPI_Datatype datatype;
93
94 if (displacement == 0)
95 xt_mpi_call(MPI_Type_contiguous(blocklength, old_type, &datatype),
96 comm);
97 else
99 &displacement, old_type,
100 &datatype), comm);
101
102 xt_mpi_call(MPI_Type_commit(&datatype), comm);
103
104 return datatype;
105
106}
107
108static MPI_Datatype
109gen_mpi_datatype_vector(int count, int blocklength, int stride,
110 int offset, MPI_Datatype old_type, MPI_Comm comm) {
111
112 MPI_Datatype datatype;
113
114 xt_mpi_call(MPI_Type_vector(count, blocklength, stride, old_type,
115 &datatype), comm);
116 if (offset != 0) {
117
118 MPI_Datatype datatype_;
119 int hindexed_blocklength = 1;
120 MPI_Aint old_type_size, old_type_lb;
121
122 xt_mpi_call(MPI_Type_get_extent(old_type, &old_type_lb,
123 &old_type_size), comm);
124
125 MPI_Aint displacement = offset * old_type_size;
126
127 xt_mpi_call(MPI_Type_create_hindexed(1, &hindexed_blocklength,
128 &displacement, datatype, &datatype_),
129 comm);
130 xt_mpi_call(MPI_Type_free(&datatype), comm);
131 datatype = datatype_;
132 }
133 xt_mpi_call(MPI_Type_commit(&datatype), comm);
134
135 return datatype;
136}
137
138static MPI_Datatype
139gen_mpi_datatype_indexed_block(int const * displacements, int blocklength,
140 int count, MPI_Datatype old_type, MPI_Comm comm)
141{
142 MPI_Datatype datatype;
143
145 (void *)displacements,
146 old_type, &datatype), comm);
147 xt_mpi_call(MPI_Type_commit(&datatype), comm);
148
149 return datatype;
150}
151
152static MPI_Datatype
153gen_mpi_datatype_indexed(const int *displacements, const int *blocklengths,
154 int count, MPI_Datatype old_type, MPI_Comm comm) {
155
156 MPI_Datatype datatype;
157
158 xt_mpi_call(MPI_Type_indexed(count, (int*)blocklengths, (void*)displacements,
159 old_type, &datatype), comm);
160 xt_mpi_call(MPI_Type_commit(&datatype), comm);
161
162 return datatype;
163}
164
165static inline int
166check_for_vector_type(const int *displacements, const int *blocklengths,
167 int count) {
168
169 int blocklength = blocklengths[0];
170
171 for (int i = 1; i < count; ++i)
172 if (blocklengths[i] != blocklength)
173 return 0;
174
175 int stride = displacements[1] - displacements[0];
176
177 for (int i = 1; i + 1 < count; ++i)
178 if (displacements[i+1] - displacements[i] != stride)
179 return 0;
180
181 return 1;
182}
183
184static inline int check_for_indexed_block_type(const int *blocklengths,
185 int count) {
186
187 int blocklength = blocklengths[0];
188
189 for (int i = 1; i < count; ++i)
190 if (blocklengths[i] != blocklength)
191 return 0;
192
193 return 1;
194}
195#endif
196
197#ifdef COMPACT_DT
198static MPI_Datatype
199xt_mpi_generate_compact_datatype_block(const int *disp, const int *blocklengths,
200 int count, MPI_Datatype old_type,
201 MPI_Comm comm);
202
203static MPI_Datatype
204xt_mpi_generate_compact_datatype(int const *disp, int disp_len,
205 MPI_Datatype old_type, MPI_Comm comm);
206#endif
207
208MPI_Datatype
209xt_mpi_generate_datatype_block(const int *displacements,
210 const int *blocklengths,
211 int count, MPI_Datatype old_type,
212 MPI_Comm comm) {
213
214#ifdef COMPACT_DT
215 return xt_mpi_generate_compact_datatype_block(displacements, blocklengths,
216 count, old_type, comm);
217#else
218 MPI_Datatype datatype;
219
220 if (count == 0)
221 datatype = MPI_DATATYPE_NULL;
222 else if (count == 1 && blocklengths[0] == 1 && displacements[0] == 0)
223 datatype = copy_mpi_datatype(old_type, comm);
224 else if (count == 1 && blocklengths[0] == 1)
225 datatype = gen_mpi_datatype_simple(displacements[0], old_type, comm);
226 else if (count == 1)
227 datatype = gen_mpi_datatype_contiguous(displacements[0], blocklengths[0],
228 old_type, comm);
229 else if (check_for_vector_type(displacements, blocklengths, count))
230 datatype = gen_mpi_datatype_vector(count, blocklengths[0],
231 displacements[1] - displacements[0],
232 displacements[0], old_type, comm);
233 else if (check_for_indexed_block_type(blocklengths, count))
234 datatype = gen_mpi_datatype_indexed_block(displacements, blocklengths[0],
235 count, old_type, comm);
236 else
237 datatype = gen_mpi_datatype_indexed(displacements, blocklengths, count,
238 old_type, comm);
239
240 return datatype;
241#endif
242}
243
244MPI_Datatype
245xt_mpi_generate_datatype(int const * displacements, int count,
246 MPI_Datatype old_type, MPI_Comm comm)
247{
248 if (count <= 0)
249 return MPI_DATATYPE_NULL;
250
251#ifdef COMPACT_DT
252 return xt_mpi_generate_compact_datatype(displacements, count, old_type, comm);
253#else
254 int * blocklengths = xmalloc((size_t)count * sizeof(*blocklengths));
255 int new_count = 0;
256 {
257 int i = 0;
258 do {
259 int j = 1;
260 while (i + j < count && displacements[i] + j == displacements[i + j])
261 ++j;
262 blocklengths[new_count++] = j;
263 i += j;
264 } while (i < count);
265 }
266
267 int * tmp_displ = NULL;
268 const int *displ;
269
270 if (new_count != count) {
271
272 tmp_displ = xmalloc((size_t)new_count * sizeof(*tmp_displ));
273
274 int offset = 0;
275
276 for (int i = 0; i < new_count; ++i) {
277
278 tmp_displ[i] = displacements[offset];
279 offset += blocklengths[i];
280 }
281
282 displ = tmp_displ;
283 } else
284 displ = displacements;
285
286 MPI_Datatype datatype;
287
288 datatype = xt_mpi_generate_datatype_block(displ, blocklengths, new_count,
289 old_type, comm);
290
291 free(blocklengths);
292
293 free(tmp_displ);
294
295 return datatype;
296#endif
297}
298
299#define XT_MPI_STRP_PRS_PREFIX
300#define XT_MPI_STRP_PRS_UNITSTRIDE 1
301#define XT_MPI_STRP_PRS_AOFS_TYPE int
302#define XT_MPI_STRP_PRS_DISP_ADJUST(val) ((val) * params->old_type_extent)
303#define XT_MPI_STRP_PRS_BLOCK_VEC_CREATE Xt_mpi_ddt_cache_acquire_vector
304#define XT_MPI_STRP_PRS_INDEXED_BLOCK_CREATE \
305 Xt_mpi_ddt_cache_acquire_indexed_block
306#define XT_MPI_STRP_PRS_INDEXED_CREATE Xt_mpi_ddt_cache_acquire_indexed
308#undef XT_MPI_STRP_PRS_PREFIX
309#undef XT_MPI_STRP_PRS_UNITSTRIDE
310#undef XT_MPI_STRP_PRS_AOFS_TYPE
311#undef XT_MPI_STRP_PRS_DISP_ADJUST
312#undef XT_MPI_STRP_PRS_BLOCK_VEC_CREATE
313#undef XT_MPI_STRP_PRS_INDEXED_BLOCK_CREATE
314#undef XT_MPI_STRP_PRS_INDEXED_CREATE
315
316#if MPI_VERSION < 3
317static inline int
318XtMPI_Type_create_hindexed_block(int count, int blocklength,
319 const MPI_Aint array_of_displacements[],
320 MPI_Datatype oldtype, MPI_Datatype *newtype)
321{
322 size_t count_ = count > 0 ? (size_t)count : 0;
323 MPI_Datatype *restrict oldtypes = xmalloc(count_ * sizeof (*oldtypes)
324 + count_ * sizeof (int));
325 int *restrict blocklengths = (int *)(oldtypes + count_);
326 for (size_t i = 0; i < count_; ++i) {
327 blocklengths[i] = blocklength;
328 oldtypes[i] = oldtype;
329 }
330 int rc = MPI_Type_create_struct(count, blocklengths,
331 CAST_MPI_SEND_BUF(array_of_displacements),
332 oldtypes, newtype);
333 free(oldtypes);
334 return rc;
335}
336
337#define MPI_Type_create_hindexed_block XtMPI_Type_create_hindexed_block
338#endif
339
340#define XT_MPI_STRP_PRS_PREFIX a
341#define XT_MPI_STRP_PRS_UNITSTRIDE params->old_type_extent
342#define XT_MPI_STRP_PRS_AOFS_TYPE MPI_Aint
343#define XT_MPI_STRP_PRS_DISP_ADJUST(val) (val)
344#define XT_MPI_STRP_PRS_BLOCK_VEC_CREATE Xt_mpi_ddt_cache_acquire_hvector
345#define XT_MPI_STRP_PRS_INDEXED_BLOCK_CREATE \
346 Xt_mpi_ddt_cache_acquire_hindexed_block
347#define XT_MPI_STRP_PRS_INDEXED_CREATE Xt_mpi_ddt_cache_acquire_hindexed
349
350
351static MPI_Datatype
352xt_mpi_generate_compact_datatype_block(const int *disp, const int *blocklengths,
353 int count, MPI_Datatype old_type,
354 MPI_Comm comm)
355{
356 struct Xt_mpi_strp_prs_params params;
358 MPI_Datatype dt = xt_mpi_ddt_block_gen(count, disp, blocklengths, &params);
360 return dt;
361}
362
363MPI_Datatype
364xt_mpi_ddt_block_gen(int count, const int *disp, const int *blocklengths,
365 struct Xt_mpi_strp_prs_params *params)
366{
367 size_t count_ = (size_t)0;
368 for (int i=0; i<count; ++i)
369 count_ += (size_t)(blocklengths[i] > 0);
370 if (count_ < 1) return MPI_DATATYPE_NULL;
371 struct Xt_offset_ext *restrict v = xmalloc(sizeof(*v) * count_);
372 size_t j=0;
373 for (size_t i=0; i<(size_t)count; ++i) {
374 v[j].start = disp[i];
375 v[j].stride = 1;
376 int bl = blocklengths[i];
377 v[j].size = bl;
378 j += (size_t)(bl > 0);
379 }
380 MPI_Datatype dt = parse_stripe(v, count_, params);
381 free(v);
382 return dt;
383}
384
385MPI_Datatype
386xt_mpi_generate_compact_datatype(const int *disp, int disp_len,
387 MPI_Datatype old_type, MPI_Comm comm)
388{
389 if (disp_len < 1) return MPI_DATATYPE_NULL;
390
391 size_t vlen = xt_disp2ext_count((size_t)disp_len, disp);
392 struct Xt_offset_ext *v = xmalloc(sizeof(*v) * vlen);
393 xt_disp2ext((size_t)disp_len, disp, v);
394 struct Xt_mpi_strp_prs_params params;
396 MPI_Datatype dt = parse_stripe(v, vlen, &params);
398 free(v);
399 return dt;
400}
401
402
403
404/*
405 * Local Variables:
406 * c-basic-offset: 2
407 * coding: utf-8
408 * indent-tabs-mode: nil
409 * show-trailing-whitespace: t
410 * require-trailing-newline: t
411 * End:
412 */
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
int MPI_Type_create_struct(int count, XT_MPI2_CONST int array_of_block_lengths[], XT_MPI2_CONST MPI_Aint array_of_displacements[], XT_MPI2_CONST MPI_Datatype array_of_types[], MPI_Datatype *newtype)
int MPI_Type_create_indexed_block(int count, int blocklength, XT_MPI2_CONST int array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_free(MPI_Datatype *datatype)
int MPI_Type_indexed(int count, XT_MPI2_CONST int array_of_blocklengths[], XT_MPI2_CONST int array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_create_hindexed(int count, XT_MPI2_CONST int array_of_blocklengths[], XT_MPI2_CONST MPI_Aint array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_dup(MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype *newtype)
int MPI_Type_commit(MPI_Datatype *datatype)
size_t xt_disp2ext_count(size_t disp_len, const int *disp)
Definition xt_mpi.c:92
size_t xt_disp2ext(size_t disp_len, const int *disp, struct Xt_offset_ext *restrict v)
Definition xt_mpi.c:133
utility routines for MPI
#define xt_mpi_call(call, comm)
Definition xt_mpi.h:68
MPI_Datatype xt_mpi_generate_datatype(int const *displacements, int count, MPI_Datatype old_type, MPI_Comm comm)
static MPI_Datatype xt_mpi_generate_compact_datatype(int const *disp, int disp_len, MPI_Datatype old_type, MPI_Comm comm)
static MPI_Datatype xt_mpi_generate_compact_datatype_block(const int *disp, const int *blocklengths, int count, MPI_Datatype old_type, MPI_Comm comm)
MPI_Datatype xt_mpi_ddt_block_gen(int count, const int *disp, const int *blocklengths, struct Xt_mpi_strp_prs_params *params)
static int XtMPI_Type_create_hindexed_block(int count, int blocklength, const MPI_Aint array_of_displacements[], MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_Datatype xt_mpi_generate_datatype_block(const int *displacements, const int *blocklengths, int count, MPI_Datatype old_type, MPI_Comm comm)
static void xt_destroy_mpi_strp_prs_params(struct Xt_mpi_strp_prs_params *params)
static void xt_init_mpi_strp_prs_params(struct Xt_mpi_strp_prs_params *params, MPI_Datatype old_type, MPI_Comm comm)