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