Actual source code: plog.c

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

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

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

  9:       ***

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

 20: #if defined(PETSC_HAVE_THREADSAFETY)

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

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

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

 38: #endif

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

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

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

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

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

102: PetscBool PetscLogGpuTimeFlag = PETSC_FALSE;

104: PetscLogState petsc_log_state = NULL;

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

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

115: #undef PETSC_LOG_HANDLERS_HOT_BLANK

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

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

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

141:   #endif

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

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

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

166:   Not collective

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

171:   Level: developer

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

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

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

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

202:   Collective on `PETSC_COMM_WORLD`

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

209:   Level: developer

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

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

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

236:   Logically collective

238:   Input Parameters:
239: . h - a `PetscLogHandler`

241:   Level: developer

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

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

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

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

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

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

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

298:   Logically collective

300:   Input Parameters:
301: . h - a `PetscLogHandler`

303:   Level: developer

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

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

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

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

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

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

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

361:   Not Collective

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

366:   Level: beginner

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

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

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

415: PETSC_INTERN PetscErrorCode PetscLogTypeBegin(PetscLogHandlerType type)
416: {
417:   PetscLogHandler handler;

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

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

433:   Logically Collective on `PETSC_COMM_WORLD`

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

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

449:   Level: advanced

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

455:   This routine may be called more than once.

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

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

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

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

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

478:   Options Database Key:
479: . -log_trace [filename] - Begins `PetscLogTraceBegin()`

481:   Level: intermediate

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

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

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

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

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

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

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

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

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

526:   Level: advanced

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

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

542:   Logically Collective on `PETSC_COMM_WORLD`

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

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

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

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

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

572:   Level: advanced

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

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

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

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

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

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

603:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

605:   Options Database Key:
606: . -log_mpe - Prints extensive log information

608:   Level: advanced

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

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

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

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

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

645:   Collective on `PETSC_COMM_WORLD`, No Fortran Support

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

650:   Level: advanced

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

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

668:   Not Collective

670:   Input Parameter:
671: . flag - `PETSC_TRUE` if actions are to be logged

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

677:   Level: intermediate

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

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

691:     if (h) PetscCall(PetscLogHandlerSetLogActions(h, flag));
692:   }
693:   PetscFunctionReturn(PETSC_SUCCESS);
694: }

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

699:   Not Collective

701:   Input Parameter:
702: . flag - `PETSC_TRUE` if objects are to be logged

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

708:   Level: intermediate

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

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

722:     if (h) PetscCall(PetscLogHandlerSetLogObjects(h, flag));
723:   }
724:   PetscFunctionReturn(PETSC_SUCCESS);
725: }

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

731:   Not Collective

733:   Input Parameter:
734: . sname - The name to associate with that stage

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

739:   Level: intermediate

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

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

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

757:   Not Collective

759:   Input Parameter:
760: . stage - The stage on which to log

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

777:   Level: intermediate

779:   Note:
780:   Use `PetscLogStageRegister()` to register a stage.

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

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

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

802:   Not Collective

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

819:   Level: intermediate

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

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

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

843:   Not Collective

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

849:   Level: intermediate

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

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

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

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

869:   Not Collective

871:   Input Parameter:
872: . stage - The stage

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

877:   Level: intermediate

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

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

892: /*@
893:   PetscLogStageSetVisible - Determines stage visibility in `PetscLogView()`

895:   Not Collective

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

901:   Level: intermediate

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

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

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

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

921: /*@
922:   PetscLogStageGetVisible - Returns stage visibility in `PetscLogView()`

924:   Not Collective

926:   Input Parameter:
927: . stage - The stage

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

932:   Level: intermediate

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

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

947: /*@
948:   PetscLogStageGetId - Returns the stage id when given the stage name.

950:   Not Collective

952:   Input Parameter:
953: . name - The stage name

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

958:   Level: intermediate

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

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

973: /*@
974:   PetscLogStageGetName - Returns the stage name when given the stage id.

976:   Not Collective

978:   Input Parameter:
979: . stage - The stage

981:   Output Parameter:
982: . name - The stage name

984:   Level: intermediate

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

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

1002: /*------------------------------------------------ Event Functions --------------------------------------------------*/

1004: /*@
1005:   PetscLogEventRegister - Registers an event name for logging operations

1007:   Not Collective

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

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

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

1031:   Level: intermediate

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

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

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

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

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

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

1069: /*@
1070:   PetscLogEventSetCollective - Indicates that a particular event is collective.

1072:   Logically Collective

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

1078:   Level: developer

1080:   Notes:
1081:   New events returned from `PetscLogEventRegister()` are collective by default.

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

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

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

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

1102:   Not Collective

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

1108:   Level: developer

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

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

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

1125:   Not Collective

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

1130:   Level: developer

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

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

1144:   Not Collective

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

1149:   Level: developer

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

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

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

1166:   Not Collective

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

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

1181:   Level: advanced

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

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

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

1199: /*@
1200:   PetscLogEventActivate - Indicates that a particular event should be logged.

1202:   Not Collective

1204:   Input Parameter:
1205: . event - The event id

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

1215:   Level: advanced

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

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

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

1233:   Not Collective

1235:   Input Parameter:
1236: . event - The event id

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

1246:   Level: advanced

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

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

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

1264:   Not Collective

1266:   Input Parameter:
1267: . event - The event id

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

1277:   Level: advanced

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

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

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

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

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

1301:   Not Collective

1303:   Input Parameter:
1304: . event - The event id

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

1314:   Level: advanced

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

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

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

1333: /*@
1334:   PetscLogEventSetActiveAll - Turns on logging of all events

1336:   Not Collective

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

1342:   Level: advanced

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

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

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

1359:   Not Collective

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

1366:   Level: developer

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

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

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

1383:   Not Collective

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

1388:   Level: developer

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

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

1402:   Not Collective

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

1407:   Level: developer

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

1418: /*MC
1419:   PetscLogEventSync - Synchronizes the beginning of a user event.

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

1425:   Collective

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

1431:   Example Usage:
1432: .vb
1433:   PetscLogEvent USER_EVENT;

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

1442:   Level: developer

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

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

1451: /*MC
1452:   PetscLogEventBegin - Logs the beginning of a user event.

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

1458:   Not Collective

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

1467:   Fortran Synopsis:
1468:   void PetscLogEventBegin(int e, PetscErrorCode ierr)

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

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

1482:   Level: intermediate

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

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

1493: /*MC
1494:   PetscLogEventEnd - Log the end of a user event.

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

1500:   Not Collective

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

1509:   Fortran Synopsis:
1510:   void PetscLogEventEnd(int e, PetscErrorCode ierr)

1512:   Example Usage:
1513: .vb
1514:   PetscLogEvent USER_EVENT;

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

1524:   Level: intermediate

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

1529: /*@C
1530:   PetscLogStageGetPerfInfo - Return the performance information about the given stage

1532:   No Fortran Support

1534:   Input Parameters:
1535: . stage - The stage number or `PETSC_DETERMINE` for the current stage

1537:   Output Parameter:
1538: . info - This structure is filled with the performance information

1540:   Level: intermediate

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

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

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

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

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

1572:   No Fortran Support

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

1578:   Output Parameter:
1579: . info - This structure is filled with the performance information

1581:   Level: intermediate

1583:   Note:
1584:   This is a low level routine used by the logging functions in PETSc

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

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

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

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

1613:   Not Collective

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

1620:   Options Database Key:
1621: . -log_view - Activates log summary

1623:   Level: developer

1625:   Note:
1626:   This is to enable logging of convergence

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

1637:     if (h) {
1638:       PetscEventPerfInfo *event_info;

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

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

1650:   Not Collective

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

1657:   Options Database Key:
1658: . -log_view - Activates log summary

1660:   Level: developer

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

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

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

1677:     if (h) {
1678:       PetscEventPerfInfo *event_info;

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

1687: /*@
1688:   PetscLogEventGetId - Returns the event id when given the event name.

1690:   Not Collective

1692:   Input Parameter:
1693: . name - The event name

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

1698:   Level: intermediate

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

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

1713: /*@
1714:   PetscLogEventGetName - Returns the event name when given the event id.

1716:   Not Collective

1718:   Input Parameter:
1719: . event - The event

1721:   Output Parameter:
1722: . name - The event name

1724:   Level: intermediate

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

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

1742: /*@
1743:   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.

1745:   Not collective

1747:   Level: advanced

1749:   Notes:
1750:   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()`).

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

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

1762:     if (h) PetscCall(PetscLogHandlerEventsPause(h));
1763:   }
1764:   PetscFunctionReturn(PETSC_SUCCESS);
1765: }

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

1770:   Not collective

1772:   Level: advanced

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

1782:     if (h) PetscCall(PetscLogHandlerEventsResume(h));
1783:   }
1784:   PetscFunctionReturn(PETSC_SUCCESS);
1785: }

1787: /*------------------------------------------------ Class Functions --------------------------------------------------*/

1789: /*MC
1790:    PetscLogObjectCreate - Log the creation of a `PetscObject`

1792:    Synopsis:
1793: #include <petsclog.h>
1794:    PetscErrorCode PetscLogObjectCreate(PetscObject h)

1796:    Not Collective

1798:    Input Parameters:
1799: .  h - A `PetscObject`

1801:    Level: developer

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

1807: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectDestroy()`
1808: M*/

1810: /*MC
1811:    PetscLogObjectDestroy - Logs the destruction of a `PetscObject`

1813:    Synopsis:
1814: #include <petsclog.h>
1815:    PetscErrorCode PetscLogObjectDestroy(PetscObject h)

1817:    Not Collective

1819:    Input Parameters:
1820: .  h - A `PetscObject`

1822:    Level: developer

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

1828: .seealso: [](ch_profiling), `PetscLogHandler`, `PetscLogObjectCreate()`
1829: M*/

1831: /*@
1832:   PetscLogClassGetClassId - Returns the `PetscClassId` when given the class name.

1834:   Not Collective

1836:   Input Parameter:
1837: . name - The class name

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

1842:   Level: intermediate

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

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

1866: /*@C
1867:   PetscLogClassIdGetName - Returns a `PetscClassId`'s name.

1869:   Not Collective

1871:   Input Parameter:
1872: . classid - A `PetscClassId`

1874:   Output Parameter:
1875: . name - The class name

1877:   Level: intermediate

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

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

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

1900:   Collective on `PETSC_COMM_WORLD`

1902:   Input Parameter:
1903: . sname - an optional file name

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

1914:   Level: advanced

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

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

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

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

1935:   Collective on `PETSC_COMM_WORLD`

1937:   Input Parameter:
1938: . sname - filename for the MPE logfile

1940:   Level: advanced

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

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

1967: /*@
1968:   PetscLogView - Prints a summary of the logging.

1970:   Collective

1972:   Input Parameter:
1973: . viewer - an ASCII viewer

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

1985:   Level: beginner

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

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

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

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

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

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

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

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

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

2058:   Collective on `PETSC_COMM_WORLD`

2060:   Level: developer

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

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

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

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

2088:   Logically Collective on `PETSC_COMM_WORLD`

2090:   Input Parameter:
2091: . newThresh - the threshold to use

2093:   Output Parameter:
2094: . oldThresh - the previously set threshold value

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

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

2109:   Level: advanced

2111:   Note:
2112:   This threshold is only used by the nested log handler

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

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

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

2132:   Not Collective

2134:   Output Parameter:
2135: . flops - number of floating point operations

2137:   Level: intermediate

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

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

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

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

2158:   Not Collective

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

2165:   Level: developer

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

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

2185: /*MC
2186:   PetscLogFlops - Adds floating point operations to the global counter.

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

2192:   Not Collective

2194:   Input Parameter:
2195: . f - flop counter

2197:   Example Usage:
2198: .vb
2199:   PetscLogEvent USER_EVENT;

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

2208:   Level: intermediate

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

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

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

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

2225:   Not Collective

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

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

2241:   Level: intermediate

2243:   Note:
2244:   Only works in C/C++, not Fortran

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

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

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

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

2264:   Synopsis:
2265: #include <petsclog.h>
2266:   void PetscPreLoadEnd(void);

2268:   Not Collective

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

2279:   Level: intermediate

2281:   Note:
2282:   Only works in C/C++ not Fortran

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

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

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

2294:   Not Collective

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

2305:   Level: intermediate

2307:   Note:
2308:   Only works in C/C++ not Fortran

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

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

2316: /*@
2317:   PetscLogGpuTime - turn on the logging of GPU time for GPU kernels

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

2322:   Level: advanced

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

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

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

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

2344: /*@
2345:   PetscLogGpuTimeBegin - Start timer for device

2347:   Level: intermediate

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

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

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

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

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

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

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

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

2382:   PetscFunctionBegin;
2383:   PetscCall(PetscLogEventBeginIsActive(&isActive));
2384:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2385:     #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2386:   {
2387:     PetscDeviceContext dctx;

2389:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2390:     PetscCall(PetscDeviceContextBeginTimer_Internal(dctx));
2391:   }
2392:     #else
2393:   PetscCall(PetscTimeSubtract(&petsc_gtime));
2394:     #endif
2395:   PetscFunctionReturn(PETSC_SUCCESS);
2396: }

2398: /*@
2399:   PetscLogGpuTimeEnd - Stop timer for device

2401:   Level: intermediate

2403: .seealso: [](ch_profiling), `PetscLogView()`, `PetscLogGpuFlops()`, `PetscLogGpuTimeBegin()`
2404: @*/
2405: PetscErrorCode PetscLogGpuTimeEnd(void)
2406: {
2407:   PetscBool isActive;

2409:   PetscFunctionBegin;
2410:   PetscCall(PetscLogEventEndIsActive(&isActive));
2411:   if (!isActive || !PetscLogGpuTimeFlag) PetscFunctionReturn(PETSC_SUCCESS);
2412:     #if defined(PETSC_HAVE_DEVICE) && !defined(PETSC_HAVE_KOKKOS_WITHOUT_GPU)
2413:   {
2414:     PetscDeviceContext dctx;
2415:     PetscLogDouble     elapsed;

2417:     PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
2418:     PetscCall(PetscDeviceContextEndTimer_Internal(dctx, &elapsed));
2419:     petsc_gtime += (elapsed / 1000.0);
2420:   }
2421:     #else
2422:   PetscCall(PetscTimeAdd(&petsc_gtime));
2423:     #endif
2424:   PetscFunctionReturn(PETSC_SUCCESS);
2425: }

2427:   #endif /* end of PETSC_HAVE_DEVICE */

2429: #endif /* PETSC_USE_LOG*/

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

2433: PETSC_EXTERN PetscErrorCode PetscASend(int count, int datatype)
2434: {
2435:   PetscFunctionBegin;
2436: #if PetscDefined(USE_LOG)
2437:   PetscCall(PetscAddLogDouble(&petsc_send_ct, &petsc_send_ct_th, 1));
2438:   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2439:   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_send_len, &petsc_send_len_th));
2440:   #endif
2441: #endif
2442:   PetscFunctionReturn(PETSC_SUCCESS);
2443: }

2445: PETSC_EXTERN PetscErrorCode PetscARecv(int count, int datatype)
2446: {
2447:   PetscFunctionBegin;
2448: #if PetscDefined(USE_LOG)
2449:   PetscCall(PetscAddLogDouble(&petsc_recv_ct, &petsc_recv_ct_th, 1));
2450:   #if !defined(MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO)
2451:   PetscCall(PetscMPITypeSize(count, MPI_Type_f2c((MPI_Fint)datatype), &petsc_recv_len, &petsc_recv_len_th));
2452:   #endif
2453: #endif
2454:   PetscFunctionReturn(PETSC_SUCCESS);
2455: }

2457: PETSC_EXTERN PetscErrorCode PetscAReduce(void)
2458: {
2459:   PetscFunctionBegin;
2460:   if (PetscDefined(USE_LOG)) PetscCall(PetscAddLogDouble(&petsc_allreduce_ct, &petsc_allreduce_ct_th, 1));
2461:   PetscFunctionReturn(PETSC_SUCCESS);
2462: }

2464: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2465: PetscClassId PETSC_OBJECT_CLASSID  = 0;

2467: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

2469: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
2470: {
2471:   int stage;

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

2489:     /* All processors sync here for more consistent logging */
2490:     PetscCallMPI(MPI_Barrier(PETSC_COMM_WORLD));
2491:     PetscCall(PetscTime(&petsc_BaseTime));
2492:     PetscCall(PetscLogStagePush(stage));
2493:   }
2494:   PetscFunctionReturn(PETSC_SUCCESS);
2495: }

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

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

2545:     petsc_ctog_ct    = 0.0;
2546:     petsc_gtoc_ct    = 0.0;
2547:     petsc_ctog_sz    = 0.0;
2548:     petsc_gtoc_sz    = 0.0;
2549:     petsc_gflops     = 0.0;
2550:     petsc_gtime      = 0.0;
2551:     petsc_ctog_ct_th = 0.0;
2552:     petsc_gtoc_ct_th = 0.0;
2553:     petsc_ctog_sz_th = 0.0;
2554:     petsc_gtoc_sz_th = 0.0;
2555:     petsc_gflops_th  = 0.0;
2556:     petsc_gtime_th   = 0.0;
2557:   }
2558:   PETSC_LARGEST_CLASSID    = PETSC_SMALLEST_CLASSID;
2559:   PETSC_OBJECT_CLASSID     = 0;
2560:   PetscLogInitializeCalled = PETSC_FALSE;
2561:   PetscFunctionReturn(PETSC_SUCCESS);
2562: }

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

2567:   Not Collective

2569:   Input Parameter:
2570: . name - The class name

2572:   Output Parameter:
2573: . oclass - The class id or classid

2575:   Level: developer

2577: .seealso: [](ch_profiling), `PetscLogEventRegister()`
2578: @*/
2579: PetscErrorCode PetscClassIdRegister(const char name[], PetscClassId *oclass)
2580: {
2581:   PetscFunctionBegin;
2582:   *oclass = ++PETSC_LARGEST_CLASSID;
2583: #if defined(PETSC_USE_LOG)
2584:   {
2585:     PetscLogState state;
2586:     PetscLogClass logclass;

2588:     PetscCall(PetscLogGetState(&state));
2589:     if (state) PetscCall(PetscLogStateClassRegister(state, name, *oclass, &logclass));
2590:   }
2591: #endif
2592:   PetscFunctionReturn(PETSC_SUCCESS);
2593: }