Yet Another eXchange Tool  0.9.0
xt_xmap_intersection_common.h
Go to the documentation of this file.
1 
15 /*
16  * Keywords:
17  * Maintainer: Jörg Behrens <behrens@dkrz.de>
18  * Moritz Hanke <hanke@dkrz.de>
19  * Thomas Jahns <jahns@dkrz.de>
20  * URL: https://doc.redmine.dkrz.de/yaxt/html/
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions are
24  * met:
25  *
26  * Redistributions of source code must retain the above copyright notice,
27  * this list of conditions and the following disclaimer.
28  *
29  * Redistributions in binary form must reproduce the above copyright
30  * notice, this list of conditions and the following disclaimer in the
31  * documentation and/or other materials provided with the distribution.
32  *
33  * Neither the name of the DKRZ GmbH nor the names of its contributors
34  * may be used to endorse or promote products derived from this software
35  * without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
38  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
39  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
40  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
41  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
46  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  */
49 #ifndef XT_XMAP_INTERSECTION_COMMON_H
50 #define XT_XMAP_INTERSECTION_COMMON_H
51 
52 #ifdef HAVE_CONFIG_H
53 #include <config.h>
54 #endif
55 
56 struct pos_run {
57  size_t len;
59 };
60 
61 #include "core/core.h"
62 #include "xt_stripe_util.h"
63 
64 /* how many pos values have monotonically either positively or
65  * negatively consecutive values */
66 static inline struct pos_run get_pos_run_len(
67  size_t num_pos, const int *restrict pos)
68 {
69  size_t i = 0, j = 1;
70  int direction = 0;
71  int start = pos[0];
72  if (j < num_pos) {
73  direction = isign_mask(pos[1] - pos[0]);
74  while (j < num_pos
75  && pos[j] == start + (~direction & (int)(j - i)) +
76  (direction & -(int)(j - i)))
77  ++j;
78  direction = direction & ((j == 1) - 1);
79  }
80  return (struct pos_run){ .start = start, .len = j, .direction = direction };
81 }
82 
83 /* compute number of position extents that would be required
84  to represent positions array */
85 static size_t count_pos_ext(size_t num_pos, const int *restrict pos)
86 {
87  size_t i = 0, num_pos_ext = 0;
88  while (i < num_pos) {
89  i += get_pos_run_len(num_pos - i, pos + i).len;
90  ++num_pos_ext;
91  }
92  return num_pos_ext;
93 }
94 
95 /*
96  * generate position extents for given positions array
97  */
98 static inline void generate_pos_ext(
99  size_t num_pos, const int *restrict pos,
100  size_t num_pos_ext, struct Xt_pos_ext *restrict pos_ext)
101 {
102 #ifdef NDEBUG
103  (void)num_pos_ext;
104 #endif
105  size_t i = 0, temp_num_pos_ext = 0;
106  while (i < num_pos)
107  {
108  struct pos_run rn = get_pos_run_len(num_pos - i, pos + i);
109  pos_ext[temp_num_pos_ext]
110  = (struct Xt_pos_ext){ .start = rn.start,
111  .size = (rn.direction*2 + 1) * (int)rn.len };
112  ++temp_num_pos_ext;
113  i += rn.len;
114  }
115  assert(num_pos_ext == temp_num_pos_ext);
116 }
117 
118 /* compute number of positions that would be required
119  to represent position extents */
120 static inline size_t count_pos(
121  size_t num_pos_ext, const struct Xt_pos_ext *restrict pos_ext)
122 {
123  size_t num_pos = 0;
124  for (size_t i = 0; i < num_pos_ext; ++i) num_pos += (size_t)(pos_ext[i].size);
125  return num_pos;
126 }
127 
128 static inline void generate_pos(
129  size_t num_pos_ext, const struct Xt_pos_ext *restrict pos_ext,
130  size_t num_pos, int *restrict pos)
131 {
132 #ifdef NDEBUG
133  (void)num_pos;
134 #endif
135  size_t ofs = 0;
136  for (size_t i = 0; i < num_pos_ext; ++i) {
137  int abssize = abs(pos_ext[i].size);
138  int step = isign(pos_ext[i].size);
139  for (int j = 0; j < abssize; ++j)
140  pos[ofs + (size_t)j] = pos_ext[i].start + j * step;
141  ofs += (size_t)abssize;
142  }
143  assert(ofs == num_pos);
144 }
145 
146 static inline void
147 print_miss_msg(Xt_idxlist dst_idxlist, int missing_pos,
148  MPI_Comm comm, const char *source, int line)
149  __attribute__((noreturn));
150 
151 static inline void
152 print_miss_msg(Xt_idxlist dst_idxlist, int missing_pos,
153  MPI_Comm comm, const char *source, int line)
154 {
155  Xt_int missing_index;
156  xt_idxlist_get_index_at_position(dst_idxlist, missing_pos, &missing_index);
157  static const char fmt[] = "ERROR: destination intersections do not match "
158  "with destination index list (first missing index %lld "
159  "at position %d)";
160  char error_message[sizeof (fmt)
161  + (sizeof (long long) + sizeof (int)) * CHAR_BIT / 8 * 3];
162  sprintf(error_message, fmt, (long long)missing_index, missing_pos);
163  Xt_abort(comm, error_message, source, line);
164 }
165 
166 #endif
167 
168 /*
169  * Local Variables:
170  * c-basic-offset: 2
171  * coding: utf-8
172  * indent-tabs-mode: nil
173  * show-trailing-whitespace: t
174  * require-trailing-newline: t
175  * End:
176  */
int MPI_Comm
Definition: core.h:64
#define __attribute__(x)
Definition: core.h:82
static int isign(int x)
static int isign_mask(int x)
XT_INT Xt_int
Definition: xt_core.h:68
int xt_idxlist_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)
Definition: xt_idxlist.c:158
static size_t count_pos(size_t num_pos_ext, const struct Xt_pos_ext *restrict pos_ext)
static struct pos_run get_pos_run_len(size_t num_pos, const int *restrict pos)
static void print_miss_msg(Xt_idxlist dst_idxlist, int missing_pos, MPI_Comm comm, const char *source, int line) __attribute__((noreturn))
static size_t count_pos_ext(size_t num_pos, const int *restrict pos)
static void generate_pos(size_t num_pos_ext, const struct Xt_pos_ext *restrict pos_ext, size_t num_pos, int *restrict pos)
static void generate_pos_ext(size_t num_pos, const int *restrict pos, size_t num_pos_ext, struct Xt_pos_ext *restrict pos_ext)