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 PetscDefined(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 */
 87: PetscLogDouble petsc_genergy        = 0.0; /* The energy (estimated with power*gtime) consumed on a GPU */
 88: PetscLogDouble petsc_genergy_meter  = 0.0; /* Readings from the energy meter on a GPU */

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

101: PetscBool PetscLogMemory = PETSC_FALSE;
102: PetscBool PetscLogSyncOn = PETSC_FALSE;

104: PetscBool PetscLogGpuTimeFlag        = PETSC_FALSE;
105: PetscBool PetscLogGpuEnergyFlag      = PETSC_FALSE;
106: PetscBool PetscLogGpuEnergyMeterFlag = PETSC_FALSE;

108: PetscInt PetscLogNumViewersCreated   = 0;
109: PetscInt PetscLogNumViewersDestroyed = 0;

111: PetscLogState petsc_log_state = NULL;

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

115: PetscLogHandlerHot PetscLogHandlers[PETSC_LOG_HANDLER_MAX] = {
116:   PETSC_LOG_HANDLER_HOT_BLANK,
117:   PETSC_LOG_HANDLER_HOT_BLANK,
118:   PETSC_LOG_HANDLER_HOT_BLANK,
119:   PETSC_LOG_HANDLER_HOT_BLANK,
120: };

122: #undef PETSC_LOG_HANDLERS_HOT_BLANK

124: #if PetscDefined(USE_LOG)
125: #include <../src/sys/logging/handler/impls/default/logdefault.h>

127:   #if PetscDefined(HAVE_THREADSAFETY)
128: /*@
129:   PetscAddLogDouble - Atomically add a `PetscLogDouble` value to both a global counter and its per-thread counterpart

131:   Not Collective; No Fortran Support

133:   Input Parameters:
134: + tot    - pointer to the global counter to update
135: . tot_th - pointer to the per-thread counter to update
136: - value  - the value to add to both counters

138:   Level: developer

140:   Note:
141:   When PETSc is built without thread safety this is a fast macro that performs the same update without locking.

143: .seealso: `PetscAddLogDoubleCnt()`, `PetscLogFlops()`, `PetscLogDouble`
144: @*/
145: PetscErrorCode PetscAddLogDouble(PetscLogDouble *tot, PetscLogDouble *tot_th, PetscLogDouble value)
146: {
147:   *tot_th += value;
148:   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
149:   *tot += value;
150:   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
151:   return PETSC_SUCCESS;
152: }

154: /*@
155:   PetscAddLogDoubleCnt - Atomically update both a count pair and a size pair of `PetscLogDouble` counters (global and per-thread)

157:   Not Collective; No Fortran Support

159:   Input Parameters:
160: + cnt    - pointer to the global count counter to increment by one
161: . tot    - pointer to the global size counter to update
162: . cnt_th - pointer to the per-thread count counter to increment by one
163: . tot_th - pointer to the per-thread size counter to update
164: - value  - the size value to add to the size counters

166:   Level: developer

168: .seealso: `PetscAddLogDouble()`, `PetscLogFlops()`, `PetscLogDouble`
169: @*/
170: PetscErrorCode PetscAddLogDoubleCnt(PetscLogDouble *cnt, PetscLogDouble *tot, PetscLogDouble *cnt_th, PetscLogDouble *tot_th, PetscLogDouble value)
171: {
172:   *cnt_th = *cnt_th + 1;
173:   *tot_th += value;
174:   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
175:   *tot += (PetscLogDouble)value;
176:   *cnt += *cnt + 1;
177:   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
178:   return PETSC_SUCCESS;
179: }

181:   #endif

183: static PetscErrorCode PetscLogTryGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
184: {
185:   PetscFunctionBegin;
186:   PetscAssertPointer(handler, 2);
187:   *handler = NULL;
188:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
189:     PetscLogHandler h = PetscLogHandlers[i].handler;
190:     if (h) {
191:       PetscBool match;

193:       PetscCall(PetscObjectTypeCompare((PetscObject)h, type, &match));
194:       if (match) {
195:         *handler = PetscLogHandlers[i].handler;
196:         PetscFunctionReturn(PETSC_SUCCESS);
197:       }
198:     }
199:   }
200:   PetscFunctionReturn(PETSC_SUCCESS);
201: }

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

206:   Not collective

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

211:   Level: developer

213:   Notes:
214:   The default handler is started with `PetscLogDefaultBegin()`,
215:   if the options flags `-log_all` or `-log_view` is given without arguments,
216:   or for `-log_view :output:format` if `format` is not `ascii_xml` or `ascii_flamegraph`.

218: .seealso: [](ch_profiling)
219: @*/
220: PetscErrorCode PetscLogGetDefaultHandler(PetscLogHandler *handler)
221: {
222:   PetscFunctionBegin;
223:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, handler));
224:   PetscFunctionReturn(PETSC_SUCCESS);
225: }

227: static PetscErrorCode PetscLogGetHandler(PetscLogHandlerType type, PetscLogHandler *handler)
228: {
229:   PetscFunctionBegin;
230:   PetscAssertPointer(handler, 2);
231:   PetscCall(PetscLogTryGetHandler(type, handler));
232:   PetscCheck(*handler != NULL, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "A PetscLogHandler of type %s has not been started.", type);
233:   PetscFunctionReturn(PETSC_SUCCESS);
234: }

236: /*@
237:   PetscLogGetState - Get the `PetscLogState` for PETSc's global logging, used
238:   by all default log handlers (`PetscLogDefaultBegin()`,
239:   `PetscLogNestedBegin()`, `PetscLogTraceBegin()`, `PetscLogMPEBegin()`,
240:   `PetscLogPerfstubsBegin()`).

242:   Collective on `PETSC_COMM_WORLD`

244:   Output Parameter:
245: . state - The `PetscLogState` changed by registrations (such as
246:           `PetscLogEventRegister()`) and actions (such as `PetscLogEventBegin()` or
247:           `PetscLogStagePush()`), or `NULL` if logging is not active

249:   Level: developer

251: .seealso: [](ch_profiling), `PetscLogState`
252: @*/
253: PetscErrorCode PetscLogGetState(PetscLogState *state)
254: {
255:   PetscFunctionBegin;
256:   PetscAssertPointer(state, 1);
257:   *state = petsc_log_state;
258:   PetscFunctionReturn(PETSC_SUCCESS);
259: }

261: static PetscErrorCode PetscLogHandlerCopyToHot(PetscLogHandler h, PetscLogHandlerHot *hot)
262: {
263:   PetscFunctionBegin;
264:   hot->handler       = h;
265:   hot->eventBegin    = h->ops->eventbegin;
266:   hot->eventEnd      = h->ops->eventend;
267:   hot->eventSync     = h->ops->eventsync;
268:   hot->objectCreate  = h->ops->objectcreate;
269:   hot->objectDestroy = h->ops->objectdestroy;
270:   PetscFunctionReturn(PETSC_SUCCESS);
271: }

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

276:   Logically collective

278:   Input Parameters:
279: . h - a `PetscLogHandler`

281:   Level: developer

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

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

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

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

297: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStop()`, `PetscInitialize()`
298: @*/
299: PetscErrorCode PetscLogHandlerStart(PetscLogHandler h)
300: {
301:   PetscFunctionBegin;
302:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
303:     if (PetscLogHandlers[i].handler == h) PetscFunctionReturn(PETSC_SUCCESS);
304:   }
305:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
306:     if (PetscLogHandlers[i].handler == NULL) {
307:       PetscCall(PetscObjectReference((PetscObject)h));
308:       PetscCall(PetscLogHandlerCopyToHot(h, &PetscLogHandlers[i]));
309:       if (petsc_log_state) {
310:         PetscLogStage stack_height;
311:         PetscIntStack orig_stack, temp_stack;

313:         PetscCall(PetscLogHandlerSetState(h, petsc_log_state));
314:         stack_height = petsc_log_state->stage_stack->top + 1;
315:         PetscCall(PetscIntStackCreate(&temp_stack));
316:         orig_stack                     = petsc_log_state->stage_stack;
317:         petsc_log_state->stage_stack   = temp_stack;
318:         petsc_log_state->current_stage = -1;
319:         for (int s = 0; s < stack_height; s++) {
320:           PetscLogStage stage = orig_stack->stack[s];
321:           PetscCall(PetscLogHandlerStagePush(h, stage));
322:           PetscCall(PetscIntStackPush(temp_stack, stage));
323:           petsc_log_state->current_stage = stage;
324:         }
325:         PetscCall(PetscIntStackDestroy(temp_stack));
326:         petsc_log_state->stage_stack = orig_stack;
327:       }
328:       PetscFunctionReturn(PETSC_SUCCESS);
329:     }
330:   }
331:   SETERRQ(PetscObjectComm((PetscObject)h), PETSC_ERR_ARG_WRONGSTATE, "%d log handlers already started, cannot start another", PETSC_LOG_HANDLER_MAX);
332:   PetscFunctionReturn(PETSC_SUCCESS);
333: }

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

338:   Logically collective

340:   Input Parameters:
341: . h - a `PetscLogHandler`

343:   Level: developer

345:   Note:
346:   After `PetscLogHandlerStop()`, the handler can still access the global logging state
347:   with `PetscLogHandlerGetState()`, so that it can access the registry when post-processing
348:   (for instance, in `PetscLogHandlerView()`),

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

353: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogState`, `PetscLogHandlerStart()`
354: @*/
355: PetscErrorCode PetscLogHandlerStop(PetscLogHandler h)
356: {
357:   PetscFunctionBegin;
358:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
359:     if (PetscLogHandlers[i].handler == h) {
360:       if (petsc_log_state) {
361:         PetscLogState state;
362:         PetscLogStage stack_height;
363:         PetscIntStack orig_stack, temp_stack;

365:         PetscCall(PetscLogHandlerGetState(h, &state));
366:         PetscCheck(state == petsc_log_state, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "Called PetscLogHandlerStop() for a PetscLogHander that was not started.");
367:         stack_height = petsc_log_state->stage_stack->top + 1;
368:         PetscCall(PetscIntStackCreate(&temp_stack));
369:         orig_stack                   = petsc_log_state->stage_stack;
370:         petsc_log_state->stage_stack = temp_stack;
371:         for (int s = 0; s < stack_height; s++) {
372:           PetscLogStage stage = orig_stack->stack[s];

374:           PetscCall(PetscIntStackPush(temp_stack, stage));
375:         }
376:         for (int s = 0; s < stack_height; s++) {
377:           PetscLogStage stage;
378:           PetscBool     empty;

380:           PetscCall(PetscIntStackPop(temp_stack, &stage));
381:           PetscCall(PetscIntStackEmpty(temp_stack, &empty));
382:           if (!empty) PetscCall(PetscIntStackTop(temp_stack, &petsc_log_state->current_stage));
383:           else petsc_log_state->current_stage = -1;
384:           PetscCall(PetscLogHandlerStagePop(h, stage));
385:         }
386:         PetscCall(PetscIntStackDestroy(temp_stack));
387:         petsc_log_state->stage_stack = orig_stack;
388:         PetscCall(PetscIntStackTop(petsc_log_state->stage_stack, &petsc_log_state->current_stage));
389:       }
390:       PetscCall(PetscArrayzero(&PetscLogHandlers[i], 1));
391:       PetscCall(PetscObjectDereference((PetscObject)h));
392:     }
393:   }
394:   PetscFunctionReturn(PETSC_SUCCESS);
395: }

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

400:   Not Collective

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

405:   Level: beginner

407: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`
408: @*/
409: PetscErrorCode PetscLogIsActive(PetscBool *isActive)
410: {
411:   PetscFunctionBegin;
412:   *isActive = PETSC_FALSE;
413:   if (petsc_log_state) {
414:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
415:       if (PetscLogHandlers[i].handler) {
416:         *isActive = PETSC_TRUE;
417:         PetscFunctionReturn(PETSC_SUCCESS);
418:       }
419:     }
420:   }
421:   PetscFunctionReturn(PETSC_SUCCESS);
422: }

424: PETSC_UNUSED static PetscErrorCode PetscLogEventBeginIsActive(PetscBool *isActive)
425: {
426:   PetscFunctionBegin;
427:   *isActive = PETSC_FALSE;
428:   if (petsc_log_state) {
429:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
430:       if (PetscLogHandlers[i].eventBegin) {
431:         *isActive = PETSC_TRUE;
432:         PetscFunctionReturn(PETSC_SUCCESS);
433:       }
434:     }
435:   }
436:   PetscFunctionReturn(PETSC_SUCCESS);
437: }

439: PETSC_UNUSED static PetscErrorCode PetscLogEventEndIsActive(PetscBool *isActive)
440: {
441:   PetscFunctionBegin;
442:   *isActive = PETSC_FALSE;
443:   if (petsc_log_state) {
444:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
445:       if (PetscLogHandlers[i].eventEnd) {
446:         *isActive = PETSC_TRUE;
447:         PetscFunctionReturn(PETSC_SUCCESS);
448:       }
449:     }
450:   }
451:   PetscFunctionReturn(PETSC_SUCCESS);
452: }

454: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
455: {
456:   PetscLogHandler handler;

458:   PetscFunctionBegin;
459:   PetscCall(PetscLogTryGetHandler(type, &handler));
460:   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
461:   PetscCall(PetscLogHandlerCreate(PETSC_COMM_WORLD, &handler));
462:   PetscCall(PetscLogHandlerSetType(handler, type));
463:   PetscCall(PetscLogHandlerStart(handler));
464:   PetscCall(PetscLogHandlerDestroy(&handler));
465:   PetscFunctionReturn(PETSC_SUCCESS);
466: }

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

472:   Logically Collective on `PETSC_COMM_WORLD`

474:   Options Database Key:
475: . -log_view viewer_specification - Displays summary of flop and timing (profiling) information (for PETSc configured `--with-log`, which is the default).
476:                                    This option must be provided before `PetscInitialize()`. See `PetscOptionsCreateViewer()` for the
477:                                    format of `viewer_specification`

479:   Example Usage:
480: .vb
481:       PetscInitialize(...);
482:       PetscLogDefaultBegin();
483:        ... code ...
484:       PetscLogView(viewer); or PetscLogDump();
485:       PetscFinalize();
486: .ve

488:   Level: advanced

490:   Notes:
491:   `PetscLogView()` or `PetscLogDump()` actually cause the printing of
492:   the logging information.

494:   This routine may be called more than once.

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

499: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`
500: @*/
501: PetscErrorCode PetscLogDefaultBegin(void)
502: {
503:   PetscFunctionBegin;
504:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERDEFAULT));
505:   PetscFunctionReturn(PETSC_SUCCESS);
506: }

508: /*@
509:   PetscLogTraceBegin - Begins trace logging.  Every time a PETSc event
510:   begins or ends, the event name is printed.

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

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

517:   Options Database Key:
518: . -log_trace [filename] - Begins `PetscLogTraceBegin()`

520:   Level: intermediate

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

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

530: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogView()`, `PetscLogDefaultBegin()`
531: @*/
532: PetscErrorCode PetscLogTraceBegin(FILE *file)
533: {
534:   PetscLogHandler handler;

536:   PetscFunctionBegin;
537:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERTRACE, &handler));
538:   if (handler) PetscFunctionReturn(PETSC_SUCCESS);
539:   PetscCall(PetscLogHandlerCreateTrace(PETSC_COMM_WORLD, file, &handler));
540:   PetscCall(PetscLogHandlerStart(handler));
541:   PetscCall(PetscLogHandlerDestroy(&handler));
542:   PetscFunctionReturn(PETSC_SUCCESS);
543: }

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

547: /*@
548:   PetscLogNestedBegin - Turns on nested logging of objects and events. This logs flop
549:   rates and object creation and should not slow programs down much.

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

553:   Options Database Key:
554: . -log_view :filename.xml:ascii_xml - Prints an XML summary of flop and timing information to the file `filename.xml`.
555:                                       See `PetscOptionsCreateViewer()` for other possible viewer specifications

557:   Example Usage:
558: .vb
559:       PetscInitialize(...);
560:       PetscLogNestedBegin();
561:        ... code ...
562:       PetscLogView(viewer);
563:       PetscFinalize();
564: .ve

566:   Level: advanced

568: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`
569: @*/
570: PetscErrorCode PetscLogNestedBegin(void)
571: {
572:   PetscFunctionBegin;
573:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERNESTED));
574:   PetscFunctionReturn(PETSC_SUCCESS);
575: }

577: /*@
578:   PetscLogLegacyCallbacksBegin - Create and start a log handler from callbacks
579:   matching the now deprecated function pointers `PetscLogPLB`, `PetscLogPLE`,
580:   `PetscLogPHC`, `PetscLogPHD`.

582:   Logically Collective on `PETSC_COMM_WORLD`

584:   Input Parameters:
585: + PetscLogPLB - A callback that will be executed by `PetscLogEventBegin()` (or `NULL`)
586: . PetscLogPLE - A callback that will be executed by `PetscLogEventEnd()` (or `NULL`)
587: . PetscLogPHC - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)
588: - PetscLogPHD - A callback that will be executed by `PetscLogObjectCreate()` (or `NULL`)

590:   Calling sequence of `PetscLogPLB`:
591: + e  - a `PetscLogEvent` that is beginning
592: . _i - deprecated, unused
593: . o1 - a `PetscObject` associated with `e` (or `NULL`)
594: . o2 - a `PetscObject` associated with `e` (or `NULL`)
595: . o3 - a `PetscObject` associated with `e` (or `NULL`)
596: - o4 - a `PetscObject` associated with `e` (or `NULL`)

598:   Calling sequence of `PetscLogPLE`:
599: + e  - a `PetscLogEvent` that is beginning
600: . _i - deprecated, unused
601: . o1 - a `PetscObject` associated with `e` (or `NULL`)
602: . o2 - a `PetscObject` associated with `e` (or `NULL`)
603: . o3 - a `PetscObject` associated with `e` (or `NULL`)
604: - o4 - a `PetscObject` associated with `e` (or `NULL`)

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

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

612:   Level: advanced

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

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

621: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
622: @*/
623: 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))
624: {
625:   PetscLogHandler handler;

627:   PetscFunctionBegin;
628:   PetscCall(PetscLogHandlerCreateLegacy(PETSC_COMM_WORLD, PetscLogPLB, PetscLogPLE, PetscLogPHC, PetscLogPHD, &handler));
629:   PetscCall(PetscLogHandlerStart(handler));
630:   PetscCall(PetscLogHandlerDestroy(&handler));
631:   PetscFunctionReturn(PETSC_SUCCESS);
632: }

634:   #if PetscDefined(HAVE_MPE)
635:     #include <mpe.h>
636: static PetscBool PetscBeganMPE = PETSC_FALSE;
637:   #endif

639: /*@
640:   PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files and slows the
641:   program down.

643:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

645:   Options Database Key:
646: . -log_mpe - Prints extensive log information

648:   Level: advanced

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

655: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogDefaultBegin()`, `PetscLogEventActivate()`,
656:           `PetscLogEventDeactivate()`
657: @*/
658: PetscErrorCode PetscLogMPEBegin(void)
659: {
660:   PetscFunctionBegin;
661:   #if PetscDefined(HAVE_MPE)
662:   /* Do MPE initialization */
663:   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
664:     PetscCall(PetscInfo(0, "Initializing MPE.\n"));
665:     PetscCall(MPE_Init_log());

667:     PetscBeganMPE = PETSC_TRUE;
668:   } else {
669:     PetscCall(PetscInfo(0, "MPE already initialized. Not attempting to reinitialize.\n"));
670:   }
671:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERMPE));
672:   #else
673:   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
674:   #endif
675:   PetscFunctionReturn(PETSC_SUCCESS);
676: }

678:   #if PetscDefined(HAVE_TAU_PERFSTUBS)
679: #include <../src/sys/perfstubs/timer.h>
680:   #endif

682: /*@
683:   PetscLogPerfstubsBegin - Turns on logging of events using the perfstubs interface.

685:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

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

690:   Level: advanced

692: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogEventActivate()`
693: @*/
694: PetscErrorCode PetscLogPerfstubsBegin(void)
695: {
696:   PetscFunctionBegin;
697:   #if PetscDefined(HAVE_TAU_PERFSTUBS)
698:   PetscCall(PetscLogTypeBegin(PETSCLOGHANDLERPERFSTUBS));
699:   #else
700:   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without perfstubs support, reconfigure with --with-tau-perfstubs");
701:   #endif
702:   PetscFunctionReturn(PETSC_SUCCESS);
703: }

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

708:   Not Collective

710:   Input Parameter:
711: . flag - `PETSC_TRUE` if actions are to be logged

713:   Options Database Key:
714: + -log_exclude_actions - (deprecated) Does nothing
715: - -log_include_actions - Turn on action logging

717:   Level: intermediate

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

723: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
724: @*/
725: PetscErrorCode PetscLogActions(PetscBool flag)
726: {
727:   PetscFunctionBegin;
728:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
729:     PetscLogHandler h = PetscLogHandlers[i].handler;

731:     if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
732:   }
733:   PetscFunctionReturn(PETSC_SUCCESS);
734: }

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

739:   Not Collective

741:   Input Parameter:
742: . flag - `PETSC_TRUE` if objects are to be logged

744:   Options Database Key:
745: + -log_exclude_objects - (deprecated) Does nothing
746: - -log_include_objects - Turns on object logging

748:   Level: intermediate

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

754: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogGetDefaultHandler()`
755: @*/
756: PetscErrorCode PetscLogObjects(PetscBool flag)
757: {
758:   PetscFunctionBegin;
759:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
760:     PetscLogHandler h = PetscLogHandlers[i].handler;

762:     if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
763:   }
764:   PetscFunctionReturn(PETSC_SUCCESS);
765: }

767: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
768: /*@
769:   PetscLogStageRegister - Attaches a character string name to a logging stage.

771:   Not Collective

773:   Input Parameter:
774: . sname - The name to associate with that stage

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

779:   Level: intermediate

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

787:   PetscFunctionBegin;
788:   *stage = -1;
789:   PetscCall(PetscLogGetState(&state));
790:   if (state) PetscCall(PetscLogStateStageRegister(state, sname, stage));
791:   PetscFunctionReturn(PETSC_SUCCESS);
792: }

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

797:   Not Collective

799:   Input Parameter:
800: . stage - The stage on which to log

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:   Note:
820:   Use `PetscLogStageRegister()` to register a stage.

822: .seealso: [](ch_profiling), `PetscLogStagePop()`, `PetscLogStageRegister()`, `PetscBarrier()`
823: @*/
824: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
825: {
826:   PetscLogState state;

828:   PetscFunctionBegin;
829:   PetscCall(PetscLogGetState(&state));
830:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
831:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
832:     PetscLogHandler h = PetscLogHandlers[i].handler;
833:     if (h) PetscCall(PetscLogHandlerStagePush(h, stage));
834:   }
835:   PetscCall(PetscLogStateStagePush(state, stage));
836:   PetscFunctionReturn(PETSC_SUCCESS);
837: }

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

842:   Not Collective

844:   Example Usage:
845:   If the option `-log_view` is used to run the program containing the
846:   following code, then 2 sets of summary data will be printed during
847:   PetscFinalize().
848: .vb
849:       PetscInitialize(int *argc,char ***args,0,0);
850:       [stage 0 of code]
851:       PetscLogStagePush(1);
852:       [stage 1 of code]
853:       PetscLogStagePop();
854:       PetscBarrier(...);
855:       [more stage 0 of code]
856:       PetscFinalize();
857: .ve

859:   Level: intermediate

861: .seealso: [](ch_profiling), `PetscLogStagePush()`, `PetscLogStageRegister()`, `PetscBarrier()`
862: @*/
863: PetscErrorCode PetscLogStagePop(void)
864: {
865:   PetscLogState state;
866:   PetscLogStage current_stage;

868:   PetscFunctionBegin;
869:   PetscCall(PetscLogGetState(&state));
870:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
871:   current_stage = state->current_stage;
872:   PetscCall(PetscLogStateStagePop(state));
873:   for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
874:     PetscLogHandler h = PetscLogHandlers[i].handler;
875:     if (h) PetscCall(PetscLogHandlerStagePop(h, current_stage));
876:   }
877:   PetscFunctionReturn(PETSC_SUCCESS);
878: }

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

883:   Not Collective

885:   Input Parameters:
886: + stage    - The stage
887: - isActive - The activity flag, `PETSC_TRUE` for logging, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

889:   Level: intermediate

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

894: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
895: @*/
896: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
897: {
898:   PetscLogState state;

900:   PetscFunctionBegin;
901:   PetscCall(PetscLogGetState(&state));
902:   if (state) PetscCall(PetscLogStateStageSetActive(state, stage, isActive));
903:   PetscFunctionReturn(PETSC_SUCCESS);
904: }

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

909:   Not Collective

911:   Input Parameter:
912: . stage - The stage

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

917:   Level: intermediate

919: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
920: @*/
921: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
922: {
923:   PetscLogState state;

925:   PetscFunctionBegin;
926:   *isActive = PETSC_FALSE;
927:   PetscCall(PetscLogGetState(&state));
928:   if (state) PetscCall(PetscLogStateStageGetActive(state, stage, isActive));
929:   PetscFunctionReturn(PETSC_SUCCESS);
930: }

932: /*@
933:   PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`

935:   Not Collective

937:   Input Parameters:
938: + stage     - The stage
939: - isVisible - The visibility flag, `PETSC_TRUE` to print, else `PETSC_FALSE` (defaults to `PETSC_TRUE`)

941:   Level: intermediate

943:   Developer Notes:
944:   Visibility only affects the default log handler in `PetscLogView()`; stages that are
945:   set to invisible are suppressed from output.

947: .seealso: [](ch_profiling), `PetscLogStageGetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
948: @*/
949: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
950: {
951:   PetscFunctionBegin;
952:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
953:     PetscLogHandler h = PetscLogHandlers[i].handler;

955:     if (h) PetscCall(PetscLogHandlerStageSetVisible(h, stage, isVisible));
956:   }
957:   PetscFunctionReturn(PETSC_SUCCESS);
958: }

960: /*@
961:   PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`

963:   Not Collective

965:   Input Parameter:
966: . stage - The stage

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

971:   Level: intermediate

973: .seealso: [](ch_profiling), `PetscLogStageSetVisible()`, `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
974: @*/
975: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
976: {
977:   PetscLogHandler handler;

979:   PetscFunctionBegin;
980:   *isVisible = PETSC_FALSE;
981:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
982:   if (handler) PetscCall(PetscLogHandlerStageGetVisible(handler, stage, isVisible));
983:   PetscFunctionReturn(PETSC_SUCCESS);
984: }

986: /*@
987:   PetscLogStageGetId - Returns the stage id when given the stage name.

989:   Not Collective

991:   Input Parameter:
992: . name - The stage name

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

997:   Level: intermediate

999: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1000: @*/
1001: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
1002: {
1003:   PetscLogState state;

1005:   PetscFunctionBegin;
1006:   *stage = -1;
1007:   PetscCall(PetscLogGetState(&state));
1008:   if (state) PetscCall(PetscLogStateGetStageFromName(state, name, stage));
1009:   PetscFunctionReturn(PETSC_SUCCESS);
1010: }

1012: /*@
1013:   PetscLogStageGetName - Returns the stage name when given the stage id.

1015:   Not Collective

1017:   Input Parameter:
1018: . stage - The stage

1020:   Output Parameter:
1021: . name - The stage name

1023:   Level: intermediate

1025: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogStagePush()`, `PetscLogStagePop()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1026: @*/
1027: PetscErrorCode PetscLogStageGetName(PetscLogStage stage, const char *name[])
1028: {
1029:   PetscLogStageInfo stage_info;
1030:   PetscLogState     state;

1032:   PetscFunctionBegin;
1033:   *name = NULL;
1034:   PetscCall(PetscLogGetState(&state));
1035:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1036:   PetscCall(PetscLogStateStageGetInfo(state, stage, &stage_info));
1037:   *name = stage_info.name;
1038:   PetscFunctionReturn(PETSC_SUCCESS);
1039: }

1041: /*------------------------------------------------ Event Functions --------------------------------------------------*/

1043: /*@
1044:   PetscLogEventRegister - Registers an event name for logging operations

1046:   Not Collective

1048:   Input Parameters:
1049: + name    - The name associated with the event
1050: - classid - The classid associated to the class for this event, obtain either with
1051:             `PetscClassIdRegister()` or use a predefined one such as `KSP_CLASSID`, `SNES_CLASSID`, the predefined ones
1052:             are only available in C code

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

1057:   Example Usage:
1058: .vb
1059:       PetscLogEvent USER_EVENT;
1060:       PetscClassId classid;
1061:       PetscLogDouble user_event_flops;
1062:       PetscClassIdRegister("class name",&classid);
1063:       PetscLogEventRegister("User event name",classid,&USER_EVENT);
1064:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
1065:          [code segment to monitor]
1066:          PetscLogFlops(user_event_flops);
1067:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
1068: .ve

1070:   Level: intermediate

1072:   Notes:
1073:   PETSc automatically logs library events if the code has been
1074:   configured with `--with-log` (which is the default) and
1075:   `-log_view` or `-log_all` is specified.  `PetscLogEventRegister()` is
1076:   intended for logging user events to supplement this PETSc
1077:   information.

1079:   PETSc can gather data for use with the utilities Jumpshot
1080:   (part of the MPICH distribution).  If PETSc has been compiled
1081:   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
1082:   MPICH), the user can employ another command line option, `-log_mpe`,
1083:   to create a logfile, "mpe.log", which can be visualized
1084:   Jumpshot.

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

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

1094: .seealso: [](ch_profiling), `PetscLogStageRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
1095:           `PetscLogEventActivate()`, `PetscLogEventDeactivate()`, `PetscClassIdRegister()`
1096: @*/
1097: PetscErrorCode PetscLogEventRegister(const char name[], PetscClassId classid, PetscLogEvent *event)
1098: {
1099:   PetscLogState state;

1101:   PetscFunctionBegin;
1102:   *event = -1;
1103:   PetscCall(PetscLogGetState(&state));
1104:   if (state) PetscCall(PetscLogStateEventRegister(state, name, classid, event));
1105:   PetscFunctionReturn(PETSC_SUCCESS);
1106: }

1108: /*@
1109:   PetscLogEventSetCollective - Indicates that a particular event is collective.

1111:   Logically Collective

1113:   Input Parameters:
1114: + event      - The event id
1115: - collective - `PetscBool` indicating whether a particular event is collective

1117:   Level: developer

1119:   Notes:
1120:   New events returned from `PetscLogEventRegister()` are collective by default.

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

1126: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogEventRegister()`
1127: @*/
1128: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event, PetscBool collective)
1129: {
1130:   PetscLogState state;

1132:   PetscFunctionBegin;
1133:   PetscCall(PetscLogGetState(&state));
1134:   if (state) PetscCall(PetscLogStateEventSetCollective(state, event, collective));
1135:   PetscFunctionReturn(PETSC_SUCCESS);
1136: }

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

1141:   Not Collective

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

1147:   Level: developer

1149: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`, `PetscLogEventActivateClass()`
1150: */
1151: static PetscErrorCode PetscLogClassSetActiveAll(PetscClassId classid, PetscBool isActive)
1152: {
1153:   PetscLogState state;

1155:   PetscFunctionBegin;
1156:   PetscCall(PetscLogGetState(&state));
1157:   if (state) PetscCall(PetscLogStateClassSetActiveAll(state, classid, isActive));
1158:   PetscFunctionReturn(PETSC_SUCCESS);
1159: }

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

1164:   Not Collective

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

1169:   Level: developer

1171: .seealso: [](ch_profiling), `PetscLogEventActivateClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1172: @*/
1173: PetscErrorCode PetscLogEventIncludeClass(PetscClassId classid)
1174: {
1175:   PetscFunctionBegin;
1176:   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_TRUE));
1177:   PetscFunctionReturn(PETSC_SUCCESS);
1178: }

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

1183:   Not Collective

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

1188:   Level: developer

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

1193: .seealso: [](ch_profiling), `PetscLogEventDeactivateClass()`, `PetscLogEventActivateClass()`, `PetscLogEventDeactivate()`, `PetscLogEventActivate()`
1194: @*/
1195: PetscErrorCode PetscLogEventExcludeClass(PetscClassId classid)
1196: {
1197:   PetscFunctionBegin;
1198:   PetscCall(PetscLogClassSetActiveAll(classid, PETSC_FALSE));
1199:   PetscFunctionReturn(PETSC_SUCCESS);
1200: }

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

1205:   Not Collective

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

1212:   Usage:
1213: .vb
1214:       PetscLogEventSetActive(VEC_SetValues, PETSC_FALSE);
1215:         [code where you do not want to log VecSetValues()]
1216:       PetscLogEventSetActive(VEC_SetValues, PETSC_TRUE);
1217:         [code where you do want to log VecSetValues()]
1218: .ve

1220:   Level: advanced

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

1226: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1227: */
1228: static PetscErrorCode PetscLogEventSetActive(PetscLogStage stage, PetscLogEvent event, PetscBool isActive)
1229: {
1230:   PetscLogState state;

1232:   PetscFunctionBegin;
1233:   PetscCall(PetscLogGetState(&state));
1234:   if (state) PetscCall(PetscLogStateEventSetActive(state, stage, event, isActive));
1235:   PetscFunctionReturn(PETSC_SUCCESS);
1236: }

1238: /*@
1239:   PetscLogEventActivate - Indicates that a particular event should be logged.

1241:   Not Collective

1243:   Input Parameter:
1244: . event - The event id

1246:   Example Usage:
1247: .vb
1248:       PetscLogEventDeactivate(VEC_SetValues);
1249:         [code where you do not want to log VecSetValues()]
1250:       PetscLogEventActivate(VEC_SetValues);
1251:         [code where you do want to log VecSetValues()]
1252: .ve

1254:   Level: advanced

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

1260: .seealso: [](ch_profiling), `PetscLogEventDeactivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1261: @*/
1262: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
1263: {
1264:   PetscFunctionBegin;
1265:   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_TRUE));
1266:   PetscFunctionReturn(PETSC_SUCCESS);
1267: }

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

1272:   Not Collective

1274:   Input Parameter:
1275: . event - The event id

1277:   Example Usage:
1278: .vb
1279:       PetscLogEventDeactivate(VEC_SetValues);
1280:         [code where you do not want to log VecSetValues()]
1281:       PetscLogEventActivate(VEC_SetValues);
1282:         [code where you do want to log VecSetValues()]
1283: .ve

1285:   Level: advanced

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

1291: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`
1292: @*/
1293: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
1294: {
1295:   PetscFunctionBegin;
1296:   PetscCall(PetscLogEventSetActive(PETSC_DEFAULT, event, PETSC_FALSE));
1297:   PetscFunctionReturn(PETSC_SUCCESS);
1298: }

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

1303:   Not Collective

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

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

1316:   Level: advanced

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

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

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

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

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

1340:   Not Collective

1342:   Input Parameter:
1343: . event - The event id

1345:   Example Usage:
1346: .vb
1347:       PetscLogEventDeactivatePush(VEC_SetValues);
1348:         [code where you do not want to log VecSetValues()]
1349:       PetscLogEventDeactivatePop(VEC_SetValues);
1350:         [code where you do want to log VecSetValues()]
1351: .ve

1353:   Level: advanced

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

1359: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivatePush()`
1360: @*/
1361: PetscErrorCode PetscLogEventDeactivatePop(PetscLogEvent event)
1362: {
1363:   PetscFunctionBegin;
1364:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1365:     PetscLogHandler h = PetscLogHandlers[i].handler;

1367:     if (h) PetscCall(PetscLogHandlerEventDeactivatePop(h, PETSC_DEFAULT, event));
1368:   }
1369:   PetscFunctionReturn(PETSC_SUCCESS);
1370: }

1372: /*@
1373:   PetscLogEventSetActiveAll - Turns on logging of all events

1375:   Not Collective

1377:   Input Parameters:
1378: + event    - The event id
1379: - isActive - The activity flag determining whether the event is logged

1381:   Level: advanced

1383: .seealso: [](ch_profiling), `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1384: @*/
1385: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
1386: {
1387:   PetscLogState state;

1389:   PetscFunctionBegin;
1390:   PetscCall(PetscLogGetState(&state));
1391:   if (state) PetscCall(PetscLogStateEventSetActiveAll(state, event, isActive));
1392:   PetscFunctionReturn(PETSC_SUCCESS);
1393: }

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

1398:   Not Collective

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

1405:   Level: developer

1407: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventActivate()`, `PetscLogEventActivateAll()`, `PetscLogStageSetActive()`
1408: */
1409: static PetscErrorCode PetscLogClassSetActive(PetscLogStage stage, PetscClassId classid, PetscBool isActive)
1410: {
1411:   PetscLogState state;

1413:   PetscFunctionBegin;
1414:   PetscCall(PetscLogGetState(&state));
1415:   if (state) PetscCall(PetscLogStateClassSetActive(state, stage, classid, isActive));
1416:   PetscFunctionReturn(PETSC_SUCCESS);
1417: }

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

1422:   Not Collective

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

1427:   Level: developer

1429: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventDeactivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1430: @*/
1431: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
1432: {
1433:   PetscFunctionBegin;
1434:   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_TRUE));
1435:   PetscFunctionReturn(PETSC_SUCCESS);
1436: }

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

1441:   Not Collective

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

1446:   Level: developer

1448: .seealso: [](ch_profiling), `PetscLogEventIncludeClass()`, `PetscLogEventExcludeClass()`, `PetscLogEventActivateClass()`, `PetscLogEventActivate()`, `PetscLogEventDeactivate()`
1449: @*/
1450: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
1451: {
1452:   PetscFunctionBegin;
1453:   PetscCall(PetscLogClassSetActive(PETSC_DEFAULT, classid, PETSC_FALSE));
1454:   PetscFunctionReturn(PETSC_SUCCESS);
1455: }

1457: /*MC
1458:   PetscLogEventSync - Synchronizes the beginning of an event.

1460:   Synopsis:
1461: #include <petsclog.h>
1462:   PetscErrorCode PetscLogEventSync(PetscLogEvent e, MPI_Comm comm)

1464:   Collective

1466:   Input Parameters:
1467: + e    - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1468: - comm - an MPI communicator

1470:   Example Usage:
1471: .vb
1472:   PetscLogEvent USER_EVENT;

1474:   PetscLogEventRegister("User event", 0, &USER_EVENT);
1475:   PetscLogEventSync(USER_EVENT, PETSC_COMM_WORLD);
1476:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1477:   [code segment to monitor]
1478:   PetscLogEventEnd(USER_EVENT, 0, 0, 0 , 0);
1479: .ve

1481:   Level: developer

1483:   Note:
1484:   This routine should be called only if there is not a `PetscObject` available to pass to
1485:   `PetscLogEventBegin()`.

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

1490: /*MC
1491:   PetscLogEventBegin - Logs the beginning of an event.

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

1497:   Not Collective

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

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

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

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

1521:   Level: intermediate

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

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

1532: /*MC
1533:   PetscLogEventEnd - Log the end of an event.

1535:   Synopsis:
1536: #include <petsclog.h>
1537:   PetscErrorCode PetscLogEventEnd(PetscLogEvent e, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)

1539:   Not Collective

1541:   Input Parameters:
1542: + e  - `PetscLogEvent` obtained from `PetscLogEventRegister()`
1543: . o1 - object associated with the event, or `NULL`
1544: . o2 - object associated with the event, or `NULL`
1545: . o3 - object associated with the event, or `NULL`
1546: - o4 - object associated with the event, or `NULL`

1548:   Fortran Synopsis:
1549:   void PetscLogEventEnd(int e, PetscErrorCode ierr)

1551:   Example Usage:
1552: .vb
1553:   PetscLogEvent USER_EVENT;

1555:   PetscLogDouble user_event_flops;
1556:   PetscLogEventRegister("User event", 0, &USER_EVENT);
1557:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
1558:   [code segment to monitor]
1559:   PetscLogFlops(user_event_flops);
1560:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
1561: .ve

1563:   Level: intermediate

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

1568: /*@
1569:   PetscLogStageGetPerfInfo - Return the performance information about the given stage

1571:   No Fortran Support

1573:   Input Parameters:
1574: . stage - The stage number or `PETSC_DETERMINE` for the current stage

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

1579:   Level: intermediate

1581:   Notes:
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 PetscLogStageGetPerfInfo(PetscLogStage stage, PetscEventPerfInfo *info)
1591: {
1592:   PetscLogHandler     handler;
1593:   PetscEventPerfInfo *event_info;

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

1608: /*@
1609:   PetscLogEventGetPerfInfo - Return the performance information about the given event in the given stage

1611:   No Fortran Support

1613:   Input Parameters:
1614: + stage - The stage number or `PETSC_DETERMINE` for the current stage
1615: - event - The event number

1617:   Output Parameter:
1618: . info - This structure is filled with the performance information

1620:   Level: intermediate

1622:   Note:
1623:   This is a low level routine used by the logging functions in PETSc

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

1629: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogGetDefaultHandler()`
1630: @*/
1631: PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo *info)
1632: {
1633:   PetscLogHandler     handler;
1634:   PetscEventPerfInfo *event_info;

1636:   PetscFunctionBegin;
1637:   PetscAssertPointer(info, 3);
1638:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1639:   if (handler) {
1640:     PetscCall(PetscLogHandlerGetEventPerfInfo(handler, stage, event, &event_info));
1641:     *info = *event_info;
1642:   } else {
1643:     PetscCall(PetscInfo(NULL, "Default log handler is not running, PetscLogEventGetPerfInfo() returning zeros\n"));
1644:     PetscCall(PetscMemzero(info, sizeof(*info)));
1645:   }
1646:   PetscFunctionReturn(PETSC_SUCCESS);
1647: }

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

1652:   Not Collective

1654:   Input Parameters:
1655: + event - The event id to log
1656: . n     - The dof index, in [0, 8)
1657: - dof   - The number of dofs

1659:   Level: developer

1661:   Note:
1662:   This is to enable logging of convergence

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

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

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

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

1686:   Not Collective

1688:   Input Parameters:
1689: + event - The event id to log
1690: . n     - The error index, in [0, 8)
1691: - error - The error

1693:   Level: developer

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

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

1701: .seealso: `PetscLogEventSetDof()`, `PetscLogEventRegister()`, `PetscLogGetDefaultHandler()`
1702: @*/
1703: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1704: {
1705:   PetscFunctionBegin;
1706:   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1707:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1708:     PetscLogHandler h = PetscLogHandlers[i].handler;

1710:     if (h) {
1711:       PetscEventPerfInfo *event_info;

1713:       PetscCall(PetscLogHandlerGetEventPerfInfo(h, PETSC_DEFAULT, event, &event_info));
1714:       if (event_info) event_info->errors[n] = error;
1715:     }
1716:   }
1717:   PetscFunctionReturn(PETSC_SUCCESS);
1718: }

1720: /*@
1721:   PetscLogEventGetId - Returns the event id when given the event name.

1723:   Not Collective

1725:   Input Parameter:
1726: . name - The event name

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

1731:   Level: intermediate

1733: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1734: @*/
1735: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1736: {
1737:   PetscLogState state;

1739:   PetscFunctionBegin;
1740:   *event = -1;
1741:   PetscCall(PetscLogGetState(&state));
1742:   if (state) PetscCall(PetscLogStateGetEventFromName(state, name, event));
1743:   PetscFunctionReturn(PETSC_SUCCESS);
1744: }

1746: /*@
1747:   PetscLogEventGetName - Returns the event name when given the event id.

1749:   Not Collective

1751:   Input Parameter:
1752: . event - The event

1754:   Output Parameter:
1755: . name - The event name

1757:   Level: intermediate

1759: .seealso: [](ch_profiling), `PetscLogEventRegister()`, `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadStage()`
1760: @*/
1761: PetscErrorCode PetscLogEventGetName(PetscLogEvent event, const char *name[])
1762: {
1763:   PetscLogEventInfo event_info;
1764:   PetscLogState     state;

1766:   PetscFunctionBegin;
1767:   *name = NULL;
1768:   PetscCall(PetscLogGetState(&state));
1769:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1770:   PetscCall(PetscLogStateEventGetInfo(state, event, &event_info));
1771:   *name = event_info.name;
1772:   PetscFunctionReturn(PETSC_SUCCESS);
1773: }

1775: /*@
1776:   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.

1778:   Not collective

1780:   Level: advanced

1782:   Notes:
1783:   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()`).

1785:   Other log handlers (such as `PetscLogNestedBegin()`) will ignore this function.

1787: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsResume()`, `PetscLogGetDefaultHandler()`
1788: @*/
1789: PetscErrorCode PetscLogEventsPause(void)
1790: {
1791:   PetscFunctionBegin;
1792:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1793:     PetscLogHandler h = PetscLogHandlers[i].handler;

1795:     if (h) PetscCall(PetscLogHandlerEventsPause(h));
1796:   }
1797:   PetscFunctionReturn(PETSC_SUCCESS);
1798: }

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

1803:   Not collective

1805:   Level: advanced

1807: .seealso: [](ch_profiling), `PetscLogEventDeactivatePush()`, `PetscLogEventDeactivatePop()`, `PetscLogEventsPause()`, `PetscLogGetDefaultHandler()`
1808: @*/
1809: PetscErrorCode PetscLogEventsResume(void)
1810: {
1811:   PetscFunctionBegin;
1812:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
1813:     PetscLogHandler h = PetscLogHandlers[i].handler;

1815:     if (h) PetscCall(PetscLogHandlerEventsResume(h));
1816:   }
1817:   PetscFunctionReturn(PETSC_SUCCESS);
1818: }

1820: /*------------------------------------------------ Class Functions --------------------------------------------------*/

1822: /*MC
1823:    PetscLogObjectCreate - Log the creation of a `PetscObject`

1825:    Synopsis:
1826: #include <petsclog.h>
1827:    PetscErrorCode PetscLogObjectCreate(PetscObject h)

1829:    Not Collective

1831:    Input Parameters:
1832: .  h - A `PetscObject`

1834:    Level: developer

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

1840: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1841: M*/

1843: /*MC
1844:    PetscLogObjectDestroy - Logs the destruction of a `PetscObject`

1846:    Synopsis:
1847: #include <petsclog.h>
1848:    PetscErrorCode PetscLogObjectDestroy(PetscObject h)

1850:    Not Collective

1852:    Input Parameters:
1853: .  h - A `PetscObject`

1855:    Level: developer

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

1861: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1862: M*/

1864: /*@
1865:   PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.

1867:   Not Collective

1869:   Input Parameter:
1870: . name - The class name

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

1875:   Level: intermediate

1877: .seealso: [](ch_profiling), `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogStageGetId()`
1878: @*/
1879: PetscErrorCode PetscLogClassGetClassId(const char name[], PetscClassId *classid)
1880: {
1881:   PetscLogClass     log_class;
1882:   PetscLogClassInfo class_info;
1883:   PetscLogState     state;

1885:   PetscFunctionBegin;
1886:   *classid = -1;
1887:   PetscCall(PetscLogGetState(&state));
1888:   if (!state) PetscFunctionReturn(PETSC_SUCCESS);
1889:   PetscCall(PetscLogStateGetClassFromName(state, name, &log_class));
1890:   if (log_class < 0) {
1891:     *classid = -1;
1892:     PetscFunctionReturn(PETSC_SUCCESS);
1893:   }
1894:   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1895:   *classid = class_info.classid;
1896:   PetscFunctionReturn(PETSC_SUCCESS);
1897: }

1899: /*@
1900:   PetscLogClassIdGetName - Returns a `PetscClassId`'s name.

1902:   Not Collective

1904:   Input Parameter:
1905: . classid - A `PetscClassId`

1907:   Output Parameter:
1908: . name - The class name

1910:   Level: intermediate

1912: .seealso: [](ch_profiling), `PetscLogClassRegister()`, `PetscLogClassBegin()`, `PetscLogClassEnd()`, `PetscPreLoadBegin()`, `PetscPreLoadEnd()`, `PetscPreLoadClass()`
1913: @*/
1914: PetscErrorCode PetscLogClassIdGetName(PetscClassId classid, const char *name[])
1915: {
1916:   PetscLogClass     log_class;
1917:   PetscLogClassInfo class_info;
1918:   PetscLogState     state;

1920:   PetscFunctionBegin;
1921:   PetscCall(PetscLogGetState(&state));
1922:   PetscCall(PetscLogStateGetClassFromClassId(state, classid, &log_class));
1923:   PetscCall(PetscLogStateClassGetInfo(state, log_class, &class_info));
1924:   *name = class_info.name;
1925:   PetscFunctionReturn(PETSC_SUCCESS);
1926: }

1928: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1929: /*@
1930:   PetscLogDump - Dumps logs of objects to a file. There is currently no utility to read the dump file.

1932:   Collective on `PETSC_COMM_WORLD`

1934:   Input Parameter:
1935: . sname - an optional file name

1937:   Example Usage:
1938: .vb
1939:   PetscInitialize(...);
1940:   PetscLogDefaultBegin();
1941:   // ... code ...
1942:   PetscLogDump(filename);
1943:   PetscFinalize();
1944: .ve

1946:   Level: advanced

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

1952: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogView()`, `PetscLogGetDefaultHandler()`
1953: @*/
1954: PetscErrorCode PetscLogDump(const char sname[])
1955: {
1956:   PetscLogHandler handler;

1958:   PetscFunctionBegin;
1959:   PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
1960:   PetscCall(PetscLogHandlerDump(handler, sname));
1961:   PetscFunctionReturn(PETSC_SUCCESS);
1962: }

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

1967:   Collective on `PETSC_COMM_WORLD`

1969:   Input Parameter:
1970: . sname - filename for the MPE logfile

1972:   Level: advanced

1974: .seealso: [](ch_profiling), `PetscLogDump()`, `PetscLogMPEBegin()`
1975: @*/
1976: PetscErrorCode PetscLogMPEDump(const char sname[])
1977: {
1978:   PetscFunctionBegin;
1979:   #if PetscDefined(HAVE_MPE)
1980:   if (PetscBeganMPE) {
1981:     char name[PETSC_MAX_PATH_LEN];

1983:     PetscCall(PetscInfo(0, "Finalizing MPE.\n"));
1984:     if (sname) {
1985:       PetscCall(PetscStrncpy(name, sname, sizeof(name)));
1986:     } else {
1987:       PetscCall(PetscGetProgramName(name, sizeof(name)));
1988:     }
1989:     PetscCall(MPE_Finish_log(name));
1990:   } else {
1991:     PetscCall(PetscInfo(0, "Not finalizing MPE (not started by PETSc).\n"));
1992:   }
1993:   #else
1994:   SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "PETSc was configured without MPE support, reconfigure with --with-mpe or --download-mpe");
1995:   #endif
1996:   PetscFunctionReturn(PETSC_SUCCESS);
1997: }

1999: /*@
2000:   PetscLogView - Prints a summary of the logging.

2002:   Collective

2004:   Input Parameter:
2005: . viewer - an ASCII viewer

2007:   Options Database Keys:
2008: + -log_view viewer_specification - Views summary of the logging at the conclusion of the program, see `PetscOptionsCreateViewer()` for the format of `viewer_specification`
2009: . -log_view_memory (true|false)  - Also display memory usage in each event
2010: . -log_view_gpu_time             - Also display time in each event for GPU kernels (Note this may slow the computation)
2011: . -log_view_gpu_energy           - Also display energy (estimated with power*gtime) in Joules for GPU kernels
2012: . -log_view_gpu_energy_meter     - [Experimental] Also display energy (readings from energy meters) in Joules for GPU kernels.
2013:                                    This option is ignored if `-log_view_gpu_energy` is provided.
2014: . -log_all [filename]            - Saves a file `Log.rank` for each MPI process with details of each step of the computation, where
2015:                                    `rank` is the rank of each MPI process
2016: - -log_trace [filename]          - Displays a trace of what each process is doing

2018:   Level: beginner

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

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

2026:   If PETSc is configured with `--with-log=0` then this functionality is not available

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

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

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

2046:   Example Usage:
2047: .vb
2048:  -log_view :filename                      - Prints summary of log information to a file
2049:  -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
2050:  -log_view :filename.xml:ascii_xml        - Saves a summary of the logging information in a nested format (see above for how to view it)
2051:  -log_view :filename.txt:ascii_flamegraph - Saves logging information in a format suitable for visualising as a Flame Graph (see above for how to view it)
2052:  -log_view :filename.csv:ascii_csv        - Saves logging information as a comma-separated values file
2053: .ve

2055: .seealso: [](ch_profiling), `PetscLogDefaultBegin()`, `PetscLogDump()`
2056: @*/
2057: PetscErrorCode PetscLogView(PetscViewer viewer)
2058: {
2059:   PetscBool         isascii;
2060:   PetscViewerFormat format;
2061:   int               stage;
2062:   PetscLogState     state;
2063:   PetscIntStack     temp_stack;
2064:   PetscLogHandler   handler;
2065:   PetscBool         is_empty;

2067:   PetscFunctionBegin;
2068:   PetscCall(PetscLogGetState(&state));
2069:   /* Pop off any stages the user forgot to remove */
2070:   PetscCall(PetscIntStackCreate(&temp_stack));
2071:   PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2072:   while (stage >= 0) {
2073:     PetscCall(PetscLogStagePop());
2074:     PetscCall(PetscIntStackPush(temp_stack, stage));
2075:     PetscCall(PetscLogStateGetCurrentStage(state, &stage));
2076:   }
2077:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
2078:   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Currently can only view logging to ASCII");
2079:   PetscCall(PetscViewerGetFormat(viewer, &format));
2080:   if (format == PETSC_VIEWER_ASCII_XML || format == PETSC_VIEWER_ASCII_FLAMEGRAPH) {
2081:     PetscCall(PetscLogGetHandler(PETSCLOGHANDLERNESTED, &handler));
2082:     PetscCall(PetscLogHandlerView(handler, viewer));
2083:   } else {
2084:     PetscCall(PetscLogGetHandler(PETSCLOGHANDLERDEFAULT, &handler));
2085:     PetscCall(PetscLogHandlerView(handler, viewer));
2086:   }
2087:   PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2088:   while (!is_empty) {
2089:     PetscCall(PetscIntStackPop(temp_stack, &stage));
2090:     PetscCall(PetscLogStagePush(stage));
2091:     PetscCall(PetscIntStackEmpty(temp_stack, &is_empty));
2092:   }
2093:   PetscCall(PetscIntStackDestroy(temp_stack));
2094:   PetscFunctionReturn(PETSC_SUCCESS);
2095: }

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

2100:   Collective on `PETSC_COMM_WORLD`

2102:   Options Database Key:
2103: . -log_view viewer_specification,viewer_specification - list of up to four specifications of viewers, see `PetscOptionsCreateViewer()` for their format

2105:   Level: developer

2107:   Note:
2108:   This function has a different API and behavior than `PetscObjectViewFromOptions()`

2110: .seealso: [](ch_profiling), `PetscLogView()`
2111: @*/
2112: PetscErrorCode PetscLogViewFromOptions(void)
2113: {
2114:   PetscInt          n_max = PETSC_LOG_VIEW_FROM_OPTIONS_MAX;
2115:   PetscViewer       viewers[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2116:   PetscViewerFormat formats[PETSC_LOG_VIEW_FROM_OPTIONS_MAX];
2117:   PetscBool         flg;

2119:   PetscFunctionBegin;
2120:   PetscCall(PetscOptionsCreateViewers(PETSC_COMM_WORLD, NULL, NULL, "-log_view", &n_max, viewers, formats, &flg));
2121:   /*
2122:      PetscLogHandlerView_Default_Info() wants to be sure that the only objects still around are these viewers, so keep track of how many there are
2123:    */
2124:   PetscLogNumViewersCreated = n_max;
2125:   for (PetscInt i = 0; i < n_max; i++) {
2126:     PetscInt refct;

2128:     PetscCall(PetscViewerPushFormat(viewers[i], formats[i]));
2129:     PetscCall(PetscLogView(viewers[i]));
2130:     PetscCall(PetscViewerPopFormat(viewers[i]));
2131:     PetscCall(PetscObjectGetReference((PetscObject)viewers[i], &refct));
2132:     PetscCall(PetscViewerDestroy(&viewers[i]));
2133:     if (refct == 1) PetscLogNumViewersDestroyed++;
2134:   }
2135:   PetscLogNumViewersDestroyed = 0;
2136:   PetscFunctionReturn(PETSC_SUCCESS);
2137: }

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

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

2145:   Logically Collective on `PETSC_COMM_WORLD`

2147:   Input Parameter:
2148: . newThresh - the threshold to use

2150:   Output Parameter:
2151: . oldThresh - the previously set threshold value

2153:   Options Database Key:
2154: . -log_threshold threshold - provide the threshold

2156:   Example Usage:
2157: .vb
2158:   PetscInitialize(...);
2159:   PetscLogNestedBegin();
2160:   PetscLogSetThreshold(0.1,&oldthresh);
2161:   // ... code ...
2162:   PetscLogView(viewer);
2163:   PetscFinalize();
2164: .ve

2166:   Level: advanced

2168:   Note:
2169:   This threshold is only used by the nested log handler

2171: .seealso: `PetscLogDump()`, `PetscLogView()`, `PetscLogTraceBegin()`, `PetscLogDefaultBegin()`,
2172:           `PetscLogNestedBegin()`
2173: @*/
2174: PetscErrorCode PetscLogSetThreshold(PetscLogDouble newThresh, PetscLogDouble *oldThresh)
2175: {
2176:   PetscLogHandler handler;

2178:   PetscFunctionBegin;
2179:   PetscCall(PetscLogTryGetHandler(PETSCLOGHANDLERNESTED, &handler));
2180:   PetscCall(PetscLogHandlerNestedSetThreshold(handler, newThresh, oldThresh));
2181:   PetscFunctionReturn(PETSC_SUCCESS);
2182: }

2184: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
2185: /*@
2186:   PetscGetFlops - Returns the number of flops used on this processor
2187:   since the program began.

2189:   Not Collective

2191:   Output Parameter:
2192: . flops - number of floating point operations

2194:   Level: intermediate

2196:   Notes:
2197:   A global counter logs all PETSc flop counts.  The user can use
2198:   `PetscLogFlops()` to increment this counter to include flops for the
2199:   application code.

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

2203: .seealso: [](ch_profiling), `PetscLogGpuFlops()`, `PetscTime()`, `PetscLogFlops()`
2204: @*/
2205: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
2206: {
2207:   PetscFunctionBegin;
2208:   *flops = petsc_TotalFlops;
2209:   PetscFunctionReturn(PETSC_SUCCESS);
2210: }

2212: /*@
2213:   PetscLogObjectState - Record information about an object with the default log handler

2215:   Not Collective

2217:   Input Parameters:
2218: + obj    - the `PetscObject`
2219: . format - a printf-style format string
2220: - ...    - `printf()` arguments to format

2222:   Level: developer

2224: .seealso: [](ch_profiling), `PetscLogObjectCreate()`, `PetscLogObjectDestroy()`, `PetscLogGetDefaultHandler()`
2225: @*/
2226: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2227: {
2228:   PetscFunctionBegin;
2229:   for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2230:     PetscLogHandler h = PetscLogHandlers[i].handler;

2232:     if (h) {
2233:       va_list Argp;
2234:       va_start(Argp, format);
2235:       PetscCall(PetscLogHandlerLogObjectState_Internal(h, obj, format, Argp));
2236:       va_end(Argp);
2237:     }
2238:   }
2239:   PetscFunctionReturn(PETSC_SUCCESS);
2240: }

2242: /*MC
2243:   PetscLogFlops - Adds floating point operations to the global counter.

2245:   Synopsis:
2246: #include <petsclog.h>
2247:   PetscErrorCode PetscLogFlops(PetscLogDouble f)

2249:   Not Collective

2251:   Input Parameter:
2252: . f - flop counter

2254:   Example Usage:
2255: .vb
2256:   PetscLogEvent USER_EVENT;

2258:   PetscLogEventRegister("User event", 0, &USER_EVENT);
2259:   PetscLogEventBegin(USER_EVENT, 0, 0, 0, 0);
2260:   [code segment to monitor]
2261:   PetscLogFlops(user_flops)
2262:   PetscLogEventEnd(USER_EVENT, 0, 0, 0, 0);
2263: .ve

2265:   Level: intermediate

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

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

2274: /*MC
2275:   PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice) to get accurate
2276:   timings

2278:   Synopsis:
2279: #include <petsclog.h>
2280:   void PetscPreLoadBegin(PetscBool flag, char *name);

2282:   Not Collective

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

2289:   Example Usage:
2290: .vb
2291:   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2292:   // lines of code
2293:   PetscPreLoadStage("second stage");
2294:   // lines of code
2295:   PetscPreLoadEnd();
2296: .ve

2298:   Level: intermediate

2300:   Note:
2301:   Only works in C/C++, not Fortran

2303:   Flags available within the macro\:
2304: + PetscPreLoadingUsed - `PETSC_TRUE` if we are or have done preloading
2305: . PetscPreLoadingOn   - `PETSC_TRUE` if it is CURRENTLY doing preload
2306: . PetscPreLoadIt      - `0` for the first computation (with preloading turned off it is only
2307:                         `0`) `1`  for the second
2308: - PetscPreLoadMax     - number of times it will do the computation, only one when preloading is
2309:                         turned on

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

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

2317: /*MC
2318:   PetscPreLoadEnd - End a segment of code that may be preloaded (run twice) to get accurate
2319:   timings

2321:   Synopsis:
2322: #include <petsclog.h>
2323:   void PetscPreLoadEnd(void);

2325:   Not Collective

2327:   Example Usage:
2328: .vb
2329:   PetscPreLoadBegin(PETSC_TRUE, "first stage");
2330:   // lines of code
2331:   PetscPreLoadStage("second stage");
2332:   // lines of code
2333:   PetscPreLoadEnd();
2334: .ve

2336:   Level: intermediate

2338:   Note:
2339:   Only works in C/C++ not Fortran

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

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

2347:   Synopsis:
2348: #include <petsclog.h>
2349:   void PetscPreLoadStage(char *name);

2351:   Not Collective

2353:   Example Usage:
2354: .vb
2355:   PetscPreLoadBegin(PETSC_TRUE,"first stage");
2356:   // lines of code
2357:   PetscPreLoadStage("second stage");
2358:   // lines of code
2359:   PetscPreLoadEnd();
2360: .ve

2362:   Level: intermediate

2364:   Note:
2365:   Only works in C/C++ not Fortran

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

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

2373: /*@
2374:   PetscLogGpuTime - turn on the logging of GPU time for GPU kernels

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

2379:   Level: advanced

2381:   Notes:
2382:   Turning on the timing of the GPU kernels can slow down the entire computation and should only
2383:   be used when studying the performance of individual operations on GPU such as vector operations and
2384:   matrix-vector operations.

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

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

2391: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTimeBegin()`
2392: @*/
2393: PetscErrorCode PetscLogGpuTime(void)
2394: {
2395:   PetscFunctionBegin;
2396:   PetscCheck(petsc_gtime == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU logging has already been turned on");
2397:   PetscLogGpuTimeFlag = PETSC_TRUE;
2398:   PetscFunctionReturn(PETSC_SUCCESS);
2399: }

2401: /*@
2402:   PetscLogGpuTimeBegin - Start timer for device

2404:   Level: intermediate

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

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

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

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

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

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

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

2433: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeEnd()`, `PetscLogGpuTime()`
2434: @*/
2435: PetscErrorCode PetscLogGpuTimeBegin(void)
2436: {
2437:   PetscBool isActive;

2439:   PetscFunctionBegin;
2440:   PetscCall(PetscLogEventBeginIsActive(&isActive));
2441:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2442:   if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2443:     PetscDeviceContext dctx;

2445:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2446:     PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2447:   } else {
2448:     PetscCall(PetscTimeSubtract(&petsc_gtime));
2449:   }
2450:   PetscFunctionReturn(PETSC_SUCCESS);
2451: }

2453: /*@
2454:   PetscLogGpuTimeEnd - Stop timer for device

2456:   Level: intermediate

2458: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2459: @*/
2460: PetscErrorCode PetscLogGpuTimeEnd(void)
2461: {
2462:   PetscBool isActive;

2464:   PetscFunctionBegin;
2465:   PetscCall(PetscLogEventEndIsActive(&isActive));
2466:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2467:   if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2468:     PetscDeviceContext dctx;
2469:     PetscLogDouble     elapsed;

2471:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2472:     PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2473:     petsc_gtime += (elapsed / 1000.0);
2474:     #if PetscDefined(HAVE_CUDA_VERSION_12_2PLUS)
2475:     if (PetscLogGpuEnergyFlag) {
2476:       PetscLogDouble power;
2477:       PetscCall(PetscDeviceContextGetPower_Internal(dctx, &power));
2478:       petsc_genergy += (power * elapsed / 1000000.0); // convert to Joules
2479:     }
2480:     #endif
2481:   } else {
2482:     PetscCall(PetscTimeAdd(&petsc_gtime));
2483:   }
2484:   PetscFunctionReturn(PETSC_SUCCESS);
2485: }

2487: /*@
2488:   PetscLogGpuEnergy - turn on the logging of GPU energy (estimated with power*gtime) for GPU kernels

2490:   Options Database Key:
2491: . -log_view_gpu_energy - provide the GPU energy consumption (estimated with power*gtime) for all events in the `-log_view` output

2493:   Level: advanced

2495:   Note:
2496:   This option is mutually exclusive to `-log_view_gpu_energy_meter`.

2498:   Developer Note:
2499:   This option turns on energy monitoring of GPU kernels and requires CUDA version >= 12.2. The energy consumption is estimated as
2500:   instant_power * gpu_kernel_time. Due to the delay in NVML power sampling, we read the instantaneous power draw at the end of each
2501:   event using `nvmlDeviceGetFieldValues()` with the field ID `NVML_FI_DEV_POWER_INSTANT`.

2503: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeter()`
2504: @*/
2505: PetscErrorCode PetscLogGpuEnergy(void)
2506: {
2507:   PetscFunctionBegin;
2508:   PetscCheck(PetscDefined(HAVE_CUDA_VERSION_12_2PLUS), PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS, "-log_view_gpu_energy requires CUDA version >= 12.2");
2509:   PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2510:   PetscLogGpuEnergyFlag      = PETSC_TRUE;
2511:   PetscLogGpuEnergyMeterFlag = PETSC_FALSE;
2512:   PetscFunctionReturn(PETSC_SUCCESS);
2513: }

2515: /*@
2516:   PetscLogGpuEnergyMeter - turn on the logging of GPU energy (readings from energy meters) for GPU kernels

2518:   Options Database Key:
2519: . -log_view_gpu_energy_meter - provide the GPU energy (readings from energy meters) consumption for all events in the `-log_view` output

2521:   Level: advanced

2523:   Note:
2524:   This option is mutually exclusive to `-log_view_gpu_energy`.

2526:   Developer Note:
2527:   This option turns on energy monitoring of GPU kernels. The energy consumption is measured directly using the NVML API
2528:   `nvmlDeviceGetTotalEnergyConsumption()`, which returns the total energy used by the GPU since the driver was last initialized.
2529:   For newer GPUs, energy readings are updated every 20-100ms, so this approach may be inaccurate for short-duration GPU events.

2531: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeterBegin()`
2532: @*/
2533: PetscErrorCode PetscLogGpuEnergyMeter(void)
2534: {
2535:   PetscFunctionBegin;
2536:   PetscCheck(petsc_genergy == 0.0, PETSC_COMM_SELF, PETSC_ERR_SUP, "GPU energy logging has already been turned on");
2537:   PetscLogGpuEnergyMeterFlag = PETSC_TRUE;
2538:   PetscLogGpuEnergyFlag      = PETSC_FALSE;
2539:   PetscFunctionReturn(PETSC_SUCCESS);
2540: }

2542: /*@
2543:   PetscLogGpuEnergyMeterBegin - Start energy meter for device

2545:   Level: intermediate

2547:   Notes:
2548:   The GPU event energy meter captures the energy used by the GPU between `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()`.

2550:   `PetscLogGpuEnergyMeterBegin()` and `PetscLogGpuEnergyMeterEnd()` collect the energy readings using `nvmlDeviceGetTotalEnergyConsumption()`.
2551:   The function `cupmStreamSynchronize()` is called before the energy query to ensure completion.

2553: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterEnd()`, `PetscLogGpuEnergyMeter()`
2554: @*/
2555: PetscErrorCode PetscLogGpuEnergyMeterBegin(void)
2556: {
2557:   PetscBool isActive;

2559:   PetscFunctionBegin;
2560:   PetscCall(PetscLogEventBeginIsActive(&isActive));
2561:   if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2562:   if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2563:     PetscDeviceContext dctx;

2565:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2566:     PetscCall(PetscDeviceContextBeginEnergyMeter_Internal(dctx));
2567:   }
2568:   PetscFunctionReturn(PETSC_SUCCESS);
2569: }

2571: /*@
2572:   PetscLogGpuEnergyMeterEnd - Stop energy meter for device

2574:   Level: intermediate

2576: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuEnergyMeterBegin()`
2577: @*/
2578: PetscErrorCode PetscLogGpuEnergyMeterEnd(void)
2579: {
2580:   PetscBool isActive;

2582:   PetscFunctionBegin;
2583:   PetscCall(PetscLogEventEndIsActive(&isActive));
2584:   if (!isActive || !PetscLogGpuEnergyMeterFlag) PetscFunctionReturn(PETSC_SUCCESS);
2585:   if (!PetscDefined(HAVE_KOKKOS_WITHOUT_GPU)) {
2586:     PetscDeviceContext dctx;
2587:     PetscLogDouble     energy;

2589:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2590:     PetscCall(PetscDeviceContextEndEnergyMeter_Internal(dctx, &energy));
2591:     petsc_genergy_meter += (energy / 1000.0); // convert to Joules
2592:   }
2593:   PetscFunctionReturn(PETSC_SUCCESS);
2594: }
2595:   #endif /* end of PETSC_HAVE_DEVICE */

2597: #endif /* PETSC_USE_LOG*/

2599: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2600: PetscClassId PETSC_OBJECT_CLASSID  = 0;

2602: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

2604: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2605: {
2606:   int stage;

2608:   PetscFunctionBegin;
2609:   if (PetscLogInitializeCalled) PetscFunctionReturn(PETSC_SUCCESS);
2610:   PetscLogInitializeCalled = PETSC_TRUE;
2611:   if (PetscDefined(USE_LOG)) {
2612:     /* Setup default logging structures */
2613:     PetscCall(PetscLogStateCreate(&petsc_log_state));
2614:     for (PetscInt i = 0; i < PETSC_LOG_HANDLER_MAX; i++) {
2615:       if (PetscLogHandlers[i].handler) PetscCall(PetscLogHandlerSetState(PetscLogHandlers[i].handler, petsc_log_state));
2616:     }
2617:     PetscCall(PetscLogStateStageRegister(petsc_log_state, "Main Stage", &stage));
2618:     PetscCall(PetscSpinlockCreate(&PetscLogSpinLock));
2619: #if PetscDefined(HAVE_THREADSAFETY)
2620:     petsc_log_tid = 0;
2621:     petsc_log_gid = 0;
2622: #endif

2624:     /* All processors sync here for more consistent logging */
2625:     PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2626:     PetscCall(PetscTime(&petsc_BaseTime));
2627:     PetscCall(PetscLogStagePush(stage));
2628:   }
2629:   PetscFunctionReturn(PETSC_SUCCESS);
2630: }

2632: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
2633: {
2634:   PetscFunctionBegin;
2635:   if (PetscDefined(USE_LOG)) {
2636:     /* Resetting phase */
2637:     // pop remaining stages
2638:     if (petsc_log_state) {
2639:       while (petsc_log_state->current_stage >= 0) PetscCall(PetscLogStagePop());
2640:     }
2641:     for (int i = 0; i < PETSC_LOG_HANDLER_MAX; i++) PetscCall(PetscLogHandlerDestroy(&PetscLogHandlers[i].handler));
2642:     PetscCall(PetscArrayzero(PetscLogHandlers, PETSC_LOG_HANDLER_MAX));
2643:     PetscCall(PetscLogStateDestroy(&petsc_log_state));

2645:     petsc_TotalFlops         = 0.0;
2646:     petsc_BaseTime           = 0.0;
2647:     petsc_TotalFlops         = 0.0;
2648:     petsc_send_ct            = 0.0;
2649:     petsc_recv_ct            = 0.0;
2650:     petsc_send_len           = 0.0;
2651:     petsc_recv_len           = 0.0;
2652:     petsc_isend_ct           = 0.0;
2653:     petsc_irecv_ct           = 0.0;
2654:     petsc_isend_len          = 0.0;
2655:     petsc_irecv_len          = 0.0;
2656:     petsc_wait_ct            = 0.0;
2657:     petsc_wait_any_ct        = 0.0;
2658:     petsc_wait_all_ct        = 0.0;
2659:     petsc_sum_of_waits_ct    = 0.0;
2660:     petsc_allreduce_ct       = 0.0;
2661:     petsc_gather_ct          = 0.0;
2662:     petsc_scatter_ct         = 0.0;
2663:     petsc_TotalFlops_th      = 0.0;
2664:     petsc_send_ct_th         = 0.0;
2665:     petsc_recv_ct_th         = 0.0;
2666:     petsc_send_len_th        = 0.0;
2667:     petsc_recv_len_th        = 0.0;
2668:     petsc_isend_ct_th        = 0.0;
2669:     petsc_irecv_ct_th        = 0.0;
2670:     petsc_isend_len_th       = 0.0;
2671:     petsc_irecv_len_th       = 0.0;
2672:     petsc_wait_ct_th         = 0.0;
2673:     petsc_wait_any_ct_th     = 0.0;
2674:     petsc_wait_all_ct_th     = 0.0;
2675:     petsc_sum_of_waits_ct_th = 0.0;
2676:     petsc_allreduce_ct_th    = 0.0;
2677:     petsc_gather_ct_th       = 0.0;
2678:     petsc_scatter_ct_th      = 0.0;

2680:     petsc_ctog_ct       = 0.0;
2681:     petsc_gtoc_ct       = 0.0;
2682:     petsc_ctog_sz       = 0.0;
2683:     petsc_gtoc_sz       = 0.0;
2684:     petsc_gflops        = 0.0;
2685:     petsc_gtime         = 0.0;
2686:     petsc_genergy       = 0.0;
2687:     petsc_genergy_meter = 0.0;
2688:     petsc_ctog_ct_th    = 0.0;
2689:     petsc_gtoc_ct_th    = 0.0;
2690:     petsc_ctog_sz_th    = 0.0;
2691:     petsc_gtoc_sz_th    = 0.0;
2692:     petsc_gflops_th     = 0.0;
2693:     petsc_gtime_th      = 0.0;
2694:   }
2695:   PETSC_LARGEST_CLASSID    = PETSC_SMALLEST_CLASSID;
2696:   PETSC_OBJECT_CLASSID     = 0;
2697:   PetscLogInitializeCalled = PETSC_FALSE;
2698:   PetscFunctionReturn(PETSC_SUCCESS);
2699: }

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

2704:   Not Collective

2706:   Input Parameter:
2707: . name - The class name

2709:   Output Parameter:
2710: . oclass - The class id or classid

2712:   Level: developer

2714: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2715: @*/
2716: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2717: {
2718:   PetscFunctionBegin;
2719:   *oclass = ++PETSC_LARGEST_CLASSID;
2720: #if PetscDefined(USE_LOG)
2721:   {
2722:     PetscLogState state;
2723:     PetscLogClass logclass;

2725:     PetscCall(PetscLogGetState(&state));
2726:     if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2727:   }
2728: #endif
2729:   PetscFunctionReturn(PETSC_SUCCESS);
2730: }