Actual source code: eventlog.c


  2: /*
  3:      This defines part of the private API for logging performance information. It is intended to be used only by the
  4:    PETSc PetscLog...() interface and not elsewhere, nor by users. Hence the prototypes for these functions are NOT
  5:    in the public PETSc include files.

  7: */
  8: #include <petsc/private/logimpl.h>
  9: #include <petscdevice.h>
 10: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
 11: #include <../src/sys/perfstubs/timer.h>
 12: #endif

 14: PetscBool PetscLogSyncOn = PETSC_FALSE;
 15: PetscBool PetscLogMemory = PETSC_FALSE;
 16: #if defined(PETSC_HAVE_DEVICE)
 17: PetscBool PetscLogGpuTraffic = PETSC_FALSE;
 18: #endif

 20: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
 21: /* Note: these functions do not have prototypes in a public directory, so they are considered "internal" and not exported. */

 23: /*@C
 24:   PetscEventRegLogCreate - This creates a `PetscEventRegLog` object.

 26:   Not collective

 28:   Input Parameter:
 29: . eventLog - The `PetscEventRegLog`

 31:   Level: developer

 33:   Note:
 34:   This is a low level routine used by the logging functions in PETSc

 36: .seealso: `PetscEventRegLogDestroy()`, `PetscStageLogCreate()`
 37: @*/
 38: PetscErrorCode PetscEventRegLogCreate(PetscEventRegLog *eventLog)
 39: {
 40:   PetscEventRegLog l;

 42:   PetscFunctionBegin;
 43:   PetscCall(PetscNew(&l));
 44:   l->numEvents = 0;
 45:   l->maxEvents = 100;
 46:   PetscCall(PetscMalloc1(l->maxEvents, &l->eventInfo));
 47:   *eventLog = l;
 48:   PetscFunctionReturn(PETSC_SUCCESS);
 49: }

 51: /*@C
 52:   PetscEventRegLogDestroy - This destroys a `PetscEventRegLog` object.

 54:   Not collective

 56:   Input Parameter:
 57: . eventLog - The `PetscEventRegLog`

 59:   Level: developer

 61:   Note:
 62:   This is a low level routine used by the logging functions in PETSc

 64: .seealso: `PetscEventRegLogCreate()`
 65: @*/
 66: PetscErrorCode PetscEventRegLogDestroy(PetscEventRegLog eventLog)
 67: {
 68:   int e;

 70:   PetscFunctionBegin;
 71:   for (e = 0; e < eventLog->numEvents; e++) PetscCall(PetscFree(eventLog->eventInfo[e].name));
 72:   PetscCall(PetscFree(eventLog->eventInfo));
 73:   PetscCall(PetscFree(eventLog));
 74:   PetscFunctionReturn(PETSC_SUCCESS);
 75: }

 77: /*@C
 78:   PetscEventPerfLogCreate - This creates a `PetscEventPerfLog` object.

 80:   Not collective

 82:   Input Parameter:
 83: . eventLog - The `PetscEventPerfLog`

 85:   Level: developer

 87:   Note:
 88:   This is a low level routine used by the logging functions in PETSc

 90: .seealso: `PetscEventPerfLogDestroy()`, `PetscStageLogCreate()`
 91: @*/
 92: PetscErrorCode PetscEventPerfLogCreate(PetscEventPerfLog *eventLog)
 93: {
 94:   PetscEventPerfLog l;

 96:   PetscFunctionBegin;
 97:   PetscCall(PetscNew(&l));
 98:   l->numEvents = 0;
 99:   l->maxEvents = 100;
100:   PetscCall(PetscCalloc1(l->maxEvents, &l->eventInfo));
101:   *eventLog = l;
102:   PetscFunctionReturn(PETSC_SUCCESS);
103: }

105: /*@C
106:   PetscEventPerfLogDestroy - This destroys a `PetscEventPerfLog` object.

108:   Not collective

110:   Input Parameter:
111: . eventLog - The `PetscEventPerfLog`

113:   Level: developer

115:   Note:
116:   This is a low level routine used by the logging functions in PETSc

118: .seealso: `PetscEventPerfLogCreate()`
119: @*/
120: PetscErrorCode PetscEventPerfLogDestroy(PetscEventPerfLog eventLog)
121: {
122:   PetscFunctionBegin;
123:   PetscCall(PetscFree(eventLog->eventInfo));
124:   PetscCall(PetscFree(eventLog));
125:   PetscFunctionReturn(PETSC_SUCCESS);
126: }

128: /*------------------------------------------------ General Functions -------------------------------------------------*/
129: /*@C
130:   PetscEventPerfInfoClear - This clears a `PetscEventPerfInfo` object.

132:   Not collective

134:   Input Parameter:
135: . eventInfo - The `PetscEventPerfInfo`

137:   Level: developer

139:   Note:
140:   This is a low level routine used by the logging functions in PETSc

142: .seealso: `PetscEventPerfLogCreate()`
143: @*/
144: PetscErrorCode PetscEventPerfInfoClear(PetscEventPerfInfo *eventInfo)
145: {
146:   PetscFunctionBegin;
147:   eventInfo->id            = -1;
148:   eventInfo->active        = PETSC_TRUE;
149:   eventInfo->visible       = PETSC_TRUE;
150:   eventInfo->depth         = 0;
151:   eventInfo->count         = 0;
152:   eventInfo->flops         = 0.0;
153:   eventInfo->flops2        = 0.0;
154:   eventInfo->flopsTmp      = 0.0;
155:   eventInfo->time          = 0.0;
156:   eventInfo->time2         = 0.0;
157:   eventInfo->timeTmp       = 0.0;
158:   eventInfo->syncTime      = 0.0;
159:   eventInfo->dof[0]        = -1.0;
160:   eventInfo->dof[1]        = -1.0;
161:   eventInfo->dof[2]        = -1.0;
162:   eventInfo->dof[3]        = -1.0;
163:   eventInfo->dof[4]        = -1.0;
164:   eventInfo->dof[5]        = -1.0;
165:   eventInfo->dof[6]        = -1.0;
166:   eventInfo->dof[7]        = -1.0;
167:   eventInfo->errors[0]     = -1.0;
168:   eventInfo->errors[1]     = -1.0;
169:   eventInfo->errors[2]     = -1.0;
170:   eventInfo->errors[3]     = -1.0;
171:   eventInfo->errors[4]     = -1.0;
172:   eventInfo->errors[5]     = -1.0;
173:   eventInfo->errors[6]     = -1.0;
174:   eventInfo->errors[7]     = -1.0;
175:   eventInfo->numMessages   = 0.0;
176:   eventInfo->messageLength = 0.0;
177:   eventInfo->numReductions = 0.0;
178: #if defined(PETSC_HAVE_DEVICE)
179:   eventInfo->CpuToGpuCount = 0.0;
180:   eventInfo->GpuToCpuCount = 0.0;
181:   eventInfo->CpuToGpuSize  = 0.0;
182:   eventInfo->GpuToCpuSize  = 0.0;
183:   eventInfo->GpuFlops      = 0.0;
184:   eventInfo->GpuTime       = 0.0;
185: #endif
186:   PetscFunctionReturn(PETSC_SUCCESS);
187: }

189: /*@C
190:   PetscEventPerfInfoCopy - Copy the activity and visibility data in eventInfo to outInfo

192:   Not collective

194:   Input Parameter:
195: . eventInfo - The input `PetscEventPerfInfo`

197:   Output Parameter:
198: . outInfo   - The output `PetscEventPerfInfo`

200:   Level: developer

202:   Note:
203:   This is a low level routine used by the logging functions in PETSc

205: .seealso: `PetscEventPerfInfoClear()`
206: @*/
207: PetscErrorCode PetscEventPerfInfoCopy(const PetscEventPerfInfo *eventInfo, PetscEventPerfInfo *outInfo)
208: {
209:   PetscFunctionBegin;
210:   outInfo->id      = eventInfo->id;
211:   outInfo->active  = eventInfo->active;
212:   outInfo->visible = eventInfo->visible;
213:   PetscFunctionReturn(PETSC_SUCCESS);
214: }

216: /*@C
217:   PetscEventPerfInfoAdd - Add data in eventInfo to outInfo

219:   Not collective

221:   Input Parameter:
222: . eventInfo - The input `PetscEventPerfInfo`

224:   Output Parameter:
225: . outInfo   - The output `PetscEventPerfInfo`

227:   Level: developer

229:   Note:
230:   This is a low level routine used by the logging functions in PETSc

232: .seealso: `PetscEventPerfInfoClear()`
233: @*/
234: PetscErrorCode PetscEventPerfInfoAdd(const PetscEventPerfInfo *eventInfo, PetscEventPerfInfo *outInfo)
235: {
236:   PetscFunctionBegin;
237:   outInfo->count += eventInfo->count;
238:   outInfo->time += eventInfo->time;
239:   outInfo->time2 += eventInfo->time2;
240:   outInfo->flops += eventInfo->flops;
241:   outInfo->flops2 += eventInfo->flops2;
242:   outInfo->numMessages += eventInfo->numMessages;
243:   outInfo->messageLength += eventInfo->messageLength;
244:   outInfo->numReductions += eventInfo->numReductions;
245: #if defined(PETSC_HAVE_DEVICE)
246:   outInfo->CpuToGpuCount += eventInfo->CpuToGpuCount;
247:   outInfo->GpuToCpuCount += eventInfo->GpuToCpuCount;
248:   outInfo->CpuToGpuSize += eventInfo->CpuToGpuSize;
249:   outInfo->GpuToCpuSize += eventInfo->GpuToCpuSize;
250:   outInfo->GpuFlops += eventInfo->GpuFlops;
251:   outInfo->GpuTime += eventInfo->GpuTime;
252: #endif
253:   outInfo->memIncrease += eventInfo->memIncrease;
254:   outInfo->mallocSpace += eventInfo->mallocSpace;
255:   outInfo->mallocIncreaseEvent += eventInfo->mallocIncreaseEvent;
256:   outInfo->mallocIncrease += eventInfo->mallocIncrease;
257:   PetscFunctionReturn(PETSC_SUCCESS);
258: }

260: /*@C
261:   PetscEventPerfLogEnsureSize - This ensures that a `PetscEventPerfLog` is at least of a certain size.

263:   Not collective

265:   Input Parameters:
266: + eventLog - The `PetscEventPerfLog`
267: - size     - The size

269:   Level: developer

271:   Note:
272:   This is a low level routine used by the logging functions in PETSc

274: .seealso: `PetscEventPerfLogCreate()`
275: @*/
276: PetscErrorCode PetscEventPerfLogEnsureSize(PetscEventPerfLog eventLog, int size)
277: {
278:   PetscEventPerfInfo *eventInfo;

280:   PetscFunctionBegin;
281:   while (size > eventLog->maxEvents) {
282:     PetscCall(PetscCalloc1(eventLog->maxEvents * 2, &eventInfo));
283:     PetscCall(PetscArraycpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents));
284:     PetscCall(PetscFree(eventLog->eventInfo));
285:     eventLog->eventInfo = eventInfo;
286:     eventLog->maxEvents *= 2;
287:   }
288:   while (eventLog->numEvents < size) PetscCall(PetscEventPerfInfoClear(&eventLog->eventInfo[eventLog->numEvents++]));
289:   PetscFunctionReturn(PETSC_SUCCESS);
290: }

292: #if defined(PETSC_HAVE_MPE)
293:   #include <mpe.h>
294: PETSC_INTERN PetscErrorCode PetscLogMPEGetRGBColor(const char *[]);
295: PetscErrorCode              PetscLogEventBeginMPE(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
296: {
297:   PetscFunctionBegin;
298:   PetscCall(MPE_Log_event(petsc_stageLog->eventLog->eventInfo[event].mpe_id_begin, 0, NULL));
299:   PetscFunctionReturn(PETSC_SUCCESS);
300: }

302: PetscErrorCode PetscLogEventEndMPE(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
303: {
304:   PetscFunctionBegin;
305:   PetscCall(MPE_Log_event(petsc_stageLog->eventLog->eventInfo[event].mpe_id_end, 0, NULL));
306:   PetscFunctionReturn(PETSC_SUCCESS);
307: }
308: #endif

310: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
311: /*@C
312:   PetscEventRegLogRegister - Registers an event for logging operations in an application code.

314:   Not Collective

316:   Input Parameters:
317: + eventLog - The `PetscEventLog`
318: . ename    - The name associated with the event
319: - classid   - The classid associated to the class for this event

321:   Output Parameter:
322: . event    - The event

324:   Example of Usage:
325: .vb
326:       int USER_EVENT;
327:       PetscLogDouble user_event_flops;
328:       PetscLogEventRegister("User event name",0,&USER_EVENT);
329:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
330:          [code segment to monitor]
331:          PetscLogFlops(user_event_flops);
332:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
333: .ve

335:   Level: developer

337:   Notes:
338:   PETSc can gather data for use with the utilities Jumpshot
339:   (part of the MPICH distribution).  If PETSc has been compiled
340:   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
341:   MPICH), the user can employ another command line option, -log_mpe,
342:   to create a logfile, "mpe.log", which can be visualized
343:   Jumpshot.

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

347: .seealso: `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
348:           `PetscEventLogActivate()`, `PetscEventLogDeactivate()`
349: @*/
350: PetscErrorCode PetscEventRegLogRegister(PetscEventRegLog eventLog, const char ename[], PetscClassId classid, PetscLogEvent *event)
351: {
352:   PetscEventRegInfo *eventInfo;
353:   int                e;

355:   PetscFunctionBegin;
358:   /* Should check classid I think */
359:   e = eventLog->numEvents++;
360:   if (eventLog->numEvents > eventLog->maxEvents) {
361:     PetscCall(PetscCalloc1(eventLog->maxEvents * 2, &eventInfo));
362:     PetscCall(PetscArraycpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents));
363:     PetscCall(PetscFree(eventLog->eventInfo));
364:     eventLog->eventInfo = eventInfo;
365:     eventLog->maxEvents *= 2;
366:   }

368:   PetscCall(PetscStrallocpy(ename, &(eventLog->eventInfo[e].name)));
369:   eventLog->eventInfo[e].classid    = classid;
370:   eventLog->eventInfo[e].collective = PETSC_TRUE;
371: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
372:   if (perfstubs_initialized == PERFSTUBS_SUCCESS) PetscStackCallExternalVoid("ps_timer_create_", eventLog->eventInfo[e].timer = ps_timer_create_(eventLog->eventInfo[e].name));
373: #endif
374: #if defined(PETSC_HAVE_MPE)
375:   if (PetscLogPLB == PetscLogEventBeginMPE) {
376:     const char *color;
377:     PetscMPIInt rank;
378:     int         beginID, endID;

380:     beginID = MPE_Log_get_event_number();
381:     endID   = MPE_Log_get_event_number();

383:     eventLog->eventInfo[e].mpe_id_begin = beginID;
384:     eventLog->eventInfo[e].mpe_id_end   = endID;

386:     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
387:     if (rank == 0) {
388:       PetscCall(PetscLogMPEGetRGBColor(&color));
389:       MPE_Describe_state(beginID, endID, eventLog->eventInfo[e].name, (char *)color);
390:     }
391:   }
392: #endif
393:   *event = e;
394:   PetscFunctionReturn(PETSC_SUCCESS);
395: }

397: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
398: /*@C
399:   PetscEventPerfLogActivate - Indicates that a particular event should be logged.

401:   Not Collective

403:   Input Parameters:
404: + eventLog - The `PetscEventPerfLog`
405: - event    - The event

407:    Usage:
408: .vb
409:       PetscEventPerfLogDeactivate(log, VEC_SetValues);
410:         [code where you do not want to log VecSetValues()]
411:       PetscEventPerfLogActivate(log, VEC_SetValues);
412:         [code where you do want to log VecSetValues()]
413: .ve

415:   Level: developer

417:   Notes:
418:   The event may be either a pre-defined PETSc event (found in
419:   include/petsclog.h) or an event number obtained with `PetscEventRegLogRegister()`.

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

423: .seealso: `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogDeactivatePop()`, `PetscEventPerfLogDeactivatePush()`
424: @*/
425: PetscErrorCode PetscEventPerfLogActivate(PetscEventPerfLog eventLog, PetscLogEvent event)
426: {
427:   PetscFunctionBegin;
428:   eventLog->eventInfo[event].active = PETSC_TRUE;
429:   PetscFunctionReturn(PETSC_SUCCESS);
430: }

432: /*@C
433:   PetscEventPerfLogDeactivate - Indicates that a particular event should not be logged.

435:   Not Collective

437:   Input Parameters:
438: + eventLog - The `PetscEventPerfLog`
439: - event    - The event

441:    Usage:
442: .vb
443:       PetscEventPerfLogDeactivate(log, VEC_SetValues);
444:         [code where you do not want to log VecSetValues()]
445:       PetscEventPerfLogActivate(log, VEC_SetValues);
446:         [code where you do want to log VecSetValues()]
447: .ve

449:    Level: developer

451:   Notes:
452:   The event may be either a pre-defined PETSc event (found in
453:   include/petsclog.h) or an event number obtained with `PetscEventRegLogRegister()`.

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

457: .seealso: `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivatePop()`, `PetscEventPerfLogDeactivatePush()`
458: @*/
459: PetscErrorCode PetscEventPerfLogDeactivate(PetscEventPerfLog eventLog, PetscLogEvent event)
460: {
461:   PetscFunctionBegin;
462:   eventLog->eventInfo[event].active = PETSC_FALSE;
463:   PetscFunctionReturn(PETSC_SUCCESS);
464: }

466: /*@C
467:   PetscEventPerfLogDeactivatePush - Indicates that a particular event should not be logged.

469:   Not Collective

471:   Input Parameters:
472: + eventLog - The `PetscEventPerfLog`
473: - event    - The event

475:    Usage:
476: .vb
477:       PetscEventPerfLogDeactivatePush(log, VEC_SetValues);
478:         [code where you do not want to log VecSetValues()]
479:       PetscEventPerfLogDeactivatePop(log, VEC_SetValues);
480:         [code where you do want to log VecSetValues()]
481: .ve

483:   Level: developer

485:   Notes:
486:   The event may be either a pre-defined PETSc event (found in
487:   include/petsclog.h) or an event number obtained with `PetscEventRegLogRegister()`.

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

491: .seealso: `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivatePop()`
492: @*/
493: PetscErrorCode PetscEventPerfLogDeactivatePush(PetscEventPerfLog eventLog, PetscLogEvent event)
494: {
495:   PetscFunctionBegin;
496:   eventLog->eventInfo[event].depth++;
497:   PetscFunctionReturn(PETSC_SUCCESS);
498: }

500: /*@C
501:   PetscEventPerfLogDeactivatePop - Indicates that a particular event should  be logged.

503:   Not Collective

505:   Input Parameters:
506: + eventLog - The `PetscEventPerfLog`
507: - event    - The event

509:    Usage:
510: .vb
511:       PetscEventPerfLogDeactivatePush(log, VEC_SetValues);
512:         [code where you do not want to log VecSetValues()]
513:       PetscEventPerfLogDeactivatePop(log, VEC_SetValues);
514:         [code where you do want to log VecSetValues()]
515: .ve

517:   Level: developer

519:   Notes:
520:   The event may be either a pre-defined PETSc event (found in
521:   include/petsclog.h) or an event number obtained with `PetscEventRegLogRegister()`.

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

525: .seealso: `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivatePush()`
526: @*/
527: PetscErrorCode PetscEventPerfLogDeactivatePop(PetscEventPerfLog eventLog, PetscLogEvent event)
528: {
529:   PetscFunctionBegin;
530:   eventLog->eventInfo[event].depth--;
531:   PetscFunctionReturn(PETSC_SUCCESS);
532: }

534: /*@C
535:   PetscEventPerfLogActivateClass - Activates event logging for a PETSc object class.

537:   Not Collective

539:   Input Parameters:
540: + eventLog    - The `PetscEventPerfLog`
541: . eventRegLog - The `PetscEventRegLog`
542: - classid      - The class id, for example `MAT_CLASSID`, `SNES_CLASSID`

544:   Level: developer

546:   Note:
547:   This is a low level routine used by the logging functions in PETSc

549: .seealso: `PetscEventPerfLogDeactivateClass()`, `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivate()`
550: @*/
551: PetscErrorCode PetscEventPerfLogActivateClass(PetscEventPerfLog eventLog, PetscEventRegLog eventRegLog, PetscClassId classid)
552: {
553:   int e;

555:   PetscFunctionBegin;
556:   for (e = 0; e < eventLog->numEvents; e++) {
557:     int c = eventRegLog->eventInfo[e].classid;
558:     if (c == classid) eventLog->eventInfo[e].active = PETSC_TRUE;
559:   }
560:   PetscFunctionReturn(PETSC_SUCCESS);
561: }

563: /*@C
564:   PetscEventPerfLogDeactivateClass - Deactivates event logging for a PETSc object class.

566:   Not Collective

568:   Input Parameters:
569: + eventLog    - The `PetscEventPerfLog`
570: . eventRegLog - The `PetscEventRegLog`
571: - classid - The class id, for example `MAT_CLASSID`, `SNES_CLASSID`

573:   Level: developer

575:   Note:
576:   This is a low level routine used by the logging functions in PETSc

578: .seealso: `PetscEventPerfLogDeactivateClass()`, `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogActivate()`
579: @*/
580: PetscErrorCode PetscEventPerfLogDeactivateClass(PetscEventPerfLog eventLog, PetscEventRegLog eventRegLog, PetscClassId classid)
581: {
582:   int e;

584:   PetscFunctionBegin;
585:   for (e = 0; e < eventLog->numEvents; e++) {
586:     int c = eventRegLog->eventInfo[e].classid;
587:     if (c == classid) eventLog->eventInfo[e].active = PETSC_FALSE;
588:   }
589:   PetscFunctionReturn(PETSC_SUCCESS);
590: }

592: /*------------------------------------------------ Query Functions --------------------------------------------------*/
593: /*@C
594:   PetscEventRegLogGetEvent - This function returns the event id given the event name.

596:   Not Collective

598:   Input Parameters:
599: + eventLog - The `PetscEventRegLog`
600: - name     - The stage name

602:   Output Parameter:
603: . event    - The event id, or -1 if not found

605:   Level: developer

607:   Note:
608:   This is a low level routine used by the logging functions in PETSc

610: .seealso: `PetscEventRegLogRegister()`
611: @*/
612: PetscErrorCode PetscEventRegLogGetEvent(PetscEventRegLog eventLog, const char name[], PetscLogEvent *event)
613: {
614:   PetscBool match;
615:   int       e;

617:   PetscFunctionBegin;
620:   *event = -1;
621:   for (e = 0; e < eventLog->numEvents; e++) {
622:     PetscCall(PetscStrcasecmp(eventLog->eventInfo[e].name, name, &match));
623:     if (match) {
624:       *event = e;
625:       break;
626:     }
627:   }
628:   PetscFunctionReturn(PETSC_SUCCESS);
629: }

631: /*@C
632:   PetscEventPerfLogSetVisible - This function determines whether an event is printed during `PetscLogView()`

634:   Not Collective

636:   Input Parameters:
637: + eventLog  - The `PetscEventPerfLog`
638: . event     - The event to log
639: - isVisible - The visibility flag, `PETSC_TRUE` for printing, otherwise `PETSC_FALSE` (default is `PETSC_TRUE`)

641:   Options Database Key:
642: . -log_view - Activates log summary

644:   Level: developer

646:   Note:
647:   This is a low level routine used by the logging functions in PETSc

649: .seealso: `PetscEventPerfLogGetVisible()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
650: @*/
651: PetscErrorCode PetscEventPerfLogSetVisible(PetscEventPerfLog eventLog, PetscLogEvent event, PetscBool isVisible)
652: {
653:   PetscFunctionBegin;
654:   eventLog->eventInfo[event].visible = isVisible;
655:   PetscFunctionReturn(PETSC_SUCCESS);
656: }

658: /*@C
659:   PetscEventPerfLogGetVisible - This function returns whether an event is printed during `PetscLogView()`

661:   Not Collective

663:   Input Parameters:
664: + eventLog  - The `PetscEventPerfLog`
665: - event     - The event id to log

667:   Output Parameter:
668: . isVisible - The visibility flag, `PETSC_TRUE` for printing, otherwise `PETSC_FALSE` (default is `PETSC_TRUE`)

670:   Options Database Key:
671: . -log_view - Activates log summary

673:   Level: developer

675:   Note:
676:   This is a low level routine used by the logging functions in PETSc

678: .seealso: `PetscEventPerfLogSetVisible()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
679: @*/
680: PetscErrorCode PetscEventPerfLogGetVisible(PetscEventPerfLog eventLog, PetscLogEvent event, PetscBool *isVisible)
681: {
682:   PetscFunctionBegin;
684:   *isVisible = eventLog->eventInfo[event].visible;
685:   PetscFunctionReturn(PETSC_SUCCESS);
686: }

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

691:   Input Parameters:
692: + stage - The stage number or `PETSC_DETERMINE` for the current stage
693: - event - The event number

695:   Output Parameter:
696: . info - This structure is filled with the performance information

698:   Level: Intermediate

700:   Note:
701:   This is a low level routine used by the logging functions in PETSc

703: .seealso: `PetscLogEventGetFlops()`
704: @*/
705: PetscErrorCode PetscLogEventGetPerfInfo(int stage, PetscLogEvent event, PetscEventPerfInfo *info)
706: {
707:   PetscStageLog     stageLog;
708:   PetscEventPerfLog eventLog = NULL;

710:   PetscFunctionBegin;
712:   PetscCheck(PetscLogPLB, PETSC_COMM_SELF, PETSC_ERR_SUP, "Must use -log_view or PetscLogDefaultBegin() before calling this routine");
713:   PetscCall(PetscLogGetStageLog(&stageLog));
714:   if (stage < 0) PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
715:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));
716:   *info = eventLog->eventInfo[event];
717:   PetscFunctionReturn(PETSC_SUCCESS);
718: }

720: PetscErrorCode PetscLogEventGetFlops(PetscLogEvent event, PetscLogDouble *flops)
721: {
722:   PetscStageLog     stageLog;
723:   PetscEventPerfLog eventLog = NULL;
724:   int               stage;

726:   PetscFunctionBegin;
727:   PetscCheck(PetscLogPLB, PETSC_COMM_SELF, PETSC_ERR_SUP, "Must use -log_view or PetscLogDefaultBegin() before calling this routine");
728:   PetscCall(PetscLogGetStageLog(&stageLog));
729:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
730:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));
731:   *flops = eventLog->eventInfo[event].flops;
732:   PetscFunctionReturn(PETSC_SUCCESS);
733: }

735: PetscErrorCode PetscLogEventZeroFlops(PetscLogEvent event)
736: {
737:   PetscStageLog     stageLog;
738:   PetscEventPerfLog eventLog = NULL;
739:   int               stage;

741:   PetscFunctionBegin;
742:   PetscCall(PetscLogGetStageLog(&stageLog));
743:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
744:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));

746:   eventLog->eventInfo[event].flops    = 0.0;
747:   eventLog->eventInfo[event].flops2   = 0.0;
748:   eventLog->eventInfo[event].flopsTmp = 0.0;
749:   PetscFunctionReturn(PETSC_SUCCESS);
750: }

752: PetscErrorCode PetscLogEventSynchronize(PetscLogEvent event, MPI_Comm comm)
753: {
754:   PetscStageLog     stageLog;
755:   PetscEventRegLog  eventRegLog;
756:   PetscEventPerfLog eventLog = NULL;
757:   int               stage;
758:   PetscLogDouble    time = 0.0;

760:   PetscFunctionBegin;
761:   if (!PetscLogSyncOn || comm == MPI_COMM_NULL) PetscFunctionReturn(PETSC_SUCCESS);
762:   PetscCall(PetscLogGetStageLog(&stageLog));
763:   PetscCall(PetscStageLogGetEventRegLog(stageLog, &eventRegLog));
764:   if (!eventRegLog->eventInfo[event].collective) PetscFunctionReturn(PETSC_SUCCESS);
765:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
766:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));
767:   if (eventLog->eventInfo[event].depth > 0) PetscFunctionReturn(PETSC_SUCCESS);

769:   PetscCall(PetscTimeSubtract(&time));
770:   PetscCallMPI(MPI_Barrier(comm));
771:   PetscCall(PetscTimeAdd(&time));
772:   eventLog->eventInfo[event].syncTime += time;
773:   PetscFunctionReturn(PETSC_SUCCESS);
774: }

776: #if defined(PETSC_HAVE_CUDA)
777:   #include <nvToolsExt.h>
778: #endif
779: #if defined(PETSC_HAVE_THREADSAFETY)
780: static PetscErrorCode PetscLogGetStageEventPerfInfo_threaded(PetscLogStage stage, PetscLogEvent event, PetscEventPerfInfo **eventInfo)
781: {
782:   PetscHashIJKKey     key;
783:   PetscEventPerfInfo *leventInfo;

785:   PetscFunctionBegin;
786:   key.i = PetscLogGetTid();
787:   key.j = stage;
788:   key.k = event;
789:   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
790:   PetscCall(PetscHMapEventGet(eventInfoMap_th, key, &leventInfo));
791:   if (!leventInfo) {
792:     PetscCall(PetscNew(&leventInfo));
793:     PetscCall(PetscHMapEventSet(eventInfoMap_th, key, leventInfo));
794:   }
795:   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
796:   *eventInfo = leventInfo;
797:   PetscFunctionReturn(PETSC_SUCCESS);
798: }
799: #endif

801: PetscErrorCode PetscLogEventBeginDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
802: {
803:   PetscStageLog       stageLog;
804:   PetscEventPerfLog   eventLog  = NULL;
805:   PetscEventPerfInfo *eventInfo = NULL;
806:   int                 stage;

808:   PetscFunctionBegin;
809:   /* Synchronization */
810:   PetscCall(PetscLogEventSynchronize(event, PetscObjectComm(o1)));
811:   PetscCall(PetscLogGetStageLog(&stageLog));
812:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
813:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));
814: #if defined(PETSC_HAVE_THREADSAFETY)
815:   PetscCall(PetscLogGetStageEventPerfInfo_threaded(stage, event, &eventInfo));
816:   if (eventInfo->depth == 0) {
817:     PetscCall(PetscEventPerfInfoClear(eventInfo));
818:     PetscCall(PetscEventPerfInfoCopy(eventLog->eventInfo + event, eventInfo));
819:   }
820: #else
821:   eventInfo = eventLog->eventInfo + event;
822: #endif
823:   /* Check for double counting */
824:   eventInfo->depth++;
825:   if (eventInfo->depth > 1) PetscFunctionReturn(PETSC_SUCCESS);
826: #if defined(PETSC_HAVE_CUDA)
827:   if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {
828:     PetscEventRegLog eventRegLog;
829:     PetscCall(PetscStageLogGetEventRegLog(stageLog, &eventRegLog));
830:     nvtxRangePushA(eventRegLog->eventInfo[event].name);
831:   }
832: #endif
833:   /* Log the performance info */
834: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
835:   if (perfstubs_initialized == PERFSTUBS_SUCCESS) {
836:     PetscEventRegLog regLog = NULL;
837:     PetscCall(PetscStageLogGetEventRegLog(stageLog, &regLog));
838:     if (regLog->eventInfo[event].timer != NULL) PetscStackCallExternalVoid("ps_timer_start_", ps_timer_start_(regLog->eventInfo[event].timer));
839:   }
840: #endif
841:   eventInfo->count++;
842:   eventInfo->timeTmp = 0.0;
843:   PetscCall(PetscTimeSubtract(&eventInfo->timeTmp));
844:   eventInfo->flopsTmp = -petsc_TotalFlops_th;
845:   eventInfo->numMessages -= petsc_irecv_ct_th + petsc_isend_ct_th + petsc_recv_ct_th + petsc_send_ct_th;
846:   eventInfo->messageLength -= petsc_irecv_len_th + petsc_isend_len_th + petsc_recv_len_th + petsc_send_len_th;
847:   eventInfo->numReductions -= petsc_allreduce_ct_th + petsc_gather_ct_th + petsc_scatter_ct_th;
848: #if defined(PETSC_HAVE_DEVICE)
849:   eventInfo->CpuToGpuCount -= petsc_ctog_ct_th;
850:   eventInfo->GpuToCpuCount -= petsc_gtoc_ct_th;
851:   eventInfo->CpuToGpuSize -= petsc_ctog_sz_th;
852:   eventInfo->GpuToCpuSize -= petsc_gtoc_sz_th;
853:   eventInfo->GpuFlops -= petsc_gflops_th;
854:   eventInfo->GpuTime -= petsc_gtime_th;
855: #endif
856:   if (PetscLogMemory) {
857:     PetscLogDouble usage;
858:     PetscCall(PetscMemoryGetCurrentUsage(&usage));
859:     eventInfo->memIncrease -= usage;
860:     PetscCall(PetscMallocGetCurrentUsage(&usage));
861:     eventInfo->mallocSpace -= usage;
862:     PetscCall(PetscMallocGetMaximumUsage(&usage));
863:     eventInfo->mallocIncrease -= usage;
864:     PetscCall(PetscMallocPushMaximumUsage((int)event));
865:   }
866:   PetscFunctionReturn(PETSC_SUCCESS);
867: }

869: PetscErrorCode PetscLogEventEndDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
870: {
871:   PetscStageLog       stageLog;
872:   PetscEventPerfLog   eventLog  = NULL;
873:   PetscEventPerfInfo *eventInfo = NULL;
874:   int                 stage;

876:   PetscFunctionBegin;
877:   PetscCall(PetscLogGetStageLog(&stageLog));
878:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
879:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));
880: #if defined(PETSC_HAVE_THREADSAFETY)
881:   PetscCall(PetscLogGetStageEventPerfInfo_threaded(stage, event, &eventInfo));
882: #else
883:   eventInfo = eventLog->eventInfo + event;
884: #endif
885:   /* Check for double counting */
886:   eventInfo->depth--;
887:   if (eventInfo->depth > 0) PetscFunctionReturn(PETSC_SUCCESS);
888:   else PetscCheck(eventInfo->depth == 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");

890:     /* Log performance info */
891: #if defined(PETSC_HAVE_TAU_PERFSTUBS)
892:   if (perfstubs_initialized == PERFSTUBS_SUCCESS) {
893:     PetscEventRegLog regLog = NULL;
894:     PetscCall(PetscStageLogGetEventRegLog(stageLog, &regLog));
895:     if (regLog->eventInfo[event].timer != NULL) PetscStackCallExternalVoid("ps_timer_stop_", ps_timer_stop_(regLog->eventInfo[event].timer));
896:   }
897: #endif
898:   PetscCall(PetscTimeAdd(&eventInfo->timeTmp));
899:   eventInfo->flopsTmp += petsc_TotalFlops_th;
900:   eventInfo->time += eventInfo->timeTmp;
901:   eventInfo->time2 += eventInfo->timeTmp * eventInfo->timeTmp;
902:   eventInfo->flops += eventInfo->flopsTmp;
903:   eventInfo->flops2 += eventInfo->flopsTmp * eventInfo->flopsTmp;
904:   eventInfo->numMessages += petsc_irecv_ct_th + petsc_isend_ct_th + petsc_recv_ct_th + petsc_send_ct_th;
905:   eventInfo->messageLength += petsc_irecv_len_th + petsc_isend_len_th + petsc_recv_len + petsc_send_len_th;
906:   eventInfo->numReductions += petsc_allreduce_ct_th + petsc_gather_ct_th + petsc_scatter_ct_th;
907: #if defined(PETSC_HAVE_DEVICE)
908:   eventInfo->CpuToGpuCount += petsc_ctog_ct_th;
909:   eventInfo->GpuToCpuCount += petsc_gtoc_ct_th;
910:   eventInfo->CpuToGpuSize += petsc_ctog_sz_th;
911:   eventInfo->GpuToCpuSize += petsc_gtoc_sz_th;
912:   eventInfo->GpuFlops += petsc_gflops_th;
913:   eventInfo->GpuTime += petsc_gtime_th;
914: #endif
915:   if (PetscLogMemory) {
916:     PetscLogDouble usage, musage;
917:     PetscCall(PetscMemoryGetCurrentUsage(&usage)); /* the comments below match the column labels printed in PetscLogView_Default() */
918:     eventInfo->memIncrease += usage;               /* RMI */
919:     PetscCall(PetscMallocGetCurrentUsage(&usage));
920:     eventInfo->mallocSpace += usage; /* Malloc */
921:     PetscCall(PetscMallocPopMaximumUsage((int)event, &musage));
922:     eventInfo->mallocIncreaseEvent = PetscMax(musage - usage, eventInfo->mallocIncreaseEvent); /* EMalloc */
923:     PetscCall(PetscMallocGetMaximumUsage(&usage));
924:     eventInfo->mallocIncrease += usage; /* MMalloc */
925:   }
926: #if defined(PETSC_HAVE_THREADSAFETY)
927:   PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
928:   PetscCall(PetscEventPerfInfoAdd(eventInfo, eventLog->eventInfo + event));
929:   PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
930: #endif
931: #if defined(PETSC_HAVE_CUDA)
932:   if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) nvtxRangePop();
933: #endif
934:   PetscFunctionReturn(PETSC_SUCCESS);
935: }

937: PetscErrorCode PetscLogEventBeginComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
938: {
939:   PetscStageLog     stageLog;
940:   PetscEventRegLog  eventRegLog;
941:   PetscEventPerfLog eventPerfLog = NULL;
942:   Action           *tmpAction;
943:   PetscLogDouble    start, end;
944:   PetscLogDouble    curTime;
945:   int               stage;

947:   PetscFunctionBegin;
948:   /* Dynamically enlarge logging structures */
949:   if (petsc_numActions >= petsc_maxActions) {
950:     PetscCall(PetscTime(&start));
951:     PetscCall(PetscCalloc1(petsc_maxActions * 2, &tmpAction));
952:     PetscCall(PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions));
953:     PetscCall(PetscFree(petsc_actions));

955:     petsc_actions = tmpAction;
956:     petsc_maxActions *= 2;
957:     PetscCall(PetscTime(&end));
958:     petsc_BaseTime += (end - start);
959:   }
960:   /* Record the event */
961:   PetscCall(PetscLogGetStageLog(&stageLog));
962:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
963:   PetscCall(PetscStageLogGetEventRegLog(stageLog, &eventRegLog));
964:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog));
965:   PetscCall(PetscTime(&curTime));
966:   if (petsc_logActions) {
967:     petsc_actions[petsc_numActions].time    = curTime - petsc_BaseTime;
968:     petsc_actions[petsc_numActions].action  = ACTIONBEGIN;
969:     petsc_actions[petsc_numActions].event   = event;
970:     petsc_actions[petsc_numActions].classid = eventRegLog->eventInfo[event].classid;
971:     if (o1) petsc_actions[petsc_numActions].id1 = o1->id;
972:     else petsc_actions[petsc_numActions].id1 = -1;
973:     if (o2) petsc_actions[petsc_numActions].id2 = o2->id;
974:     else petsc_actions[petsc_numActions].id2 = -1;
975:     if (o3) petsc_actions[petsc_numActions].id3 = o3->id;
976:     else petsc_actions[petsc_numActions].id3 = -1;
977:     petsc_actions[petsc_numActions].flops = petsc_TotalFlops;

979:     PetscCall(PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem));
980:     PetscCall(PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem));
981:     petsc_numActions++;
982:   }
983:   /* Check for double counting */
984:   eventPerfLog->eventInfo[event].depth++;
985:   if (eventPerfLog->eventInfo[event].depth > 1) PetscFunctionReturn(PETSC_SUCCESS);
986:   /* Log the performance info */
987:   eventPerfLog->eventInfo[event].count++;
988:   eventPerfLog->eventInfo[event].time -= curTime;
989:   eventPerfLog->eventInfo[event].flops -= petsc_TotalFlops;
990:   eventPerfLog->eventInfo[event].numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
991:   eventPerfLog->eventInfo[event].messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
992:   eventPerfLog->eventInfo[event].numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
993:   PetscFunctionReturn(PETSC_SUCCESS);
994: }

996: PetscErrorCode PetscLogEventEndComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
997: {
998:   PetscStageLog     stageLog;
999:   PetscEventRegLog  eventRegLog;
1000:   PetscEventPerfLog eventPerfLog = NULL;
1001:   Action           *tmpAction;
1002:   PetscLogDouble    start, end;
1003:   PetscLogDouble    curTime;
1004:   int               stage;

1006:   PetscFunctionBegin;
1007:   /* Dynamically enlarge logging structures */
1008:   if (petsc_numActions >= petsc_maxActions) {
1009:     PetscCall(PetscTime(&start));
1010:     PetscCall(PetscCalloc1(petsc_maxActions * 2, &tmpAction));
1011:     PetscCall(PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions));
1012:     PetscCall(PetscFree(petsc_actions));

1014:     petsc_actions = tmpAction;
1015:     petsc_maxActions *= 2;
1016:     PetscCall(PetscTime(&end));
1017:     petsc_BaseTime += (end - start);
1018:   }
1019:   /* Record the event */
1020:   PetscCall(PetscLogGetStageLog(&stageLog));
1021:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
1022:   PetscCall(PetscStageLogGetEventRegLog(stageLog, &eventRegLog));
1023:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog));
1024:   PetscCall(PetscTime(&curTime));
1025:   if (petsc_logActions) {
1026:     petsc_actions[petsc_numActions].time    = curTime - petsc_BaseTime;
1027:     petsc_actions[petsc_numActions].action  = ACTIONEND;
1028:     petsc_actions[petsc_numActions].event   = event;
1029:     petsc_actions[petsc_numActions].classid = eventRegLog->eventInfo[event].classid;
1030:     if (o1) petsc_actions[petsc_numActions].id1 = o1->id;
1031:     else petsc_actions[petsc_numActions].id1 = -1;
1032:     if (o2) petsc_actions[petsc_numActions].id2 = o2->id;
1033:     else petsc_actions[petsc_numActions].id2 = -1;
1034:     if (o3) petsc_actions[petsc_numActions].id3 = o3->id;
1035:     else petsc_actions[petsc_numActions].id3 = -1;
1036:     petsc_actions[petsc_numActions].flops = petsc_TotalFlops;

1038:     PetscCall(PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem));
1039:     PetscCall(PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem));
1040:     petsc_numActions++;
1041:   }
1042:   /* Check for double counting */
1043:   eventPerfLog->eventInfo[event].depth--;
1044:   if (eventPerfLog->eventInfo[event].depth > 0) PetscFunctionReturn(PETSC_SUCCESS);
1045:   else PetscCheck(eventPerfLog->eventInfo[event].depth >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
1046:   /* Log the performance info */
1047:   eventPerfLog->eventInfo[event].count++;
1048:   eventPerfLog->eventInfo[event].time += curTime;
1049:   eventPerfLog->eventInfo[event].flops += petsc_TotalFlops;
1050:   eventPerfLog->eventInfo[event].numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
1051:   eventPerfLog->eventInfo[event].messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
1052:   eventPerfLog->eventInfo[event].numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1053:   PetscFunctionReturn(PETSC_SUCCESS);
1054: }

1056: PetscErrorCode PetscLogEventBeginTrace(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1057: {
1058:   PetscStageLog     stageLog;
1059:   PetscEventRegLog  eventRegLog;
1060:   PetscEventPerfLog eventPerfLog = NULL;
1061:   PetscLogDouble    cur_time;
1062:   PetscMPIInt       rank;
1063:   int               stage;

1065:   PetscFunctionBegin;
1066:   if (!petsc_tracetime) PetscCall(PetscTime(&petsc_tracetime));

1068:   petsc_tracelevel++;
1069:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
1070:   PetscCall(PetscLogGetStageLog(&stageLog));
1071:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
1072:   PetscCall(PetscStageLogGetEventRegLog(stageLog, &eventRegLog));
1073:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog));
1074:   /* Check for double counting */
1075:   eventPerfLog->eventInfo[event].depth++;
1076:   if (eventPerfLog->eventInfo[event].depth > 1) PetscFunctionReturn(PETSC_SUCCESS);
1077:   /* Log performance info */
1078:   PetscCall(PetscTime(&cur_time));
1079:   PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_tracefile, "%s[%d] %g Event begin: %s\n", petsc_tracespace, rank, cur_time - petsc_tracetime, eventRegLog->eventInfo[event].name));
1080:   PetscCall(PetscStrncpy(petsc_tracespace, petsc_traceblanks, 2 * petsc_tracelevel));

1082:   petsc_tracespace[2 * petsc_tracelevel] = 0;

1084:   PetscCall(PetscFFlush(petsc_tracefile));
1085:   PetscFunctionReturn(PETSC_SUCCESS);
1086: }

1088: PetscErrorCode PetscLogEventEndTrace(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
1089: {
1090:   PetscStageLog     stageLog;
1091:   PetscEventRegLog  eventRegLog;
1092:   PetscEventPerfLog eventPerfLog = NULL;
1093:   PetscLogDouble    cur_time;
1094:   int               stage;
1095:   PetscMPIInt       rank;

1097:   PetscFunctionBegin;
1098:   petsc_tracelevel--;
1099:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
1100:   PetscCall(PetscLogGetStageLog(&stageLog));
1101:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
1102:   PetscCall(PetscStageLogGetEventRegLog(stageLog, &eventRegLog));
1103:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog));
1104:   /* Check for double counting */
1105:   eventPerfLog->eventInfo[event].depth--;
1106:   if (eventPerfLog->eventInfo[event].depth > 0) PetscFunctionReturn(PETSC_SUCCESS);
1107:   else PetscCheck(eventPerfLog->eventInfo[event].depth >= 0 && petsc_tracelevel >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");

1109:   /* Log performance info */
1110:   if (petsc_tracelevel) PetscCall(PetscStrncpy(petsc_tracespace, petsc_traceblanks, 2 * petsc_tracelevel));
1111:   petsc_tracespace[2 * petsc_tracelevel] = 0;
1112:   PetscCall(PetscTime(&cur_time));
1113:   PetscCall(PetscFPrintf(PETSC_COMM_SELF, petsc_tracefile, "%s[%d] %g Event end: %s\n", petsc_tracespace, rank, cur_time - petsc_tracetime, eventRegLog->eventInfo[event].name));
1114:   PetscCall(PetscFFlush(petsc_tracefile));
1115:   PetscFunctionReturn(PETSC_SUCCESS);
1116: }

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

1121:   Not Collective

1123:   Input Parameters:
1124: + event - The event id to log
1125: . n     - The dof index, in [0, 8)
1126: - dof   - The number of dofs

1128:   Options Database Key:
1129: . -log_view - Activates log summary

1131:   Level: developer

1133:   Note:
1134:   This is to enable logging of convergence

1136: .seealso: `PetscLogEventSetError()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
1137: @*/
1138: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1139: {
1140:   PetscStageLog     stageLog;
1141:   PetscEventPerfLog eventLog = NULL;
1142:   int               stage;

1144:   PetscFunctionBegin;
1145:   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1146:   PetscCall(PetscLogGetStageLog(&stageLog));
1147:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
1148:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));
1149:   eventLog->eventInfo[event].dof[n] = dof;
1150:   PetscFunctionReturn(PETSC_SUCCESS);
1151: }

1153: /*@C
1154:   PetscLogEventSetError - Set the nth error associated with a numerical problem associated with this event

1156:   Not Collective

1158:   Input Parameters:
1159: + event - The event id to log
1160: . n     - The error index, in [0, 8)
1161: - error - The error

1163:   Options Database Key:
1164: . -log_view - Activates log summary

1166:   Level: developer

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

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

1174: .seealso: `PetscLogEventSetDof()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
1175: @*/
1176: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1177: {
1178:   PetscStageLog     stageLog;
1179:   PetscEventPerfLog eventLog = NULL;
1180:   int               stage;

1182:   PetscFunctionBegin;
1183:   PetscCheck(!(n < 0) && !(n > 7), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Error index %" PetscInt_FMT " is not in [0, 8)", n);
1184:   PetscCall(PetscLogGetStageLog(&stageLog));
1185:   PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
1186:   PetscCall(PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog));
1187:   eventLog->eventInfo[event].errors[n] = error;
1188:   PetscFunctionReturn(PETSC_SUCCESS);
1189: }