p4est  1.0
src/p4est_base.h
Go to the documentation of this file.
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 */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines