/*1This file is part of t8code.2t8code is a C library to manage a collection (a forest) of multiple3connected adaptive space-trees of general element classes in parallel.45Copyright (C) 2015 the developers67t8code is free software; you can redistribute it and/or modify8it under the terms of the GNU General Public License as published by9the Free Software Foundation; either version 2 of the License, or10(at your option) any later version.1112t8code is distributed in the hope that it will be useful,13but WITHOUT ANY WARRANTY; without even the implied warranty of14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15GNU General Public License for more details.1617You should have received a copy of the GNU General Public License18along with t8code; if not, write to the Free Software Foundation, Inc.,1951 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.20*/2122/** \file t8.h23* This is the administrative header file for t8code.24* It includes standard C headers via subpackages.25* It also provides application-level convenience code such as logging functions.26*/2728#ifndef T8_H29#define T8_H3031#include <t8_with_macro_error.h>32#ifdef __cplusplus33#include <cinttypes>34#else35#include <inttypes.h>36#endif3738#include <sc_config.h>39#if (defined(T8_ENABLE_MPI) && !defined(SC_ENABLE_MPI)) || (!defined(T8_ENABLE_MPI) && defined(SC_ENABLE_MPI))40#error "MPI configured differently in t8code and libsc"41#endif42#if (defined(T8_ENABLE_MPIIO) && !defined(SC_ENABLE_MPIIO)) || (!defined(T8_ENABLE_MPIIO) && defined(SC_ENABLE_MPIIO))43#error "MPI I/O configured differently in t8code and libsc"44#endif4546/* indirectly also include sc.h */47#include <sc_containers.h>4849/** This macro opens the extern "C" brace needed in C headers.50* It needs to be followed by a semicolon to look like a statement. */51#define T8_EXTERN_C_BEGIN() SC_EXTERN_C_BEGIN5253/** This macro closes the extern "C" brace needed in C headers.54* It needs to be followed by a semicolon to look like a statement. */55#define T8_EXTERN_C_END() SC_EXTERN_C_END5657/** Call this after including all headers */58T8_EXTERN_C_BEGIN ();5960/** Portable way to use the const keyword determined by configure. */61#define t8_const _sc_const6263/** Portable way to use the const keyword determined by configure. */64#define t8_restrict _sc_restrict6566/** Widely used assertion. Only active in debug-mode. */67/* Note that we use the same definition as in sc.h. We are deliberately not using68* #define T8_ASSERT SC_ASSERT69* since then the assertion would not trigger if sc is not configured in debugging mode.70* However, we want it to trigger any time t8code is in debugging mode, independent of sc.71*/72#if T8_ENABLE_DEBUG73#define T8_ASSERT(c) SC_CHECK_ABORT ((c), "Assertion '" #c "'")74#else75#define T8_ASSERT(c) SC_NOOP ()76#endif7778/**Extended T8_ASSERT assertion with custom error message. Only active in debug-mode. */79#if T8_ENABLE_DEBUG80#define T8_ASSERTF(c, msg) SC_CHECK_ABORT ((c), "Assertion '" #c "': " msg)81#else82#define T8_ASSERTF(c, msg) SC_NOOP ()83#endif8485/** Allocate a \a t-array with \a n elements. */86#define T8_ALLOC(t, n) (t *) sc_malloc (t8_get_package_id (), (n) * sizeof (t))8788/** Allocate a \a t-array with \a n elements and init to zero. */89#define T8_ALLOC_ZERO(t, n) (t *) sc_calloc (t8_get_package_id (), (size_t) (n), sizeof (t))9091/** Deallocate a \a t-array. */92#define T8_FREE(p) sc_free (t8_get_package_id (), (p))9394/** Reallocate the \a t-array \a p with \a n elements. */95#define T8_REALLOC(p, t, n) (t *) sc_realloc (t8_get_package_id (), (p), (n) * sizeof (t))9697/** A type for processor-local indexing. */98typedef int32_t t8_locidx_t;99/** The format specifier for t8_locidx_t */100#define T8_LOCIDX_FORMAT PRId32101/** The MPI Datatype of t8_locidx_t */102#define T8_MPI_LOCIDX sc_MPI_INT103/** Macro to get the absolute value of a t8_locidx_t */104#define T8_LOCIDX_ABS(x) ((t8_locidx_t) labs ((long) (x)))105/** Maximum possible value of a t8_locidx_t */106#define T8_LOCIDX_MAX INT32_MAX107/** Comparison function for t8_locidx_t */108#define t8_compare_locidx(v, w) sc_int32_compare (v, w)109/** A type for holding process ids. */110typedef int t8_procidx_t;111/** A type for global indexing that holds really big numbers. */112typedef int64_t t8_gloidx_t;113/** The format specifier for t8_gloidx_t */114#define T8_GLOIDX_FORMAT PRId64115/** The MPI Datatype of t8_gloidx_t */116#define T8_MPI_GLOIDX sc_MPI_LONG_LONG_INT117/** Macro to get the absolute value of a t8_gloidx_t */118#define T8_GLOIDX_ABS(x) ((t8_gloidx_t) llabs ((long long) (x)))119/** Maximum possible value of a t8_gloidx_t*/120#define T8_GLOIDX_MAX INT64_MAX121/** Comparison function for t8_gloidx_t */122#define t8_compare_gloidx(v, w) sc_int64_compare (v, w)123124/** A type for storing SFC indices */125typedef uint64_t t8_linearidx_t;126/** The format specifier for t8_linearidx_t */127#define T8_LINEARIDX_FORMAT PRIu64128/** The MPI datatype of t8_linearidx_t */129#define T8_MPI_LINEARIDX sc_MPI_UNSIGNED_LONG_LONG130131/** The padding size is the size of a void pointer*/132#define T8_PADDING_SIZE (sizeof (void *))133/** Compute the number of bytes that have to be added to a given byte_count134* such that it is a multiple of the padding size */135#define T8_ADD_PADDING(_x) ((T8_PADDING_SIZE - ((_x) % T8_PADDING_SIZE)) % T8_PADDING_SIZE)136137/** Define machine precision for computations */138#define T8_PRECISION_EPS SC_EPS139/** Define square root of machine precision for computations */140#define T8_PRECISION_SQRT_EPS sqrt (T8_PRECISION_EPS)141142/** Access multidimensional data on one-dimensional C arrays. */143/** Access onedimensional data on one-dimensional C arrays. */144#define T8_1D_TO_1D(nx, i) (i)145/** Access twodimensional data on one-dimensional C arrays. */146#define T8_2D_TO_1D(nx, ny, i, j) ((i) * (ny) + (j))147/** Access threedimensional data on one-dimensional C arrays. */148#define T8_3D_TO_1D(nx, ny, nz, i, j, k) (((i) * (ny) + (j)) * (nz) + (k))149/** Access fourdimensional data on one-dimensional C arrays. */150#define T8_4D_TO_1D(nx, ny, nz, nl, i, j, k, l) ((((i) * (ny) + (j)) * (nz) + (k)) * (nl) + (l))151152/** Communication tags used internal to t8code. */153typedef enum {154T8_MPI_TAG_FIRST = SC_TAG_FIRST, /**< Dummy first MPT tag. */155T8_MPI_PARTITION_CMESH = SC_TAG_LAST, /**< Used for coarse mesh partitioning */156T8_MPI_PARTITION_FOREST, /**< Used for forest partitioning */157T8_MPI_GHOST_FOREST, /**< Used for for ghost layer creation */158T8_MPI_GHOST_EXC_FOREST, /**< Used for ghost data exchange */159T8_MPI_CMESH_UNIFORM_BOUNDS_START, /**< Used for cmesh uniform bounds computation. */160T8_MPI_CMESH_UNIFORM_BOUNDS_END, /**< Used for cmesh uniform bounds computation. */161T8_MPI_TEST_ELEMENT_PACK_TAG, /**< Used for testing mpi pack and unpack functionality */162T8_MPI_PFC_TAG, /**< Used for data exchange during partition for coarsening. */163T8_MPI_TAG_LAST /**< Dummy last MPI tag. */164} t8_MPI_tag_t;165166/** Query the package identity as registered in libsc.167* \return This is -1 before \ref t8_init has been called168* and a proper package identifier afterwards.169*/170int171t8_get_package_id (void);172173/** Logging function parameterized by local/global category and priority.174* \param [in] category Either SC_LC_NORMAL for outputting on every rank175* or SC_LC_GLOBAL for outputting on the root rank.176* \param [in] priority Please see sc.h for legal log priorities.177* \param [in] fmt Printf-style format string.178* \param [in] ap Argument list; see stdarg.h.179*/180void181t8_logv (int category, int priority, const char *fmt, va_list ap);182183/** Logging function parameterized by local/global category and priority.184* \param [in] category Either SC_LC_NORMAL for outputting on every rank185* or SC_LC_GLOBAL for outputting on the root rank.186* \param [in] priority Please see sc.h for legal log priorities.187* \param [in] fmt Printf-style format string.188*/189void190t8_logf (int category, int priority, const char *fmt, ...)191#ifndef T8_DOXYGEN192__attribute__ ((format (printf, 3, 4)))193#endif194;195196/** Add one space to the start of t8's default log format. */197void198t8_log_indent_push (void);199200/** Remove one space from the start of a t8's default log format. */201void202t8_log_indent_pop (void);203204/** Log a message on the root rank with priority SC_LP_ERROR.205* \param [in] fmt Printf-style format string.206*/207void208t8_global_errorf (const char *fmt, ...)209#ifndef T8_DOXYGEN210__attribute__ ((format (printf, 1, 2)))211#endif212;213214/** Log a message on the root rank with priority SC_LP_ESSENTIAL.215* \param [in] fmt Printf-style format string.216*/217void218t8_global_essentialf (const char *fmt, ...)219#ifndef T8_DOXYGEN220__attribute__ ((format (printf, 1, 2)))221#endif222;223224/** Log a message on the root rank with priority SC_LP_PRODUCTION.225* \param [in] fmt Printf-style format string.226*/227void228t8_global_productionf (const char *fmt, ...)229#ifndef T8_DOXYGEN230__attribute__ ((format (printf, 1, 2)))231#endif232;233234/** Log a message on the root rank with priority SC_LP_INFO.235* \param [in] fmt Printf-style format string.236*/237void238t8_global_infof (const char *fmt, ...)239#ifndef T8_DOXYGEN240__attribute__ ((format (printf, 1, 2)))241#endif242;243244/** Log a message, no matter what rank, with priority SC_LP_INFO.245* \param [in] fmt Printf-style format string.246*/247void248t8_infof (const char *fmt, ...)249#ifndef T8_DOXYGEN250__attribute__ ((format (printf, 1, 2)))251#endif252;253254/** Log a message, no matter what rank, with priority SC_LP_PRODUCTION.255* \param [in] fmt Printf-style format string.256*/257void258t8_productionf (const char *fmt, ...)259#ifndef T8_DOXYGEN260__attribute__ ((format (printf, 1, 2)))261#endif262;263264/** Log a message, no matter what rank, with priority SC_LP_DEBUG.265* \param [in] fmt Printf-style format string.266* \note This function does not print anything unless t8code was compiled267* in debug mode (using -DCMAKE_BUILD_TYPE=Debug, so T8_ENABLE_DEBUG is defined).268*/269void270t8_debugf (const char *fmt, ...)271#ifndef T8_DOXYGEN272__attribute__ ((format (printf, 1, 2)))273#endif274;275276/** Log a message, no matter what rank, with priority SC_LP_ERROR.277* \param [in] fmt Printf-style format string.278*/279void280t8_errorf (const char *fmt, ...)281#ifndef T8_DOXYGEN282__attribute__ ((format (printf, 1, 2)))283#endif284;285286/**287* Set a custom logging function to be used by t8code.288* When setting a custom logging function, the t8code internal logging function will be ignored.289* \param [in] log_fcn A function pointer to a logging function290*/291void292t8_set_external_log_fcn (void (*log_fcn) (int category, int priority, const char *msg));293294/** Register t8code with libsc and print version and variable information.295* \param [in] log_threshold Declared in sc.h. SC_LP_DEFAULT is fine.296* You can also choose from log levels SC_LP_*.297*/298void299t8_init (int log_threshold);300301/** Return a pointer to an array element indexed by a t8_locidx_t.302* \param [in] array The array of elements.303* \param [in] index needs to be in [0]..[elem_count-1].304* \return A void * pointing to entry \a index in \a array.305*/306void *307t8_sc_array_index_locidx (const sc_array_t *array, const t8_locidx_t index);308309/** Call this at the end of a header file to match T8_EXTERN_C_BEGIN (). */310T8_EXTERN_C_END ();311312#endif /* !T8_H */313314315