p4est  1.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
p4est_base.h
Go to the documentation of this file.
1 /*
2  This file is part of p4est.
3  p4est is a C library to manage a collection (a forest) of multiple
4  connected adaptive quadtrees or octrees in parallel.
5 
6  Copyright (C) 2010 The University of Texas System
7  Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac
8 
9  p4est is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  p4est is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with p4est; if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23 
29 #ifndef P4EST_BASE_H
30 #define P4EST_BASE_H
31 
32 /* include config headers */
33 #include <p4est_config.h>
34 #include <sc_config.h>
35 #if \
36  (defined (P4EST_ENABLE_MPI) && !defined (SC_ENABLE_MPI)) || \
37  (!defined (P4EST_ENABLE_MPI) && defined (SC_ENABLE_MPI))
38 #error "MPI configured differently in p4est and libsc"
39 #endif
40 #if \
41  (defined (P4EST_ENABLE_MPIIO) && !defined (SC_ENABLE_MPIIO)) || \
42  (!defined (P4EST_ENABLE_MPIIO) && defined (SC_ENABLE_MPIIO))
43 #error "MPI I/O configured differently in p4est and libsc"
44 #endif
45 
46 /* indirectly also include sc.h */
47 #include <sc_containers.h>
48 #define _p4est_const _sc_const
49 
50 SC_EXTERN_C_BEGIN;
51 
53 typedef int32_t p4est_qcoord_t;
54 #define p4est_qcoord_compare sc_int32_compare
55 #define P4EST_MPI_QCOORD sc_MPI_INT
56 #define P4EST_VTK_QCOORD "Int32"
57 #define P4EST_F90_QCOORD INTEGER(KIND=C_INT32_T)
58 #define P4EST_QCOORD_MIN INT32_MIN
59 #define P4EST_QCOORD_MAX INT32_MAX
60 #define P4EST_QCOORD_1 ((p4est_qcoord_t) 1)
61 
63 typedef int32_t p4est_topidx_t;
64 #define p4est_topidx_compare sc_int32_compare
65 #define P4EST_MPI_TOPIDX sc_MPI_INT
66 #define P4EST_VTK_TOPIDX "Int32"
67 #define P4EST_F90_TOPIDX INTEGER(KIND=C_INT32_T)
68 #define P4EST_TOPIDX_MIN INT32_MIN
69 #define P4EST_TOPIDX_MAX INT32_MAX
70 #define P4EST_TOPIDX_FITS_32 1
71 #define P4EST_TOPIDX_1 ((p4est_topidx_t) 1)
72 
74 typedef int32_t p4est_locidx_t;
75 #define p4est_locidx_compare sc_int32_compare
76 #define P4EST_MPI_LOCIDX sc_MPI_INT
77 #define P4EST_VTK_LOCIDX "Int32"
78 #define P4EST_F90_LOCIDX INTEGER(KIND=C_INT32_T)
79 #define P4EST_LOCIDX_MIN INT32_MIN
80 #define P4EST_LOCIDX_MAX INT32_MAX
81 #define P4EST_LOCIDX_1 ((p4est_locidx_t) 1)
82 
84 typedef int64_t p4est_gloidx_t;
85 #define p4est_gloidx_compare sc_int64_compare
86 #define P4EST_MPI_GLOIDX sc_MPI_LONG_LONG_INT
87 #define P4EST_VTK_GLOIDX "Int64"
88 #define P4EST_F90_GLOIDX INTEGER(KIND=C_INT64_T)
89 #define P4EST_GLOIDX_MIN INT64_MIN
90 #define P4EST_GLOIDX_MAX INT64_MAX
91 #define P4EST_GLOIDX_1 ((p4est_gloidx_t) 1)
92 
93 /* some error checking possibly specific to p4est */
94 #ifdef P4EST_ENABLE_DEBUG
95 #define P4EST_ASSERT(c) SC_CHECK_ABORT ((c), "Assertion '" #c "'")
96 #define P4EST_EXECUTE_ASSERT_FALSE(expression) \
97  do { int _p4est_i = (int) (expression); \
98  SC_CHECK_ABORT (!_p4est_i, "Expected false: '" #expression "'"); \
99  } while (0)
100 #define P4EST_EXECUTE_ASSERT_TRUE(expression) \
101  do { int _p4est_i = (int) (expression); \
102  SC_CHECK_ABORT (_p4est_i, "Expected true: '" #expression "'"); \
103  } while (0)
104 #else
105 #define P4EST_ASSERT(c) SC_NOOP ()
106 #define P4EST_EXECUTE_ASSERT_FALSE(expression) \
107  do { (void) (expression); } while (0)
108 #define P4EST_EXECUTE_ASSERT_TRUE(expression) \
109  do { (void) (expression); } while (0)
110 #endif
111 
112 /* macros for memory allocation, will abort if out of memory */
114 #define P4EST_ALLOC(t,n) (t *) sc_malloc (p4est_package_id, \
115  (n) * sizeof(t))
116 
117 #define P4EST_ALLOC_ZERO(t,n) (t *) sc_calloc (p4est_package_id, \
118  (size_t) (n), sizeof(t))
119 
120 #define P4EST_REALLOC(p,t,n) (t *) sc_realloc (p4est_package_id, \
121  (p), (n) * sizeof(t))
122 
123 #define P4EST_STRDUP(s) sc_strdup (p4est_package_id, (s))
124 
125 #define P4EST_FREE(p) sc_free (p4est_package_id, (p))
126 
127 /* log helper macros */
128 #define P4EST_GLOBAL_LOG(p,s) \
129  SC_GEN_LOG (p4est_package_id, SC_LC_GLOBAL, (p), (s))
130 #define P4EST_LOG(p,s) \
131  SC_GEN_LOG (p4est_package_id, SC_LC_NORMAL, (p), (s))
132 void P4EST_GLOBAL_LOGF (int priority, const char *fmt, ...)
133  __attribute__ ((format (printf, 2, 3)));
134 void P4EST_LOGF (int priority, const char *fmt, ...)
135  __attribute__ ((format (printf, 2, 3)));
136 #ifndef __cplusplus
137 #define P4EST_GLOBAL_LOGF(p,f,...) \
138  SC_GEN_LOGF (p4est_package_id, SC_LC_GLOBAL, (p), (f), __VA_ARGS__)
139 #define P4EST_LOGF(p,f,...) \
140  SC_GEN_LOGF (p4est_package_id, SC_LC_NORMAL, (p), (f), __VA_ARGS__)
141 #endif
142 
143 /* convenience global log macros will only print if identifier <= 0 */
144 #define P4EST_GLOBAL_TRACE(s) P4EST_GLOBAL_LOG (SC_LP_TRACE, (s))
145 #define P4EST_GLOBAL_LDEBUG(s) P4EST_GLOBAL_LOG (SC_LP_DEBUG, (s))
146 #define P4EST_GLOBAL_VERBOSE(s) P4EST_GLOBAL_LOG (SC_LP_VERBOSE, (s))
147 #define P4EST_GLOBAL_INFO(s) P4EST_GLOBAL_LOG (SC_LP_INFO, (s))
148 #define P4EST_GLOBAL_STATISTICS(s) P4EST_GLOBAL_LOG (SC_LP_STATISTICS, (s))
149 #define P4EST_GLOBAL_PRODUCTION(s) P4EST_GLOBAL_LOG (SC_LP_PRODUCTION, (s))
150 #define P4EST_GLOBAL_ESSENTIAL(s) P4EST_GLOBAL_LOG (SC_LP_ESSENTIAL, (s))
151 #define P4EST_GLOBAL_LERROR(s) P4EST_GLOBAL_LOG (SC_LP_ERROR, (s))
152 void P4EST_GLOBAL_TRACEF (const char *fmt, ...)
153  __attribute__ ((format (printf, 1, 2)));
154 void P4EST_GLOBAL_LDEBUGF (const char *fmt, ...)
155  __attribute__ ((format (printf, 1, 2)));
156 void P4EST_GLOBAL_VERBOSEF (const char *fmt, ...)
157  __attribute__ ((format (printf, 1, 2)));
158 void P4EST_GLOBAL_INFOF (const char *fmt, ...)
159  __attribute__ ((format (printf, 1, 2)));
160 void P4EST_GLOBAL_STATISTICSF (const char *fmt, ...)
161  __attribute__ ((format (printf, 1, 2)));
162 void P4EST_GLOBAL_PRODUCTIONF (const char *fmt, ...)
163  __attribute__ ((format (printf, 1, 2)));
164 void P4EST_GLOBAL_ESSENTIALF (const char *fmt, ...)
165  __attribute__ ((format (printf, 1, 2)));
166 void P4EST_GLOBAL_LERRORF (const char *fmt, ...)
167  __attribute__ ((format (printf, 1, 2)));
168 #ifndef __cplusplus
169 #define P4EST_GLOBAL_TRACEF(f,...) \
170  P4EST_GLOBAL_LOGF (SC_LP_TRACE, (f), __VA_ARGS__)
171 #define P4EST_GLOBAL_LDEBUGF(f,...) \
172  P4EST_GLOBAL_LOGF (SC_LP_DEBUG, (f), __VA_ARGS__)
173 #define P4EST_GLOBAL_VERBOSEF(f,...) \
174  P4EST_GLOBAL_LOGF (SC_LP_VERBOSE, (f), __VA_ARGS__)
175 #define P4EST_GLOBAL_INFOF(f,...) \
176  P4EST_GLOBAL_LOGF (SC_LP_INFO, (f), __VA_ARGS__)
177 #define P4EST_GLOBAL_STATISTICSF(f,...) \
178  P4EST_GLOBAL_LOGF (SC_LP_STATISTICS, (f), __VA_ARGS__)
179 #define P4EST_GLOBAL_PRODUCTIONF(f,...) \
180  P4EST_GLOBAL_LOGF (SC_LP_PRODUCTION, (f), __VA_ARGS__)
181 #define P4EST_GLOBAL_ESSENTIALF(f,...) \
182  P4EST_GLOBAL_LOGF (SC_LP_ESSENTIAL, (f), __VA_ARGS__)
183 #define P4EST_GLOBAL_LERRORF(f,...) \
184  P4EST_GLOBAL_LOGF (SC_LP_ERROR, (f), __VA_ARGS__)
185 #endif
186 #define P4EST_GLOBAL_NOTICE P4EST_GLOBAL_STATISTICS
187 #define P4EST_GLOBAL_NOTICEF P4EST_GLOBAL_STATISTICSF
188 
189 /* convenience log macros that are active on every processor */
190 #define P4EST_TRACE(s) P4EST_LOG (SC_LP_TRACE, (s))
191 #define P4EST_LDEBUG(s) P4EST_LOG (SC_LP_DEBUG, (s))
192 #define P4EST_VERBOSE(s) P4EST_LOG (SC_LP_VERBOSE, (s))
193 #define P4EST_INFO(s) P4EST_LOG (SC_LP_INFO, (s))
194 #define P4EST_STATISTICS(s) P4EST_LOG (SC_LP_STATISTICS, (s))
195 #define P4EST_PRODUCTION(s) P4EST_LOG (SC_LP_PRODUCTION, (s))
196 #define P4EST_ESSENTIAL(s) P4EST_LOG (SC_LP_ESSENTIAL, (s))
197 #define P4EST_LERROR(s) P4EST_LOG (SC_LP_ERROR, (s))
198 void P4EST_TRACEF (const char *fmt, ...)
199  __attribute__ ((format (printf, 1, 2)));
200 void P4EST_LDEBUGF (const char *fmt, ...)
201  __attribute__ ((format (printf, 1, 2)));
202 void P4EST_VERBOSEF (const char *fmt, ...)
203  __attribute__ ((format (printf, 1, 2)));
204 void P4EST_INFOF (const char *fmt, ...)
205  __attribute__ ((format (printf, 1, 2)));
206 void P4EST_STATISTICSF (const char *fmt, ...)
207  __attribute__ ((format (printf, 1, 2)));
208 void P4EST_PRODUCTIONF (const char *fmt, ...)
209  __attribute__ ((format (printf, 1, 2)));
210 void P4EST_ESSENTIALF (const char *fmt, ...)
211  __attribute__ ((format (printf, 1, 2)));
212 void P4EST_LERRORF (const char *fmt, ...)
213  __attribute__ ((format (printf, 1, 2)));
214 #ifndef __cplusplus
215 #define P4EST_TRACEF(f,...) \
216  P4EST_LOGF (SC_LP_TRACE, (f), __VA_ARGS__)
217 #define P4EST_LDEBUGF(f,...) \
218  P4EST_LOGF (SC_LP_DEBUG, (f), __VA_ARGS__)
219 #define P4EST_VERBOSEF(f,...) \
220  P4EST_LOGF (SC_LP_VERBOSE, (f), __VA_ARGS__)
221 #define P4EST_INFOF(f,...) \
222  P4EST_LOGF (SC_LP_INFO, (f), __VA_ARGS__)
223 #define P4EST_STATISTICSF(f,...) \
224  P4EST_LOGF (SC_LP_STATISTICS, (f), __VA_ARGS__)
225 #define P4EST_PRODUCTIONF(f,...) \
226  P4EST_LOGF (SC_LP_PRODUCTION, (f), __VA_ARGS__)
227 #define P4EST_ESSENTIALF(f,...) \
228  P4EST_LOGF (SC_LP_ESSENTIAL, (f), __VA_ARGS__)
229 #define P4EST_LERRORF(f,...) \
230  P4EST_LOGF (SC_LP_ERROR, (f), __VA_ARGS__)
231 #endif
232 #define P4EST_NOTICE P4EST_STATISTICS
233 #define P4EST_NOTICEF P4EST_STATISTICSF
234 
235 /* extern declarations */
237 extern int p4est_package_id;
238 
239 static inline void
240 p4est_log_indent_push ()
241 {
242  sc_log_indent_push_count (p4est_package_id, 1);
243 }
244 
245 static inline void
246 p4est_log_indent_pop ()
247 {
248  sc_log_indent_pop_count (p4est_package_id, 1);
249 }
250 
260 void p4est_init (sc_log_handler_t log_handler,
261  int log_threshold);
262 
267 /*@unused@*/
268 static inline unsigned
270 {
271  uint32_t a, b, c;
272 
273 #if (P4EST_TOPIDX_FITS_32)
274  a = (uint32_t) tt[0];
275  b = (uint32_t) tt[1];
276  c = 0;
277 #else
278  a = (uint32_t) (tt[0] && 0xFFFFFFFF);
279  b = (uint32_t) (tt[0] >> 32);
280  c = (uint32_t) (tt[1] && 0xFFFFFFFF);
281  sc_hash_mix (a, b, c);
282  a += (uint32_t) (tt[1] >> 32);
283 #endif
284  sc_hash_final (a, b, c);
285 
286  return (unsigned) c;
287 }
288 
293 /*@unused@*/
294 static inline unsigned
296 {
297  uint32_t a, b, c;
298 
299 #if (P4EST_TOPIDX_FITS_32)
300  a = (uint32_t) tt[0];
301  b = (uint32_t) tt[1];
302  c = (uint32_t) tt[2];
303 #else
304  a = (uint32_t) (tt[0] && 0xFFFFFFFF);
305  b = (uint32_t) (tt[0] >> 32);
306  c = (uint32_t) (tt[1] && 0xFFFFFFFF);
307  sc_hash_mix (a, b, c);
308  a += (uint32_t) (tt[1] >> 32);
309  b += (uint32_t) (tt[2] && 0xFFFFFFFF);
310  c += (uint32_t) (tt[2] >> 32);
311 #endif
312  sc_hash_final (a, b, c);
313 
314  return (unsigned) c;
315 }
316 
321 /*@unused@*/
322 static inline unsigned
324 {
325  uint32_t a, b, c;
326 
327 #if (P4EST_TOPIDX_FITS_32)
328  a = (uint32_t) tt[0];
329  b = (uint32_t) tt[1];
330  c = (uint32_t) tt[2];
331  sc_hash_mix (a, b, c);
332  a += (uint32_t) tt[3];
333 #else
334  a = (uint32_t) (tt[0] && 0xFFFFFFFF);
335  b = (uint32_t) (tt[0] >> 32);
336  c = (uint32_t) (tt[1] && 0xFFFFFFFF);
337  sc_hash_mix (a, b, c);
338  a += (uint32_t) (tt[1] >> 32);
339  b += (uint32_t) (tt[2] && 0xFFFFFFFF);
340  c += (uint32_t) (tt[2] >> 32);
341  sc_hash_mix (a, b, c);
342  a += (uint32_t) (tt[3] && 0xFFFFFFFF);
343  b += (uint32_t) (tt[3] >> 32);
344 #endif
345  sc_hash_final (a, b, c);
346 
347  return (unsigned) c;
348 }
349 
350 /*@unused@*/
351 static inline int
352 p4est_topidx_is_sorted (p4est_topidx_t * t, int length)
353 {
354  int i;
355 
356  for (i = 1; i < length; ++i) {
357  if (t[i - 1] > t[i]) {
358  return 0;
359  }
360  }
361  return 1;
362 }
363 
364 /*@unused@*/
365 static inline void
366 p4est_topidx_bsort (p4est_topidx_t * t, int length)
367 {
368  int i, j;
369  p4est_topidx_t tswap;
370 
371  /* go through all elements except the last */
372  for (i = length - 1; i > 0; --i) {
373  /* bubble up the first element until before position i */
374  for (j = 0; j < i; ++j) {
375  if (t[j] > t[j + 1]) {
376  tswap = t[j + 1];
377  t[j + 1] = t[j];
378  t[j] = tswap;
379  }
380  }
381  }
382  P4EST_ASSERT (p4est_topidx_is_sorted (t, length));
383 }
384 
385 /*@unused@*/
386 static inline uint64_t
387 p4est_partition_cut_uint64 (uint64_t global_num, int p, int num_procs)
388 {
389  uint64_t result;
390 
391  /* In theory, a double * double product should never overflow
392  due to the 15-bit exponent used internally on x87 and above.
393  Also in theory, 80-bit floats should be used internally,
394  and multiply/divide associativity goes left-to-right.
395  Still checking for funny stuff just to be sure. */
396 
397  P4EST_ASSERT (0 <= p && p <= num_procs);
398 
399  if (p == num_procs) {
400  /* prevent roundoff error and division by zero */
401  return global_num;
402  }
403 
404  result = (uint64_t)
405  (((long double) global_num * (double) p) / (double) num_procs);
406 
407  P4EST_ASSERT (result <= global_num);
408 
409  return result;
410 }
411 
412 /*@unused@*/
413 static inline p4est_gloidx_t
414 p4est_partition_cut_gloidx (p4est_gloidx_t global_num, int p, int num_procs)
415 {
416  p4est_gloidx_t result;
417 
418  /* In theory, a double * double product should never overflow
419  due to the 15-bit exponent used internally on x87 and above.
420  Also in theory, 80-bit floats should be used internally,
421  and multiply/divide associativity goes left-to-right.
422  Still checking for funny stuff just to be sure. */
423 
424  P4EST_ASSERT (global_num >= 0);
425  P4EST_ASSERT (0 <= p && p <= num_procs);
426 
427  if (p == num_procs) {
428  /* prevent roundoff error and division by zero */
429  return global_num;
430  }
431 
432  result = (p4est_gloidx_t)
433  (((long double) global_num * (double) p) / (double) num_procs);
434 
435  P4EST_ASSERT (0 <= result && result <= global_num);
436 
437  return result;
438 }
439 
440 SC_EXTERN_C_END;
441 
442 #endif /* !P4EST_BASE_H */
int32_t p4est_qcoord_t
Typedef for quadrant coordinates.
Definition: p4est_base.h:53
static unsigned p4est_topidx_hash4(const p4est_topidx_t *tt)
Compute hash value for four p4est_topidx_t integers.
Definition: p4est_base.h:323
static unsigned p4est_topidx_hash2(const p4est_topidx_t *tt)
Compute hash value for two p4est_topidx_t integers.
Definition: p4est_base.h:269
int64_t p4est_gloidx_t
Typedef for globally unique indexing of quadrants.
Definition: p4est_base.h:84
void p4est_init(sc_log_handler_t log_handler, int log_threshold)
Registers p4est with the SC Library and sets the logging behavior.
Definition: p4est_base.c:29
int p4est_package_id
the libsc package id for p4est (set in p4est_init())
Definition: p4est_base.c:26
Defines lists, arrays, hash tables, etc.
void sc_log_indent_pop_count(int package, int count)
Remove spaces from the start of a package's default log format.
int32_t p4est_topidx_t
Typedef for counting topological entities (trees, tree vertices).
Definition: p4est_base.h:63
int32_t p4est_locidx_t
Typedef for processor-local indexing of quadrants and nodes.
Definition: p4est_base.h:74
static unsigned p4est_topidx_hash3(const p4est_topidx_t *tt)
Compute hash value for three p4est_topidx_t integers.
Definition: p4est_base.h:295
void sc_log_indent_push_count(int package, int count)
Add spaces to the start of a package's default log format.