p4est
1.0
|
00001 /* 00002 This file is part of p4est. 00003 p4est is a C library to manage a collection (a forest) of multiple 00004 connected adaptive quadtrees or octrees in parallel. 00005 00006 Copyright (C) 2010 The University of Texas System 00007 Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac 00008 00009 p4est is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 p4est is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with p4est; if not, write to the Free Software Foundation, Inc., 00021 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00022 */ 00023 00029 #ifndef P4EST_BASE_H 00030 #define P4EST_BASE_H 00031 00032 /* include config headers */ 00033 #include <p4est_config.h> 00034 #include <sc_config.h> 00035 #if \ 00036 (defined (P4EST_MPI) && !defined (SC_MPI)) || \ 00037 (!defined (P4EST_MPI) && defined (SC_MPI)) 00038 #error "MPI configured differently in p4est and libsc" 00039 #endif 00040 #if \ 00041 (defined (P4EST_MPIIO) && !defined (SC_MPIIO)) || \ 00042 (!defined (P4EST_MPIIO) && defined (SC_MPIIO)) 00043 #error "MPI I/O configured differently in p4est and libsc" 00044 #endif 00045 00046 /* indirectly also include sc.h */ 00047 #include <sc_containers.h> 00048 #define _p4est_const _sc_const 00049 00050 SC_EXTERN_C_BEGIN; 00051 00053 typedef int32_t p4est_qcoord_t; 00054 #define p4est_qcoord_compare sc_int32_compare 00055 #define P4EST_MPI_QCOORD sc_MPI_INT 00056 #define P4EST_VTK_QCOORD "Int32" 00057 #define P4EST_QCOORD_MIN INT32_MIN 00058 #define P4EST_QCOORD_MAX INT32_MAX 00059 #define P4EST_QCOORD_1 ((p4est_qcoord_t) 1) 00060 00062 typedef int32_t p4est_topidx_t; 00063 #define p4est_topidx_compare sc_int32_compare 00064 #define P4EST_MPI_TOPIDX sc_MPI_INT 00065 #define P4EST_VTK_TOPIDX "Int32" 00066 #define P4EST_TOPIDX_MIN INT32_MIN 00067 #define P4EST_TOPIDX_MAX INT32_MAX 00068 #define P4EST_TOPIDX_FITS_32 1 00069 #define P4EST_TOPIDX_1 ((p4est_topidx_t) 1) 00070 00072 typedef int32_t p4est_locidx_t; 00073 #define p4est_locidx_compare sc_int32_compare 00074 #define P4EST_MPI_LOCIDX sc_MPI_INT 00075 #define P4EST_VTK_LOCIDX "Int32" 00076 #define P4EST_LOCIDX_MIN INT32_MIN 00077 #define P4EST_LOCIDX_MAX INT32_MAX 00078 #define P4EST_LOCIDX_1 ((p4est_locidx_t) 1) 00079 00081 typedef int64_t p4est_gloidx_t; 00082 #define p4est_gloidx_compare sc_int64_compare 00083 #define P4EST_MPI_GLOIDX sc_MPI_LONG_LONG_INT 00084 #define P4EST_VTK_GLOIDX "Int64" 00085 #define P4EST_GLOIDX_MIN INT64_MIN 00086 #define P4EST_GLOIDX_MAX INT64_MAX 00087 #define P4EST_GLOIDX_1 ((p4est_gloidx_t) 1) 00088 00089 /* some error checking possibly specific to p4est */ 00090 #ifdef P4EST_DEBUG 00091 #define P4EST_ASSERT(c) SC_CHECK_ABORT ((c), "Assertion '" #c "'") 00092 #define P4EST_EXECUTE_ASSERT_FALSE(expression) \ 00093 do { int _p4est_i = (int) (expression); \ 00094 SC_CHECK_ABORT (!_p4est_i, "Expected false: '" #expression "'"); \ 00095 } while (0) 00096 #define P4EST_EXECUTE_ASSERT_TRUE(expression) \ 00097 do { int _p4est_i = (int) (expression); \ 00098 SC_CHECK_ABORT (_p4est_i, "Expected true: '" #expression "'"); \ 00099 } while (0) 00100 #else 00101 #define P4EST_ASSERT(c) SC_NOOP () 00102 #define P4EST_EXECUTE_ASSERT_FALSE(expression) \ 00103 do { (void) (expression); } while (0) 00104 #define P4EST_EXECUTE_ASSERT_TRUE(expression) \ 00105 do { (void) (expression); } while (0) 00106 #endif 00107 00108 /* macros for memory allocation, will abort if out of memory */ 00110 #define P4EST_ALLOC(t,n) (t *) sc_malloc (p4est_package_id, \ 00111 (n) * sizeof(t)) 00112 00113 #define P4EST_ALLOC_ZERO(t,n) (t *) sc_calloc (p4est_package_id, \ 00114 (size_t) (n), sizeof(t)) 00115 00116 #define P4EST_REALLOC(p,t,n) (t *) sc_realloc (p4est_package_id, \ 00117 (p), (n) * sizeof(t)) 00118 00119 #define P4EST_STRDUP(s) sc_strdup (p4est_package_id, (s)) 00120 00121 #define P4EST_FREE(p) sc_free (p4est_package_id, (p)) 00122 00123 /* log helper macros */ 00124 #define P4EST_GLOBAL_LOG(p,s) \ 00125 SC_GEN_LOG (p4est_package_id, SC_LC_GLOBAL, (p), (s)) 00126 #define P4EST_LOG(p,s) \ 00127 SC_GEN_LOG (p4est_package_id, SC_LC_NORMAL, (p), (s)) 00128 void P4EST_GLOBAL_LOGF (int priority, const char *fmt, ...) 00129 __attribute__ ((format (printf, 2, 3))); 00130 void P4EST_LOGF (int priority, const char *fmt, ...) 00131 __attribute__ ((format (printf, 2, 3))); 00132 #ifndef __cplusplus 00133 #define P4EST_GLOBAL_LOGF(p,f,...) \ 00134 SC_GEN_LOGF (p4est_package_id, SC_LC_GLOBAL, (p), (f), __VA_ARGS__) 00135 #define P4EST_LOGF(p,f,...) \ 00136 SC_GEN_LOGF (p4est_package_id, SC_LC_NORMAL, (p), (f), __VA_ARGS__) 00137 #endif 00138 00139 /* convenience global log macros will only print if identifier <= 0 */ 00140 #define P4EST_GLOBAL_TRACE(s) P4EST_GLOBAL_LOG (SC_LP_TRACE, (s)) 00141 #define P4EST_GLOBAL_LDEBUG(s) P4EST_GLOBAL_LOG (SC_LP_DEBUG, (s)) 00142 #define P4EST_GLOBAL_VERBOSE(s) P4EST_GLOBAL_LOG (SC_LP_VERBOSE, (s)) 00143 #define P4EST_GLOBAL_INFO(s) P4EST_GLOBAL_LOG (SC_LP_INFO, (s)) 00144 #define P4EST_GLOBAL_STATISTICS(s) P4EST_GLOBAL_LOG (SC_LP_STATISTICS, (s)) 00145 #define P4EST_GLOBAL_PRODUCTION(s) P4EST_GLOBAL_LOG (SC_LP_PRODUCTION, (s)) 00146 #define P4EST_GLOBAL_ESSENTIAL(s) P4EST_GLOBAL_LOG (SC_LP_ESSENTIAL, (s)) 00147 #define P4EST_GLOBAL_LERROR(s) P4EST_GLOBAL_LOG (SC_LP_ERROR, (s)) 00148 void P4EST_GLOBAL_TRACEF (const char *fmt, ...) 00149 __attribute__ ((format (printf, 1, 2))); 00150 void P4EST_GLOBAL_LDEBUGF (const char *fmt, ...) 00151 __attribute__ ((format (printf, 1, 2))); 00152 void P4EST_GLOBAL_VERBOSEF (const char *fmt, ...) 00153 __attribute__ ((format (printf, 1, 2))); 00154 void P4EST_GLOBAL_INFOF (const char *fmt, ...) 00155 __attribute__ ((format (printf, 1, 2))); 00156 void P4EST_GLOBAL_STATISTICSF (const char *fmt, ...) 00157 __attribute__ ((format (printf, 1, 2))); 00158 void P4EST_GLOBAL_PRODUCTIONF (const char *fmt, ...) 00159 __attribute__ ((format (printf, 1, 2))); 00160 void P4EST_GLOBAL_ESSENTIALF (const char *fmt, ...) 00161 __attribute__ ((format (printf, 1, 2))); 00162 void P4EST_GLOBAL_LERRORF (const char *fmt, ...) 00163 __attribute__ ((format (printf, 1, 2))); 00164 #ifndef __cplusplus 00165 #define P4EST_GLOBAL_TRACEF(f,...) \ 00166 P4EST_GLOBAL_LOGF (SC_LP_TRACE, (f), __VA_ARGS__) 00167 #define P4EST_GLOBAL_LDEBUGF(f,...) \ 00168 P4EST_GLOBAL_LOGF (SC_LP_DEBUG, (f), __VA_ARGS__) 00169 #define P4EST_GLOBAL_VERBOSEF(f,...) \ 00170 P4EST_GLOBAL_LOGF (SC_LP_VERBOSE, (f), __VA_ARGS__) 00171 #define P4EST_GLOBAL_INFOF(f,...) \ 00172 P4EST_GLOBAL_LOGF (SC_LP_INFO, (f), __VA_ARGS__) 00173 #define P4EST_GLOBAL_STATISTICSF(f,...) \ 00174 P4EST_GLOBAL_LOGF (SC_LP_STATISTICS, (f), __VA_ARGS__) 00175 #define P4EST_GLOBAL_PRODUCTIONF(f,...) \ 00176 P4EST_GLOBAL_LOGF (SC_LP_PRODUCTION, (f), __VA_ARGS__) 00177 #define P4EST_GLOBAL_ESSENTIALF(f,...) \ 00178 P4EST_GLOBAL_LOGF (SC_LP_ESSENTIAL, (f), __VA_ARGS__) 00179 #define P4EST_GLOBAL_LERRORF(f,...) \ 00180 P4EST_GLOBAL_LOGF (SC_LP_ERROR, (f), __VA_ARGS__) 00181 #endif 00182 #define P4EST_GLOBAL_NOTICE P4EST_GLOBAL_STATISTICS 00183 #define P4EST_GLOBAL_NOTICEF P4EST_GLOBAL_STATISTICSF 00184 00185 /* convenience log macros that are active on every processor */ 00186 #define P4EST_TRACE(s) P4EST_LOG (SC_LP_TRACE, (s)) 00187 #define P4EST_LDEBUG(s) P4EST_LOG (SC_LP_DEBUG, (s)) 00188 #define P4EST_VERBOSE(s) P4EST_LOG (SC_LP_VERBOSE, (s)) 00189 #define P4EST_INFO(s) P4EST_LOG (SC_LP_INFO, (s)) 00190 #define P4EST_STATISTICS(s) P4EST_LOG (SC_LP_STATISTICS, (s)) 00191 #define P4EST_PRODUCTION(s) P4EST_LOG (SC_LP_PRODUCTION, (s)) 00192 #define P4EST_ESSENTIAL(s) P4EST_LOG (SC_LP_ESSENTIAL, (s)) 00193 #define P4EST_LERROR(s) P4EST_LOG (SC_LP_ERROR, (s)) 00194 void P4EST_TRACEF (const char *fmt, ...) 00195 __attribute__ ((format (printf, 1, 2))); 00196 void P4EST_LDEBUGF (const char *fmt, ...) 00197 __attribute__ ((format (printf, 1, 2))); 00198 void P4EST_VERBOSEF (const char *fmt, ...) 00199 __attribute__ ((format (printf, 1, 2))); 00200 void P4EST_INFOF (const char *fmt, ...) 00201 __attribute__ ((format (printf, 1, 2))); 00202 void P4EST_STATISTICSF (const char *fmt, ...) 00203 __attribute__ ((format (printf, 1, 2))); 00204 void P4EST_PRODUCTIONF (const char *fmt, ...) 00205 __attribute__ ((format (printf, 1, 2))); 00206 void P4EST_ESSENTIALF (const char *fmt, ...) 00207 __attribute__ ((format (printf, 1, 2))); 00208 void P4EST_LERRORF (const char *fmt, ...) 00209 __attribute__ ((format (printf, 1, 2))); 00210 #ifndef __cplusplus 00211 #define P4EST_TRACEF(f,...) \ 00212 P4EST_LOGF (SC_LP_TRACE, (f), __VA_ARGS__) 00213 #define P4EST_LDEBUGF(f,...) \ 00214 P4EST_LOGF (SC_LP_DEBUG, (f), __VA_ARGS__) 00215 #define P4EST_VERBOSEF(f,...) \ 00216 P4EST_LOGF (SC_LP_VERBOSE, (f), __VA_ARGS__) 00217 #define P4EST_INFOF(f,...) \ 00218 P4EST_LOGF (SC_LP_INFO, (f), __VA_ARGS__) 00219 #define P4EST_STATISTICSF(f,...) \ 00220 P4EST_LOGF (SC_LP_STATISTICS, (f), __VA_ARGS__) 00221 #define P4EST_PRODUCTIONF(f,...) \ 00222 P4EST_LOGF (SC_LP_PRODUCTION, (f), __VA_ARGS__) 00223 #define P4EST_ESSENTIALF(f,...) \ 00224 P4EST_LOGF (SC_LP_ESSENTIAL, (f), __VA_ARGS__) 00225 #define P4EST_LERRORF(f,...) \ 00226 P4EST_LOGF (SC_LP_ERROR, (f), __VA_ARGS__) 00227 #endif 00228 #define P4EST_NOTICE P4EST_STATISTICS 00229 #define P4EST_NOTICEF P4EST_STATISTICSF 00230 00231 /* extern declarations */ 00233 extern int p4est_package_id; 00234 00244 void p4est_init (sc_log_handler_t log_handler, 00245 int log_threshold); 00246 00251 /*@unused@*/ 00252 static inline unsigned 00253 p4est_topidx_hash2 (const p4est_topidx_t * tt) 00254 { 00255 uint32_t a, b, c; 00256 00257 #if (P4EST_TOPIDX_FITS_32) 00258 a = (uint32_t) tt[0]; 00259 b = (uint32_t) tt[1]; 00260 c = 0; 00261 #else 00262 a = (uint32_t) (tt[0] && 0xFFFFFFFF); 00263 b = (uint32_t) (tt[0] >> 32); 00264 c = (uint32_t) (tt[1] && 0xFFFFFFFF); 00265 sc_hash_mix (a, b, c); 00266 a += (uint32_t) (tt[1] >> 32); 00267 #endif 00268 sc_hash_final (a, b, c); 00269 00270 return (unsigned) c; 00271 } 00272 00277 /*@unused@*/ 00278 static inline unsigned 00279 p4est_topidx_hash3 (const p4est_topidx_t * tt) 00280 { 00281 uint32_t a, b, c; 00282 00283 #if (P4EST_TOPIDX_FITS_32) 00284 a = (uint32_t) tt[0]; 00285 b = (uint32_t) tt[1]; 00286 c = (uint32_t) tt[2]; 00287 #else 00288 a = (uint32_t) (tt[0] && 0xFFFFFFFF); 00289 b = (uint32_t) (tt[0] >> 32); 00290 c = (uint32_t) (tt[1] && 0xFFFFFFFF); 00291 sc_hash_mix (a, b, c); 00292 a += (uint32_t) (tt[1] >> 32); 00293 b += (uint32_t) (tt[2] && 0xFFFFFFFF); 00294 c += (uint32_t) (tt[2] >> 32); 00295 #endif 00296 sc_hash_final (a, b, c); 00297 00298 return (unsigned) c; 00299 } 00300 00305 /*@unused@*/ 00306 static inline unsigned 00307 p4est_topidx_hash4 (const p4est_topidx_t * tt) 00308 { 00309 uint32_t a, b, c; 00310 00311 #if (P4EST_TOPIDX_FITS_32) 00312 a = (uint32_t) tt[0]; 00313 b = (uint32_t) tt[1]; 00314 c = (uint32_t) tt[2]; 00315 sc_hash_mix (a, b, c); 00316 a += (uint32_t) tt[3]; 00317 #else 00318 a = (uint32_t) (tt[0] && 0xFFFFFFFF); 00319 b = (uint32_t) (tt[0] >> 32); 00320 c = (uint32_t) (tt[1] && 0xFFFFFFFF); 00321 sc_hash_mix (a, b, c); 00322 a += (uint32_t) (tt[1] >> 32); 00323 b += (uint32_t) (tt[2] && 0xFFFFFFFF); 00324 c += (uint32_t) (tt[2] >> 32); 00325 sc_hash_mix (a, b, c); 00326 a += (uint32_t) (tt[3] && 0xFFFFFFFF); 00327 b += (uint32_t) (tt[3] >> 32); 00328 #endif 00329 sc_hash_final (a, b, c); 00330 00331 return (unsigned) c; 00332 } 00333 00334 /*@unused@*/ 00335 static inline int 00336 p4est_topidx_is_sorted (p4est_topidx_t * t, int length) 00337 { 00338 int i; 00339 00340 for (i = 1; i < length; ++i) { 00341 if (t[i - 1] > t[i]) { 00342 return 0; 00343 } 00344 } 00345 return 1; 00346 } 00347 00348 /*@unused@*/ 00349 static inline void 00350 p4est_topidx_bsort (p4est_topidx_t * t, int length) 00351 { 00352 int i, j; 00353 p4est_topidx_t tswap; 00354 00355 /* go through all elements except the last */ 00356 for (i = length - 1; i > 0; --i) { 00357 /* bubble up the first element until before position i */ 00358 for (j = 0; j < i; ++j) { 00359 if (t[j] > t[j + 1]) { 00360 tswap = t[j + 1]; 00361 t[j + 1] = t[j]; 00362 t[j] = tswap; 00363 } 00364 } 00365 } 00366 P4EST_ASSERT (p4est_topidx_is_sorted (t, length)); 00367 } 00368 00369 /*@unused@*/ 00370 static inline uint64_t 00371 p4est_partition_cut_uint64 (uint64_t global_num, int p, int num_procs) 00372 { 00373 uint64_t result; 00374 00375 /* In theory, a double * double product should never overflow 00376 due to the 15-bit exponent used internally on x87 and above. 00377 Also in theory, 80-bit floats should be used internally, 00378 and multiply/divide associativity goes left-to-right. 00379 Still checking for funny stuff just to be sure. */ 00380 00381 P4EST_ASSERT (0 <= p && p <= num_procs); 00382 00383 if (p == num_procs) { 00384 /* prevent roundoff error and division by zero */ 00385 return global_num; 00386 } 00387 00388 result = (uint64_t) 00389 (((long double) global_num * (double) p) / (double) num_procs); 00390 00391 P4EST_ASSERT (result <= global_num); 00392 00393 return result; 00394 } 00395 00396 /*@unused@*/ 00397 static inline p4est_gloidx_t 00398 p4est_partition_cut_gloidx (p4est_gloidx_t global_num, int p, int num_procs) 00399 { 00400 p4est_gloidx_t result; 00401 00402 /* In theory, a double * double product should never overflow 00403 due to the 15-bit exponent used internally on x87 and above. 00404 Also in theory, 80-bit floats should be used internally, 00405 and multiply/divide associativity goes left-to-right. 00406 Still checking for funny stuff just to be sure. */ 00407 00408 P4EST_ASSERT (global_num >= 0); 00409 P4EST_ASSERT (0 <= p && p <= num_procs); 00410 00411 if (p == num_procs) { 00412 /* prevent roundoff error and division by zero */ 00413 return global_num; 00414 } 00415 00416 result = (p4est_gloidx_t) 00417 (((long double) global_num * (double) p) / (double) num_procs); 00418 00419 P4EST_ASSERT (0 <= result && result <= global_num); 00420 00421 return result; 00422 } 00423 00424 SC_EXTERN_C_END; 00425 00426 #endif /* !P4EST_BASE_H */