Yet Another eXchange Tool  DO_NOT_EDIT_HERE
xt_idxlist_collection.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 <stdlib.h>
51 #include <stdio.h>
52 #include <assert.h>
53 #include <string.h>
54 
55 #include "mpi.h"
56 
57 #include "xt/xt_core.h"
58 #include "xt/xt_idxlist.h"
59 #include "xt_idxlist_internal.h"
62 #include "xt/xt_idxempty.h"
63 #include "xt/xt_mpi.h"
64 #include "xt_idxlist_unpack.h"
65 #include "core/core.h"
66 #include "core/ppm_xfuncs.h"
67 #include "ensure_array_size.h"
68 
69 static void
71 
72 static size_t
74 
75 static void
76 idxlist_collection_pack(Xt_idxlist data, void *buffer, int buffer_size,
77  int *position, MPI_Comm comm);
78 
79 static Xt_idxlist
81 
82 static void
84 
85 static const Xt_int *
87 
88 static void
90  struct Xt_stripe ** stripes,
91  int * num_stripes);
92 
93 static int
95  Xt_int * index);
96 
97 static int
99  int * position);
100 
101 static int
103  int * position, int offset);
104 
105 static Xt_int
107 
108 static Xt_int
110 
113  .get_pack_size = idxlist_collection_get_pack_size,
114  .pack = idxlist_collection_pack,
115  .copy = idxlist_collection_copy,
116  .get_indices = idxlist_collection_get_indices,
117  .get_indices_const = idxlist_collection_get_indices_const,
118  .get_index_stripes = idxlist_collection_get_index_stripes,
119  .get_index_at_position = idxlist_collection_get_index_at_position,
120  .get_indices_at_positions = NULL,
121  .get_position_of_index = idxlist_collection_get_position_of_index,
122  .get_positions_of_indices = NULL,
123  .get_position_of_index_off = idxlist_collection_get_position_of_index_off,
124  .get_positions_of_indices_off = NULL,
125  .get_min_index = idxlist_collection_get_min_index,
126  .get_max_index = idxlist_collection_get_max_index,
127  .get_bounding_box = NULL,
128  .idxlist_pack_code = COLLECTION,
129 };
130 
132 
134 
136 
138 
141 };
142 
145 
146  Xt_idxlist result;
147  if (num_idxlists > 1)
148  {
149  Xt_idxlist_collection collectionlist
150  = xmalloc(sizeof (*collectionlist)
151  + (size_t)num_idxlists * sizeof (collectionlist->idxlists[0]));
152 
153  collectionlist->num_idxlists = num_idxlists;
154  collectionlist->index_array_cache = NULL;
155 
156  long long num_indices = 0;
157  for (int i = 0; i < num_idxlists; ++i)
158  {
159  collectionlist->idxlists[i] = xt_idxlist_copy(idxlists[i]);
160  num_indices += idxlists[i]->num_indices;
161  }
162 
163  assert(num_indices <= INT_MAX);
164  Xt_idxlist_init(&collectionlist->parent, &idxlist_collection_vtable,
165  (int)num_indices);
166 
167  result = (Xt_idxlist)collectionlist;
168  }
169  else if (num_idxlists == 1)
170  result = xt_idxlist_copy(idxlists[0]);
171  else /* num_idxlists == 0 */
172  result = xt_idxempty_new();
173  return result;
174 }
175 
176 static void
178 
179  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)data;
180 
181  for (int i = 0; i < collectionlist->num_idxlists; ++i)
182  xt_idxlist_delete(collectionlist->idxlists[i]);
183 
184  free(collectionlist->index_array_cache);
185  free(collectionlist);
186 }
187 
188 static size_t
190 
191  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)data;
192 
193  int size_header;
194  size_t size_idxlists = 0;
195 
196  xt_mpi_call(MPI_Pack_size(2, MPI_INT, comm, &size_header), comm);
197 
198  for (int i = 0; i < collectionlist->num_idxlists; ++i)
199  size_idxlists
200  += xt_idxlist_get_pack_size(collectionlist->idxlists[i], comm);
201 
202  return (size_t)size_header + size_idxlists;
203 }
204 
205 static void
206 idxlist_collection_pack(Xt_idxlist data, void *buffer, int buffer_size,
207  int *position, MPI_Comm comm) {
208 
209  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)data;
210  int header[2] = { COLLECTION, collectionlist->num_idxlists };
211 
212  xt_mpi_call(MPI_Pack(header, 2, MPI_INT, buffer,
213  buffer_size, position, comm), comm);
214 
215  for (int i = 0; i < collectionlist->num_idxlists; ++i)
216  xt_idxlist_pack(collectionlist->idxlists[i], buffer, buffer_size,
217  position, comm);
218 }
219 
221 xt_idxlist_collection_unpack(void *buffer, int buffer_size, int *position,
222  MPI_Comm comm) {
223 
224  int num_lists;
225  xt_mpi_call(MPI_Unpack(buffer, buffer_size, position,
226  &num_lists, 1, MPI_INT, comm), comm);
227 
228  Xt_idxlist_collection collectionlist
229  = xmalloc(sizeof (*collectionlist)
230  + (size_t)num_lists * sizeof (collectionlist->idxlists[0]));
231 
232  collectionlist->index_array_cache = NULL;
233  collectionlist->num_idxlists = num_lists;
234 
235  long long num_indices = 0;
236  for (int i = 0; i < collectionlist->num_idxlists; ++i) {
237  collectionlist->idxlists[i] = xt_idxlist_unpack(buffer, buffer_size,
238  position, comm);
239  num_indices += collectionlist->idxlists[i]->num_indices;
240  }
241 
242  assert(num_indices <= INT_MAX);
243  Xt_idxlist_init(&collectionlist->parent, &idxlist_collection_vtable,
244  (int)num_indices);
245  return (Xt_idxlist)collectionlist;
246 }
247 
250  Xt_idxlist XT_UNUSED(idxlist_dst)) {
251 
252  return NULL;
253 }
254 
255 static Xt_idxlist
257 
258  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)idxlist;
259 
260  return xt_idxlist_collection_new(collectionlist->idxlists,
261  collectionlist->num_idxlists);
262 }
263 
264 static void
266 
267  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)idxlist;
269  int offlist = 0;
270 
271  for (int i = 0; i < collectionlist->num_idxlists; ++i) {
272 
273  xt_idxlist_get_indices(collectionlist->idxlists[i], indices+offlist);
274  offlist += xt_idxlist_get_num_indices(collectionlist->idxlists[i]);
275  }
276 }
277 
278 static const Xt_int *
280 
281  Xt_idxlist_collection collection = (Xt_idxlist_collection)idxlist;
282 
283  if (collection->index_array_cache) return collection->index_array_cache;
284 
285  unsigned num_indices = (unsigned)idxlist->num_indices;
286 
287  Xt_int *tmp_index_array
288  = xmalloc(num_indices * sizeof (collection->index_array_cache[0]));
289 
290  idxlist_collection_get_indices(idxlist, tmp_index_array);
291 
292  collection->index_array_cache = tmp_index_array;
293 
294  return collection->index_array_cache;
295 }
296 
297 
298 static void
300  struct Xt_stripe ** stripes,
301  int * num_stripes) {
302 
303  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)idxlist;
304 
305  struct Xt_stripe * temp_stripes = NULL;
306  size_t temp_stripes_array_size = 0;
307  int num_temp_stripes = 0;
308 
309  if (collectionlist->num_idxlists > 0) {
310  xt_idxlist_get_index_stripes(collectionlist->idxlists[0], &temp_stripes,
311  &num_temp_stripes);
312  temp_stripes_array_size = (size_t)num_temp_stripes;
313  }
314 
315  for (int i = 1; i < collectionlist->num_idxlists; ++i) {
316 
317  struct Xt_stripe * curr_stripes;
318  int curr_num_stripes;
319 
320  xt_idxlist_get_index_stripes(collectionlist->idxlists[i], &curr_stripes,
321  &curr_num_stripes);
322 
323  ENSURE_ARRAY_SIZE(temp_stripes, temp_stripes_array_size,
324  num_temp_stripes + curr_num_stripes);
325 
326  memcpy(temp_stripes + num_temp_stripes, curr_stripes,
327  (size_t)curr_num_stripes * sizeof(*curr_stripes));
328 
329  free(curr_stripes);
330 
331  num_temp_stripes += curr_num_stripes;
332  }
333 
334  *stripes = xrealloc(temp_stripes,
335  (size_t)num_temp_stripes * sizeof(*temp_stripes));
336  *num_stripes = num_temp_stripes;
337 }
338 
339 static int
341  Xt_int * index) {
342 
343  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)idxlist;
344 
345  for (int i = 0; i < collectionlist->num_idxlists; ++i) {
346  int n = xt_idxlist_get_num_indices(collectionlist->idxlists[i]);
347  if (position >= n)
348  position -= n;
349  else {
350  return xt_idxlist_get_index_at_position(collectionlist->idxlists[i],
351  position, index);
352  }
353  }
354  return 1;
355 
356 }
357 
358 static int
360  int * position, int offset) {
361 
362  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)idxlist;
363 
364  int curr_num_indices = 0;
365 
366  int idxlist_offsets = 0;
367 
368  assert(offset >= 0);
369 
370  int i = 0;
371 
372  do {
373  idxlist_offsets += curr_num_indices;
374  curr_num_indices = xt_idxlist_get_num_indices(collectionlist->idxlists[i]);
375  } while (idxlist_offsets + curr_num_indices <= offset &&
376  ++i < collectionlist->num_idxlists);
377 
378  offset -= idxlist_offsets;
379 
380  for (;i < collectionlist->num_idxlists; ++i)
381  if (!xt_idxlist_get_position_of_index_off(collectionlist->idxlists[i],
382  index, position, offset)) {
383  *position += idxlist_offsets;
384  return 0;
385  } else {
386  idxlist_offsets
387  += xt_idxlist_get_num_indices(collectionlist->idxlists[i]);
388  offset = 0;
389  }
390 
391  return 1;
392 }
393 
394 static int
396  int * position) {
397 
398  return idxlist_collection_get_position_of_index_off(idxlist, index,
399  position, 0);
400 }
401 
402 static Xt_int
404 
405  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)idxlist;
406 
407  Xt_int tmp_min, min = 0;
408 
409  if (collectionlist->num_idxlists == 0)
410  die("idxlist_collection_get_min_index empty collection");
411 
412  min = xt_idxlist_get_min_index(collectionlist->idxlists[0]);
413 
414  for (int i = 1; i < collectionlist->num_idxlists; ++i)
415  if ((tmp_min = xt_idxlist_get_min_index(collectionlist->idxlists[i])) < min)
416  min = tmp_min;
417 
418  return min;
419 }
420 
421 static Xt_int
423 
424  Xt_idxlist_collection collectionlist = (Xt_idxlist_collection)idxlist;
425 
426  Xt_int tmp_max, max = 0;
427 
428  if (collectionlist->num_idxlists == 0)
429  die("idxlist_collection_get_max_index empty collection");
430 
431  max = xt_idxlist_get_max_index(collectionlist->idxlists[0]);
432 
433  for (int i = 1; i < collectionlist->num_idxlists; ++i)
434  if ((tmp_max = xt_idxlist_get_max_index(collectionlist->idxlists[i])) > max)
435  max = tmp_max;
436 
437  return max;
438 }
439 
440 /*
441  * Local Variables:
442  * c-basic-offset: 2
443  * coding: utf-8
444  * indent-tabs-mode: nil
445  * show-trailing-whitespace: t
446  * require-trailing-newline: t
447  * End:
448  */
Xt_idxlist xt_idxlist_unpack(void *buffer, int buffer_size, int *position, MPI_Comm comm)
int xt_idxlist_get_num_indices(Xt_idxlist idxlist)
Definition: xt_idxlist.c:97
base definitions header file
#define die(msg)
Definition: core.h:131
static void idxlist_collection_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
static const struct xt_idxlist_vtable idxlist_collection_vtable
Xt_idxlist xt_idxlist_collection_get_intersection(Xt_idxlist XT_UNUSED(idxlist_src), Xt_idxlist XT_UNUSED(idxlist_dst))
add versions of standard API functions not returning on error
Xt_idxlist xt_idxlist_collection_unpack(void *buffer, int buffer_size, int *position, MPI_Comm comm)
void xt_idxlist_get_indices(Xt_idxlist idxlist, Xt_int *indices)
Definition: xt_idxlist.c:101
void xt_idxlist_delete(Xt_idxlist idxlist)
Definition: xt_idxlist.c:73
struct Xt_idxlist_collection_ * Xt_idxlist_collection
int xt_idxlist_get_position_of_index_off(Xt_idxlist idxlist, Xt_int index, int *position, int offset)
Definition: xt_idxlist.c:253
void xt_idxlist_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
Definition: xt_idxlist.c:117
Xt_int xt_idxlist_get_min_index(Xt_idxlist idxlist)
Definition: xt_idxlist.c:296
#define xrealloc(ptr, size)
Definition: ppm_xfuncs.h:67
Xt_idxlist xt_idxlist_collection_new(Xt_idxlist *idxlists, int num_idxlists)
int xt_idxlist_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)
Definition: xt_idxlist.c:147
Xt_idxlist xt_idxempty_new(void)
Definition: xt_idxempty.c:165
static int idxlist_collection_get_position_of_index_off(Xt_idxlist idxlist, Xt_int index, int *position, int offset)
XT_INT Xt_int
Definition: xt_core.h:68
Provide non-public declarations common to all index lists.
static void idxlist_collection_get_indices(Xt_idxlist idxlist, Xt_int *indices)
static Xt_int idxlist_collection_get_min_index(Xt_idxlist idxlist)
Xt_int xt_idxlist_get_max_index(Xt_idxlist idxlist)
Definition: xt_idxlist.c:301
struct Xt_idxlist_ * Xt_idxlist
Definition: xt_core.h:80
static void Xt_idxlist_init(Xt_idxlist idxlist, const struct xt_idxlist_vtable *vtable, int num_indices)
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
static const Xt_int * idxlist_collection_get_indices_const(Xt_idxlist idxlist)
#define XT_UNUSED(x)
Definition: core.h:84
static Xt_idxlist idxlist_collection_copy(Xt_idxlist idxlist)
void(* delete)(Xt_idxlist)
static void idxlist_collection_delete(Xt_idxlist data)
Xt_idxlist xt_idxlist_copy(Xt_idxlist idxlist)
Definition: xt_idxlist.c:92
static size_t idxlist_collection_get_pack_size(Xt_idxlist data, MPI_Comm comm)
size_t xt_idxlist_get_pack_size(Xt_idxlist idxlist, MPI_Comm comm)
Definition: xt_idxlist.c:78
static int idxlist_collection_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)
static Xt_int idxlist_collection_get_max_index(Xt_idxlist idxlist)
#define xt_mpi_call(call, comm)
Definition: xt_mpi.h:68
index list declaration
static void idxlist_collection_pack(Xt_idxlist data, void *buffer, int buffer_size, int *position, MPI_Comm comm)
static int idxlist_collection_get_position_of_index(Xt_idxlist idxlist, Xt_int index, int *position)
void xt_idxlist_pack(Xt_idxlist idxlist, void *buffer, int buffer_size, int *position, MPI_Comm comm)
Definition: xt_idxlist.c:84
#define xmalloc(size)
Definition: ppm_xfuncs.h:66
int MPI_Comm
Definition: core.h:64
utility routines for MPI