Yet Another eXchange Tool 0.11.1
Loading...
Searching...
No Matches
xt_idxlist.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#include <stdio.h>
53#include <string.h>
54#ifdef HAVE_PTHREAD
55#include <pthread.h>
56#endif
57
58#include "xt/xt_core.h"
59#include "xt/xt_stripe.h"
60#include "xt_stripe_util.h"
61#include "xt/xt_idxlist.h"
62#include "xt_idxlist_internal.h"
63#include "xt/xt_idxempty.h"
64#include "xt/xt_idxvec.h"
65#include "xt_idxvec_internal.h"
66#include "xt/xt_idxstripes.h"
68#include "xt/xt_mpi.h"
69#include "xt_config_internal.h"
70#include "xt_idxlist_unpack.h"
71#include "core/core.h"
72#include "core/ppm_xfuncs.h"
73#include "instr.h"
74
76
77 idxlist->vtable->delete(idxlist);
78}
79
81 MPI_Comm comm) {
82
83 return idxlist->vtable->get_pack_size(idxlist, comm);
84}
85
86void xt_idxlist_pack(Xt_idxlist idxlist, void *buffer,
87 int buffer_size, int *position,
88 MPI_Comm comm) {
89
90 idxlist->vtable->pack(idxlist, buffer, buffer_size,
91 position, comm);
92}
93
95
96 return idxlist->vtable->copy(idxlist);
97}
98
100{
101 return idxlist->vtable->sorted_copy(idxlist, &xt_default_config);
102}
103
105{
106 return idxlist->vtable->sorted_copy(idxlist, config);
107}
108
110 return idxlist->num_indices;
111}
112
113void xt_idxlist_get_indices(Xt_idxlist idxlist, Xt_int *indices) {
114
115 idxlist->vtable->get_indices(idxlist, indices);
116}
117
118
120 if (idxlist->vtable->get_indices != NULL)
121 return idxlist->vtable->get_indices_const (idxlist);
122
123 die("xt_idxlist_get_indices_const: fatal error: "
124 "get_indices_const not implemented");
125 return NULL;
126}
127
128
130{
131 return idxlist->vtable->get_num_index_stripes(idxlist);
132}
133
134
136 struct Xt_stripe ** stripes,
137 int * num_stripes) {
138
139 size_t num_stripes_
140 = (size_t)(*num_stripes = xt_idxlist_get_num_index_stripes(idxlist));
141 struct Xt_stripe *stripes_ = *stripes = num_stripes_
142 ? xmalloc(num_stripes_ * sizeof (stripes_[0])) : NULL;
143 xt_idxlist_get_index_stripes_keep_buf(idxlist, stripes_, num_stripes_);
144}
145
146void
148 struct Xt_stripe *stripes,
149 size_t num_stripes_alloc)
150{
151 INSTR_DEF(instr_fallback,"xt_idxlist_get_index_stripes.fallback")
152
153 if (idxlist->vtable->get_index_stripes) {
154 idxlist->vtable->get_index_stripes(idxlist, stripes, num_stripes_alloc);
155
156 } else { // fall-back solution
157
158 INSTR_START(instr_fallback);
159
160 size_t num_indices = (size_t)(xt_idxlist_get_num_indices(idxlist));
161
162 Xt_int *indices = xmalloc(num_indices * sizeof (indices[0]));
163
164 xt_idxlist_get_indices(idxlist, indices);
165 xt_convert_indices_to_stripes_buf(num_indices, indices,
166 num_stripes_alloc, stripes);
167 free(indices);
168
169 INSTR_STOP(instr_fallback);
170 }
171}
172
173
174
175
177 Xt_int *idx) {
178
179 return idxlist->vtable->get_index_at_position(idxlist, position, idx);
180}
181
182int
184 int num_pos, Xt_int *indices,
185 Xt_int undef_idx) {
186
187 INSTR_DEF(instr_fallback,"xt_idxlist_get_intersection.fallback")
188
189 if ( idxlist->vtable->get_indices_at_positions ) {
190
191 return idxlist->vtable->get_indices_at_positions(idxlist, positions,
192 num_pos, indices,
193 undef_idx);
194
195 } else {
196
197 INSTR_START(instr_fallback);
198
199 // fallback solution using xt_idxlist_get_index_at_position:
200 int undef_count = 0;
201 for (int ip=0; ip<num_pos; ip++) {
202 if (xt_idxlist_get_index_at_position(idxlist, positions[ip],
203 &indices[ip]) != 0) {
204 indices[ip] = undef_idx;
205 undef_count++;
206 }
207 }
208
209 INSTR_STOP(instr_fallback);
210 return undef_count;
211 }
212}
213
215 int * position) {
216
217 return idxlist->vtable->get_position_of_index(idxlist, idx, position);
218}
219
220int
222 int num_indices, int * positions,
223 int single_match_only) {
224
225 INSTR_DEF(instr_fallback,"xt_idxlist_get_positions_of_indices.fallback")
226
227 size_t num_failed_lookups;
228 if (num_indices > 0) {
229 if (idxlist->vtable->get_positions_of_indices != NULL)
230 num_failed_lookups
231 = idxlist->vtable->get_positions_of_indices(idxlist, indices,
232 (size_t)num_indices,
233 positions,
234 single_match_only);
235 else {
236 INSTR_START(instr_fallback);
237
238 int num_tmp_indices
240 Xt_int *tmp_indices
241 = xmalloc((size_t)num_tmp_indices * sizeof (tmp_indices[0]));
242 xt_idxlist_get_indices(idxlist, tmp_indices);
243 Xt_idxlist tmp_idxvec
244 = xt_idxvec_prealloc_new(tmp_indices, num_tmp_indices);
245 num_failed_lookups
246 = tmp_idxvec->vtable->get_positions_of_indices(tmp_idxvec, indices,
247 (size_t)num_indices,
248 positions,
249 single_match_only);
250 xt_idxlist_delete(tmp_idxvec);
251 free(tmp_indices);
252
253 INSTR_STOP(instr_fallback);
254 }
255 } else
256 num_failed_lookups = 0;
257 assert(num_failed_lookups <= INT_MAX);
258 return (int)num_failed_lookups;
259}
260
261int
263 int num_stripes,
264 const struct Xt_stripe stripes[num_stripes],
265 int *num_ext,
266 struct Xt_pos_ext **pos_ext,
267 int single_match_only)
268{
270 idxlist, num_stripes, stripes, num_ext, pos_ext, single_match_only,
272}
273
274int
276 Xt_idxlist idxlist,
277 int num_stripes,
278 const struct Xt_stripe stripes[num_stripes],
279 int *num_ext,
280 struct Xt_pos_ext **pos_ext,
281 int single_match_only,
282 Xt_config config)
283{
285 return idxlist->vtable->get_pos_exts_of_index_stripes(
286 idxlist,
287 num_stripes, stripes, num_ext, pos_ext, single_match_only, config);
288 else {
289 int num_tmp_stripes
290 = idxlist->vtable->get_num_index_stripes(idxlist);
291 struct Xt_stripes_alloc stripes_alloc
292 = xt_idxstripes_alloc((size_t)num_tmp_stripes);
294 idxlist, stripes_alloc.stripes, (size_t)num_tmp_stripes);
295 Xt_idxlist idxlist_stripes
296 = xt_idxstripes_congeal(stripes_alloc);
297 int retval =
298 idxlist_stripes->vtable->get_pos_exts_of_index_stripes(
299 idxlist_stripes,
300 num_stripes, stripes, num_ext, pos_ext, single_match_only, config);
301 xt_idxlist_delete(idxlist_stripes);
302 return retval;
303 }
304}
305
307 int * position, int offset) {
308
309 return idxlist->vtable->get_position_of_index_off(idxlist, idx,
310 position, offset);
311}
312
313int
315 const Xt_int *indices,
316 int num_indices, int * positions,
317 int * offsets) {
318
319 INSTR_DEF(instr_fallback,"xt_idxlist_get_intersection.fallback")
320
321 if (idxlist->vtable->get_positions_of_indices_off != NULL)
322 return idxlist->vtable->get_positions_of_indices_off(idxlist, indices,
323 num_indices,
324 positions, offsets);
325 INSTR_START(instr_fallback);
326
327 int ret_val = 0;
328 for (int i = 0; i < num_indices; ++i) {
329
330 int temp_position, offset;
331
332 if (offsets == NULL)
333 offset = 0;
334 else
335 offset = offsets[i];
336
337 ret_val
338 = idxlist->vtable->get_position_of_index_off(idxlist, indices[i],
339 &temp_position, offset);
340
341 if (ret_val) break;
342 positions[i] = temp_position;
343 }
344
345 INSTR_STOP(instr_fallback);
346 return ret_val;
347}
348
350
351 return idxlist->vtable->get_min_index(idxlist);
352}
353
355
356 return idxlist->vtable->get_max_index(idxlist);
357}
358
360{
361 return idxlist->vtable->get_sorting(idxlist);
362}
363
364static void
366 Xt_int global_stride[ndim],
367 Xt_int global_start_index, Xt_int position[ndim]) {
368
369 idx = (Xt_int)(idx - global_start_index);
370
371 for (size_t i = 0; i < ndim - 1; ++i) {
372 position[i] = (Xt_int)(idx / global_stride[i]);
373 idx = (Xt_int)(idx % global_stride[i]);
374 }
375
376 position[ndim - 1] = idx;
377}
378
379void xt_idxlist_get_bounding_box(Xt_idxlist idxlist, unsigned ndim,
380 const Xt_int global_size[ndim],
381 Xt_int global_start_index,
382 struct Xt_bounds bounds[ndim]) {
383
384 INSTR_DEF(instr_fallback,"xt_idxlist_get_bounding_box.fallback")
385
386 int num_indices = xt_idxlist_get_num_indices(idxlist);
387
388 if (num_indices == 0) {
389
390 for (size_t i = 0; i < ndim; ++i) {
391 bounds[i].start = 0;
392 bounds[i].size = 0;
393 }
394
395 return;
396
397 } else if (idxlist->vtable->get_bounding_box != NULL) {
398
399 idxlist->vtable->get_bounding_box(idxlist, ndim, global_size,
400 global_start_index, bounds);
401 return;
402 }
403
404 INSTR_START(instr_fallback);
405
406 Xt_int global_stride[ndim];
407
408 global_stride[ndim - 1] = 1;
409
410 for (size_t i = ndim - 2; i < ndim; --i)
411 global_stride[i] = (Xt_int)(global_stride[i+1] * global_size[i+1]);
412
413 Xt_int curr_index;
414 Xt_int curr_position[ndim];
415
416 xt_idxlist_get_index_at_position(idxlist, 0, &curr_index);
417 get_position_in_ndim_space(curr_index, ndim, global_stride,
418 global_start_index, curr_position);
419
420 for (size_t i = 0; i < ndim; ++i) {
421 bounds[i].start = curr_position[i];
422 bounds[i].size = 1;
423 }
424
425 for (int j = 1; j < num_indices; ++j) {
426
427 xt_idxlist_get_index_at_position(idxlist, j, &curr_index);
428 get_position_in_ndim_space(curr_index, ndim, global_stride,
429 global_start_index, curr_position);
430
431 for (size_t i = 0; i < ndim; ++i) {
432
433 if (curr_position[i] < bounds[i].start) {
434
435 bounds[i].size = (Xt_int)(bounds[i].size + curr_position[i] - bounds[i].start);
436 bounds[i].start = curr_position[i];
437
438 } else if (curr_position[i] >= bounds[i].start + bounds[i].size) {
439
440 bounds[i].size = (Xt_int)(curr_position[i] - bounds[i].start + 1);
441 }
442 }
443 }
444
445 INSTR_STOP(instr_fallback);
446}
447
448static Xt_uid nextId = UINT64_C(1);
449#ifdef HAVE_PTHREAD
450static pthread_mutex_t nextIdMutex = PTHREAD_MUTEX_INITIALIZER;
451#endif
452
453Xt_uid
455{
456 Xt_uid thisId;
457#ifdef HAVE_PTHREAD
458 if (pthread_mutex_lock(&nextIdMutex))
459 die("unexpected pthread locking error");
460#endif
461 thisId = nextId;
462 if (!++nextId)
463 die("unique ID counter overflow");
464#ifdef HAVE_PTHREAD
465 if (pthread_mutex_unlock(&nextIdMutex))
466 die("unexpected pthread locking error");
467#endif
468 return thisId;
469}
470
471Xt_uid
473{
474 assert(idxlist->uid);
475 return idxlist->uid;
476}
477
478bool
480 Xt_config config)
481{
482 bool do_convert = false;
483 int pack_code = idxlist->vtable->idxlist_pack_code;
484 if (pack_code == VECTOR || pack_code == COLLECTION) {
485 int num_indices = xt_idxlist_get_num_indices(idxlist),
486 num_stripes = xt_idxlist_get_num_index_stripes(idxlist);
487 do_convert = num_indices > config->idxv_cnv_size
488 && ((size_t)num_indices * sizeof (Xt_int)
489 > (size_t)num_stripes * sizeof (struct Xt_stripe));
490 }
491 return do_convert;
492}
493
494int
499
500
501/*
502 * Local Variables:
503 * c-basic-offset: 2
504 * coding: utf-8
505 * indent-tabs-mode: nil
506 * show-trailing-whitespace: t
507 * require-trailing-newline: t
508 * End:
509 */
int MPI_Comm
Definition core.h:64
#define die(msg)
Definition core.h:131
#define INSTR_STOP(T)
Definition instr.h:69
#define INSTR_DEF(T, S)
Definition instr.h:66
#define INSTR_START(T)
Definition instr.h:68
add versions of standard API functions not returning on error
#define xmalloc(size)
Definition ppm_xfuncs.h:70
const struct xt_idxlist_vtable * vtable
struct Xt_stripe * stripes
size_t(* get_pack_size)(Xt_idxlist, MPI_Comm)
Xt_int(* get_max_index)(Xt_idxlist)
int(* get_position_of_index_off)(Xt_idxlist, Xt_int, int *, int)
int(* get_index_at_position)(Xt_idxlist, int, Xt_int *)
Xt_idxlist(* sorted_copy)(Xt_idxlist, Xt_config)
int(* get_indices_at_positions)(Xt_idxlist idxlist, const int *positions, int num, Xt_int *index, Xt_int undef_idx)
void(* get_index_stripes)(Xt_idxlist, struct Xt_stripe *restrict, size_t)
int(* get_pos_exts_of_index_stripes)(Xt_idxlist, int, const struct Xt_stripe *, int *, struct Xt_pos_ext **, int, Xt_config)
void(* delete)(Xt_idxlist)
void(* pack)(Xt_idxlist, void *, int, int *, MPI_Comm)
Xt_idxlist(* copy)(Xt_idxlist)
int(* get_position_of_index)(Xt_idxlist, Xt_int, int *)
int(* get_num_index_stripes)(Xt_idxlist)
int(* get_sorting)(Xt_idxlist)
void(* get_bounding_box)(Xt_idxlist idxlist, unsigned ndim, const Xt_int global_size[ndim], Xt_int global_start_index, struct Xt_bounds bounds[ndim])
void(* get_indices)(Xt_idxlist, Xt_int *indices)
size_t(* get_positions_of_indices)(Xt_idxlist, Xt_int const *, size_t, int *, int)
Xt_int(* get_min_index)(Xt_idxlist)
Xt_int const *(* get_indices_const)(Xt_idxlist idxlist)
int(* get_positions_of_indices_off)(Xt_idxlist, Xt_int const *, int, int *, int *)
struct Xt_config_ xt_default_config
Definition xt_config.c:203
implementation of configuration object
base definitions header file
uint64_t Xt_uid
Definition xt_core.h:76
XT_INT Xt_int
Definition xt_core.h:72
Xt_int xt_idxlist_get_min_index(Xt_idxlist idxlist)
Definition xt_idxlist.c:349
void xt_idxlist_get_index_stripes_keep_buf(Xt_idxlist idxlist, struct Xt_stripe *stripes, size_t num_stripes_alloc)
Definition xt_idxlist.c:147
int xt_idxlist_is_stripe_conversion_profitable(Xt_idxlist idxlist, Xt_config config)
Definition xt_idxlist.c:495
Xt_int xt_idxlist_get_max_index(Xt_idxlist idxlist)
Definition xt_idxlist.c:354
bool xt_idxlist_is_stripe_conversion_profitable_(Xt_idxlist idxlist, Xt_config config)
Definition xt_idxlist.c:479
int xt_idxlist_get_positions_of_indices_off(Xt_idxlist idxlist, const Xt_int *indices, int num_indices, int *positions, int *offsets)
Definition xt_idxlist.c:314
Xt_uid xt_idxlist_new_uid(void)
Definition xt_idxlist.c:454
int xt_idxlist_get_pos_exts_of_index_stripes_custom(Xt_idxlist idxlist, int num_stripes, const struct Xt_stripe stripes[num_stripes], int *num_ext, struct Xt_pos_ext **pos_ext, int single_match_only, Xt_config config)
Definition xt_idxlist.c:275
Xt_uid xt_idxlist_get_uid(Xt_idxlist idxlist)
Definition xt_idxlist.c:472
static Xt_uid nextId
Definition xt_idxlist.c:448
static void get_position_in_ndim_space(Xt_int idx, unsigned ndim, Xt_int global_stride[ndim], Xt_int global_start_index, Xt_int position[ndim])
Definition xt_idxlist.c:365
index list declaration
Xt_idxlist xt_idxlist_sorted_copy(Xt_idxlist idxlist)
Definition xt_idxlist.c:99
int xt_idxlist_get_positions_of_indices(Xt_idxlist idxlist, const Xt_int *indices, int num_indices, int *positions, int single_match_only)
Definition xt_idxlist.c:221
const Xt_int * xt_idxlist_get_indices_const(Xt_idxlist idxlist)
Definition xt_idxlist.c:119
int xt_idxlist_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)
Definition xt_idxlist.c:176
void xt_idxlist_get_indices(Xt_idxlist idxlist, Xt_int *indices)
Definition xt_idxlist.c:113
int xt_idxlist_get_num_index_stripes(Xt_idxlist idxlist)
Definition xt_idxlist.c:129
int xt_idxlist_get_position_of_index_off(Xt_idxlist idxlist, Xt_int index, int *position, int offset)
Definition xt_idxlist.c:306
Xt_idxlist xt_idxlist_sorted_copy_custom(Xt_idxlist idxlist, Xt_config config)
Definition xt_idxlist.c:104
void xt_idxlist_pack(Xt_idxlist idxlist, void *buffer, int buffer_size, int *position, MPI_Comm comm)
Definition xt_idxlist.c:86
size_t xt_idxlist_get_pack_size(Xt_idxlist idxlist, MPI_Comm comm)
Definition xt_idxlist.c:80
int xt_idxlist_get_indices_at_positions(Xt_idxlist idxlist, const int *positions, int num_pos, Xt_int *indices, Xt_int undef_idx)
Definition xt_idxlist.c:183
void xt_idxlist_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
Definition xt_idxlist.c:135
void xt_idxlist_get_bounding_box(Xt_idxlist idxlist, unsigned ndim, const Xt_int global_size[ndim], Xt_int global_start_index, struct Xt_bounds bounds[ndim])
Definition xt_idxlist.c:379
int xt_idxlist_get_pos_exts_of_index_stripes(Xt_idxlist idxlist, int num_stripes, const struct Xt_stripe stripes[num_stripes], int *num_ext, struct Xt_pos_ext **pos_ext, int single_match_only)
Definition xt_idxlist.c:262
Xt_idxlist xt_idxlist_copy(Xt_idxlist idxlist)
Definition xt_idxlist.c:94
int xt_idxlist_get_sorting(Xt_idxlist idxlist)
Definition xt_idxlist.c:359
int xt_idxlist_get_position_of_index(Xt_idxlist idxlist, Xt_int index, int *position)
Definition xt_idxlist.c:214
void xt_idxlist_delete(Xt_idxlist idxlist)
Definition xt_idxlist.c:75
Provide non-public declarations common to all index lists.
#define xt_idxlist_get_num_indices(idxlist)
@ VECTOR
@ COLLECTION
struct Xt_stripes_alloc xt_idxstripes_alloc(size_t num_stripes)
Xt_idxlist xt_idxstripes_congeal(struct Xt_stripes_alloc stripes_alloc)
Xt_idxlist xt_idxvec_prealloc_new(const Xt_int *idxvec, int num_indices)
Definition xt_idxvec.c:307
utility routines for MPI
size_t xt_convert_indices_to_stripes_buf(size_t num_indices, const Xt_int *restrict indices, size_t num_stripes_alloc, struct Xt_stripe *stripes)
Definition xt_stripe.c:126