Actual source code: plog.c

  1: /*
  2:       PETSc code to log object creation and destruction and PETSc events.

  4:       This provides the public API used by the rest of PETSc and by users.

  6:       These routines use a private API that is not used elsewhere in PETSc and is not
  7:       accessible to users. The private API is defined in logimpl.h and the utils directory.

  9:       ***

 11:       This file, and only this file, is for functions that interact with the global logging state
 12: */
 13: #include <petsc/private/logimpl.h>
 14: #include <petsc/private/loghandlerimpl.h>
 15: #include <petsctime.h>
 16: #include <petscviewer.h>
 17: #include <petscdevice.h>
 18: #include <petsc/private/deviceimpl.h>

 20: #if defined(PETSC_HAVE_THREADSAFETY)

 22: PetscInt           petsc_log_gid = -1; /* Global threadId counter */
 23: PETSC_TLS PetscInt petsc_log_tid = -1; /* Local threadId */

 25: /* shared variables */
 26: PetscSpinlock PetscLogSpinLock;

 28: PetscInt PetscLogGetTid(void)
 29: {
 30:   if (petsc_log_tid < 0) {
 31:     PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
 32:     petsc_log_tid = ++petsc_log_gid;
 33:     PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
 34:   }
 35:   return petsc_log_tid;
 36: }

 38: #endif

 40: /* Global counters */
 41: PetscLogDouble petsc_BaseTime        = 0.0;
 42: PetscLogDouble petsc_TotalFlops      = 0.0; /* The number of flops */
 43: PetscLogDouble petsc_send_ct         = 0.0; /* The number of sends */
 44: PetscLogDouble petsc_recv_ct         = 0.0; /* The number of receives */
 45: PetscLogDouble petsc_send_len        = 0.0; /* The total length of all sent messages */
 46: PetscLogDouble petsc_recv_len        = 0.0; /* The total length of all received messages */
 47: PetscLogDouble petsc_isend_ct        = 0.0; /* The number of immediate sends */
 48: PetscLogDouble petsc_irecv_ct        = 0.0; /* The number of immediate receives */
 49: PetscLogDouble petsc_isend_len       = 0.0; /* The total length of all immediate send messages */
 50: PetscLogDouble petsc_irecv_len       = 0.0; /* The total length of all immediate receive messages */
 51: PetscLogDouble petsc_wait_ct         = 0.0; /* The number of waits */
 52: PetscLogDouble petsc_wait_any_ct     = 0.0; /* The number of anywaits */
 53: PetscLogDouble petsc_wait_all_ct     = 0.0; /* The number of waitalls */
 54: PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */
 55: PetscLogDouble petsc_allreduce_ct    = 0.0; /* The number of reductions */
 56: PetscLogDouble petsc_gather_ct       = 0.0; /* The number of gathers and gathervs */
 57: PetscLogDouble petsc_scatter_ct      = 0.0; /* The number of scatters and scattervs */

 59: /* Thread Local storage */
 60: PETSC_TLS PetscLogDouble petsc_TotalFlops_th      = 0.0;
 61: PETSC_TLS PetscLogDouble petsc_send_ct_th         = 0.0;
 62: PETSC_TLS PetscLogDouble petsc_recv_ct_th         = 0.0;
 63: PETSC_TLS PetscLogDouble petsc_send_len_th        = 0.0;
 64: PETSC_TLS PetscLogDouble petsc_recv_len_th        = 0.0;
 65: PETSC_TLS PetscLogDouble petsc_isend_ct_th        = 0.0;
 66: PETSC_TLS PetscLogDouble petsc_irecv_ct_th        = 0.0;
 67: PETSC_TLS PetscLogDouble petsc_isend_len_th       = 0.0;
 68: PETSC_TLS PetscLogDouble petsc_irecv_len_th       = 0.0;
 69: PETSC_TLS PetscLogDouble petsc_wait_ct_th         = 0.0;
 70: PETSC_TLS PetscLogDouble petsc_wait_any_ct_th     = 0.0;
 71: PETSC_TLS PetscLogDouble petsc_wait_all_ct_th     = 0.0;
 72: PETSC_TLS PetscLogDouble petsc_sum_of_waits_ct_th = 0.0;
 73: PETSC_TLS PetscLogDouble petsc_allreduce_ct_th    = 0.0;
 74: PETSC_TLS PetscLogDouble petsc_gather_ct_th       = 0.0;
 75: PETSC_TLS PetscLogDouble petsc_scatter_ct_th      = 0.0;

 77: PetscLogDouble petsc_ctog_ct        = 0.0; /* The total number of CPU to GPU copies */
 78: PetscLogDouble petsc_gtoc_ct        = 0.0; /* The total number of GPU to CPU copies */
 79: PetscLogDouble petsc_ctog_sz        = 0.0; /* The total size of CPU to GPU copies */
 80: PetscLogDouble petsc_gtoc_sz        = 0.0; /* The total size of GPU to CPU copies */
 81: PetscLogDouble petsc_ctog_ct_scalar = 0.0; /* The total number of CPU to GPU copies */
 82: PetscLogDouble petsc_gtoc_ct_scalar = 0.0; /* The total number of GPU to CPU copies */
 83: PetscLogDouble petsc_ctog_sz_scalar = 0.0; /* The total size of CPU to GPU copies */
 84: PetscLogDouble petsc_gtoc_sz_scalar = 0.0; /* The total size of GPU to CPU copies */
 85: PetscLogDouble petsc_gflops         = 0.0; /* The flops done on a GPU */
 86: PetscLogDouble petsc_gtime          = 0.0; /* The time spent on a GPU */

 88: PETSC_TLS PetscLogDouble petsc_ctog_ct_th        = 0.0;
 89: PETSC_TLS PetscLogDouble petsc_gtoc_ct_th        = 0.0;
 90: PETSC_TLS PetscLogDouble petsc_ctog_sz_th        = 0.0;
 91: PETSC_TLS PetscLogDouble petsc_gtoc_sz_th        = 0.0;
 92: PETSC_TLS PetscLogDouble petsc_ctog_ct_scalar_th = 0.0;
 93: PETSC_TLS PetscLogDouble petsc_gtoc_ct_scalar_th = 0.0;
 94: PETSC_TLS PetscLogDouble petsc_ctog_sz_scalar_th = 0.0;
 95: PETSC_TLS PetscLogDouble petsc_gtoc_sz_scalar_th = 0.0;
 96: PETSC_TLS PetscLogDouble petsc_gflops_th         = 0.0;
 97: PETSC_TLS PetscLogDouble petsc_gtime_th          = 0.0;

 99: PetscBool PetscLogMemory = PETSC_FALSE;
100: PetscBool PetscLogSyncOn = PETSC_FALSE;

102: PetscBool PetscLogGpuTimeFlag = PETSC_FALSE;

104: PetscInt PetscLogNumViewersCreated   = 0;
105: PetscInt PetscLogNumViewersDestroyed = 0;

107: PetscLogState petsc_log_state = NULL;

109: #define PETSC_LOG_HANDLER_HOT_BLANK {NULL, NULL, NULL, NULL, NULL, NULL}

111: PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
112:   PETSC_LOG_HANDLER_HOT_BLANK,
113:   PETSC_LOG_HANDLER_HOT_BLANK,
114:   PETSC_LOG_HANDLER_HOT_BLANK,
115:   PETSC_LOG_HANDLER_HOT_BLANK,
116: };

118: #undef PETSC_LOG_HANDLERS_HOT_BLANK

120: #if defined(PETSC_USE_LOG)
121: #include <../src/sys/logging/handler/impls/default/logdefault.h>

123:   #if defined(PETSC_HAVE_THREADSAFETY)
124: PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble tmp)
125: {
126:   *tot_th += tmp;
127:   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
128:   *tot += tmp;
129:   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
130:   return PETSC_SUCCESS;
131: }

133: PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble tmp)
134: {
135:   *cnt_th = *cnt_th + 1;
136:   *tot_th += tmp;
137:   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
138:   *tot += (PetscLogDouble)tmp;
139:   *cnt += *cnt + 1;
140:   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
141:   return PETSC_SUCCESS;
142: }

144:   #endif

146: static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
147: {
148:   PetscFunctionBegin;
149:   PetscAssertPointer(handler, 2);
150:   *handler = NULL;
151:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
152:     PetscLogHandler h = PetscLogHandlers[i].handler;
153:     if (h) {
154:       PetscBool match;

156:       PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
157:       if (match) {
158:         *handler = PetscLogHandlers[i].handler;
159:         PetscFunctionReturn(PETSC_SUCCESS);
160:       }
161:     }
162:   }
163:   PetscFunctionReturn(PETSC_SUCCESS);
164: }

166: /*@
167:   PetscLogGetDefaultHandler - Get the default log handler if it is running.

169:   Not collective

171:   Output Parameter:
172: . handler - the default `PetscLogHandler`, or `NULL` if it is not running.

174:   Level: developer

176:   Notes:
177:   The default handler is started with `PetscLogDefaultBegin()`,
178:   if the options flags `-log_all` or `-log_view` is given without arguments,
179:   or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.

181: .seealso: [](ch_profiling)
182: @*/
183: PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
184: {
185:   PetscFunctionBegin;
186:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, handler));
187:   PetscFunctionReturn(PETSC_SUCCESS);
188: }

190: static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
191: {
192:   PetscFunctionBegin;
193:   PetscAssertPointer(handler, 2);
194:   PetscCall(PetscLogTryGetHandler(type, handler));
195:   PetscCheck(*handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
196:   PetscFunctionReturn(PETSC_SUCCESS);
197: }

199: /*@
200:   PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
201:   by all default log handlers (`PetscLogDefaultBegin()`,
202:   `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
203:   `PetscLogPerfstubsBegin()`).

205:   Collective on `PETSC_COMM_WORLD`

207:   Output Parameter:
208: . state - The `PetscLogState` changed by registrations (such as
209:           `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
210:           `PetscLogStagePush()`), or `NULL` if logging is not active

212:   Level: developer

214: .seealso: [](ch_profiling), `PetscLogState`
215: @*/
216: PetscErrorCode PetscLogGetState(PetscLogState *state)
217: {
218:   PetscFunctionBegin;
219:   PetscAssertPointer(state, 1);
220:   *state = petsc_log_state;
221:   PetscFunctionReturn(PETSC_SUCCESS);
222: }

224: static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
225: {
226:   PetscFunctionBegin;
227:   hot->handler       = h;
228:   hot->eventBegin    = h->ops->eventbegin;
229:   hot->eventEnd      = h->ops->eventend;
230:   hot->eventSync     = h->ops->eventsync;
231:   hot->objectCreate  = h->ops->objectcreate;
232:   hot->objectDestroy = h->ops->objectdestroy;
233:   PetscFunctionReturn(PETSC_SUCCESS);
234: }

236: /*@
237:   PetscLogHandlerStart - Connect a log handler to PETSc's global logging stream and state.

239:   Logically collective

241:   Input Parameters:
242: . h - a `PetscLogHandler`

244:   Level: developer

246:   Notes:
247:   Users should only need this if they create their own log handlers: handlers that are started
248:   from the command line (such as `-log_view` and `-log_trace`) or from a function like
249:   `PetscLogNestedBegin()` will automatically be started.

251:   There is a limit of `PESC_LOG_HANDLER_MAX` handlers that can be active at one time.

253:   To disconnect a handler from the global stream call `PetscLogHandlerStop()`.

255:   When a log handler is started, stages that have already been pushed with `PetscLogStagePush()`,
256:   will be pushed for the new log handler, but it will not be informed of any events that are
257:   in progress.  It is recommended to start any user-defined log handlers immediately following
258:   `PetscInitialize()`  before any user-defined stages are pushed.

260: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`, `PetscInitialize()`
261: @*/
262: PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
263: {
264:   PetscFunctionBegin;
265:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
266:     if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
267:   }
268:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
269:     if (PetscLogHandlers[i].handler == NULL) {
270:       PetscCall(PetscObjectReference((PetscObject)h));
271:       PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
272:       if (petsc_log_state) {
273:         PetscLogStage stack_height;
274:         PetscIntStack orig_stack, temp_stack;

276:         PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
277:         stack_height = petsc_log_state->stage_stack->top + 1;
278:         PetscCall(PetscIntStackCreate(&temp_stack));
279:         orig_stack                     = petsc_log_state->stage_stack;
280:         petsc_log_state->stage_stack   = temp_stack;
281:         petsc_log_state->current_stage = -1;
282:         for (int s = 0; s < stack_height; s++) {
283:           PetscLogStage stage = orig_stack->stack[s];
284:           PetscCall(PetscLogHandlerStagePush(h, stage));
285:           PetscCall(PetscIntStackPush(temp_stack, stage));
286:           petsc_log_state->current_stage = stage;
287:         }
288:         PetscCall(PetscIntStackDestroy(temp_stack));
289:         petsc_log_state->stage_stack = orig_stack;
290:       }
291:       PetscFunctionReturn(PETSC_SUCCESS);
292:     }
293:   }
294:   SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
295:   PetscFunctionReturn(PETSC_SUCCESS);
296: }

298: /*@
299:   PetscLogHandlerStop - Disconnect a log handler from PETSc's global logging stream.

301:   Logically collective

303:   Input Parameters:
304: . h - a `PetscLogHandler`

306:   Level: developer

308:   Note:
309:   After `PetscLogHandlerStop()`, the handler can still access the global logging state
310:   with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
311:   (for instance, in `PetscLogHandlerView()`),

313:   When a log handler is stopped, the remaining stages will be popped before it is
314:   disconnected from the log stream.

316: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
317: @*/
318: PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
319: {
320:   PetscFunctionBegin;
321:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
322:     if (PetscLogHandlers[i].handler == h) {
323:       if (petsc_log_state) {
324:         PetscLogState state;
325:         PetscLogStage stack_height;
326:         PetscIntStack orig_stack, temp_stack;

328:         PetscCall(PetscLogHandlerGetState(h, &state));
329:         PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
330:         stack_height = petsc_log_state->stage_stack->top + 1;
331:         PetscCall(PetscIntStackCreate(&temp_stack));
332:         orig_stack                   = petsc_log_state->stage_stack;
333:         petsc_log_state->stage_stack = temp_stack;
334:         for (int s = 0; s < stack_height; s++) {
335:           PetscLogStage stage = orig_stack->stack[s];

337:           PetscCall(PetscIntStackPush(temp_stack, stage));
338:         }
339:         for (int s = 0; s < stack_height; s++) {
340:           PetscLogStage stage;
341:           PetscBool     empty;

343:           PetscCall(PetscIntStackPop(temp_stack, &stage));
344:           PetscCall(PetscIntStackEmpty(temp_stack, &empty));
345:           if (!empty) {
346:             PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
347:           } else petsc_log_state->current_stage = -1;
348:           PetscCall(PetscLogHandlerStagePop(h, stage));
349:         }
350:         PetscCall(PetscIntStackDestroy(temp_stack));
351:         petsc_log_state->stage_stack = orig_stack;
352:         PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
353:       }
354:       PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
355:       PetscCall(PetscObjectDereference((PetscObject)h));
356:     }
357:   }
358:   PetscFunctionReturn(PETSC_SUCCESS);
359: }

361: /*@
362:   PetscLogIsActive - Check if logging (profiling) is currently in progress.

364:   Not Collective

366:   Output Parameter:
367: . isActive - `PETSC_TRUE` if logging is in progress, `PETSC_FALSE` otherwise

369:   Level: beginner

371: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
372: @*/
373: PetscErrorCode PetscLogIsActive(PetscBool *isActive)
374: {
375:   PetscFunctionBegin;
376:   *isActive = PETSC_FALSE;
377:   if (petsc_log_state) {
378:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
379:       if (PetscLogHandlers[i].handler) {
380:         *isActive = PETSC_TRUE;
381:         PetscFunctionReturn(PETSC_SUCCESS);
382:       }
383:     }
384:   }
385:   PetscFunctionReturn(PETSC_SUCCESS);
386: }

388: PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
389: {
390:   PetscFunctionBegin;
391:   *isActive = PETSC_FALSE;
392:   if (petsc_log_state) {
393:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
394:       if (PetscLogHandlers[i].eventBegin) {
395:         *isActive = PETSC_TRUE;
396:         PetscFunctionReturn(PETSC_SUCCESS);
397:       }
398:     }
399:   }
400:   PetscFunctionReturn(PETSC_SUCCESS);
401: }

403: PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
404: {
405:   PetscFunctionBegin;
406:   *isActive = PETSC_FALSE;
407:   if (petsc_log_state) {
408:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
409:       if (PetscLogHandlers[i].eventEnd) {
410:         *isActive = PETSC_TRUE;
411:         PetscFunctionReturn(PETSC_SUCCESS);
412:       }
413:     }
414:   }
415:   PetscFunctionReturn(PETSC_SUCCESS);
416: }

418: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
419: {
420:   PetscLogHandler handler;

422:   PetscFunctionBegin;
423:   PetscCall(PetscLogTryGetHandler(type, &handler));
424:   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
425:   PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
426:   PetscCall(PetscLogHandlerSetType(handler, type));
427:   PetscCall(PetscLogHandlerStart(handler));
428:   PetscCall(PetscLogHandlerDestroy(&handler));
429:   PetscFunctionReturn(PETSC_SUCCESS);
430: }

432: /*@
433:   PetscLogDefaultBegin - Turns on logging (profiling) of PETSc code using the default log handler (profiler). This logs time, flop
434:   rates, and object creation and should not slow programs down too much.

436:   Logically Collective on `PETSC_COMM_WORLD`

438:   Options Database Key:
439: . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing (profiling) information to the
440:                                                  screen (for PETSc configured with `--with-log=1` (which is the default)).
441:                                                  This option must be provided before `PetscInitialize()`.

443:   Example Usage:
444: .vb
445:       PetscInitialize(...);
446:       PetscLogDefaultBegin();
447:        ... code ...
448:       PetscLogView(viewer); or PetscLogDump();
449:       PetscFinalize();
450: .ve

452:   Level: advanced

454:   Notes:
455:   `PetscLogView()` or `PetscLogDump()` actually cause the printing of
456:   the logging information.

458:   This routine may be called more than once.

460:   To provide the `-log_view` option in your source code you must call  PetscCall(PetscOptionsSetValue(NULL, "-log_view", NULL));
461:   before you call `PetscInitialize()`

463: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
464: @*/
465: PetscErrorCode PetscLogDefaultBegin(void)
466: {
467:   PetscFunctionBegin;
468:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
469:   PetscFunctionReturn(PETSC_SUCCESS);
470: }

472: /*@C
473:   PetscLogTraceBegin - Begins trace logging.  Every time a PETSc event
474:   begins or ends, the event name is printed.

476:   Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support

478:   Input Parameter:
479: . file - The file to print trace in (e.g. stdout)

481:   Options Database Key:
482: . -log_trace [filename] - Begins `PetscLogTraceBegin()`

484:   Level: intermediate

486:   Notes:
487:   `PetscLogTraceBegin()` prints the processor number, the execution time (sec),
488:   then "Event begin:" or "Event end:" followed by the event name.

490:   `PetscLogTraceBegin()` allows tracing of all PETSc calls, which is useful
491:   to determine where a program is hanging without running in the
492:   debugger.  Can be used in conjunction with the -info option.

494: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
495: @*/
496: PetscErrorCode PetscLogTraceBegin(FILE *file)
497: {
498:   PetscLogHandler handler;

500:   PetscFunctionBegin;
501:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
502:   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
503:   PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
504:   PetscCall(PetscLogHandlerStart(handler));
505:   PetscCall(PetscLogHandlerDestroy(&handler));
506:   PetscFunctionReturn(PETSC_SUCCESS);
507: }

509: PETSC_INTERN PetscErrorCode PetscLogHandlerCreate_Nested(MPI_Comm, PetscLogHandler *);

511: /*@
512:   PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
513:   rates and object creation and should not slow programs down too much.

515:   Logically Collective on `PETSC_COMM_WORLD`, No Fortran Support

517:   Options Database Keys:
518: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file

520:   Example Usage:
521: .vb
522:       PetscInitialize(...);
523:       PetscLogNestedBegin();
524:        ... code ...
525:       PetscLogView(viewer);
526:       PetscFinalize();
527: .ve

529:   Level: advanced

531: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
532: @*/
533: PetscErrorCode PetscLogNestedBegin(void)
534: {
535:   PetscFunctionBegin;
536:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
537:   PetscFunctionReturn(PETSC_SUCCESS);
538: }

540: /*@C
541:   PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
542:   matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
543:   `PetscLogPHC`, `PetscLogPHD`.

545:   Logically Collective on `PETSC_COMM_WORLD`

547:   Input Parameters:
548: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
549: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
550: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
551: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)

553:   Calling sequence of `PetscLogPLB`:
554: + e  - a `PetscLogEvent` that is beginning
555: . _i - deprecated, unused
556: . o1 - a `PetscObject` associated with `e` (or `NULL`)
557: . o2 - a `PetscObject` associated with `e` (or `NULL`)
558: . o3 - a `PetscObject` associated with `e` (or `NULL`)
559: - o4 - a `PetscObject` associated with `e` (or `NULL`)

561:   Calling sequence of `PetscLogPLE`:
562: + e  - a `PetscLogEvent` that is beginning
563: . _i - deprecated, unused
564: . o1 - a `PetscObject` associated with `e` (or `NULL`)
565: . o2 - a `PetscObject` associated with `e` (or `NULL`)
566: . o3 - a `PetscObject` associated with `e` (or `NULL`)
567: - o4 - a `PetscObject` associated with `e` (or `NULL`)

569:   Calling sequence of `PetscLogPHC`:
570: . o - a `PetscObject` that has just been created

572:   Calling sequence of `PetscLogPHD`:
573: . o - a `PetscObject` that is about to be destroyed

575:   Level: advanced

577:   Notes:
578:   This is for transitioning from the deprecated function `PetscLogSet()` and should not be used in new code.

580:   This should help migrate external log handlers to use `PetscLogHandler`, but
581:   callbacks that depend on the deprecated `PetscLogStage` datatype will have to be
582:   updated.

584: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
585: @*/
586: PetscErrorCode PetscLogLegacyCallbacksBegin(PetscErrorCode (*PetscLogPLB)(PetscLogEvent e, int _i, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4), PetscErrorCode (*PetscLogPLE)(PetscLogEvent e, int _i, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4), PetscErrorCode (*PetscLogPHC)(PetscObject o), PetscErrorCode (*PetscLogPHD)(PetscObject o))
587: {
588:   PetscLogHandler handler;

590:   PetscFunctionBegin;
591:   PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
592:   PetscCall(PetscLogHandlerStart(handler));
593:   PetscCall(PetscLogHandlerDestroy(&handler));
594:   PetscFunctionReturn(PETSC_SUCCESS);
595: }

597:   #if defined(PETSC_HAVE_MPE)
598:     #include <mpe.h>
599: static PetscBool PetscBeganMPE = PETSC_FALSE;
600:   #endif

602: /*@C
603:   PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
604:   program down.

606:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

608:   Options Database Key:
609: . -log_mpe - Prints extensive log information

611:   Level: advanced

613:   Note:
614:   A related routine is `PetscLogDefaultBegin()` (with the options key `-log_view`), which is
615:   intended for production runs since it logs only flop rates and object creation (and should
616:   not significantly slow the programs).

618: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
619:           `PetscLogEventDeactivate()`
620: @*/
621: PetscErrorCode PetscLogMPEBegin(void)
622: {
623:   PetscFunctionBegin;
624:   #if defined(PETSC_HAVE_MPE)
625:   /* Do MPE initialization */
626:   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
627:     PetscCall(PetscInfo(0, "Initializing MPE.\n"));
628:     PetscCall(MPE_Init_log());

630:     PetscBeganMPE = PETSC_TRUE;
631:   } else {
632:     PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
633:   }
634:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
635:   #else
636:   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
637:   #endif
638:   PetscFunctionReturn(PETSC_SUCCESS);
639: }

641:   #if defined(PETSC_HAVE_TAU_PERFSTUBS)
642: #include <../src/sys/perfstubs/timer.h>
643:   #endif

645: /*@C
646:   PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.

648:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

650:   Options Database Key:
651: . -log_perfstubs - use an external log handler through the perfstubs interface

653:   Level: advanced

655: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
656: @*/
657: PetscErrorCode PetscLogPerfstubsBegin(void)
658: {
659:   PetscFunctionBegin;
660:   #if defined(PETSC_HAVE_TAU_PERFSTUBS)
661:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
662:   #else
663:   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
664:   #endif
665:   PetscFunctionReturn(PETSC_SUCCESS);
666: }

668: /*@
669:   PetscLogActions - Determines whether actions are logged for the default log handler.

671:   Not Collective

673:   Input Parameter:
674: . flag - `PETSC_TRUE` if actions are to be logged

676:   Options Database Key:
677: + -log_exclude_actions - (deprecated) Does nothing
678: - -log_include_actions - Turn on action logging

680:   Level: intermediate

682:   Note:
683:   Logging of actions continues to consume more memory as the program
684:   runs. Long running programs should consider turning this feature off.

686: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
687: @*/
688: PetscErrorCode PetscLogActions(PetscBool flag)
689: {
690:   PetscFunctionBegin;
691:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
692:     PetscLogHandler h = PetscLogHandlers[i].handler;

694:     if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
695:   }
696:   PetscFunctionReturn(PETSC_SUCCESS);
697: }

699: /*@
700:   PetscLogObjects - Determines whether objects are logged for the graphical viewer.

702:   Not Collective

704:   Input Parameter:
705: . flag - `PETSC_TRUE` if objects are to be logged

707:   Options Database Key:
708: + -log_exclude_objects - (deprecated) Does nothing
709: - -log_include_objects - Turns on object logging

711:   Level: intermediate

713:   Note:
714:   Logging of objects continues to consume more memory as the program
715:   runs. Long running programs should consider turning this feature off.

717: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
718: @*/
719: PetscErrorCode PetscLogObjects(PetscBool flag)
720: {
721:   PetscFunctionBegin;
722:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
723:     PetscLogHandler h = PetscLogHandlers[i].handler;

725:     if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
726:   }
727:   PetscFunctionReturn(PETSC_SUCCESS);
728: }

730: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
731: /*@
732:   PetscLogStageRegister - Attaches a character string name to a logging stage.

734:   Not Collective

736:   Input Parameter:
737: . sname - The name to associate with that stage

739:   Output Parameter:
740: . stage - The stage number or -1 if logging is not active (`PetscLogIsActive()`).

742:   Level: intermediate

744: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
745: @*/
746: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
747: {
748:   PetscLogState state;

750:   PetscFunctionBegin;
751:   *stage = -1;
752:   PetscCall(PetscLogGetState(&state));
753:   if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
754:   PetscFunctionReturn(PETSC_SUCCESS);
755: }

757: /*@
758:   PetscLogStagePush - This function pushes a stage on the logging stack. Events started and stopped until `PetscLogStagePop()` will be associated with the stage

760:   Not Collective

762:   Input Parameter:
763: . stage - The stage on which to log

765:   Example Usage:
766:   If the option -log_view is used to run the program containing the
767:   following code, then 2 sets of summary data will be printed during
768:   PetscFinalize().
769: .vb
770:       PetscInitialize(int *argc,char ***args,0,0);
771:       [stage 0 of code]
772:       PetscLogStagePush(1);
773:       [stage 1 of code]
774:       PetscLogStagePop();
775:       PetscBarrier(...);
776:       [more stage 0 of code]
777:       PetscFinalize();
778: .ve

780:   Level: intermediate

782:   Note:
783:   Use `PetscLogStageRegister()` to register a stage.

785: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
786: @*/
787: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
788: {
789:   PetscLogState state;

791:   PetscFunctionBegin;
792:   PetscCall(PetscLogGetState(&state));
793:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
794:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
795:     PetscLogHandler h = PetscLogHandlers[i].handler;
796:     if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
797:   }
798:   PetscCall(PetscLogStateStagePush(state, stage));
799:   PetscFunctionReturn(PETSC_SUCCESS);
800: }

802: /*@
803:   PetscLogStagePop - This function pops a stage from the logging stack that was pushed with `PetscLogStagePush()`

805:   Not Collective

807:   Example Usage:
808:   If the option -log_view is used to run the program containing the
809:   following code, then 2 sets of summary data will be printed during
810:   PetscFinalize().
811: .vb
812:       PetscInitialize(int *argc,char ***args,0,0);
813:       [stage 0 of code]
814:       PetscLogStagePush(1);
815:       [stage 1 of code]
816:       PetscLogStagePop();
817:       PetscBarrier(...);
818:       [more stage 0 of code]
819:       PetscFinalize();
820: .ve

822:   Level: intermediate

824: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
825: @*/
826: PetscErrorCode PetscLogStagePop(void)
827: {
828:   PetscLogState state;
829:   PetscLogStage current_stage;

831:   PetscFunctionBegin;
832:   PetscCall(PetscLogGetState(&state));
833:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
834:   current_stage = state->current_stage;
835:   PetscCall(PetscLogStateStagePop(state));
836:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
837:     PetscLogHandler h = PetscLogHandlers[i].handler;
838:     if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
839:   }
840:   PetscFunctionReturn(PETSC_SUCCESS);
841: }

843: /*@
844:   PetscLogStageSetActive - Sets if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.

846:   Not Collective

848:   Input Parameters:
849: + stage    - The stage
850: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

852:   Level: intermediate

854:   Note:
855:   If this is set to `PETSC_FALSE` the logging acts as if the stage did not exist

857: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
858: @*/
859: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
860: {
861:   PetscLogState state;

863:   PetscFunctionBegin;
864:   PetscCall(PetscLogGetState(&state));
865:   if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
866:   PetscFunctionReturn(PETSC_SUCCESS);
867: }

869: /*@
870:   PetscLogStageGetActive - Checks if a stage is used for `PetscLogEventBegin()` and `PetscLogEventEnd()`.

872:   Not Collective

874:   Input Parameter:
875: . stage - The stage

877:   Output Parameter:
878: . isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

880:   Level: intermediate

882: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
883: @*/
884: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
885: {
886:   PetscLogState state;

888:   PetscFunctionBegin;
889:   *isActive = PETSC_FALSE;
890:   PetscCall(PetscLogGetState(&state));
891:   if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
892:   PetscFunctionReturn(PETSC_SUCCESS);
893: }

895: /*@
896:   PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`

898:   Not Collective

900:   Input Parameters:
901: + stage     - The stage
902: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

904:   Level: intermediate

906:   Developer Notes:
907:   Visibility only affects the default log handler in `PetscLogView()`: stages that are
908:   set to invisible are suppressed from output.

910: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
911: @*/
912: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)

914: {
915:   PetscFunctionBegin;
916:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
917:     PetscLogHandler h = PetscLogHandlers[i].handler;

919:     if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
920:   }
921:   PetscFunctionReturn(PETSC_SUCCESS);
922: }

924: /*@
925:   PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`

927:   Not Collective

929:   Input Parameter:
930: . stage - The stage

932:   Output Parameter:
933: . isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

935:   Level: intermediate

937: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
938: @*/
939: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
940: {
941:   PetscLogHandler handler;

943:   PetscFunctionBegin;
944:   *isVisible = PETSC_FALSE;
945:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
946:   if (handler) { PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible)); }
947:   PetscFunctionReturn(PETSC_SUCCESS);
948: }

950: /*@
951:   PetscLogStageGetId - Returns the stage id when given the stage name.

953:   Not Collective

955:   Input Parameter:
956: . name - The stage name

958:   Output Parameter:
959: . stage - The stage, , or -1 if no stage with that name exists

961:   Level: intermediate

963: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
964: @*/
965: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
966: {
967:   PetscLogState state;

969:   PetscFunctionBegin;
970:   *stage = -1;
971:   PetscCall(PetscLogGetState(&state));
972:   if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
973:   PetscFunctionReturn(PETSC_SUCCESS);
974: }

976: /*@
977:   PetscLogStageGetName - Returns the stage name when given the stage id.

979:   Not Collective

981:   Input Parameter:
982: . stage - The stage

984:   Output Parameter:
985: . name - The stage name

987:   Level: intermediate

989: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
990: @*/
991: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
992: {
993:   PetscLogStageInfo stage_info;
994:   PetscLogState     state;

996:   PetscFunctionBegin;
997:   *name = NULL;
998:   PetscCall(PetscLogGetState(&state));
999:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1000:   PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
1001:   *name = stage_info.name;
1002:   PetscFunctionReturn(PETSC_SUCCESS);
1003: }

1005: /*------------------------------------------------ Event Functions --------------------------------------------------*/

1007: /*@
1008:   PetscLogEventRegister - Registers an event name for logging operations

1010:   Not Collective

1012:   Input Parameters:
1013: + name    - The name associated with the event
1014: - classid - The classid associated to the class for this event, obtain either with
1015:            `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1016:            are only available in C code

1018:   Output Parameter:
1019: . event - The event id for use with `PetscLogEventBegin()` and `PetscLogEventEnd()`.

1021:   Example Usage:
1022: .vb
1023:       PetscLogEvent USER_EVENT;
1024:       PetscClassId classid;
1025:       PetscLogDouble user_event_flops;
1026:       PetscClassIdRegister("class name",&classid);
1027:       PetscLogEventRegister("User event name",classid,&USER_EVENT);
1028:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
1029:          [code segment to monitor]
1030:          PetscLogFlops(user_event_flops);
1031:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
1032: .ve

1034:   Level: intermediate

1036:   Notes:
1037:   PETSc automatically logs library events if the code has been
1038:   configured with --with-log (which is the default) and
1039:   -log_view or -log_all is specified.  `PetscLogEventRegister()` is
1040:   intended for logging user events to supplement this PETSc
1041:   information.

1043:   PETSc can gather data for use with the utilities Jumpshot
1044:   (part of the MPICH distribution).  If PETSc has been compiled
1045:   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1046:   MPICH), the user can employ another command line option, -log_mpe,
1047:   to create a logfile, "mpe.log", which can be visualized
1048:   Jumpshot.

1050:   The classid is associated with each event so that classes of events
1051:   can be disabled simultaneously, such as all matrix events. The user
1052:   can either use an existing classid, such as `MAT_CLASSID`, or create
1053:   their own as shown in the example.

1055:   If an existing event with the same name exists, its event handle is
1056:   returned instead of creating a new event.

1058: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1059:           `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1060: @*/
1061: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1062: {
1063:   PetscLogState state;

1065:   PetscFunctionBegin;
1066:   *event = -1;
1067:   PetscCall(PetscLogGetState(&state));
1068:   if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1069:   PetscFunctionReturn(PETSC_SUCCESS);
1070: }

1072: /*@
1073:   PetscLogEventSetCollective - Indicates that a particular event is collective.

1075:   Logically Collective

1077:   Input Parameters:
1078: + event      - The event id
1079: - collective - `PetscBool` indicating whether a particular event is collective

1081:   Level: developer

1083:   Notes:
1084:   New events returned from `PetscLogEventRegister()` are collective by default.

1086:   Collective events are handled specially if the command line option `-log_sync` is used. In that case the logging saves information about
1087:   two parts of the event; the time for all the MPI ranks to synchronize and then the time for the actual computation/communication
1088:   to be performed. This option is useful to debug imbalance within the computations or communications.

1090: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1091: @*/
1092: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1093: {
1094:   PetscLogState state;

1096:   PetscFunctionBegin;
1097:   PetscCall(PetscLogGetState(&state));
1098:   if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1099:   PetscFunctionReturn(PETSC_SUCCESS);
1100: }

1102: /*
1103:   PetscLogClassSetActiveAll - Activate or inactivate logging for all events associated with a PETSc object class in every stage.

1105:   Not Collective

1107:   Input Parameters:
1108: + classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1109: - isActive - if `PETSC_FALSE`, events associated with this class will not be send to log handlers.

1111:   Level: developer

1113: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1114: */
1115: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1116: {
1117:   PetscLogState state;

1119:   PetscFunctionBegin;
1120:   PetscCall(PetscLogGetState(&state));
1121:   if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1122:   PetscFunctionReturn(PETSC_SUCCESS);
1123: }

1125: /*@
1126:   PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.

1128:   Not Collective

1130:   Input Parameter:
1131: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.

1133:   Level: developer

1135: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1136: @*/
1137: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1138: {
1139:   PetscFunctionBegin;
1140:   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1141:   PetscFunctionReturn(PETSC_SUCCESS);
1142: }

1144: /*@
1145:   PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.

1147:   Not Collective

1149:   Input Parameter:
1150: . classid - The object class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.

1152:   Level: developer

1154:   Note:
1155:   If a class is excluded then events associated with that class are not logged.

1157: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1158: @*/
1159: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1160: {
1161:   PetscFunctionBegin;
1162:   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1163:   PetscFunctionReturn(PETSC_SUCCESS);
1164: }

1166: /*
1167:   PetscLogEventSetActive - Activate or inactivate logging for an event in a given stage

1169:   Not Collective

1171:   Input Parameters:
1172: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1173: . event - A `PetscLogEvent`
1174: - isActive - If `PETSC_FALSE`, activity from this event (`PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventSync()`) will not be sent to log handlers during this stage

1176:   Usage:
1177: .vb
1178:       PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1179:         [code where you do not want to log VecSetValues()]
1180:       PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1181:         [code where you do want to log VecSetValues()]
1182: .ve

1184:   Level: advanced

1186:   Note:
1187:   The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1188:   or an event number obtained with `PetscLogEventRegister()`.

1190: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1191: */
1192: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1193: {
1194:   PetscLogState state;

1196:   PetscFunctionBegin;
1197:   PetscCall(PetscLogGetState(&state));
1198:   if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1199:   PetscFunctionReturn(PETSC_SUCCESS);
1200: }

1202: /*@
1203:   PetscLogEventActivate - Indicates that a particular event should be logged.

1205:   Not Collective

1207:   Input Parameter:
1208: . event - The event id

1210:   Example Usage:
1211: .vb
1212:       PetscLogEventDeactivate(VEC_SetValues);
1213:         [code where you do not want to log VecSetValues()]
1214:       PetscLogEventActivate(VEC_SetValues);
1215:         [code where you do want to log VecSetValues()]
1216: .ve

1218:   Level: advanced

1220:   Note:
1221:   The event may be either a pre-defined PETSc event (found in include/petsclog.h)
1222:   or an event number obtained with `PetscLogEventRegister()`.

1224: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1225: @*/
1226: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1227: {
1228:   PetscFunctionBegin;
1229:   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1230:   PetscFunctionReturn(PETSC_SUCCESS);
1231: }

1233: /*@
1234:   PetscLogEventDeactivate - Indicates that a particular event should not be logged.

1236:   Not Collective

1238:   Input Parameter:
1239: . event - The event id

1241:   Example Usage:
1242: .vb
1243:       PetscLogEventDeactivate(VEC_SetValues);
1244:         [code where you do not want to log VecSetValues()]
1245:       PetscLogEventActivate(VEC_SetValues);
1246:         [code where you do want to log VecSetValues()]
1247: .ve

1249:   Level: advanced

1251:   Note:
1252:   The event may be either a pre-defined PETSc event (found in
1253:   include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).

1255: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1256: @*/
1257: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1258: {
1259:   PetscFunctionBegin;
1260:   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1261:   PetscFunctionReturn(PETSC_SUCCESS);
1262: }

1264: /*@
1265:   PetscLogEventDeactivatePush - Indicates that a particular event should not be logged until `PetscLogEventDeactivatePop()` is called

1267:   Not Collective

1269:   Input Parameter:
1270: . event - The event id

1272:   Example Usage:
1273: .vb
1274:       PetscLogEventDeactivatePush(VEC_SetValues);
1275:         [code where you do not want to log VecSetValues()]
1276:       PetscLogEventDeactivatePop(VEC_SetValues);
1277:         [code where you do want to log VecSetValues()]
1278: .ve

1280:   Level: advanced

1282:   Note:
1283:   The event may be either a pre-defined PETSc event (found in
1284:   include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).

1286:   PETSc's default log handler (`PetscLogDefaultBegin()`) respects this function because it can make the output of `PetscLogView()` easier to interpret, but other handlers (such as the nested handler, `PetscLogNestedBegin()`) ignore it because suppressing events is not helpful in their output formats.

1288: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1289: @*/
1290: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1291: {
1292:   PetscFunctionBegin;
1293:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1294:     PetscLogHandler h = PetscLogHandlers[i].handler;

1296:     if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1297:   }
1298:   PetscFunctionReturn(PETSC_SUCCESS);
1299: }

1301: /*@
1302:   PetscLogEventDeactivatePop - Indicates that a particular event should again be logged after the logging was turned off with `PetscLogEventDeactivatePush()`

1304:   Not Collective

1306:   Input Parameter:
1307: . event - The event id

1309:   Example Usage:
1310: .vb
1311:       PetscLogEventDeactivatePush(VEC_SetValues);
1312:         [code where you do not want to log VecSetValues()]
1313:       PetscLogEventDeactivatePop(VEC_SetValues);
1314:         [code where you do want to log VecSetValues()]
1315: .ve

1317:   Level: advanced

1319:   Note:
1320:   The event may be either a pre-defined PETSc event (found in
1321:   include/petsclog.h) or an event number obtained with `PetscLogEventRegister()`).

1323: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1324: @*/
1325: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1326: {
1327:   PetscFunctionBegin;
1328:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1329:     PetscLogHandler h = PetscLogHandlers[i].handler;

1331:     if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1332:   }
1333:   PetscFunctionReturn(PETSC_SUCCESS);
1334: }

1336: /*@
1337:   PetscLogEventSetActiveAll - Turns on logging of all events

1339:   Not Collective

1341:   Input Parameters:
1342: + event    - The event id
1343: - isActive - The activity flag determining whether the event is logged

1345:   Level: advanced

1347: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1348: @*/
1349: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1350: {
1351:   PetscLogState state;

1353:   PetscFunctionBegin;
1354:   PetscCall(PetscLogGetState(&state));
1355:   if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1356:   PetscFunctionReturn(PETSC_SUCCESS);
1357: }

1359: /*
1360:   PetscLogClassSetActive - Activates event logging for a PETSc object class for the current stage

1362:   Not Collective

1364:   Input Parameters:
1365: + stage - A registered `PetscLogStage` (or `PETSC_DEFAULT` for the current stage)
1366: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.
1367: - isActive - If `PETSC_FALSE`, events associated with this class are not sent to log handlers.

1369:   Level: developer

1371: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1372: */
1373: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1374: {
1375:   PetscLogState state;

1377:   PetscFunctionBegin;
1378:   PetscCall(PetscLogGetState(&state));
1379:   if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1380:   PetscFunctionReturn(PETSC_SUCCESS);
1381: }

1383: /*@
1384:   PetscLogEventActivateClass - Activates event logging for a PETSc object class for the current stage

1386:   Not Collective

1388:   Input Parameter:
1389: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.

1391:   Level: developer

1393: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1394: @*/
1395: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1396: {
1397:   PetscFunctionBegin;
1398:   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1399:   PetscFunctionReturn(PETSC_SUCCESS);
1400: }

1402: /*@
1403:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class for the current stage

1405:   Not Collective

1407:   Input Parameter:
1408: . classid - The event class, for example `MAT_CLASSID`, `SNES_CLASSID`, etc.

1410:   Level: developer

1412: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1413: @*/
1414: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1415: {
1416:   PetscFunctionBegin;
1417:   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1418:   PetscFunctionReturn(PETSC_SUCCESS);
1419: }

1421: /*MC
1422:   PetscLogEventSync - Synchronizes the beginning of a user event.

1424:   Synopsis:
1425: #include <petsclog.h>
1426:   PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)

1428:   Collective

1430:   Input Parameters:
1431: + e    - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1432: - comm - an MPI communicator

1434:   Example Usage:
1435: .vb
1436:   PetscLogEvent USER_EVENT;

1438:   PetscLogEventRegister("User event", 0, &USER_EVENT);
1439:   PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1440:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1441:   [code segment to monitor]
1442:   PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1443: .ve

1445:   Level: developer

1447:   Note:
1448:   This routine should be called only if there is not a `PetscObject` available to pass to
1449:   `PetscLogEventBegin()`.

1451: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`
1452: M*/

1454: /*MC
1455:   PetscLogEventBegin - Logs the beginning of a user event.

1457:   Synopsis:
1458: #include <petsclog.h>
1459:   PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)

1461:   Not Collective

1463:   Input Parameters:
1464: + e  - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1465: . o1 - object associated with the event, or `NULL`
1466: . o2 - object associated with the event, or `NULL`
1467: . o3 - object associated with the event, or `NULL`
1468: - o4 - object associated with the event, or `NULL`

1470:   Fortran Synopsis:
1471:   void PetscLogEventBegin(int e, PetscErrorCode ierr)

1473:   Example Usage:
1474: .vb
1475:   PetscLogEvent USER_EVENT;

1477:   PetscLogDouble user_event_flops;
1478:   PetscLogEventRegister("User event",0, &USER_EVENT);
1479:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1480:   [code segment to monitor]
1481:   PetscLogFlops(user_event_flops);
1482:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1483: .ve

1485:   Level: intermediate

1487:   Developer Note:
1488:   `PetscLogEventBegin()` and `PetscLogEventBegin()` return error codes instead of explicitly
1489:   handling the errors that occur in the macro directly because other packages that use this
1490:   macros have used them in their own functions or methods that do not return error codes and it
1491:   would be disruptive to change the current behavior.

1493: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventEnd()`, `PetscLogFlops()`
1494: M*/

1496: /*MC
1497:   PetscLogEventEnd - Log the end of a user event.

1499:   Synopsis:
1500: #include <petsclog.h>
1501:   PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)

1503:   Not Collective

1505:   Input Parameters:
1506: + e  - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1507: . o1 - object associated with the event, or `NULL`
1508: . o2 - object associated with the event, or `NULL`
1509: . o3 - object associated with the event, or `NULL`
1510: - o4 - object associated with the event, or `NULL`

1512:   Fortran Synopsis:
1513:   void PetscLogEventEnd(int e, PetscErrorCode ierr)

1515:   Example Usage:
1516: .vb
1517:   PetscLogEvent USER_EVENT;

1519:   PetscLogDouble user_event_flops;
1520:   PetscLogEventRegister("User event", 0, &USER_EVENT);
1521:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1522:   [code segment to monitor]
1523:   PetscLogFlops(user_event_flops);
1524:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1525: .ve

1527:   Level: intermediate

1529: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogFlops()`
1530: M*/

1532: /*@C
1533:   PetscLogStageGetPerfInfo - Return the performance information about the given stage

1535:   No Fortran Support

1537:   Input Parameters:
1538: . stage - The stage number or `PETSC_DETERMINE` for the current stage

1540:   Output Parameter:
1541: . info - This structure is filled with the performance information

1543:   Level: intermediate

1545:   Notes:
1546:   This is a low level routine used by the logging functions in PETSc.

1548:   A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1549:   `PetscLogDefaultBegin()` or from the command line with `-log_view`.  If it was not started,
1550:   all performance statistics in `info` will be zeroed.

1552: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1553: @*/
1554: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1555: {
1556:   PetscLogHandler     handler;
1557:   PetscEventPerfInfo *event_info;

1559:   PetscFunctionBegin;
1560:   PetscAssertPointer(info, 2);
1561:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1562:   if (handler) {
1563:     PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1564:     *info = *event_info;
1565:   } else {
1566:     PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1567:     PetscCall(PetscMemzero(info, sizeof(*info)));
1568:   }
1569:   PetscFunctionReturn(PETSC_SUCCESS);
1570: }

1572: /*@C
1573:   PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage

1575:   No Fortran Support

1577:   Input Parameters:
1578: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1579: - event - The event number

1581:   Output Parameter:
1582: . info - This structure is filled with the performance information

1584:   Level: intermediate

1586:   Note:
1587:   This is a low level routine used by the logging functions in PETSc

1589:   A `PETSCLOGHANDLERDEFAULT` must be running for this to work, having been started either with
1590:   `PetscLogDefaultBegin()` or from the command line with `-log_view`.  If it was not started,
1591:   all performance statistics in `info` will be zeroed.

1593: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1594: @*/
1595: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1596: {
1597:   PetscLogHandler     handler;
1598:   PetscEventPerfInfo *event_info;

1600:   PetscFunctionBegin;
1601:   PetscAssertPointer(info, 3);
1602:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1603:   if (handler) {
1604:     PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1605:     *info = *event_info;
1606:   } else {
1607:     PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1608:     PetscCall(PetscMemzero(info, sizeof(*info)));
1609:   }
1610:   PetscFunctionReturn(PETSC_SUCCESS);
1611: }

1613: /*@
1614:   PetscLogEventSetDof - Set the nth number of degrees of freedom of a numerical problem associated with this event

1616:   Not Collective

1618:   Input Parameters:
1619: + event - The event id to log
1620: . n     - The dof index, in [0, 8)
1621: - dof   - The number of dofs

1623:   Options Database Key:
1624: . -log_view - Activates log summary

1626:   Level: developer

1628:   Note:
1629:   This is to enable logging of convergence

1631: .seealso: `PetscLogEventSetError()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1632: @*/
1633: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1634: {
1635:   PetscFunctionBegin;
1636:   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1637:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1638:     PetscLogHandler h = PetscLogHandlers[i].handler;

1640:     if (h) {
1641:       PetscEventPerfInfo *event_info;

1643:       PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1644:       if (event_info) event_info->dof[n] = dof;
1645:     }
1646:   }
1647:   PetscFunctionReturn(PETSC_SUCCESS);
1648: }

1650: /*@
1651:   PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event

1653:   Not Collective

1655:   Input Parameters:
1656: + event - The event id to log
1657: . n     - The error index, in [0, 8)
1658: - error - The error

1660:   Options Database Key:
1661: . -log_view - Activates log summary

1663:   Level: developer

1665:   Notes:
1666:   This is to enable logging of convergence, and enable users to interpret the errors as they wish. For example,
1667:   as different norms, or as errors for different fields

1669:   This is a low level routine used by the logging functions in PETSc

1671: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1672: @*/
1673: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1674: {
1675:   PetscFunctionBegin;
1676:   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1677:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1678:     PetscLogHandler h = PetscLogHandlers[i].handler;

1680:     if (h) {
1681:       PetscEventPerfInfo *event_info;

1683:       PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1684:       if (event_info) event_info->errors[n] = error;
1685:     }
1686:   }
1687:   PetscFunctionReturn(PETSC_SUCCESS);
1688: }

1690: /*@
1691:   PetscLogEventGetId - Returns the event id when given the event name.

1693:   Not Collective

1695:   Input Parameter:
1696: . name - The event name

1698:   Output Parameter:
1699: . event - The event, or -1 if no event with that name exists

1701:   Level: intermediate

1703: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1704: @*/
1705: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1706: {
1707:   PetscLogState state;

1709:   PetscFunctionBegin;
1710:   *event = -1;
1711:   PetscCall(PetscLogGetState(&state));
1712:   if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1713:   PetscFunctionReturn(PETSC_SUCCESS);
1714: }

1716: /*@
1717:   PetscLogEventGetName - Returns the event name when given the event id.

1719:   Not Collective

1721:   Input Parameter:
1722: . event - The event

1724:   Output Parameter:
1725: . name - The event name

1727:   Level: intermediate

1729: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1730: @*/
1731: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1732: {
1733:   PetscLogEventInfo event_info;
1734:   PetscLogState     state;

1736:   PetscFunctionBegin;
1737:   *name = NULL;
1738:   PetscCall(PetscLogGetState(&state));
1739:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1740:   PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1741:   *name = event_info.name;
1742:   PetscFunctionReturn(PETSC_SUCCESS);
1743: }

1745: /*@
1746:   PetscLogEventsPause - Put event logging into "paused" mode: timers and counters for in-progress events are paused, and any events that happen before logging is resumed with `PetscLogEventsResume()` are logged in the "Main Stage" of execution.

1748:   Not collective

1750:   Level: advanced

1752:   Notes:
1753:   When an external library or runtime has is initialized it can involve lots of setup time that skews the statistics of any unrelated running events: this function is intended to isolate such calls in the default log summary (`PetscLogDefaultBegin()`, `PetscLogView()`).

1755:   Other log handlers (such as the nested handler, `PetscLogNestedBegin()`) will ignore this function.

1757: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1758: @*/
1759: PetscErrorCode PetscLogEventsPause(void)
1760: {
1761:   PetscFunctionBegin;
1762:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1763:     PetscLogHandler h = PetscLogHandlers[i].handler;

1765:     if (h) PetscCall(PetscLogHandlerEventsPause(h));
1766:   }
1767:   PetscFunctionReturn(PETSC_SUCCESS);
1768: }

1770: /*@
1771:   PetscLogEventsResume - Return logging to normal behavior after it was paused with `PetscLogEventsPause()`.

1773:   Not collective

1775:   Level: advanced

1777: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1778: @*/
1779: PetscErrorCode PetscLogEventsResume(void)
1780: {
1781:   PetscFunctionBegin;
1782:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1783:     PetscLogHandler h = PetscLogHandlers[i].handler;

1785:     if (h) PetscCall(PetscLogHandlerEventsResume(h));
1786:   }
1787:   PetscFunctionReturn(PETSC_SUCCESS);
1788: }

1790: /*------------------------------------------------ Class Functions --------------------------------------------------*/

1792: /*MC
1793:    PetscLogObjectCreate - Log the creation of a `PetscObject`

1795:    Synopsis:
1796: #include <petsclog.h>
1797:    PetscErrorCode PetscLogObjectCreate(PetscObject h)

1799:    Not Collective

1801:    Input Parameters:
1802: .  h - A `PetscObject`

1804:    Level: developer

1806:    Developer Note:
1807:      Called internally by PETSc when creating objects: users do not need to call this directly.
1808:      Notification of the object creation is sent to each `PetscLogHandler` that is running.

1810: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1811: M*/

1813: /*MC
1814:    PetscLogObjectDestroy - Logs the destruction of a `PetscObject`

1816:    Synopsis:
1817: #include <petsclog.h>
1818:    PetscErrorCode PetscLogObjectDestroy(PetscObject h)

1820:    Not Collective

1822:    Input Parameters:
1823: .  h - A `PetscObject`

1825:    Level: developer

1827:    Developer Note:
1828:      Called internally by PETSc when destroying objects: users do not need to call this directly.
1829:      Notification of the object creation is sent to each `PetscLogHandler` that is running.

1831: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1832: M*/

1834: /*@
1835:   PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.

1837:   Not Collective

1839:   Input Parameter:
1840: . name - The class name

1842:   Output Parameter:
1843: . classid - The `PetscClassId` id, or -1 if no class with that name exists

1845:   Level: intermediate

1847: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1848: @*/
1849: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1850: {
1851:   PetscLogClass     log_class;
1852:   PetscLogClassInfo class_info;
1853:   PetscLogState     state;

1855:   PetscFunctionBegin;
1856:   *classid = -1;
1857:   PetscCall(PetscLogGetState(&state));
1858:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1859:   PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1860:   if (log_class < 0) {
1861:     *classid = -1;
1862:     PetscFunctionReturn(PETSC_SUCCESS);
1863:   }
1864:   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1865:   *classid = class_info.classid;
1866:   PetscFunctionReturn(PETSC_SUCCESS);
1867: }

1869: /*@C
1870:   PetscLogClassIdGetName - Returns a `PetscClassId`'s name.

1872:   Not Collective

1874:   Input Parameter:
1875: . classid - A `PetscClassId`

1877:   Output Parameter:
1878: . name - The class name

1880:   Level: intermediate

1882: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1883: @*/
1884: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1885: {
1886:   PetscLogClass     log_class;
1887:   PetscLogClassInfo class_info;
1888:   PetscLogState     state;

1890:   PetscFunctionBegin;
1891:   PetscCall(PetscLogGetState(&state));
1892:   PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1893:   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1894:   *name = class_info.name;
1895:   PetscFunctionReturn(PETSC_SUCCESS);
1896: }

1898: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1899: /*@
1900:   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1901:   be read by bin/petscview. This program no longer exists.

1903:   Collective on `PETSC_COMM_WORLD`

1905:   Input Parameter:
1906: . sname - an optional file name

1908:   Example Usage:
1909: .vb
1910:   PetscInitialize(...);
1911:   PetscLogDefaultBegin();
1912:   // ... code ...
1913:   PetscLogDump(filename);
1914:   PetscFinalize();
1915: .ve

1917:   Level: advanced

1919:   Note:
1920:   The default file name is Log.<rank> where <rank> is the MPI process rank. If no name is specified,
1921:   this file will be used.

1923: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1924: @*/
1925: PetscErrorCode PetscLogDump(const char sname[])
1926: {
1927:   PetscLogHandler handler;

1929:   PetscFunctionBegin;
1930:   PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1931:   PetscCall(PetscLogHandlerDump(handler, sname));
1932:   PetscFunctionReturn(PETSC_SUCCESS);
1933: }

1935: /*@
1936:   PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.

1938:   Collective on `PETSC_COMM_WORLD`

1940:   Input Parameter:
1941: . sname - filename for the MPE logfile

1943:   Level: advanced

1945: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1946: @*/
1947: PetscErrorCode PetscLogMPEDump(const char sname[])
1948: {
1949:   PetscFunctionBegin;
1950:   #if defined(PETSC_HAVE_MPE)
1951:   if (PetscBeganMPE) {
1952:     char name[PETSC_MAX_PATH_LEN];

1954:     PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1955:     if (sname) {
1956:       PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1957:     } else {
1958:       PetscCall(PetscGetProgramName(name, sizeof(name)));
1959:     }
1960:     PetscCall(MPE_Finish_log(name));
1961:   } else {
1962:     PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1963:   }
1964:   #else
1965:   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1966:   #endif
1967:   PetscFunctionReturn(PETSC_SUCCESS);
1968: }

1970: /*@
1971:   PetscLogView - Prints a summary of the logging.

1973:   Collective

1975:   Input Parameter:
1976: . viewer - an ASCII viewer

1978:   Options Database Keys:
1979: + -log_view [:filename]                    - Prints summary of log information
1980: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1981: . -log_view :filename.xml:ascii_xml        - Saves a summary of the logging information in a nested format (see below for how to view it)
1982: . -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see below for how to view it)
1983: . -log_view_memory                         - Also display memory usage in each event
1984: . -log_view_gpu_time                       - Also display time in each event for GPU kernels (Note this may slow the computation)
1985: . -log_all                                 - Saves a file Log.rank for each MPI rank with details of each step of the computation
1986: - -log_trace [filename]                    - Displays a trace of what each process is doing

1988:   Level: beginner

1990:   Notes:
1991:   It is possible to control the logging programmatically but we recommend using the options database approach whenever possible
1992:   By default the summary is printed to stdout.

1994:   Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()

1996:   If PETSc is configured with --with-logging=0 then this functionality is not available

1998:   To view the nested XML format filename.xml first copy  ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1999:   directory then open filename.xml with your browser. Specific notes for certain browsers
2000: .vb
2001:     Firefox and Internet explorer - simply open the file
2002:     Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
2003:     Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
2004: .ve
2005:   or one can use the package <http://xmlsoft.org/XSLT/xsltproc2.html> to translate the xml file to html and then open it with
2006:   your browser.
2007:   Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
2008:   window and render the XML log file contents.

2010:   The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij  MARITIME  RESEARCH  INSTITUTE  NETHERLANDS

2012:   The Flame Graph output can be visualised using either the original Flame Graph script <https://github.com/brendangregg/FlameGraph>
2013:   or using speedscope <https://www.speedscope.app>.
2014:   Old XML profiles may be converted into this format using the script ${PETSC_DIR}/lib/petsc/bin/xml2flamegraph.py.

2016: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2017: @*/
2018: PetscErrorCode PetscLogView(PetscViewer viewer)
2019: {
2020:   PetscBool         isascii;
2021:   PetscViewerFormat format;
2022:   int               stage;
2023:   PetscLogState     state;
2024:   PetscIntStack     temp_stack;
2025:   PetscLogHandler   handler;
2026:   PetscBool         is_empty;

2028:   PetscFunctionBegin;
2029:   PetscCall(PetscLogGetState(&state));
2030:   /* Pop off any stages the user forgot to remove */
2031:   PetscCall(PetscIntStackCreate(&temp_stack));
2032:   PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2033:   while (stage >= 0) {
2034:     PetscCall(PetscLogStagePop());
2035:     PetscCall(PetscIntStackPush(temp_stack, stage));
2036:     PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2037:   }
2038:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2039:   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2040:   PetscCall(PetscViewerGetFormat(viewer, &format));
2041:   if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2042:     PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2043:     PetscCall(PetscLogHandlerView(handler, viewer));
2044:   } else {
2045:     PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2046:     PetscCall(PetscLogHandlerView(handler, viewer));
2047:   }
2048:   PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2049:   while (!is_empty) {
2050:     PetscCall(PetscIntStackPop(temp_stack, &stage));
2051:     PetscCall(PetscLogStagePush(stage));
2052:     PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2053:   }
2054:   PetscCall(PetscIntStackDestroy(temp_stack));
2055:   PetscFunctionReturn(PETSC_SUCCESS);
2056: }

2058: /*@C
2059:   PetscLogViewFromOptions - Processes command line options to determine if/how a `PetscLog` is to be viewed.

2061:   Collective on `PETSC_COMM_WORLD`

2063:   Level: developer

2065: .seealso: [](ch_profiling), `PetscLogView()`
2066: @*/
2067: PetscErrorCode PetscLogViewFromOptions(void)
2068: {
2069:   PetscInt          n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2070:   PetscViewer       viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2071:   PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2072:   PetscBool         flg;

2074:   PetscFunctionBegin;
2075:   PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2076:   /*
2077:      PetscLogHandlerView_Default_Info() wants to be sure that the only objects still around are these viewers, so keep track of how many there are
2078:    */
2079:   PetscLogNumViewersCreated = n_max;
2080:   for (PetscInt i = 0; i < n_max; i++) {
2081:     PetscInt refct;

2083:     PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2084:     PetscCall(PetscLogView(viewers[i]));
2085:     PetscCall(PetscViewerPopFormat(viewers[i]));
2086:     PetscCall(PetscObjectGetReference((PetscObject)viewers[i], &refct));
2087:     PetscCall(PetscViewerDestroy(&viewers[i]));
2088:     if (refct == 1) PetscLogNumViewersDestroyed++;
2089:   }
2090:   PetscFunctionReturn(PETSC_SUCCESS);
2091: }

2093: PETSC_INTERN PetscErrorCode PetscLogHandlerNestedSetThreshold(PetscLogHandler, PetscLogDouble, PetscLogDouble *);

2095: /*@
2096:   PetscLogSetThreshold - Set the threshold time for logging the events; this is a percentage out of 100, so 1. means any event
2097:   that takes 1 or more percent of the time.

2099:   Logically Collective on `PETSC_COMM_WORLD`

2101:   Input Parameter:
2102: . newThresh - the threshold to use

2104:   Output Parameter:
2105: . oldThresh - the previously set threshold value

2107:   Options Database Keys:
2108: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file

2110:   Example Usage:
2111: .vb
2112:   PetscInitialize(...);
2113:   PetscLogNestedBegin();
2114:   PetscLogSetThreshold(0.1,&oldthresh);
2115:   // ... code ...
2116:   PetscLogView(viewer);
2117:   PetscFinalize();
2118: .ve

2120:   Level: advanced

2122:   Note:
2123:   This threshold is only used by the nested log handler

2125: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2126:           `PetscLogNestedBegin()`
2127: @*/
2128: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2129: {
2130:   PetscLogHandler handler;

2132:   PetscFunctionBegin;
2133:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2134:   PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2135:   PetscFunctionReturn(PETSC_SUCCESS);
2136: }

2138: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2139: /*@
2140:   PetscGetFlops - Returns the number of flops used on this processor
2141:   since the program began.

2143:   Not Collective

2145:   Output Parameter:
2146: . flops - number of floating point operations

2148:   Level: intermediate

2150:   Notes:
2151:   A global counter logs all PETSc flop counts.  The user can use
2152:   `PetscLogFlops()` to increment this counter to include flops for the
2153:   application code.

2155:   A separate counter `PetscLogGpuFlops()` logs the flops that occur on any GPU associated with this MPI rank

2157: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2158: @*/
2159: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2160: {
2161:   PetscFunctionBegin;
2162:   *flops = petsc_TotalFlops;
2163:   PetscFunctionReturn(PETSC_SUCCESS);
2164: }

2166: /*@C
2167:   PetscLogObjectState - Record information about an object with the default log handler

2169:   Not Collective

2171:   Input Parameters:
2172: + obj    - the `PetscObject`
2173: . format - a printf-style format string
2174: - ...    - printf arguments to format

2176:   Level: developer

2178: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2179: @*/
2180: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2181: {
2182:   PetscFunctionBegin;
2183:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2184:     PetscLogHandler h = PetscLogHandlers[i].handler;

2186:     if (h) {
2187:       va_list Argp;
2188:       va_start(Argp, format);
2189:       PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2190:       va_end(Argp);
2191:     }
2192:   }
2193:   PetscFunctionReturn(PETSC_SUCCESS);
2194: }

2196: /*MC
2197:   PetscLogFlops - Adds floating point operations to the global counter.

2199:   Synopsis:
2200: #include <petsclog.h>
2201:   PetscErrorCode PetscLogFlops(PetscLogDouble f)

2203:   Not Collective

2205:   Input Parameter:
2206: . f - flop counter

2208:   Example Usage:
2209: .vb
2210:   PetscLogEvent USER_EVENT;

2212:   PetscLogEventRegister("User event", 0, &USER_EVENT);
2213:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2214:   [code segment to monitor]
2215:   PetscLogFlops(user_flops)
2216:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2217: .ve

2219:   Level: intermediate

2221:   Note:
2222:    A global counter logs all PETSc flop counts. The user can use PetscLogFlops() to increment
2223:    this counter to include flops for the application code.

2225: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscGetFlops()`
2226: M*/

2228: /*MC
2229:   PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2230:   timings

2232:   Synopsis:
2233: #include <petsclog.h>
2234:   void PetscPreLoadBegin(PetscBool flag, char *name);

2236:   Not Collective

2238:   Input Parameters:
2239: + flag - `PETSC_TRUE` to run twice, `PETSC_FALSE` to run once, may be overridden with command
2240:          line option `-preload true|false`
2241: - name - name of first stage (lines of code timed separately with `-log_view`) to be preloaded

2243:   Example Usage:
2244: .vb
2245:   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2246:   // lines of code
2247:   PetscPreLoadStage("second stage");
2248:   // lines of code
2249:   PetscPreLoadEnd();
2250: .ve

2252:   Level: intermediate

2254:   Note:
2255:   Only works in C/C++, not Fortran

2257:   Flags available within the macro\:
2258: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2259: . PetscPreLoadingOn   - `PETSC_TRUE` if it is CURRENTLY doing preload
2260: . PetscPreLoadIt      - `0` for the first computation (with preloading turned off it is only
2261:                         `0`) `1`  for the second
2262: - PetscPreLoadMax     - number of times it will do the computation, only one when preloading is
2263:                         turned on

2265:   The first two variables are available throughout the program, the second two only between the
2266:   `PetscPreLoadBegin()` and `PetscPreLoadEnd()`

2268: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
2269: M*/

2271: /*MC
2272:   PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2273:   timings

2275:   Synopsis:
2276: #include <petsclog.h>
2277:   void PetscPreLoadEnd(void);

2279:   Not Collective

2281:   Example Usage:
2282: .vb
2283:   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2284:   // lines of code
2285:   PetscPreLoadStage("second stage");
2286:   // lines of code
2287:   PetscPreLoadEnd();
2288: .ve

2290:   Level: intermediate

2292:   Note:
2293:   Only works in C/C++ not Fortran

2295: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadStage()`
2296: M*/

2298: /*MC
2299:   PetscPreLoadStage - Start a new segment of code to be timed separately to get accurate timings

2301:   Synopsis:
2302: #include <petsclog.h>
2303:   void PetscPreLoadStage(char *name);

2305:   Not Collective

2307:   Example Usage:
2308: .vb
2309:   PetscPreLoadBegin(PETSC_TRUE,"first stage");
2310:   // lines of code
2311:   PetscPreLoadStage("second stage");
2312:   // lines of code
2313:   PetscPreLoadEnd();
2314: .ve

2316:   Level: intermediate

2318:   Note:
2319:   Only works in C/C++ not Fortran

2321: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`
2322: M*/

2324:   #if PetscDefined(HAVE_DEVICE)
2325: #include <petsc/private/deviceimpl.h>

2327: /*@
2328:   PetscLogGpuTime - turn on the logging of GPU time for GPU kernels

2330:   Options Database Key:
2331: . -log_view_gpu_time - provide the GPU times for all events in the `-log_view` output

2333:   Level: advanced

2335:   Notes:
2336:   Turning on the timing of the GPU kernels can slow down the entire computation and should only
2337:   be used when studying the performance of individual operations on GPU such as vector operations and
2338:   matrix-vector operations.

2340:   If this option is not used then times for most of the events in the `-log_view` output will be listed as Nan, indicating the times are not available

2342:   This routine should only be called once near the beginning of the program. Once it is started
2343:   it cannot be turned off.

2345: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2346: @*/
2347: PetscErrorCode PetscLogGpuTime(void)
2348: {
2349:   PetscFunctionBegin;
2350:   PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2351:   PetscLogGpuTimeFlag = PETSC_TRUE;
2352:   PetscFunctionReturn(PETSC_SUCCESS);
2353: }

2355: /*@
2356:   PetscLogGpuTimeBegin - Start timer for device

2358:   Level: intermediate

2360:   Notes:
2361:   When GPU is enabled, the timer is run on the GPU, it is a separate logging of time
2362:   devoted to GPU computations (excluding kernel launch times).

2364:   When GPU is not available, the timer is run on the CPU, it is a separate logging of
2365:   time devoted to GPU computations (including kernel launch times).

2367:   There is no need to call WaitForCUDA() or WaitForHIP() between `PetscLogGpuTimeBegin()` and
2368:   `PetscLogGpuTimeEnd()`

2370:   This timer should NOT include times for data transfers between the GPU and CPU, nor setup
2371:   actions such as allocating space.

2373:   The regular logging captures the time for data transfers and any CPU activities during the
2374:   event. It is used to compute the flop rate on the GPU as it is actively engaged in running a
2375:   kernel.

2377:   Developer Notes:
2378:   The GPU event timer captures the execution time of all the kernels launched in the default
2379:   stream by the CPU between `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()`.

2381:   `PetscLogGpuTimeBegin()` and `PetscLogGpuTimeEnd()` insert the begin and end events into the
2382:   default stream (stream 0). The device will record a time stamp for the event when it reaches
2383:   that event in the stream. The function xxxEventSynchronize() is called in
2384:   `PetscLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2385:   timer event is recorded.

2387: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2388: @*/
2389: PetscErrorCode PetscLogGpuTimeBegin(void)
2390: {
2391:   PetscBool isActive;

2393:   PetscFunctionBegin;
2394:   PetscCall(PetscLogEventBeginIsActive(&isActive));
2395:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2396:     #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2397:   {
2398:     PetscDeviceContext dctx;

2400:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2401:     PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2402:   }
2403:     #else
2404:   PetscCall(PetscTimeSubtract(&petsc_gtime));
2405:     #endif
2406:   PetscFunctionReturn(PETSC_SUCCESS);
2407: }

2409: /*@
2410:   PetscLogGpuTimeEnd - Stop timer for device

2412:   Level: intermediate

2414: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2415: @*/
2416: PetscErrorCode PetscLogGpuTimeEnd(void)
2417: {
2418:   PetscBool isActive;

2420:   PetscFunctionBegin;
2421:   PetscCall(PetscLogEventEndIsActive(&isActive));
2422:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2423:     #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2424:   {
2425:     PetscDeviceContext dctx;
2426:     PetscLogDouble     elapsed;

2428:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2429:     PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2430:     petsc_gtime += (elapsed / 1000.0);
2431:   }
2432:     #else
2433:   PetscCall(PetscTimeAdd(&petsc_gtime));
2434:     #endif
2435:   PetscFunctionReturn(PETSC_SUCCESS);
2436: }

2438:   #endif /* end of PETSC_HAVE_DEVICE */

2440: #endif /* PETSC_USE_LOG*/

2442: /* -- Utility functions for logging from Fortran -- */

2444: PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2445: {
2446:   PetscFunctionBegin;
2447: #if PetscDefined(USE_LOG)
2448:   PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2449:   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2450:   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2451:   #endif
2452: #endif
2453:   PetscFunctionReturn(PETSC_SUCCESS);
2454: }

2456: PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2457: {
2458:   PetscFunctionBegin;
2459: #if PetscDefined(USE_LOG)
2460:   PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2461:   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2462:   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2463:   #endif
2464: #endif
2465:   PetscFunctionReturn(PETSC_SUCCESS);
2466: }

2468: PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2469: {
2470:   PetscFunctionBegin;
2471:   if (PetscDefined(USE_LOG)) PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2472:   PetscFunctionReturn(PETSC_SUCCESS);
2473: }

2475: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2476: PetscClassId PETSC_OBJECT_CLASSID  = 0;

2478: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

2480: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2481: {
2482:   int stage;

2484:   PetscFunctionBegin;
2485:   if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2486:   PetscLogInitializeCalled = PETSC_TRUE;
2487:   if (PetscDefined(USE_LOG)) {
2488:     /* Setup default logging structures */
2489:     PetscCall(PetscLogStateCreate(&petsc_log_state));
2490:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2491:       if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2492:     }
2493:     PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2494:     PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2495: #if defined(PETSC_HAVE_THREADSAFETY)
2496:     petsc_log_tid = 0;
2497:     petsc_log_gid = 0;
2498: #endif

2500:     /* All processors sync here for more consistent logging */
2501:     PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2502:     PetscCall(PetscTime(&petsc_BaseTime));
2503:     PetscCall(PetscLogStagePush(stage));
2504:   }
2505:   PetscFunctionReturn(PETSC_SUCCESS);
2506: }

2508: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2509: {
2510:   PetscFunctionBegin;
2511:   if (PetscDefined(USE_LOG)) {
2512:     /* Resetting phase */
2513:     // pop remaining stages
2514:     if (petsc_log_state) {
2515:       while (petsc_log_state->current_stage >= 0) { PetscCall(PetscLogStagePop()); }
2516:     }
2517:     for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2518:     PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2519:     PetscCall(PetscLogStateDestroy(&petsc_log_state));

2521:     petsc_TotalFlops         = 0.0;
2522:     petsc_BaseTime           = 0.0;
2523:     petsc_TotalFlops         = 0.0;
2524:     petsc_send_ct            = 0.0;
2525:     petsc_recv_ct            = 0.0;
2526:     petsc_send_len           = 0.0;
2527:     petsc_recv_len           = 0.0;
2528:     petsc_isend_ct           = 0.0;
2529:     petsc_irecv_ct           = 0.0;
2530:     petsc_isend_len          = 0.0;
2531:     petsc_irecv_len          = 0.0;
2532:     petsc_wait_ct            = 0.0;
2533:     petsc_wait_any_ct        = 0.0;
2534:     petsc_wait_all_ct        = 0.0;
2535:     petsc_sum_of_waits_ct    = 0.0;
2536:     petsc_allreduce_ct       = 0.0;
2537:     petsc_gather_ct          = 0.0;
2538:     petsc_scatter_ct         = 0.0;
2539:     petsc_TotalFlops_th      = 0.0;
2540:     petsc_send_ct_th         = 0.0;
2541:     petsc_recv_ct_th         = 0.0;
2542:     petsc_send_len_th        = 0.0;
2543:     petsc_recv_len_th        = 0.0;
2544:     petsc_isend_ct_th        = 0.0;
2545:     petsc_irecv_ct_th        = 0.0;
2546:     petsc_isend_len_th       = 0.0;
2547:     petsc_irecv_len_th       = 0.0;
2548:     petsc_wait_ct_th         = 0.0;
2549:     petsc_wait_any_ct_th     = 0.0;
2550:     petsc_wait_all_ct_th     = 0.0;
2551:     petsc_sum_of_waits_ct_th = 0.0;
2552:     petsc_allreduce_ct_th    = 0.0;
2553:     petsc_gather_ct_th       = 0.0;
2554:     petsc_scatter_ct_th      = 0.0;

2556:     petsc_ctog_ct    = 0.0;
2557:     petsc_gtoc_ct    = 0.0;
2558:     petsc_ctog_sz    = 0.0;
2559:     petsc_gtoc_sz    = 0.0;
2560:     petsc_gflops     = 0.0;
2561:     petsc_gtime      = 0.0;
2562:     petsc_ctog_ct_th = 0.0;
2563:     petsc_gtoc_ct_th = 0.0;
2564:     petsc_ctog_sz_th = 0.0;
2565:     petsc_gtoc_sz_th = 0.0;
2566:     petsc_gflops_th  = 0.0;
2567:     petsc_gtime_th   = 0.0;
2568:   }
2569:   PETSC_LARGEST_CLASSID    = PETSC_SMALLEST_CLASSID;
2570:   PETSC_OBJECT_CLASSID     = 0;
2571:   PetscLogInitializeCalled = PETSC_FALSE;
2572:   PetscFunctionReturn(PETSC_SUCCESS);
2573: }

2575: /*@
2576:   PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.

2578:   Not Collective

2580:   Input Parameter:
2581: . name - The class name

2583:   Output Parameter:
2584: . oclass - The class id or classid

2586:   Level: developer

2588: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2589: @*/
2590: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2591: {
2592:   PetscFunctionBegin;
2593:   *oclass = ++PETSC_LARGEST_CLASSID;
2594: #if defined(PETSC_USE_LOG)
2595:   {
2596:     PetscLogState state;
2597:     PetscLogClass logclass;

2599:     PetscCall(PetscLogGetState(&state));
2600:     if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2601:   }
2602: #endif
2603:   PetscFunctionReturn(PETSC_SUCCESS);
2604: }