Yet Another eXchange Tool  0.9.0
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://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 <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"
67 #include "xt_idxstripes_internal.h"
68 #include "xt/xt_mpi.h"
69 #include "xt_idxlist_unpack.h"
70 #include "core/core.h"
71 #include "core/ppm_xfuncs.h"
72 #include "instr.h"
73 
75 
76  idxlist->vtable->delete(idxlist);
77 }
78 
80  MPI_Comm comm) {
81 
82  return idxlist->vtable->get_pack_size(idxlist, comm);
83 }
84 
85 void xt_idxlist_pack(Xt_idxlist idxlist, void *buffer,
86  int buffer_size, int *position,
87  MPI_Comm comm) {
88 
89  idxlist->vtable->pack(idxlist, buffer, buffer_size,
90  position, comm);
91 }
92 
94 
95  return idxlist->vtable->copy(idxlist);
96 }
97 
99  return idxlist->num_indices;
100 }
101 
102 void xt_idxlist_get_indices(Xt_idxlist idxlist, Xt_int *indices) {
103 
104  idxlist->vtable->get_indices(idxlist, indices);
105 }
106 
107 
109  if (idxlist->vtable->get_indices != NULL)
110  return idxlist->vtable->get_indices_const (idxlist);
111 
112  die("xt_idxlist_get_indices_const: fatal error: "
113  "get_indices_const not implemented");
114  return NULL;
115 }
116 
117 
119  struct Xt_stripe ** stripes,
120  int * num_stripes) {
121 
122  *stripes = NULL;
123  *num_stripes = 0;
124  xt_idxlist_get_index_stripes_keep_buf(idxlist, stripes, num_stripes);
125 }
126 
128  struct Xt_stripe ** stripes,
129  int * num_stripes) {
130 
131  INSTR_DEF(instr_fallback,"xt_idxlist_get_index_stripes.fallback")
132 
133  if (idxlist->vtable->get_index_stripes != NULL) {
134  idxlist->vtable->get_index_stripes(idxlist, stripes, num_stripes);
135 
136  } else { // fall-back solution
137 
138  INSTR_START(instr_fallback);
139 
140  int num_indices = xt_idxlist_get_num_indices(idxlist);
141 
142  Xt_int *indices = xmalloc((size_t)num_indices * sizeof (indices[0]));
143 
144  xt_idxlist_get_indices(idxlist, indices);
145 
146  xt_convert_indices_to_stripes_keep_buf(indices, num_indices,
147  stripes, num_stripes);
148 
149  free(indices);
150 
151  INSTR_STOP(instr_fallback);
152  }
153 }
154 
155 
156 
157 
159  Xt_int *idx) {
160 
161  return idxlist->vtable->get_index_at_position(idxlist, position, idx);
162 }
163 
164 int
165 xt_idxlist_get_indices_at_positions(Xt_idxlist idxlist, const int *positions,
166  int num_pos, Xt_int *indices,
167  Xt_int undef_idx) {
168 
169  INSTR_DEF(instr_fallback,"xt_idxlist_get_intersection.fallback")
170 
171  if ( idxlist->vtable->get_indices_at_positions ) {
172 
173  return idxlist->vtable->get_indices_at_positions(idxlist, positions,
174  num_pos, indices,
175  undef_idx);
176 
177  } else {
178 
179  INSTR_START(instr_fallback);
180 
181  // fallback solution using xt_idxlist_get_index_at_position:
182  int undef_count = 0;
183  for (int ip=0; ip<num_pos; ip++) {
184  if (xt_idxlist_get_index_at_position(idxlist, positions[ip],
185  &indices[ip]) != 0) {
186  indices[ip] = undef_idx;
187  undef_count++;
188  }
189  }
190 
191  INSTR_STOP(instr_fallback);
192  return undef_count;
193  }
194 }
195 
197  int * position) {
198 
199  return idxlist->vtable->get_position_of_index(idxlist, idx, position);
200 }
201 
202 int
204  int num_indices, int * positions,
205  int single_match_only) {
206 
207  INSTR_DEF(instr_fallback,"xt_idxlist_get_positions_of_indices.fallback")
208 
209  if (idxlist->vtable->get_positions_of_indices != NULL)
210  return idxlist->vtable->get_positions_of_indices(idxlist, indices,
211  num_indices,
212  positions,
213  single_match_only);
214  else {
215  INSTR_START(instr_fallback);
216 
217  int num_tmp_indices;
218  num_tmp_indices = xt_idxlist_get_num_indices(idxlist);
219  Xt_int *tmp_indices;
220  tmp_indices = xmalloc((size_t)num_tmp_indices * sizeof (tmp_indices[0]));
221  xt_idxlist_get_indices(idxlist, tmp_indices);
222  Xt_idxlist tmp_idxvec;
223  tmp_idxvec = xt_idxvec_prealloc_new(tmp_indices, num_tmp_indices);
224  int retval
225  = tmp_idxvec->vtable->get_positions_of_indices(tmp_idxvec, indices,
226  num_indices, positions,
227  single_match_only);
228  xt_idxlist_delete(tmp_idxvec);
229  free(tmp_indices);
230 
231  INSTR_STOP(instr_fallback);
232  return retval;
233  }
234 }
235 
236 int
238  int num_stripes,
239  const struct Xt_stripe stripes[num_stripes],
240  int *num_ext,
241  struct Xt_pos_ext **pos_ext,
242  int single_match_only)
243 {
245  return idxlist->vtable->get_pos_exts_of_index_stripes(
246  idxlist,
247  num_stripes, stripes, num_ext, pos_ext, single_match_only);
248  else {
249  int num_tmp_stripes;
250  struct Xt_stripe *tmp_stripes;
251  xt_idxlist_get_index_stripes(idxlist, &tmp_stripes, &num_tmp_stripes);
252  Xt_idxlist idxlist_stripes
253  = xt_idxstripes_prealloc_new(tmp_stripes, num_tmp_stripes);
254  int retval =
255  idxlist_stripes->vtable->get_pos_exts_of_index_stripes(
256  idxlist_stripes,
257  num_stripes, stripes, num_ext, pos_ext, single_match_only);
258  xt_idxlist_delete(idxlist_stripes);
259  free(tmp_stripes);
260  return retval;
261  }
262 }
263 
265  int * position, int offset) {
266 
267  return idxlist->vtable->get_position_of_index_off(idxlist, idx,
268  position, offset);
269 }
270 
271 int
273  const Xt_int *indices,
274  int num_indices, int * positions,
275  int * offsets) {
276 
277  INSTR_DEF(instr_fallback,"xt_idxlist_get_intersection.fallback")
278 
279  if (idxlist->vtable->get_positions_of_indices_off != NULL)
280  return idxlist->vtable->get_positions_of_indices_off(idxlist, indices,
281  num_indices,
282  positions, offsets);
283  INSTR_START(instr_fallback);
284 
285  int ret_val = 0;
286  for (int i = 0; i < num_indices; ++i) {
287 
288  int temp_position, offset;
289 
290  if (offsets == NULL)
291  offset = 0;
292  else
293  offset = offsets[i];
294 
295  ret_val
296  = idxlist->vtable->get_position_of_index_off(idxlist, indices[i],
297  &temp_position, offset);
298 
299  if (ret_val) break;
300  positions[i] = temp_position;
301  }
302 
303  INSTR_STOP(instr_fallback);
304  return ret_val;
305 }
306 
308 
309  return idxlist->vtable->get_min_index(idxlist);
310 }
311 
313 
314  return idxlist->vtable->get_max_index(idxlist);
315 }
316 
317 static void
319  Xt_int global_stride[ndim],
320  Xt_int global_start_index, Xt_int position[ndim]) {
321 
322  idx = (Xt_int)(idx - global_start_index);
323 
324  for (size_t i = 0; i < ndim - 1; ++i) {
325  position[i] = (Xt_int)(idx / global_stride[i]);
326  idx = (Xt_int)(idx % global_stride[i]);
327  }
328 
329  position[ndim - 1] = idx;
330 }
331 
332 void xt_idxlist_get_bounding_box(Xt_idxlist idxlist, unsigned ndim,
333  const Xt_int global_size[ndim],
334  Xt_int global_start_index,
335  struct Xt_bounds bounds[ndim]) {
336 
337  INSTR_DEF(instr_fallback,"xt_idxlist_get_bounding_box.fallback")
338 
339  int num_indices = xt_idxlist_get_num_indices(idxlist);
340 
341  if (num_indices == 0) {
342 
343  for (size_t i = 0; i < ndim; ++i) {
344  bounds[i].start = 0;
345  bounds[i].size = 0;
346  }
347 
348  return;
349 
350  } else if (idxlist->vtable->get_bounding_box != NULL) {
351 
352  idxlist->vtable->get_bounding_box(idxlist, ndim, global_size,
353  global_start_index, bounds);
354  return;
355  }
356 
357  INSTR_START(instr_fallback);
358 
359  Xt_int global_stride[ndim];
360 
361  global_stride[ndim - 1] = 1;
362 
363  for (size_t i = ndim - 2; i < ndim; --i)
364  global_stride[i] = (Xt_int)(global_stride[i+1] * global_size[i+1]);
365 
366  Xt_int curr_index;
367  Xt_int curr_position[ndim];
368 
369  xt_idxlist_get_index_at_position(idxlist, 0, &curr_index);
370  get_position_in_ndim_space(curr_index, ndim, global_stride,
371  global_start_index, curr_position);
372 
373  for (size_t i = 0; i < ndim; ++i) {
374  bounds[i].start = curr_position[i];
375  bounds[i].size = 1;
376  }
377 
378  for (int j = 1; j < num_indices; ++j) {
379 
380  xt_idxlist_get_index_at_position(idxlist, j, &curr_index);
381  get_position_in_ndim_space(curr_index, ndim, global_stride,
382  global_start_index, curr_position);
383 
384  for (size_t i = 0; i < ndim; ++i) {
385 
386  if (curr_position[i] < bounds[i].start) {
387 
388  bounds[i].size = (Xt_int)(bounds[i].size + curr_position[i] - bounds[i].start);
389  bounds[i].start = curr_position[i];
390 
391  } else if (curr_position[i] >= bounds[i].start + bounds[i].size) {
392 
393  bounds[i].size = (Xt_int)(curr_position[i] - bounds[i].start + 1);
394  }
395  }
396  }
397 
398  INSTR_STOP(instr_fallback);
399 }
400 
401 static Xt_uid nextId = UINT64_C(1);
402 #ifdef HAVE_PTHREAD
403 static pthread_mutex_t nextIdMutex = PTHREAD_MUTEX_INITIALIZER;
404 #endif
405 
406 Xt_uid
408 {
409  Xt_uid thisId;
410 #ifdef HAVE_PTHREAD
411  if (pthread_mutex_lock(&nextIdMutex))
412  die("unexpected pthread locking error");
413 #endif
414  thisId = nextId;
415  if (!++nextId)
416  die("unique ID counter overflow");
417 #ifdef HAVE_PTHREAD
418  if (pthread_mutex_unlock(&nextIdMutex))
419  die("unexpected pthread locking error");
420 #endif
421  return thisId;
422 }
423 
424 Xt_uid
426 {
427  assert(idxlist->uid);
428  return idxlist->uid;
429 }
430 
431 /*
432  * Local Variables:
433  * c-basic-offset: 2
434  * coding: utf-8
435  * indent-tabs-mode: nil
436  * show-trailing-whitespace: t
437  * require-trailing-newline: t
438  * End:
439  */
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
Xt_int start
Definition: xt_stripe.h:55
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 *)
int(* get_indices_at_positions)(Xt_idxlist idxlist, const int *positions, int num, Xt_int *index, Xt_int undef_idx)
Xt_int const *(* get_indices_const)(Xt_idxlist idxlist)
void(* delete)(Xt_idxlist)
int(* get_pos_exts_of_index_stripes)(Xt_idxlist, int, const struct Xt_stripe *, int *, struct Xt_pos_ext **, int)
void(* pack)(Xt_idxlist, void *, int, int *, MPI_Comm)
void(* get_index_stripes)(Xt_idxlist, struct Xt_stripe **, int *)
Xt_idxlist(* copy)(Xt_idxlist)
int(* get_position_of_index)(Xt_idxlist, Xt_int, int *)
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)
Xt_int(* get_min_index)(Xt_idxlist)
int(* get_positions_of_indices)(Xt_idxlist, Xt_int const *, int, int *, int)
int(* get_positions_of_indices_off)(Xt_idxlist, Xt_int const *, int, int *, int *)
base definitions header file
uint64_t Xt_uid
Definition: xt_core.h:72
XT_INT Xt_int
Definition: xt_core.h:68
void xt_idxlist_get_index_stripes_keep_buf(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
Definition: xt_idxlist.c:127
int xt_idxlist_get_num_indices(Xt_idxlist idxlist)
Definition: xt_idxlist.c:98
int xt_idxlist_get_positions_of_indices(Xt_idxlist idxlist, Xt_int const *indices, int num_indices, int *positions, int single_match_only)
Definition: xt_idxlist.c:203
Xt_int xt_idxlist_get_min_index(Xt_idxlist idxlist)
Definition: xt_idxlist.c:307
Xt_int xt_idxlist_get_max_index(Xt_idxlist idxlist)
Definition: xt_idxlist.c:312
int xt_idxlist_get_position_of_index(Xt_idxlist idxlist, Xt_int idx, int *position)
Definition: xt_idxlist.c:196
void xt_idxlist_get_indices(Xt_idxlist idxlist, Xt_int *indices)
Definition: xt_idxlist.c:102
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:272
Xt_uid xt_idxlist_new_uid(void)
Definition: xt_idxlist.c:407
int xt_idxlist_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *idx)
Definition: xt_idxlist.c:158
int xt_idxlist_get_position_of_index_off(Xt_idxlist idxlist, Xt_int idx, int *position, int offset)
Definition: xt_idxlist.c:264
Xt_uid xt_idxlist_get_uid(Xt_idxlist idxlist)
Definition: xt_idxlist.c:425
void xt_idxlist_pack(Xt_idxlist idxlist, void *buffer, int buffer_size, int *position, MPI_Comm comm)
Definition: xt_idxlist.c:85
size_t xt_idxlist_get_pack_size(Xt_idxlist idxlist, MPI_Comm comm)
Definition: xt_idxlist.c:79
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:165
void xt_idxlist_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
Definition: xt_idxlist.c:118
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:332
static Xt_uid nextId
Definition: xt_idxlist.c:401
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:237
Xt_idxlist xt_idxlist_copy(Xt_idxlist idxlist)
Definition: xt_idxlist.c:93
const Xt_int * xt_idxlist_get_indices_const(Xt_idxlist idxlist)
Definition: xt_idxlist.c:108
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:318
void xt_idxlist_delete(Xt_idxlist idxlist)
Definition: xt_idxlist.c:74
index list declaration
Provide non-public declarations common to all index lists.
Xt_idxlist xt_idxstripes_prealloc_new(const struct Xt_stripe *stripes, int num_stripes)
Xt_idxlist xt_idxvec_prealloc_new(const Xt_int *idxvec, int num_indices)
Definition: xt_idxvec.c:192
utility routines for MPI
void xt_convert_indices_to_stripes_keep_buf(const Xt_int *restrict indices, int num_indices, struct Xt_stripe **stripes, int *num_stripes)
Definition: xt_stripe.c:74