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: #define PETSC_LOG_HANDLER_HOT_BLANK \
107:   { \
108:     NULL, NULL, NULL, NULL, NULL, NULL \
109:   }

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

118: #undef PETSC_LOG_HANDLERS_HOT_BLANK

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

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

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

144:   #endif

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

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

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

169:   Not collective

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

174:   Level: developer

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

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

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

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

205:   Collective on `PETSC_COMM_WORLD`

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

212:   Level: developer

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

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

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

239:   Logically collective

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

244:   Level: developer

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

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

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

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

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

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

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

301:   Logically collective

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

306:   Level: developer

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

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

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

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

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

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

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

364:   Not Collective

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

369:   Level: beginner

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

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

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

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

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

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

437:   Logically Collective on `PETSC_COMM_WORLD`

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

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

452:   Level: advanced

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

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

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

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

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

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

479:   Level: intermediate

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

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

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

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

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

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

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

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

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

524:   Level: advanced

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

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

540:   Logically Collective on `PETSC_COMM_WORLD`

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

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

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

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

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

570:   Level: advanced

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

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

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

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

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

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

601:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

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

606:   Level: advanced

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

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

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

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

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

643:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

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

648:   Level: advanced

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

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

666:   Not Collective

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

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

675:   Level: intermediate

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

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

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

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

697:   Not Collective

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

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

706:   Level: intermediate

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

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

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

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

729:   Not Collective

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

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

737:   Level: intermediate

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

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

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

755:   Not Collective

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

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

775:   Level: intermediate

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

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

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

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

800:   Not Collective

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

817:   Level: intermediate

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

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

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

841:   Not Collective

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

847:   Level: intermediate

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

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

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

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

867:   Not Collective

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

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

875:   Level: intermediate

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

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

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

893:   Not Collective

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

899:   Level: intermediate

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

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

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

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

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

922:   Not Collective

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

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

930:   Level: intermediate

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

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

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

948:   Not Collective

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

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

956:   Level: intermediate

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

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

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

974:   Not Collective

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

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

982:   Level: intermediate

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

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

1000: /*------------------------------------------------ Event Functions --------------------------------------------------*/

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

1005:   Not Collective

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

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

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

1029:   Level: intermediate

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

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

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

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

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

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

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

1070:   Logically Collective

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

1076:   Level: developer

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

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

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

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

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

1100:   Not Collective

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

1106:   Level: developer

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

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

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

1123:   Not Collective

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

1128:   Level: developer

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

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

1142:   Not Collective

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

1147:   Level: developer

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

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

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

1164:   Not Collective

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

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

1179:   Level: advanced

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

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

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

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

1200:   Not Collective

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

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

1213:   Level: advanced

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

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

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

1231:   Not Collective

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

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

1244:   Level: advanced

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

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

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

1262:   Not Collective

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

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

1275:   Level: advanced

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

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

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

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

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

1299:   Not Collective

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

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

1312:   Level: advanced

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

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

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

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

1334:   Not Collective

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

1340:   Level: advanced

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

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

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

1357:   Not Collective

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

1364:   Level: developer

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

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

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

1381:   Not Collective

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

1386:   Level: developer

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

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

1400:   Not Collective

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

1405:   Level: developer

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

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

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

1423:   Collective

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

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

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

1440:   Level: developer

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

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

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

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

1456:   Not Collective

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

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

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

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

1480:   Level: intermediate

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

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

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

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

1498:   Not Collective

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

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

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

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

1522:   Level: intermediate

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

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

1530:   No Fortran Support

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

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

1538:   Level: intermediate

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

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

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

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

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

1570:   No Fortran Support

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

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

1579:   Level: intermediate

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

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

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

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

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

1611:   Not Collective

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

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

1621:   Level: developer

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

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

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

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

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

1648:   Not Collective

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

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

1658:   Level: developer

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

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

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

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

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

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

1688:   Not Collective

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

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

1696:   Level: intermediate

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

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

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

1714:   Not Collective

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

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

1722:   Level: intermediate

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

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

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

1743:   Not collective

1745:   Level: advanced

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

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

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

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

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

1768:   Not collective

1770:   Level: advanced

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

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

1785: /*------------------------------------------------ Class Functions --------------------------------------------------*/

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

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

1794:    Not Collective

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

1799:    Level: developer

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

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

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

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

1815:    Not Collective

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

1820:    Level: developer

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

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

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

1832:   Not Collective

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

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

1840:   Level: intermediate

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

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

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

1867:   Not Collective

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

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

1875:   Level: intermediate

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

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

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

1898:   Collective on `PETSC_COMM_WORLD`

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

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

1912:   Level: advanced

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

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

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

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

1933:   Collective on `PETSC_COMM_WORLD`

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

1938:   Level: advanced

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

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

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

1968:   Collective

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

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

1983:   Level: beginner

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

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

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

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

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

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

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

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

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

2056:   Collective on `PETSC_COMM_WORLD`

2058:   Level: developer

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

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

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

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

2086:   Logically Collective on `PETSC_COMM_WORLD`

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

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

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

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

2107:   Level: advanced

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

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

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

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

2130:   Not Collective

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

2135:   Level: intermediate

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

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

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

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

2156:   Not Collective

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

2163:   Level: developer

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

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

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

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

2190:   Not Collective

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

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

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

2206:   Level: intermediate

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

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

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

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

2223:   Not Collective

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

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

2239:   Level: intermediate

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

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

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

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

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

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

2266:   Not Collective

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

2277:   Level: intermediate

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

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

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

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

2292:   Not Collective

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

2303:   Level: intermediate

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

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

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

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

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

2320:   Level: advanced

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

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

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

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

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

2345:   Level: intermediate

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

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

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

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

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

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

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

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

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

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

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

2397:   Level: intermediate

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

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

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

2421:   #endif /* end of PETSC_HAVE_DEVICE */

2423: #endif /* PETSC_USE_LOG*/

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

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

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

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

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

2461: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

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

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

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

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

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

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

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

2561:   Not Collective

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

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

2569:   Level: developer

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

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