Actual source code: plog.c

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

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

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

  9:       ***

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

 20: #if defined(PETSC_HAVE_THREADSAFETY)

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

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

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

 38: #endif

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

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

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

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

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

102: PetscBool PetscLogGpuTimeFlag = PETSC_FALSE;

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

107: PetscLogState petsc_log_state = NULL;

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

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

118: #undef PETSC_LOG_HANDLERS_HOT_BLANK

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

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

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

144:   #endif

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

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

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

169:   Not collective

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

174:   Level: developer

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

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

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

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

205:   Collective on `PETSC_COMM_WORLD`

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

212:   Level: developer

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

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

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

239:   Logically collective

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

244:   Level: developer

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

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

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

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

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

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

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

301:   Logically collective

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

306:   Level: developer

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

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

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

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

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

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

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

363:   Not Collective

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

368:   Level: beginner

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

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

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

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

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

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

435:   Logically Collective on `PETSC_COMM_WORLD`

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

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

451:   Level: advanced

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

457:   This routine may be called more than once.

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

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

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

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

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

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

483:   Level: intermediate

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

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

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

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

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

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

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

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

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

528:   Level: advanced

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

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

544:   Logically Collective on `PETSC_COMM_WORLD`

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

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

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

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

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

574:   Level: advanced

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

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

583: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogHandlerStart()`, `PetscLogState`
584: @*/
585: 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))
586: {
587:   PetscLogHandler handler;

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

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

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

605:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

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

610:   Level: advanced

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

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

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

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

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

647:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

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

652:   Level: advanced

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

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

670:   Not Collective

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

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

679:   Level: intermediate

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

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

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

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

701:   Not Collective

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

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

710:   Level: intermediate

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

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

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

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

733:   Not Collective

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

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

741:   Level: intermediate

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

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

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

759:   Not Collective

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

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

779:   Level: intermediate

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

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

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

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

804:   Not Collective

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

821:   Level: intermediate

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

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

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

845:   Not Collective

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

851:   Level: intermediate

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

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

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

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

871:   Not Collective

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

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

879:   Level: intermediate

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

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

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

897:   Not Collective

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

903:   Level: intermediate

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

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

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

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

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

926:   Not Collective

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

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

934:   Level: intermediate

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

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

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

952:   Not Collective

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

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

960:   Level: intermediate

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

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

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

978:   Not Collective

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

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

986:   Level: intermediate

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

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

1004: /*------------------------------------------------ Event Functions --------------------------------------------------*/

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

1009:   Not Collective

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

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

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

1033:   Level: intermediate

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

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

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

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

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

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

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

1074:   Logically Collective

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

1080:   Level: developer

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

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

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

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

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

1104:   Not Collective

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

1110:   Level: developer

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

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

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

1127:   Not Collective

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

1132:   Level: developer

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

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

1146:   Not Collective

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

1151:   Level: developer

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

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

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

1168:   Not Collective

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

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

1183:   Level: advanced

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

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

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

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

1204:   Not Collective

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

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

1217:   Level: advanced

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

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

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

1235:   Not Collective

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

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

1248:   Level: advanced

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

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

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

1266:   Not Collective

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

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

1279:   Level: advanced

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

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

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

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

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

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

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

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

1338:   Not Collective

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

1344:   Level: advanced

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

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

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

1361:   Not Collective

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

1368:   Level: developer

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

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

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

1385:   Not Collective

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

1390:   Level: developer

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

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

1404:   Not Collective

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

1409:   Level: developer

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

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

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

1427:   Collective

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

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

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

1444:   Level: developer

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

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

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

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

1460:   Not Collective

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

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

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

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

1484:   Level: intermediate

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

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

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

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

1502:   Not Collective

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

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

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

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

1526:   Level: intermediate

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

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

1534:   No Fortran Support

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

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

1542:   Level: intermediate

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

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

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

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

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

1574:   No Fortran Support

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

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

1583:   Level: intermediate

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

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

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

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

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

1615:   Not Collective

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

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

1625:   Level: developer

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

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

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

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

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

1652:   Not Collective

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

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

1662:   Level: developer

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

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

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

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

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

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

1692:   Not Collective

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

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

1700:   Level: intermediate

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

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

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

1718:   Not Collective

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

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

1726:   Level: intermediate

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

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

1744: /*@
1745:   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.

1747:   Not collective

1749:   Level: advanced

1751:   Notes:
1752:   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()`).

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

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

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

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

1772:   Not collective

1774:   Level: advanced

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

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

1789: /*------------------------------------------------ Class Functions --------------------------------------------------*/

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

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

1798:    Not Collective

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

1803:    Level: developer

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

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

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

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

1819:    Not Collective

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

1824:    Level: developer

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

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

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

1836:   Not Collective

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

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

1844:   Level: intermediate

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

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

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

1871:   Not Collective

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

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

1879:   Level: intermediate

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

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

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

1902:   Collective on `PETSC_COMM_WORLD`

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

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

1916:   Level: advanced

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

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

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

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

1937:   Collective on `PETSC_COMM_WORLD`

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

1942:   Level: advanced

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

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

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

1972:   Collective

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

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

1987:   Level: beginner

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

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

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

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

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

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

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

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

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

2060:   Collective on `PETSC_COMM_WORLD`

2062:   Level: developer

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

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

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

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

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

2099:   Logically Collective on `PETSC_COMM_WORLD`

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

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

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

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

2120:   Level: advanced

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

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

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

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

2143:   Not Collective

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

2148:   Level: intermediate

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

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

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

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

2169:   Not Collective

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

2176:   Level: developer

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

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

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

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

2203:   Not Collective

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

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

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

2219:   Level: intermediate

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

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

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

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

2236:   Not Collective

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

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

2252:   Level: intermediate

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

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

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

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

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

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

2279:   Not Collective

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

2290:   Level: intermediate

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

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

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

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

2305:   Not Collective

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

2316:   Level: intermediate

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

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

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

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

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

2333:   Level: advanced

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

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

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

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

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

2358:   Level: intermediate

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

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

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

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

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

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

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

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

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

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

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

2412:   Level: intermediate

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

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

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

2438:   #endif /* end of PETSC_HAVE_DEVICE */

2440: #endif /* PETSC_USE_LOG*/

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

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

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

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

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

2478: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

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

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

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

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

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

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

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

2578:   Not Collective

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

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

2586:   Level: developer

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

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