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: PetscLogState petsc_log_state = NULL;

106: // clang-format off
107: #define PETSC_LOG_HANDLER_HOT_BLANK {NULL, NULL, NULL, NULL, NULL, NULL}
108: // clang-format on

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

117: #undef PETSC_LOG_HANDLERS_HOT_BLANK

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

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

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

143:   #endif

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

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

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

168:   Not collective

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

173:   Level: developer

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

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

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

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

204:   Collective on `PETSC_COMM_WORLD`

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

211:   Level: developer

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

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

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

238:   Logically collective

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

243:   Level: developer

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

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

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

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

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

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

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

300:   Logically collective

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

305:   Level: developer

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

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

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

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

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

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

360: /*@
361:   PetscLogIsActive - Check if logging is currently in progress.

363:   Not Collective

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

368:   Level: beginner

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

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

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

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

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

431: /*@
432:   PetscLogDefaultBegin - Turns on logging of objects and events using the default log handler. This logs flop
433:   rates and object creation and should not slow programs down too much.
434:   This routine may be called more than once.

436:   Logically Collective on `PETSC_COMM_WORLD`

438:   Options Database Key:
439: . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
440:                                                  screen (for code configured with --with-log=1 (which is the default))

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

451:   Level: advanced

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

457: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
458: @*/
459: PetscErrorCode PetscLogDefaultBegin(void)
460: {
461:   PetscFunctionBegin;
462:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
463:   PetscFunctionReturn(PETSC_SUCCESS);
464: }

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

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

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

475:   Options Database Key:
476: . -log_trace [filename] - Begins `PetscLogTraceBegin()`

478:   Level: intermediate

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

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

488: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
489: @*/
490: PetscErrorCode PetscLogTraceBegin(FILE *file)
491: {
492:   PetscLogHandler handler;

494:   PetscFunctionBegin;
495:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
496:   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
497:   PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
498:   PetscCall(PetscLogHandlerStart(handler));
499:   PetscCall(PetscLogHandlerDestroy(&handler));
500:   PetscFunctionReturn(PETSC_SUCCESS);
501: }

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

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

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

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

514:   Example Usage:
515: .vb
516:       PetscInitialize(...);
517:       PetscLogNestedBegin();
518:        ... code ...
519:       PetscLogView(viewer);
520:       PetscFinalize();
521: .ve

523:   Level: advanced

525: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
526: @*/
527: PetscErrorCode PetscLogNestedBegin(void)
528: {
529:   PetscFunctionBegin;
530:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
531:   PetscFunctionReturn(PETSC_SUCCESS);
532: }

534: /*@C
535:   PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
536:   matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
537:   `PetscLogPHC`, `PetscLogPHD`.

539:   Logically Collective on `PETSC_COMM_WORLD`

541:   Input Parameters:
542: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
543: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
544: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
545: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)

547:   Calling sequence of `PetscLogPLB`:
548: + e  - a `PetscLogEvent` that is beginning
549: . _i - deprecated, unused
550: . o1 - a `PetscObject` associated with `e` (or `NULL`)
551: . o2 - a `PetscObject` associated with `e` (or `NULL`)
552: . o3 - a `PetscObject` associated with `e` (or `NULL`)
553: - o4 - a `PetscObject` associated with `e` (or `NULL`)

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

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

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

569:   Level: advanced

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

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

578: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
579: @*/
580: 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))
581: {
582:   PetscLogHandler handler;

584:   PetscFunctionBegin;
585:   PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
586:   PetscCall(PetscLogHandlerStart(handler));
587:   PetscCall(PetscLogHandlerDestroy(&handler));
588:   PetscFunctionReturn(PETSC_SUCCESS);
589: }

591:   #if defined(PETSC_HAVE_MPE)
592:     #include <mpe.h>
593: static PetscBool PetscBeganMPE = PETSC_FALSE;
594:   #endif

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

600:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

602:   Options Database Key:
603: . -log_mpe - Prints extensive log information

605:   Level: advanced

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

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

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

635:   #if defined(PETSC_HAVE_TAU_PERFSTUBS)
636: #include <../src/sys/perfstubs/timer.h>
637:   #endif

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

642:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

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

647:   Level: advanced

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

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

665:   Not Collective

667:   Input Parameter:
668: . flag - `PETSC_TRUE` if actions are to be logged

670:   Options Database Key:
671: + -log_exclude_actions - (deprecated) Does nothing
672: - -log_include_actions - Turn on action logging

674:   Level: intermediate

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

680: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
681: @*/
682: PetscErrorCode PetscLogActions(PetscBool flag)
683: {
684:   PetscFunctionBegin;
685:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
686:     PetscLogHandler h = PetscLogHandlers[i].handler;

688:     if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
689:   }
690:   PetscFunctionReturn(PETSC_SUCCESS);
691: }

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

696:   Not Collective

698:   Input Parameter:
699: . flag - `PETSC_TRUE` if objects are to be logged

701:   Options Database Key:
702: + -log_exclude_objects - (deprecated) Does nothing
703: - -log_include_objects - Turns on object logging

705:   Level: intermediate

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

711: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
712: @*/
713: PetscErrorCode PetscLogObjects(PetscBool flag)
714: {
715:   PetscFunctionBegin;
716:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
717:     PetscLogHandler h = PetscLogHandlers[i].handler;

719:     if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
720:   }
721:   PetscFunctionReturn(PETSC_SUCCESS);
722: }

724: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
725: /*@
726:   PetscLogStageRegister - Attaches a character string name to a logging stage.

728:   Not Collective

730:   Input Parameter:
731: . sname - The name to associate with that stage

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

736:   Level: intermediate

738: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`
739: @*/
740: PetscErrorCode PetscLogStageRegister(const char sname[], PetscLogStage *stage)
741: {
742:   PetscLogState state;

744:   PetscFunctionBegin;
745:   *stage = -1;
746:   PetscCall(PetscLogGetState(&state));
747:   if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
748:   PetscFunctionReturn(PETSC_SUCCESS);
749: }

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

754:   Not Collective

756:   Input Parameter:
757: . stage - The stage on which to log

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

774:   Level: intermediate

776:   Note:
777:   Use `PetscLogStageRegister()` to register a stage.

779: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
780: @*/
781: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
782: {
783:   PetscLogState state;

785:   PetscFunctionBegin;
786:   PetscCall(PetscLogGetState(&state));
787:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
788:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
789:     PetscLogHandler h = PetscLogHandlers[i].handler;
790:     if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
791:   }
792:   PetscCall(PetscLogStateStagePush(state, stage));
793:   PetscFunctionReturn(PETSC_SUCCESS);
794: }

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

799:   Not Collective

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

816:   Level: intermediate

818: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
819: @*/
820: PetscErrorCode PetscLogStagePop(void)
821: {
822:   PetscLogState state;
823:   PetscLogStage current_stage;

825:   PetscFunctionBegin;
826:   PetscCall(PetscLogGetState(&state));
827:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
828:   current_stage = state->current_stage;
829:   PetscCall(PetscLogStateStagePop(state));
830:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
831:     PetscLogHandler h = PetscLogHandlers[i].handler;
832:     if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
833:   }
834:   PetscFunctionReturn(PETSC_SUCCESS);
835: }

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

840:   Not Collective

842:   Input Parameters:
843: + stage    - The stage
844: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

846:   Level: intermediate

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

851: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
852: @*/
853: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
854: {
855:   PetscLogState state;

857:   PetscFunctionBegin;
858:   PetscCall(PetscLogGetState(&state));
859:   if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
860:   PetscFunctionReturn(PETSC_SUCCESS);
861: }

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

866:   Not Collective

868:   Input Parameter:
869: . stage - The stage

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

874:   Level: intermediate

876: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
877: @*/
878: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
879: {
880:   PetscLogState state;

882:   PetscFunctionBegin;
883:   *isActive = PETSC_FALSE;
884:   PetscCall(PetscLogGetState(&state));
885:   if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
886:   PetscFunctionReturn(PETSC_SUCCESS);
887: }

889: /*@
890:   PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`

892:   Not Collective

894:   Input Parameters:
895: + stage     - The stage
896: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

898:   Level: intermediate

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

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

908: {
909:   PetscFunctionBegin;
910:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
911:     PetscLogHandler h = PetscLogHandlers[i].handler;

913:     if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
914:   }
915:   PetscFunctionReturn(PETSC_SUCCESS);
916: }

918: /*@
919:   PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`

921:   Not Collective

923:   Input Parameter:
924: . stage - The stage

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

929:   Level: intermediate

931: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
932: @*/
933: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
934: {
935:   PetscLogHandler handler;

937:   PetscFunctionBegin;
938:   *isVisible = PETSC_FALSE;
939:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
940:   if (handler) { PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible)); }
941:   PetscFunctionReturn(PETSC_SUCCESS);
942: }

944: /*@
945:   PetscLogStageGetId - Returns the stage id when given the stage name.

947:   Not Collective

949:   Input Parameter:
950: . name - The stage name

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

955:   Level: intermediate

957: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
958: @*/
959: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
960: {
961:   PetscLogState state;

963:   PetscFunctionBegin;
964:   *stage = -1;
965:   PetscCall(PetscLogGetState(&state));
966:   if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
967:   PetscFunctionReturn(PETSC_SUCCESS);
968: }

970: /*@
971:   PetscLogStageGetName - Returns the stage name when given the stage id.

973:   Not Collective

975:   Input Parameter:
976: . stage - The stage

978:   Output Parameter:
979: . name - The stage name

981:   Level: intermediate

983: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
984: @*/
985: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
986: {
987:   PetscLogStageInfo stage_info;
988:   PetscLogState     state;

990:   PetscFunctionBegin;
991:   *name = NULL;
992:   PetscCall(PetscLogGetState(&state));
993:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
994:   PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
995:   *name = stage_info.name;
996:   PetscFunctionReturn(PETSC_SUCCESS);
997: }

999: /*------------------------------------------------ Event Functions --------------------------------------------------*/

1001: /*@
1002:   PetscLogEventRegister - Registers an event name for logging operations

1004:   Not Collective

1006:   Input Parameters:
1007: + name    - The name associated with the event
1008: - classid - The classid associated to the class for this event, obtain either with
1009:            `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1010:            are only available in C code

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

1015:   Example Usage:
1016: .vb
1017:       PetscLogEvent USER_EVENT;
1018:       PetscClassId classid;
1019:       PetscLogDouble user_event_flops;
1020:       PetscClassIdRegister("class name",&classid);
1021:       PetscLogEventRegister("User event name",classid,&USER_EVENT);
1022:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
1023:          [code segment to monitor]
1024:          PetscLogFlops(user_event_flops);
1025:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
1026: .ve

1028:   Level: intermediate

1030:   Notes:
1031:   PETSc automatically logs library events if the code has been
1032:   configured with --with-log (which is the default) and
1033:   -log_view or -log_all is specified.  `PetscLogEventRegister()` is
1034:   intended for logging user events to supplement this PETSc
1035:   information.

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

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

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

1052: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1053:           `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1054: @*/
1055: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1056: {
1057:   PetscLogState state;

1059:   PetscFunctionBegin;
1060:   *event = -1;
1061:   PetscCall(PetscLogGetState(&state));
1062:   if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1063:   PetscFunctionReturn(PETSC_SUCCESS);
1064: }

1066: /*@
1067:   PetscLogEventSetCollective - Indicates that a particular event is collective.

1069:   Logically Collective

1071:   Input Parameters:
1072: + event      - The event id
1073: - collective - Boolean flag indicating whether a particular event is collective

1075:   Level: developer

1077:   Notes:
1078:   New events returned from `PetscLogEventRegister()` are collective by default.

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

1084: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1085: @*/
1086: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1087: {
1088:   PetscLogState state;

1090:   PetscFunctionBegin;
1091:   PetscCall(PetscLogGetState(&state));
1092:   if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1093:   PetscFunctionReturn(PETSC_SUCCESS);
1094: }

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

1099:   Not Collective

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

1105:   Level: developer

1107: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1108: */
1109: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1110: {
1111:   PetscLogState state;

1113:   PetscFunctionBegin;
1114:   PetscCall(PetscLogGetState(&state));
1115:   if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1116:   PetscFunctionReturn(PETSC_SUCCESS);
1117: }

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

1122:   Not Collective

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

1127:   Level: developer

1129: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1130: @*/
1131: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1132: {
1133:   PetscFunctionBegin;
1134:   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1135:   PetscFunctionReturn(PETSC_SUCCESS);
1136: }

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

1141:   Not Collective

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

1146:   Level: developer

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

1151: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1152: @*/
1153: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1154: {
1155:   PetscFunctionBegin;
1156:   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1157:   PetscFunctionReturn(PETSC_SUCCESS);
1158: }

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

1163:   Not Collective

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

1170:   Usage:
1171: .vb
1172:       PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1173:         [code where you do not want to log VecSetValues()]
1174:       PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1175:         [code where you do want to log VecSetValues()]
1176: .ve

1178:   Level: advanced

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

1184: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1185: */
1186: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1187: {
1188:   PetscLogState state;

1190:   PetscFunctionBegin;
1191:   PetscCall(PetscLogGetState(&state));
1192:   if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1193:   PetscFunctionReturn(PETSC_SUCCESS);
1194: }

1196: /*@
1197:   PetscLogEventActivate - Indicates that a particular event should be logged.

1199:   Not Collective

1201:   Input Parameter:
1202: . event - The event id

1204:   Example Usage:
1205: .vb
1206:       PetscLogEventDeactivate(VEC_SetValues);
1207:         [code where you do not want to log VecSetValues()]
1208:       PetscLogEventActivate(VEC_SetValues);
1209:         [code where you do want to log VecSetValues()]
1210: .ve

1212:   Level: advanced

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

1218: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1219: @*/
1220: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1221: {
1222:   PetscFunctionBegin;
1223:   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1224:   PetscFunctionReturn(PETSC_SUCCESS);
1225: }

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

1230:   Not Collective

1232:   Input Parameter:
1233: . event - The event id

1235:   Example Usage:
1236: .vb
1237:       PetscLogEventDeactivate(VEC_SetValues);
1238:         [code where you do not want to log VecSetValues()]
1239:       PetscLogEventActivate(VEC_SetValues);
1240:         [code where you do want to log VecSetValues()]
1241: .ve

1243:   Level: advanced

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

1249: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1250: @*/
1251: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1252: {
1253:   PetscFunctionBegin;
1254:   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1255:   PetscFunctionReturn(PETSC_SUCCESS);
1256: }

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

1261:   Not Collective

1263:   Input Parameter:
1264: . event - The event id

1266:   Example Usage:
1267: .vb
1268:       PetscLogEventDeactivatePush(VEC_SetValues);
1269:         [code where you do not want to log VecSetValues()]
1270:       PetscLogEventDeactivatePop(VEC_SetValues);
1271:         [code where you do want to log VecSetValues()]
1272: .ve

1274:   Level: advanced

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

1280:   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.

1282: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePop()`
1283: @*/
1284: PetscErrorCode PetscLogEventDeactivatePush(PetscLogEvent event)
1285: {
1286:   PetscFunctionBegin;
1287:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1288:     PetscLogHandler h = PetscLogHandlers[i].handler;

1290:     if (h) PetscCall(PetscLogHandlerEventDeactivatePush(h, PETSC_DEFAULT, event));
1291:   }
1292:   PetscFunctionReturn(PETSC_SUCCESS);
1293: }

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

1298:   Not Collective

1300:   Input Parameter:
1301: . event - The event id

1303:   Example Usage:
1304: .vb
1305:       PetscLogEventDeactivatePush(VEC_SetValues);
1306:         [code where you do not want to log VecSetValues()]
1307:       PetscLogEventDeactivatePop(VEC_SetValues);
1308:         [code where you do want to log VecSetValues()]
1309: .ve

1311:   Level: advanced

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

1317: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1318: @*/
1319: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1320: {
1321:   PetscFunctionBegin;
1322:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1323:     PetscLogHandler h = PetscLogHandlers[i].handler;

1325:     if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1326:   }
1327:   PetscFunctionReturn(PETSC_SUCCESS);
1328: }

1330: /*@
1331:   PetscLogEventSetActiveAll - Turns on logging of all events

1333:   Not Collective

1335:   Input Parameters:
1336: + event    - The event id
1337: - isActive - The activity flag determining whether the event is logged

1339:   Level: advanced

1341: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1342: @*/
1343: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1344: {
1345:   PetscLogState state;

1347:   PetscFunctionBegin;
1348:   PetscCall(PetscLogGetState(&state));
1349:   if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1350:   PetscFunctionReturn(PETSC_SUCCESS);
1351: }

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

1356:   Not Collective

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

1363:   Level: developer

1365: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1366: */
1367: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1368: {
1369:   PetscLogState state;

1371:   PetscFunctionBegin;
1372:   PetscCall(PetscLogGetState(&state));
1373:   if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1374:   PetscFunctionReturn(PETSC_SUCCESS);
1375: }

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

1380:   Not Collective

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

1385:   Level: developer

1387: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1388: @*/
1389: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1390: {
1391:   PetscFunctionBegin;
1392:   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1393:   PetscFunctionReturn(PETSC_SUCCESS);
1394: }

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

1399:   Not Collective

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

1404:   Level: developer

1406: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1407: @*/
1408: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1409: {
1410:   PetscFunctionBegin;
1411:   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1412:   PetscFunctionReturn(PETSC_SUCCESS);
1413: }

1415: /*MC
1416:   PetscLogEventSync - Synchronizes the beginning of a user event.

1418:   Synopsis:
1419: #include <petsclog.h>
1420:   PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)

1422:   Collective

1424:   Input Parameters:
1425: + e    - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1426: - comm - an MPI communicator

1428:   Example Usage:
1429: .vb
1430:   PetscLogEvent USER_EVENT;

1432:   PetscLogEventRegister("User event", 0, &USER_EVENT);
1433:   PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1434:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1435:   [code segment to monitor]
1436:   PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1437: .ve

1439:   Level: developer

1441:   Note:
1442:   This routine should be called only if there is not a `PetscObject` available to pass to
1443:   `PetscLogEventBegin()`.

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

1448: /*MC
1449:   PetscLogEventBegin - Logs the beginning of a user event.

1451:   Synopsis:
1452: #include <petsclog.h>
1453:   PetscErrorCode PetscLogEventBegin(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)

1455:   Not Collective

1457:   Input Parameters:
1458: + e  - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1459: . o1 - object associated with the event, or `NULL`
1460: . o2 - object associated with the event, or `NULL`
1461: . o3 - object associated with the event, or `NULL`
1462: - o4 - object associated with the event, or `NULL`

1464:   Fortran Synopsis:
1465:   void PetscLogEventBegin(int e, PetscErrorCode ierr)

1467:   Example Usage:
1468: .vb
1469:   PetscLogEvent USER_EVENT;

1471:   PetscLogDouble user_event_flops;
1472:   PetscLogEventRegister("User event",0, &USER_EVENT);
1473:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1474:   [code segment to monitor]
1475:   PetscLogFlops(user_event_flops);
1476:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1477: .ve

1479:   Level: intermediate

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

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

1490: /*MC
1491:   PetscLogEventEnd - Log the end of a user event.

1493:   Synopsis:
1494: #include <petsclog.h>
1495:   PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)

1497:   Not Collective

1499:   Input Parameters:
1500: + e  - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1501: . o1 - object associated with the event, or `NULL`
1502: . o2 - object associated with the event, or `NULL`
1503: . o3 - object associated with the event, or `NULL`
1504: - o4 - object associated with the event, or `NULL`

1506:   Fortran Synopsis:
1507:   void PetscLogEventEnd(int e, PetscErrorCode ierr)

1509:   Example Usage:
1510: .vb
1511:   PetscLogEvent USER_EVENT;

1513:   PetscLogDouble user_event_flops;
1514:   PetscLogEventRegister("User event", 0, &USER_EVENT);
1515:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1516:   [code segment to monitor]
1517:   PetscLogFlops(user_event_flops);
1518:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1519: .ve

1521:   Level: intermediate

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

1526: /*@C
1527:   PetscLogStageGetPerfInfo - Return the performance information about the given stage

1529:   No Fortran Support

1531:   Input Parameters:
1532: . stage - The stage number or `PETSC_DETERMINE` for the current stage

1534:   Output Parameter:
1535: . info - This structure is filled with the performance information

1537:   Level: intermediate

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

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

1546: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1547: @*/
1548: PetscErrorCode PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1549: {
1550:   PetscLogHandler     handler;
1551:   PetscEventPerfInfo *event_info;

1553:   PetscFunctionBegin;
1554:   PetscAssertPointer(info, 2);
1555:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1556:   if (handler) {
1557:     PetscCall(PetscLogHandlerGetStagePerfInfo(handler, stage, &event_info));
1558:     *info = *event_info;
1559:   } else {
1560:     PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogStageGetPerfInfo() returning zeros\n"));
1561:     PetscCall(PetscMemzero(info, sizeof(*info)));
1562:   }
1563:   PetscFunctionReturn(PETSC_SUCCESS);
1564: }

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

1569:   No Fortran Support

1571:   Input Parameters:
1572: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1573: - event - The event number

1575:   Output Parameter:
1576: . info - This structure is filled with the performance information

1578:   Level: intermediate

1580:   Note:
1581:   This is a low level routine used by the logging functions in PETSc

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

1587: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1588: @*/
1589: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1590: {
1591:   PetscLogHandler     handler;
1592:   PetscEventPerfInfo *event_info;

1594:   PetscFunctionBegin;
1595:   PetscAssertPointer(info, 3);
1596:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1597:   if (handler) {
1598:     PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1599:     *info = *event_info;
1600:   } else {
1601:     PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1602:     PetscCall(PetscMemzero(info, sizeof(*info)));
1603:   }
1604:   PetscFunctionReturn(PETSC_SUCCESS);
1605: }

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

1610:   Not Collective

1612:   Input Parameters:
1613: + event - The event id to log
1614: . n     - The dof index, in [0, 8)
1615: - dof   - The number of dofs

1617:   Options Database Key:
1618: . -log_view - Activates log summary

1620:   Level: developer

1622:   Note:
1623:   This is to enable logging of convergence

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

1634:     if (h) {
1635:       PetscEventPerfInfo *event_info;

1637:       PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1638:       if (event_info) event_info->dof[n] = dof;
1639:     }
1640:   }
1641:   PetscFunctionReturn(PETSC_SUCCESS);
1642: }

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

1647:   Not Collective

1649:   Input Parameters:
1650: + event - The event id to log
1651: . n     - The error index, in [0, 8)
1652: - error - The error

1654:   Options Database Key:
1655: . -log_view - Activates log summary

1657:   Level: developer

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

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

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

1674:     if (h) {
1675:       PetscEventPerfInfo *event_info;

1677:       PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1678:       if (event_info) event_info->errors[n] = error;
1679:     }
1680:   }
1681:   PetscFunctionReturn(PETSC_SUCCESS);
1682: }

1684: /*@
1685:   PetscLogEventGetId - Returns the event id when given the event name.

1687:   Not Collective

1689:   Input Parameter:
1690: . name - The event name

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

1695:   Level: intermediate

1697: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1698: @*/
1699: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1700: {
1701:   PetscLogState state;

1703:   PetscFunctionBegin;
1704:   *event = -1;
1705:   PetscCall(PetscLogGetState(&state));
1706:   if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1707:   PetscFunctionReturn(PETSC_SUCCESS);
1708: }

1710: /*@
1711:   PetscLogEventGetName - Returns the event name when given the event id.

1713:   Not Collective

1715:   Input Parameter:
1716: . event - The event

1718:   Output Parameter:
1719: . name - The event name

1721:   Level: intermediate

1723: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1724: @*/
1725: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1726: {
1727:   PetscLogEventInfo event_info;
1728:   PetscLogState     state;

1730:   PetscFunctionBegin;
1731:   *name = NULL;
1732:   PetscCall(PetscLogGetState(&state));
1733:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1734:   PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1735:   *name = event_info.name;
1736:   PetscFunctionReturn(PETSC_SUCCESS);
1737: }

1739: /*@
1740:   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.

1742:   Not collective

1744:   Level: advanced

1746:   Notes:
1747:   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()`).

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

1751: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1752: @*/
1753: PetscErrorCode PetscLogEventsPause(void)
1754: {
1755:   PetscFunctionBegin;
1756:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1757:     PetscLogHandler h = PetscLogHandlers[i].handler;

1759:     if (h) PetscCall(PetscLogHandlerEventsPause(h));
1760:   }
1761:   PetscFunctionReturn(PETSC_SUCCESS);
1762: }

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

1767:   Not collective

1769:   Level: advanced

1771: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1772: @*/
1773: PetscErrorCode PetscLogEventsResume(void)
1774: {
1775:   PetscFunctionBegin;
1776:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1777:     PetscLogHandler h = PetscLogHandlers[i].handler;

1779:     if (h) PetscCall(PetscLogHandlerEventsResume(h));
1780:   }
1781:   PetscFunctionReturn(PETSC_SUCCESS);
1782: }

1784: /*------------------------------------------------ Class Functions --------------------------------------------------*/

1786: /*MC
1787:    PetscLogObjectCreate - Log the creation of a `PetscObject`

1789:    Synopsis:
1790: #include <petsclog.h>
1791:    PetscErrorCode PetscLogObjectCreate(PetscObject h)

1793:    Not Collective

1795:    Input Parameters:
1796: .  h - A `PetscObject`

1798:    Level: developer

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

1804: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1805: M*/

1807: /*MC
1808:    PetscLogObjectDestroy - Logs the destruction of a `PetscObject`

1810:    Synopsis:
1811: #include <petsclog.h>
1812:    PetscErrorCode PetscLogObjectDestroy(PetscObject h)

1814:    Not Collective

1816:    Input Parameters:
1817: .  h - A `PetscObject`

1819:    Level: developer

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

1825: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1826: M*/

1828: /*@
1829:   PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.

1831:   Not Collective

1833:   Input Parameter:
1834: . name - The class name

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

1839:   Level: intermediate

1841: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1842: @*/
1843: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1844: {
1845:   PetscLogClass     log_class;
1846:   PetscLogClassInfo class_info;
1847:   PetscLogState     state;

1849:   PetscFunctionBegin;
1850:   *classid = -1;
1851:   PetscCall(PetscLogGetState(&state));
1852:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1853:   PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1854:   if (log_class < 0) {
1855:     *classid = -1;
1856:     PetscFunctionReturn(PETSC_SUCCESS);
1857:   }
1858:   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1859:   *classid = class_info.classid;
1860:   PetscFunctionReturn(PETSC_SUCCESS);
1861: }

1863: /*@C
1864:   PetscLogClassIdGetName - Returns a `PetscClassId`'s name.

1866:   Not Collective

1868:   Input Parameter:
1869: . classid - A `PetscClassId`

1871:   Output Parameter:
1872: . name - The class name

1874:   Level: intermediate

1876: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1877: @*/
1878: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char **name)
1879: {
1880:   PetscLogClass     log_class;
1881:   PetscLogClassInfo class_info;
1882:   PetscLogState     state;

1884:   PetscFunctionBegin;
1885:   PetscCall(PetscLogGetState(&state));
1886:   PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1887:   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1888:   *name = class_info.name;
1889:   PetscFunctionReturn(PETSC_SUCCESS);
1890: }

1892: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1893: /*@
1894:   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1895:   be read by bin/petscview. This program no longer exists.

1897:   Collective on `PETSC_COMM_WORLD`

1899:   Input Parameter:
1900: . sname - an optional file name

1902:   Example Usage:
1903: .vb
1904:   PetscInitialize(...);
1905:   PetscLogDefaultBegin();
1906:   // ... code ...
1907:   PetscLogDump(filename);
1908:   PetscFinalize();
1909: .ve

1911:   Level: advanced

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

1917: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1918: @*/
1919: PetscErrorCode PetscLogDump(const char sname[])
1920: {
1921:   PetscLogHandler handler;

1923:   PetscFunctionBegin;
1924:   PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1925:   PetscCall(PetscLogHandlerDump(handler, sname));
1926:   PetscFunctionReturn(PETSC_SUCCESS);
1927: }

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

1932:   Collective on `PETSC_COMM_WORLD`

1934:   Input Parameter:
1935: . sname - filename for the MPE logfile

1937:   Level: advanced

1939: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1940: @*/
1941: PetscErrorCode PetscLogMPEDump(const char sname[])
1942: {
1943:   PetscFunctionBegin;
1944:   #if defined(PETSC_HAVE_MPE)
1945:   if (PetscBeganMPE) {
1946:     char name[PETSC_MAX_PATH_LEN];

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

1964: /*@
1965:   PetscLogView - Prints a summary of the logging.

1967:   Collective

1969:   Input Parameter:
1970: . viewer - an ASCII viewer

1972:   Options Database Keys:
1973: + -log_view [:filename]                    - Prints summary of log information
1974: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1975: . -log_view :filename.xml:ascii_xml        - Saves a summary of the logging information in a nested format (see below for how to view it)
1976: . -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)
1977: . -log_view_memory                         - Also display memory usage in each event
1978: . -log_view_gpu_time                       - Also display time in each event for GPU kernels (Note this may slow the computation)
1979: . -log_all                                 - Saves a file Log.rank for each MPI rank with details of each step of the computation
1980: - -log_trace [filename]                    - Displays a trace of what each process is doing

1982:   Level: beginner

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

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

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

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

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

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

2010: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2011: @*/
2012: PetscErrorCode PetscLogView(PetscViewer viewer)
2013: {
2014:   PetscBool         isascii;
2015:   PetscViewerFormat format;
2016:   int               stage;
2017:   PetscLogState     state;
2018:   PetscIntStack     temp_stack;
2019:   PetscLogHandler   handler;
2020:   PetscBool         is_empty;

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

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

2055:   Collective on `PETSC_COMM_WORLD`

2057:   Level: developer

2059: .seealso: [](ch_profiling), `PetscLogView()`
2060: @*/
2061: PetscErrorCode PetscLogViewFromOptions(void)
2062: {
2063:   PetscInt          n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2064:   PetscViewer       viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2065:   PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2066:   PetscBool         flg;

2068:   PetscFunctionBegin;
2069:   PetscCall(PetscOptionsGetViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2070:   for (PetscInt i = 0; i < n_max; i++) {
2071:     PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2072:     PetscCall(PetscLogView(viewers[i]));
2073:     PetscCall(PetscViewerPopFormat(viewers[i]));
2074:     PetscCall(PetscOptionsRestoreViewer(&viewers[i]));
2075:   }
2076:   PetscFunctionReturn(PETSC_SUCCESS);
2077: }

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

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

2085:   Logically Collective on `PETSC_COMM_WORLD`

2087:   Input Parameter:
2088: . newThresh - the threshold to use

2090:   Output Parameter:
2091: . oldThresh - the previously set threshold value

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

2096:   Example Usage:
2097: .vb
2098:   PetscInitialize(...);
2099:   PetscLogNestedBegin();
2100:   PetscLogSetThreshold(0.1,&oldthresh);
2101:   // ... code ...
2102:   PetscLogView(viewer);
2103:   PetscFinalize();
2104: .ve

2106:   Level: advanced

2108:   Note:
2109:   This threshold is only used by the nested log handler

2111: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2112:           `PetscLogNestedBegin()`
2113: @*/
2114: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2115: {
2116:   PetscLogHandler handler;

2118:   PetscFunctionBegin;
2119:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2120:   PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2121:   PetscFunctionReturn(PETSC_SUCCESS);
2122: }

2124: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2125: /*@
2126:   PetscGetFlops - Returns the number of flops used on this processor
2127:   since the program began.

2129:   Not Collective

2131:   Output Parameter:
2132: . flops - number of floating point operations

2134:   Level: intermediate

2136:   Notes:
2137:   A global counter logs all PETSc flop counts.  The user can use
2138:   `PetscLogFlops()` to increment this counter to include flops for the
2139:   application code.

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

2143: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2144: @*/
2145: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2146: {
2147:   PetscFunctionBegin;
2148:   *flops = petsc_TotalFlops;
2149:   PetscFunctionReturn(PETSC_SUCCESS);
2150: }

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

2155:   Not Collective

2157:   Input Parameters:
2158: + obj    - the `PetscObject`
2159: . format - a printf-style format string
2160: - ...    - printf arguments to format

2162:   Level: developer

2164: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2165: @*/
2166: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2167: {
2168:   PetscFunctionBegin;
2169:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2170:     PetscLogHandler h = PetscLogHandlers[i].handler;

2172:     if (h) {
2173:       va_list Argp;
2174:       va_start(Argp, format);
2175:       PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2176:       va_end(Argp);
2177:     }
2178:   }
2179:   PetscFunctionReturn(PETSC_SUCCESS);
2180: }

2182: /*MC
2183:   PetscLogFlops - Adds floating point operations to the global counter.

2185:   Synopsis:
2186: #include <petsclog.h>
2187:   PetscErrorCode PetscLogFlops(PetscLogDouble f)

2189:   Not Collective

2191:   Input Parameter:
2192: . f - flop counter

2194:   Example Usage:
2195: .vb
2196:   PetscLogEvent USER_EVENT;

2198:   PetscLogEventRegister("User event", 0, &USER_EVENT);
2199:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2200:   [code segment to monitor]
2201:   PetscLogFlops(user_flops)
2202:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2203: .ve

2205:   Level: intermediate

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

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

2214: /*MC
2215:   PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2216:   timings

2218:   Synopsis:
2219: #include <petsclog.h>
2220:   void PetscPreLoadBegin(PetscBool flag, char *name);

2222:   Not Collective

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

2229:   Example Usage:
2230: .vb
2231:   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2232:   // lines of code
2233:   PetscPreLoadStage("second stage");
2234:   // lines of code
2235:   PetscPreLoadEnd();
2236: .ve

2238:   Level: intermediate

2240:   Note:
2241:   Only works in C/C++, not Fortran

2243:   Flags available within the macro\:
2244: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2245: . PetscPreLoadingOn   - `PETSC_TRUE` if it is CURRENTLY doing preload
2246: . PetscPreLoadIt      - `0` for the first computation (with preloading turned off it is only
2247:                         `0`) `1`  for the second
2248: - PetscPreLoadMax     - number of times it will do the computation, only one when preloading is
2249:                         turned on

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

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

2257: /*MC
2258:   PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2259:   timings

2261:   Synopsis:
2262: #include <petsclog.h>
2263:   void PetscPreLoadEnd(void);

2265:   Not Collective

2267:   Example Usage:
2268: .vb
2269:   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2270:   // lines of code
2271:   PetscPreLoadStage("second stage");
2272:   // lines of code
2273:   PetscPreLoadEnd();
2274: .ve

2276:   Level: intermediate

2278:   Note:
2279:   Only works in C/C++ not Fortran

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

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

2287:   Synopsis:
2288: #include <petsclog.h>
2289:   void PetscPreLoadStage(char *name);

2291:   Not Collective

2293:   Example Usage:
2294: .vb
2295:   PetscPreLoadBegin(PETSC_TRUE,"first stage");
2296:   // lines of code
2297:   PetscPreLoadStage("second stage");
2298:   // lines of code
2299:   PetscPreLoadEnd();
2300: .ve

2302:   Level: intermediate

2304:   Note:
2305:   Only works in C/C++ not Fortran

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

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

2313: /*@
2314:   PetscLogGpuTime - turn on the logging of GPU time for GPU kernels

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

2319:   Level: advanced

2321:   Notes:
2322:   Turning on the timing of the GPU kernels can slow down the entire computation and should only
2323:   be used when studying the performance of individual operations on GPU such as vector operations and
2324:   matrix-vector operations.

2326:   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

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

2331: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2332: @*/
2333: PetscErrorCode PetscLogGpuTime(void)
2334: {
2335:   PetscFunctionBegin;
2336:   PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2337:   PetscLogGpuTimeFlag = PETSC_TRUE;
2338:   PetscFunctionReturn(PETSC_SUCCESS);
2339: }

2341: /*@
2342:   PetscLogGpuTimeBegin - Start timer for device

2344:   Level: intermediate

2346:   Notes:
2347:   When CUDA or HIP is enabled, the timer is run on the GPU, it is a separate logging of time
2348:   devoted to GPU computations (excluding kernel launch times).

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

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

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

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

2363:   Developer Notes:
2364:   The GPU event timer captures the execution time of all the kernels launched in the default
2365:   stream by the CPU between `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()`.

2367:   `PetscLogGpuTimeBegin()` and `PetsLogGpuTimeEnd()` insert the begin and end events into the
2368:   default stream (stream 0). The device will record a time stamp for the event when it reaches
2369:   that event in the stream. The function xxxEventSynchronize() is called in
2370:   `PetsLogGpuTimeEnd()` to block CPU execution, but not continued GPU execution, until the
2371:   timer event is recorded.

2373: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2374: @*/
2375: PetscErrorCode PetscLogGpuTimeBegin(void)
2376: {
2377:   PetscBool isActive;

2379:   PetscFunctionBegin;
2380:   PetscCall(PetscLogEventBeginIsActive(&isActive));
2381:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2382:   if (PetscDefined(HAVE_DEVICE)) {
2383:     PetscDeviceContext dctx;

2385:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2386:     PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2387:   } else {
2388:     PetscCall(PetscTimeSubtract(&petsc_gtime));
2389:   }
2390:   PetscFunctionReturn(PETSC_SUCCESS);
2391: }

2393: /*@
2394:   PetscLogGpuTimeEnd - Stop timer for device

2396:   Level: intermediate

2398: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2399: @*/
2400: PetscErrorCode PetscLogGpuTimeEnd(void)
2401: {
2402:   PetscBool isActive;

2404:   PetscFunctionBegin;
2405:   PetscCall(PetscLogEventEndIsActive(&isActive));
2406:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2407:   if (PetscDefined(HAVE_DEVICE)) {
2408:     PetscDeviceContext dctx;
2409:     PetscLogDouble     elapsed;

2411:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2412:     PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2413:     petsc_gtime += (elapsed / 1000.0);
2414:   } else {
2415:     PetscCall(PetscTimeAdd(&petsc_gtime));
2416:   }
2417:   PetscFunctionReturn(PETSC_SUCCESS);
2418: }

2420:   #endif /* end of PETSC_HAVE_DEVICE */

2422: #endif /* PETSC_USE_LOG*/

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

2426: PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2427: {
2428:   PetscFunctionBegin;
2429: #if PetscDefined(USE_LOG)
2430:   PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2431:   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2432:   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2433:   #endif
2434: #endif
2435:   PetscFunctionReturn(PETSC_SUCCESS);
2436: }

2438: PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2439: {
2440:   PetscFunctionBegin;
2441: #if PetscDefined(USE_LOG)
2442:   PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2443:   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2444:   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2445:   #endif
2446: #endif
2447:   PetscFunctionReturn(PETSC_SUCCESS);
2448: }

2450: PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2451: {
2452:   PetscFunctionBegin;
2453:   if (PetscDefined(USE_LOG)) PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2454:   PetscFunctionReturn(PETSC_SUCCESS);
2455: }

2457: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2458: PetscClassId PETSC_OBJECT_CLASSID  = 0;

2460: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

2462: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2463: {
2464:   int stage;

2466:   PetscFunctionBegin;
2467:   if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2468:   PetscLogInitializeCalled = PETSC_TRUE;
2469:   if (PetscDefined(USE_LOG)) {
2470:     /* Setup default logging structures */
2471:     PetscCall(PetscLogStateCreate(&petsc_log_state));
2472:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2473:       if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2474:     }
2475:     PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2476:     PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2477: #if defined(PETSC_HAVE_THREADSAFETY)
2478:     petsc_log_tid = 0;
2479:     petsc_log_gid = 0;
2480: #endif

2482:     /* All processors sync here for more consistent logging */
2483:     PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2484:     PetscCall(PetscTime(&petsc_BaseTime));
2485:     PetscCall(PetscLogStagePush(stage));
2486:   }
2487:   PetscFunctionReturn(PETSC_SUCCESS);
2488: }

2490: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2491: {
2492:   PetscFunctionBegin;
2493:   if (PetscDefined(USE_LOG)) {
2494:     /* Resetting phase */
2495:     // pop remaining stages
2496:     if (petsc_log_state) {
2497:       while (petsc_log_state->current_stage >= 0) { PetscCall(PetscLogStagePop()); }
2498:     }
2499:     for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2500:     PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2501:     PetscCall(PetscLogStateDestroy(&petsc_log_state));

2503:     petsc_TotalFlops         = 0.0;
2504:     petsc_BaseTime           = 0.0;
2505:     petsc_TotalFlops         = 0.0;
2506:     petsc_send_ct            = 0.0;
2507:     petsc_recv_ct            = 0.0;
2508:     petsc_send_len           = 0.0;
2509:     petsc_recv_len           = 0.0;
2510:     petsc_isend_ct           = 0.0;
2511:     petsc_irecv_ct           = 0.0;
2512:     petsc_isend_len          = 0.0;
2513:     petsc_irecv_len          = 0.0;
2514:     petsc_wait_ct            = 0.0;
2515:     petsc_wait_any_ct        = 0.0;
2516:     petsc_wait_all_ct        = 0.0;
2517:     petsc_sum_of_waits_ct    = 0.0;
2518:     petsc_allreduce_ct       = 0.0;
2519:     petsc_gather_ct          = 0.0;
2520:     petsc_scatter_ct         = 0.0;
2521:     petsc_TotalFlops_th      = 0.0;
2522:     petsc_send_ct_th         = 0.0;
2523:     petsc_recv_ct_th         = 0.0;
2524:     petsc_send_len_th        = 0.0;
2525:     petsc_recv_len_th        = 0.0;
2526:     petsc_isend_ct_th        = 0.0;
2527:     petsc_irecv_ct_th        = 0.0;
2528:     petsc_isend_len_th       = 0.0;
2529:     petsc_irecv_len_th       = 0.0;
2530:     petsc_wait_ct_th         = 0.0;
2531:     petsc_wait_any_ct_th     = 0.0;
2532:     petsc_wait_all_ct_th     = 0.0;
2533:     petsc_sum_of_waits_ct_th = 0.0;
2534:     petsc_allreduce_ct_th    = 0.0;
2535:     petsc_gather_ct_th       = 0.0;
2536:     petsc_scatter_ct_th      = 0.0;

2538:     petsc_ctog_ct    = 0.0;
2539:     petsc_gtoc_ct    = 0.0;
2540:     petsc_ctog_sz    = 0.0;
2541:     petsc_gtoc_sz    = 0.0;
2542:     petsc_gflops     = 0.0;
2543:     petsc_gtime      = 0.0;
2544:     petsc_ctog_ct_th = 0.0;
2545:     petsc_gtoc_ct_th = 0.0;
2546:     petsc_ctog_sz_th = 0.0;
2547:     petsc_gtoc_sz_th = 0.0;
2548:     petsc_gflops_th  = 0.0;
2549:     petsc_gtime_th   = 0.0;
2550:   }
2551:   PETSC_LARGEST_CLASSID    = PETSC_SMALLEST_CLASSID;
2552:   PETSC_OBJECT_CLASSID     = 0;
2553:   PetscLogInitializeCalled = PETSC_FALSE;
2554:   PetscFunctionReturn(PETSC_SUCCESS);
2555: }

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

2560:   Not Collective

2562:   Input Parameter:
2563: . name - The class name

2565:   Output Parameter:
2566: . oclass - The class id or classid

2568:   Level: developer

2570: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2571: @*/
2572: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2573: {
2574:   PetscFunctionBegin;
2575:   *oclass = ++PETSC_LARGEST_CLASSID;
2576: #if defined(PETSC_USE_LOG)
2577:   {
2578:     PetscLogState state;
2579:     PetscLogClass logclass;

2581:     PetscCall(PetscLogGetState(&state));
2582:     if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2583:   }
2584: #endif
2585:   PetscFunctionReturn(PETSC_SUCCESS);
2586: }