Actual source code: logimpl.h

      1: #pragma once
      2: /* all of the logging files have problems with automatic integer casting so checking is turned off for them here */
      3: #if defined(__GNUC__) || defined(__clang__)
      4:   #pragma GCC diagnostic ignored "-Wconversion"
      5: #endif

      7: #include <petsc/private/petscimpl.h>

      9: #include <petsc/private/logimpldeprecated.h>

     11: /* --- Macros for resizable arrays that show up frequently in the implementation of logging --- */

     13: #define PETSC_LOG_RESIZABLE_ARRAY(Container, Entry, Key, Constructor, Destructor, Equal) \
     14:   typedef struct _n_PetscLog##Container    *PetscLog##Container; \
     15:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Create(int, PetscLog##Container *); \
     16:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Destroy(PetscLog##Container *); \
     17:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Recapacity(PetscLog##Container, int); \
     18:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Resize(PetscLog##Container, int); \
     19:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Push(PetscLog##Container, Entry); \
     20:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Find(PetscLog##Container, Key, int *); \
     21:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetSize(PetscLog##Container, PetscInt *, PetscInt *); \
     22:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Get(PetscLog##Container, PetscInt, Entry *); \
     23:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetRef(PetscLog##Container, PetscInt, Entry **); \
     24:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Set(PetscLog##Container, PetscInt, Entry); \
     25:   struct _n_PetscLog##Container { \
     26:     int    num_entries; \
     27:     int    max_entries; \
     28:     Entry *array; \
     29:   }; \
     30:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Create(int max_init, PetscLog##Container *a_p) \
     31:   { \
     32:     PetscLog##Container a; \
     33:     PetscErrorCode (*constructor)(Entry *) = Constructor; \
     34:     PetscFunctionBegin; \
     35:     PetscCall(PetscNew(a_p)); \
     36:     a              = *a_p; \
     37:     a->num_entries = 0; \
     38:     a->max_entries = max_init; \
     39:     if (constructor) { \
     40:       PetscCall(PetscMalloc1(max_init, &a->array)); \
     41:     } else { \
     42:       PetscCall(PetscCalloc1(max_init, &a->array)); \
     43:     } \
     44:     PetscFunctionReturn(PETSC_SUCCESS); \
     45:   } \
     46:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Destroy(PetscLog##Container *a_p) \
     47:   { \
     48:     PetscLog##Container a; \
     49:     PetscErrorCode (*destructor)(Entry *) = Destructor; \
     50:     PetscFunctionBegin; \
     51:     a    = *a_p; \
     52:     *a_p = NULL; \
     53:     if (a == NULL) PetscFunctionReturn(PETSC_SUCCESS); \
     54:     if (destructor) { \
     55:       for (int i = 0; i < a->num_entries; i++) PetscCall((*destructor)(&a->array[i])); \
     56:     } \
     57:     PetscCall(PetscFree(a->array)); \
     58:     PetscCall(PetscFree(a)); \
     59:     PetscFunctionReturn(PETSC_SUCCESS); \
     60:   } \
     61:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Recapacity(PetscLog##Container a, int new_size) \
     62:   { \
     63:     PetscErrorCode (*constructor)(Entry *) = Constructor; \
     64:     PetscFunctionBegin; \
     65:     if (new_size > a->max_entries) { \
     66:       int    new_max_entries = 2; \
     67:       int    rem_size        = PetscMax(0, new_size - 1); \
     68:       Entry *new_array; \
     69:       while (rem_size >>= 1) new_max_entries *= 2; \
     70:       if (constructor) { \
     71:         PetscCall(PetscMalloc1(new_max_entries, &new_array)); \
     72:       } else { \
     73:         PetscCall(PetscCalloc1(new_max_entries, &new_array)); \
     74:       } \
     75:       PetscCall(PetscArraycpy(new_array, a->array, a->num_entries)); \
     76:       PetscCall(PetscFree(a->array)); \
     77:       a->array       = new_array; \
     78:       a->max_entries = new_max_entries; \
     79:     } \
     80:     PetscFunctionReturn(PETSC_SUCCESS); \
     81:   } \
     82:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Resize(PetscLog##Container a, int new_size) \
     83:   { \
     84:     PetscErrorCode (*constructor)(Entry *) = Constructor; \
     85:     PetscFunctionBegin; \
     86:     PetscCall(PetscLog##Container##Recapacity(a, new_size)); \
     87:     if (constructor) \
     88:       for (int i = a->num_entries; i < new_size; i++) PetscCall((*constructor)(&a->array[i])); \
     89:     a->num_entries = PetscMax(a->num_entries, new_size); \
     90:     PetscFunctionReturn(PETSC_SUCCESS); \
     91:   } \
     92:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Push(PetscLog##Container a, Entry new_entry) \
     93:   { \
     94:     PetscFunctionBegin; \
     95:     PetscCall(PetscLog##Container##Recapacity(a, a->num_entries + 1)); \
     96:     a->array[a->num_entries++] = new_entry; \
     97:     PetscFunctionReturn(PETSC_SUCCESS); \
     98:   } \
     99:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Find(PetscLog##Container a, Key key, int *idx_p) \
    100:   { \
    101:     PetscErrorCode (*equal)(Entry *, Key, PetscBool *) = Equal; \
    102:     PetscFunctionBegin; \
    103:     *idx_p = -1; \
    104:     if (equal) { \
    105:       for (int i = 0; i < a->num_entries; i++) { \
    106:         PetscBool is_equal; \
    107:         PetscCall((*equal)(&a->array[i], key, &is_equal)); \
    108:         if (is_equal) { \
    109:           *idx_p = i; \
    110:           break; \
    111:         } \
    112:       } \
    113:     } \
    114:     PetscFunctionReturn(PETSC_SUCCESS); \
    115:   } \
    116:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetSize(PetscLog##Container a, PetscInt *num_entries, PetscInt *max_entries) \
    117:   { \
    118:     PetscFunctionBegin; \
    119:     if (num_entries) *num_entries = a->num_entries; \
    120:     if (max_entries) *max_entries = a->max_entries; \
    121:     PetscFunctionReturn(PETSC_SUCCESS); \
    122:   } \
    123:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Get(PetscLog##Container a, PetscInt i, Entry *entry) \
    124:   { \
    125:     PetscFunctionBegin; \
    126:     PetscCheck(i >= 0 && i < a->num_entries, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is not in range [0,%d)", i, a->num_entries); \
    127:     *entry = a->array[i]; \
    128:     PetscFunctionReturn(PETSC_SUCCESS); \
    129:   } \
    130:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##GetRef(PetscLog##Container a, PetscInt i, Entry **entry) \
    131:   { \
    132:     PetscFunctionBegin; \
    133:     PetscCheck(i >= 0 && i < a->num_entries, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is not in range [0,%d)", i, a->num_entries); \
    134:     *entry = &a->array[i]; \
    135:     PetscFunctionReturn(PETSC_SUCCESS); \
    136:   } \
    137:   static inline PETSC_UNUSED PetscErrorCode PetscLog##Container##Set(PetscLog##Container a, PetscInt i, Entry entry) \
    138:   { \
    139:     PetscFunctionBegin; \
    140:     PetscCheck(i >= 0 && i < a->num_entries, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Index %" PetscInt_FMT " is not in range [0,%d)", i, a->num_entries); \
    141:     a->array[i] = entry; \
    142:     PetscFunctionReturn(PETSC_SUCCESS); \
    143:   }

    145: /* --- the registry: information about registered things ---

    147:    Log handler instances should not change the registry: it is shared
    148:    data that should be useful to more than one type of logging

    150:  */

    152: PETSC_INTERN PetscErrorCode PetscLogRegistryCreate(PetscLogRegistry *);
    153: PETSC_INTERN PetscErrorCode PetscLogRegistryDestroy(PetscLogRegistry);
    154: PETSC_INTERN PetscErrorCode PetscLogRegistryStageRegister(PetscLogRegistry, const char[], PetscLogStage *);
    155: PETSC_INTERN PetscErrorCode PetscLogRegistryEventRegister(PetscLogRegistry, const char[], PetscClassId, PetscLogStage *);
    156: PETSC_INTERN PetscErrorCode PetscLogRegistryClassRegister(PetscLogRegistry, const char[], PetscClassId, PetscLogClass *);
    157: PETSC_INTERN PetscErrorCode PetscLogRegistryGetEventFromName(PetscLogRegistry, const char[], PetscLogEvent *);
    158: PETSC_INTERN PetscErrorCode PetscLogRegistryGetStageFromName(PetscLogRegistry, const char[], PetscLogStage *);
    159: PETSC_INTERN PetscErrorCode PetscLogRegistryGetClassFromClassId(PetscLogRegistry, PetscClassId, PetscLogClass *);
    160: PETSC_INTERN PetscErrorCode PetscLogRegistryGetClassFromName(PetscLogRegistry, const char[], PetscLogClass *);
    161: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumEvents(PetscLogRegistry, PetscInt *, PetscInt *);
    162: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumStages(PetscLogRegistry, PetscInt *, PetscInt *);
    163: PETSC_INTERN PetscErrorCode PetscLogRegistryGetNumClasses(PetscLogRegistry, PetscInt *, PetscInt *);
    164: PETSC_INTERN PetscErrorCode PetscLogRegistryEventGetInfo(PetscLogRegistry, PetscLogEvent, PetscLogEventInfo *);
    165: PETSC_INTERN PetscErrorCode PetscLogRegistryStageGetInfo(PetscLogRegistry, PetscLogStage, PetscLogStageInfo *);
    166: PETSC_INTERN PetscErrorCode PetscLogRegistryClassGetInfo(PetscLogRegistry, PetscLogClass, PetscLogClassInfo *);
    167: PETSC_INTERN PetscErrorCode PetscLogRegistryEventSetCollective(PetscLogRegistry, PetscLogEvent, PetscBool);

    169: /* --- globally synchronized registry information --- */

    171: typedef struct _n_PetscLogGlobalNames *PetscLogGlobalNames;

    173: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesCreate(MPI_Comm, PetscInt, const char **, PetscLogGlobalNames *);
    174: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesDestroy(PetscLogGlobalNames *);
    175: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGetSize(PetscLogGlobalNames, PetscInt *, PetscInt *);
    176: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGlobalGetName(PetscLogGlobalNames, PetscInt, const char **);
    177: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesGlobalGetLocal(PetscLogGlobalNames, PetscInt, PetscInt *);
    178: PETSC_INTERN PetscErrorCode PetscLogGlobalNamesLocalGetGlobal(PetscLogGlobalNames, PetscInt, PetscInt *);
    179: PETSC_INTERN PetscErrorCode PetscLogRegistryCreateGlobalStageNames(MPI_Comm, PetscLogRegistry, PetscLogGlobalNames *);
    180: PETSC_INTERN PetscErrorCode PetscLogRegistryCreateGlobalEventNames(MPI_Comm, PetscLogRegistry, PetscLogGlobalNames *);

    182: /* A simple stack */
    183: struct _n_PetscIntStack {
    184:   int  top;   /* The top of the stack */
    185:   int  max;   /* The maximum stack size */
    186:   int *stack; /* The storage */
    187: };

    189: /* Thread-safety internals */

    191: /* SpinLock for shared Log variables */
    192: PETSC_INTERN PetscSpinlock PetscLogSpinLock;

    194: #if defined(PETSC_HAVE_THREADSAFETY)
    195:   #if defined(__cplusplus)
    196:     #define PETSC_TLS thread_local
    197:   #else
    198:     #define PETSC_TLS _Thread_local
    199:   #endif
    200:   #define PETSC_INTERN_TLS extern PETSC_TLS PETSC_VISIBILITY_INTERNAL

    202: /* Access PETSc internal thread id */
    203: PETSC_INTERN PetscInt PetscLogGetTid(void);
    204: #else
    205:   #define PETSC_TLS
    206:   #define PETSC_INTERN_TLS PETSC_INTERN
    207: #endif

    209: PETSC_EXTERN PetscBool PetscLogGpuTimeFlag;
    210: PETSC_INTERN PetscInt  PetscLogNumViewersCreated;
    211: PETSC_INTERN PetscInt  PetscLogNumViewersDestroyed;

    213: #if PetscDefined(USE_LOG)
    214: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type);
    215: #else
    216:   #define PetscLogTypeBegin(t) ((void)(t), PETSC_SUCCESS)
    217: #endif

    219: #define PETSC_LOG_VIEW_FROM_OPTIONS_MAX 4