Yet Another eXchange Tool 0.11.4
Loading...
Searching...
No Matches
xt_mpi_stripe_parse_func.h
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
51#define XT_TOKEN_PASTE2_(a,b) a##b
52#define XT_TOKEN_PASTE2(a,b) XT_TOKEN_PASTE2_(a,b)
53#define XT_TOKEN_PASTE3_(a,b,c) a##b##c
54#define XT_TOKEN_PASTE3(a,b,c) XT_TOKEN_PASTE3_(a,b,c)
55
56#define XT_MPI_OFFSET_EXT \
57 struct XT_TOKEN_PASTE3(Xt_,XT_MPI_STRP_PRS_PREFIX,offset_ext)
58#define XT_MPI_STRP_PRS_MATCH_BLOCK_VEC \
59 XT_TOKEN_PASTE2(XT_MPI_STRP_PRS_PREFIX,match_block_vec)
60#define XT_MPI_STRP_PRS_MATCH_INDEXED \
61 XT_TOKEN_PASTE2(XT_MPI_STRP_PRS_PREFIX,match_indexed)
62#define XT_MPI_STRP_PRS_MATCH_SIMPLE_VEC \
63 XT_TOKEN_PASTE2(XT_MPI_STRP_PRS_PREFIX,match_simple_vec)
64#define XT_MPI_STRP_PRS_MATCH_CONTIGUOUS \
65 XT_TOKEN_PASTE2(XT_MPI_STRP_PRS_PREFIX,match_contiguous)
66#define XT_MPI_STRP_PRS_GEN_FALLBACK_TYPE \
67 XT_TOKEN_PASTE2(XT_MPI_STRP_PRS_PREFIX,gen_fallback_type)
68#define XT_MPI_STRP_PRS_ENTRY \
69 XT_TOKEN_PASTE3(parse_,XT_MPI_STRP_PRS_PREFIX,stripe)
70#define XT_MPI_STRP_PRS_ENTRY_LIBINTERNAL \
71 XT_TOKEN_PASTE3(xt_mpi_parse_,XT_MPI_STRP_PRS_PREFIX,stripe)
72#define XT_MPI_STRP_PRS_DRIVER \
73 XT_TOKEN_PASTE3(xt_mpi_generate_datatype_,XT_MPI_STRP_PRS_PREFIX,stripe)
74
78static bool
80 (size_t *pstart_,
81 const XT_MPI_OFFSET_EXT *v,
82 size_t vlen,
83 MPI_Aint *disp, MPI_Datatype *dt,
84 struct Xt_mpi_strp_prs_params *params) {
85 // using at least 3 vectors
86 size_t p = *pstart_, pstart = p;
87 if (p+2 >= vlen || v[p].stride != XT_MPI_STRP_PRS_UNITSTRIDE
88 || v[p+1].stride != XT_MPI_STRP_PRS_UNITSTRIDE ) return false;
89 int bl = v[p].size;
90 assert(bl > 0);
91 if (v[p+1].size != bl) return false;
92
93 XT_MPI_STRP_PRS_AOFS_TYPE vstride = v[p+1].start - v[p].start;
94
95 p += 2;
96 while( p < vlen && v[p].stride == XT_MPI_STRP_PRS_UNITSTRIDE
97 && v[p].size == bl && v[p].start - v[p-1].start == vstride ) {
98 p++;
99 }
100 size_t n = p - pstart;
101 if (n<3) return false;
102 *pstart_ = p;
103
104 XT_MPI_STRP_PRS_AOFS_TYPE disp_ = n == vlen ? 0 : v[pstart].start;
105 *disp = XT_MPI_STRP_PRS_DISP_ADJUST(disp_);
106
108 &params->ddt_list, (int)n, bl, vstride, params->old_type, params->comm);
109
110 XT_MPI_STRP_PRS_AOFS_TYPE start = v[pstart].start - disp_;
111
112 if (start) {
113 MPI_Datatype dt1 = *dt;
114 // (start != 0) => add offset:
116 1, &(int){1},
117 &(MPI_Aint){XT_MPI_STRP_PRS_DISP_ADJUST(start)}, dt1, dt),
118 params->comm);
119 Xt_mpi_ddt_cache_entry_release(&params->ddt_list, &dt1, params->comm);
120 }
121 return n != 0;
122}
123
124static bool
126 size_t *pstart_,
127 const XT_MPI_OFFSET_EXT *v,
128 size_t vlen,
129 MPI_Aint *disp, MPI_Datatype *dt,
130 struct Xt_mpi_strp_prs_params *params) {
131 // we only accept non-trivial matches
132 size_t p = *pstart_, pstart = p;
133 if (p >= vlen || v[p].stride != XT_MPI_STRP_PRS_UNITSTRIDE || v[p].size < 2)
134 return false;
135
136 do
137 ++p;
138 while (p < vlen && v[p].stride == XT_MPI_STRP_PRS_UNITSTRIDE);
139
140 size_t n = p - pstart;
141
142 if (n < 2) return false;
143 *pstart_ = p;
144
145 XT_MPI_STRP_PRS_AOFS_TYPE start = n == vlen ? 0 : v[pstart].start;
146 *disp = XT_MPI_STRP_PRS_DISP_ADJUST(start);
147 XT_MPI_STRP_PRS_AOFS_TYPE *restrict d
148 = xmalloc(n * sizeof (int) + n * sizeof (*d));
149 int *restrict bl = (int * restrict)(d + n);
150 bool hom_bl = true;
151 d[0] = v[pstart].start - start;
152 int bl0 = bl[0] = v[pstart].size;
153 for (size_t i = 1; i < n; i++) {
154 size_t iv = pstart + i;
155 d[i] = v[iv].start - start;
156 bl[i] = v[iv].size;
157 hom_bl &= (bl[i] == bl0);
158 }
159
160 if (hom_bl) {
162 &params->ddt_list, (int)n, bl0, d, params->old_type, params->comm);
163 } else {
165 &params->ddt_list, (int)n, bl, d, params->old_type, params->comm);
166 }
167
168 free(d);
169 return n != 0;
170}
171
172static bool
174 size_t *pstart_,
175 const XT_MPI_OFFSET_EXT *v,
176 size_t vlen,
177 MPI_Aint *disp, MPI_Datatype *dt,
178 struct Xt_mpi_strp_prs_params *params) {
179 // we only accept non-trivial matches (nsteps>2) with stride /= 1
180 // using only one vector from v
181 size_t p = *pstart_;
182 if (p >= vlen) return false;
183 int nstrides = v[p].size;
184 XT_MPI_STRP_PRS_AOFS_TYPE stride = v[p].stride;
185 if (nstrides < 2 || stride == XT_MPI_STRP_PRS_UNITSTRIDE ) return false;
186
187 *pstart_ = p + 1;
188
189 XT_MPI_STRP_PRS_AOFS_TYPE disp_ = vlen > 1 ? v[p].start : 0;
190 *disp = XT_MPI_STRP_PRS_DISP_ADJUST(disp_);
191
193 &params->ddt_list, nstrides, 1, stride, params->old_type, params->comm);
194
195 XT_MPI_STRP_PRS_AOFS_TYPE start = v[p].start - disp_;
196 if (start) {
197 MPI_Datatype dt1 = *dt;
198
199 // (start != 0) => add offset:
201 1, &(int){1},
202 &(MPI_Aint){XT_MPI_STRP_PRS_DISP_ADJUST(start)}, dt1, dt),
203 params->comm);
204 Xt_mpi_ddt_cache_entry_release(&params->ddt_list, &dt1, params->comm);
205 }
206 return nstrides != 0;
207}
208
209static bool
211 size_t *pstart_,
212 const XT_MPI_OFFSET_EXT *v,
213 size_t vlen,
214 MPI_Aint *restrict disp, MPI_Datatype *dt,
215 struct Xt_mpi_strp_prs_params *params) {
216 size_t p = *pstart_;
217 if (p >= vlen || v[p].stride != XT_MPI_STRP_PRS_UNITSTRIDE || v[p].size < 2)
218 return false;
219
220 XT_MPI_STRP_PRS_AOFS_TYPE disp_ = vlen > 1 ? v[p].start : 0;
221 *disp = XT_MPI_STRP_PRS_DISP_ADJUST(disp_);
222 XT_MPI_STRP_PRS_AOFS_TYPE d = v[p].start - disp_;
223
224 if (!d)
226 &params->ddt_list, v[p].size, params->old_type, params->comm);
227 else
229 &params->ddt_list, 1, v[p].size, &d, params->old_type, params->comm);
230
231 *pstart_ = p+1;
232 return true;
233}
234
235static void
237 size_t set_start, size_t set_end,
238 const XT_MPI_OFFSET_EXT *v,
239 size_t vlen,
240 MPI_Aint *disp,
241 MPI_Datatype *dt, struct Xt_mpi_strp_prs_params *params) {
242 size_t ia = set_start;
243 size_t ib = set_end;
244 if (ib <= ia || ib > vlen) return;
245
246 int n = 0;
247 for (size_t i=ia; i < ib; i++)
248 n += v[i].size;
249
250 /* todo: given the guarantees for v that fceb584 introduced,
251 * this check should never fire */
252 assert(n>0);
253
254 // generate absolute datatype if ia == 0 && ib == vlen,
255 // else generate relative datatype that gets embedded by the caller
256 XT_MPI_STRP_PRS_AOFS_TYPE start = (ia == 0 && ib == vlen) ? 0 : v[ia].start;
257
258 *disp = XT_MPI_STRP_PRS_DISP_ADJUST(start);
259
260 XT_MPI_STRP_PRS_AOFS_TYPE *restrict d = xmalloc(sizeof (*d) * (size_t)n);
261 size_t p=0;
262#ifndef NDEBUG
263 /* did any element of v have non-positive size? */
264 bool found_np = false;
265#endif
266
267 for (size_t i=ia; i < ib; i++) {
268#ifndef NDEBUG
269 found_np |= v[i].size <= 0;
270#endif
271 size_t v_i_size = (size_t)(v[i].size > 0 ? v[i].size : 0);
272 for (size_t k=0; k < v_i_size; k++) {
273 d[p] = v[i].start + (XT_MPI_STRP_PRS_AOFS_TYPE)k * v[i].stride - start;
274 p++;
275 }
276 }
277 assert(!found_np);
278
279 if (n==1 && d[0] == 0) {
280 *dt = params->old_type;
281 } else {
283 &params->ddt_list, n, 1, d, params->old_type, params->comm);
284 }
285 free(d);
286}
287
288static MPI_Datatype
290 const XT_MPI_OFFSET_EXT *v,
291 size_t vlen,
292 struct Xt_mpi_strp_prs_params *params);
293
294MPI_Datatype
296 size_t vlen,
297 const XT_MPI_OFFSET_EXT v[vlen],
298 struct Xt_mpi_strp_prs_params *params)
299{
300 return XT_MPI_STRP_PRS_ENTRY(v, vlen, params);
301}
302
303static MPI_Datatype
305 const XT_MPI_OFFSET_EXT *v,
306 size_t vlen,
307 struct Xt_mpi_strp_prs_params *params)
308{
309 /* [set_start,set_end) describes the prefix of non-matching
310 * elements in v that then need to be handled with gen_fallback_type */
311 size_t set_start = 0, set_end = 0;
312 MPI_Aint *restrict wdisp
313 = xmalloc(sizeof(MPI_Datatype) * vlen + sizeof (MPI_Aint) * vlen);
314 MPI_Datatype *restrict wdt = (MPI_Datatype *)(wdisp + vlen);
315 /* [p,vlen) is the part of v that still needs matching performed */
316 /* m is the index of the next datatype and displacements to write
317 * to wdt and wdisp respectively */
318 size_t p = 0, m = 0;
319 while (p<vlen) {
320 /* depending on whether there is a non-empty prefix, the datatype
321 * and displacement corresponding to a match need to be written
322 * to wdt[m+1] and wdisp[m+1] or wdt[m] and wdisp[m] respectively */
323 size_t mm = m + (set_start < set_end);
325 &p, v, vlen,
326 wdisp+mm, wdt+mm, params))
328 &p, v, vlen,
329 wdisp+mm, wdt+mm, params))
331 &p, v, vlen,
332 wdisp+mm, wdt+mm, params))
334 &p, v, vlen,
335 wdisp+mm, wdt+mm, params)) ) {
336 /* in case a match is found, generate fallback datatype for
337 * non-matching, preceding extents */
338 if (set_start < set_end) {
340 set_start, set_end, v, vlen,
341 wdisp+m, wdt+m, params);
342 m++;
343 }
344 m++;
345 set_start = p;
346 } else {
347 /* assign ext investigated last to prefix */
348 set_end = ++p;
349 }
350 }
351 if (set_start < set_end) {
353 set_start, set_end, v, vlen,
354 wdisp+m, wdt+m, params);
355 m++;
356 }
357 size_t wlen = m;
358 MPI_Datatype result_dt, old_type = params->old_type;
359 if (wlen == 1 ) {
360 assert(wdisp[0] == 0);
361 if (wdt[0] == old_type)
362 xt_mpi_call(MPI_Type_dup(old_type, wdt), params->comm);
363 result_dt = wdt[0];
364 } else {
365 int *restrict wblocklength
366 = wlen * sizeof (int) <= (vlen - wlen) * sizeof (*wdt)
367 ? (void *)(wdt + wlen) : xmalloc(wlen * sizeof (*wblocklength));
368 for(size_t i=0; i<wlen; i++)
369 wblocklength[i] = 1;
371 &params->ddt_list, (int)wlen, wblocklength, wdisp, wdt, params->comm);
372 if (wlen * sizeof (int) > (vlen - wlen) * sizeof (*wdt))
373 free(wblocklength);
374 for (size_t i = 0; i < wlen; i++)
375 if (wdt[i] != old_type)
376 Xt_mpi_ddt_cache_entry_release(&params->ddt_list, wdt+i, params->comm);
377 }
378 xt_mpi_call(MPI_Type_commit(&result_dt), params->comm);
379 free(wdisp);
380 return result_dt;
381}
382
383MPI_Datatype
385 int count, MPI_Datatype old_type,
386 MPI_Comm comm)
387{
388 size_t count_ = (size_t)0;
389 for (int i=0; i<count; ++i)
390 count_ += (size_t)(v[i].size > 0);
391 if (count_ < 1) return MPI_DATATYPE_NULL;
392 const XT_MPI_OFFSET_EXT *v_comp;
393 XT_MPI_OFFSET_EXT *v_comp_;
394 if ((size_t)count != count_) {
395 v_comp = v_comp_ = xmalloc(count_ * sizeof (*v_comp));
396 for (size_t i=0, j=0; i<(size_t)count; ++i) {
397 v_comp_[j] = v[i];
398 j+= v[i].size > 0;
399 }
400 } else {
401 v_comp_ = NULL;
402 v_comp = v;
403 }
404 struct Xt_mpi_strp_prs_params params;
406 MPI_Datatype dt = XT_MPI_STRP_PRS_ENTRY(v_comp, count_, &params);
407 if ((size_t)count != count_)
408 free(v_comp_);
409 return dt;
410}
411
412
413#undef XT_MPI_STRP_PRS_ENTRY
414#undef XT_MPI_STRP_PRS_GEN_FALLBACK_TYPE
415#undef XT_MPI_STRP_PRS_MATCH_CONTIGUOUS
416#undef XT_MPI_STRP_PRS_MATCH_SIMPLE_VEC
417#undef XT_MPI_STRP_PRS_MATCH_INDEXED
418#undef XT_MPI_STRP_PRS_MATCH_BLOCK_VEC
419#undef XT_MPI_OFFSET_EXT
420
421#undef XT_TOKEN_PASTE2
422#undef XT_TOKEN_PASTE2_
423#undef XT_TOKEN_PASTE3
424#undef XT_TOKEN_PASTE3_
425
426/*
427 * Local Variables:
428 * c-basic-offset: 2
429 * coding: utf-8
430 * indent-tabs-mode: nil
431 * show-trailing-whitespace: t
432 * require-trailing-newline: t
433 * End:
434 */
int MPI_Comm
Definition core.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:70
struct Xt_mpiddt_list ddt_list
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_commit(MPI_Datatype *datatype)
#define xt_mpi_call(call, comm)
Definition xt_mpi.h:68
MPI_Datatype Xt_mpi_ddt_cache_acquire_contiguous(struct Xt_mpiddt_list *ddt_list, int count, MPI_Datatype oldtype, MPI_Comm comm)
MPI_Datatype Xt_mpi_ddt_cache_acquire_struct(struct Xt_mpiddt_list *ddt_list, int count, const int blocklength[count], const MPI_Aint disp[count], const MPI_Datatype oldtype[count], MPI_Comm comm)
void Xt_mpi_ddt_cache_entry_release(struct Xt_mpiddt_list *ddt_list, MPI_Datatype *dt, MPI_Comm comm)
#define XT_MPI_STRP_PRS_UNITSTRIDE
#define XT_MPI_STRP_PRS_BLOCK_VEC_CREATE
#define XT_MPI_STRP_PRS_DISP_ADJUST(val)
#define XT_MPI_STRP_PRS_INDEXED_BLOCK_CREATE
#define XT_MPI_STRP_PRS_AOFS_TYPE
#define XT_MPI_STRP_PRS_INDEXED_CREATE
static void xt_init_mpi_strp_prs_params(struct Xt_mpi_strp_prs_params *params, MPI_Datatype old_type, MPI_Comm comm)
#define XT_MPI_OFFSET_EXT
#define XT_MPI_STRP_PRS_DRIVER
#define XT_MPI_STRP_PRS_ENTRY
#define XT_MPI_STRP_PRS_GEN_FALLBACK_TYPE
#define XT_MPI_STRP_PRS_ENTRY_LIBINTERNAL
#define XT_MPI_STRP_PRS_MATCH_CONTIGUOUS
#define XT_MPI_STRP_PRS_MATCH_INDEXED
#define XT_MPI_STRP_PRS_MATCH_SIMPLE_VEC
#define XT_MPI_STRP_PRS_MATCH_BLOCK_VEC