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>

 11: PetscBool PetscLogSyncOn = PETSC_FALSE;
 12: PetscBool PetscLogMemory = PETSC_FALSE;
 13: #if defined(PETSC_HAVE_DEVICE)
 14: PetscBool PetscLogGpuTraffic = PETSC_FALSE;
 15: #endif

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

 20: /*@C
 21:   PetscEventRegLogCreate - This creates a `PetscEventRegLog` object.

 23:   Not collective

 25:   Input Parameter:
 26: . eventLog - The `PetscEventRegLog`

 28:   Level: developer

 30:   Note:
 31:   This is a low level routine used by the logging functions in PETSc

 33: .seealso: `PetscEventRegLogDestroy()`, `PetscStageLogCreate()`
 34: @*/
 35: PetscErrorCode PetscEventRegLogCreate(PetscEventRegLog *eventLog)
 36: {
 37:   PetscEventRegLog l;

 39:   PetscNew(&l);
 40:   l->numEvents = 0;
 41:   l->maxEvents = 100;
 42:   PetscMalloc1(l->maxEvents, &l->eventInfo);
 43:   *eventLog = l;
 44:   return 0;
 45: }

 47: /*@C
 48:   PetscEventRegLogDestroy - This destroys a `PetscEventRegLog` object.

 50:   Not collective

 52:   Input Parameter:
 53: . eventLog - The `PetscEventRegLog`

 55:   Level: developer

 57:   Note:
 58:   This is a low level routine used by the logging functions in PETSc

 60: .seealso: `PetscEventRegLogCreate()`
 61: @*/
 62: PetscErrorCode PetscEventRegLogDestroy(PetscEventRegLog eventLog)
 63: {
 64:   int e;

 66:   for (e = 0; e < eventLog->numEvents; e++) PetscFree(eventLog->eventInfo[e].name);
 67:   PetscFree(eventLog->eventInfo);
 68:   PetscFree(eventLog);
 69:   return 0;
 70: }

 72: /*@C
 73:   PetscEventPerfLogCreate - This creates a `PetscEventPerfLog` object.

 75:   Not collective

 77:   Input Parameter:
 78: . eventLog - The `PetscEventPerfLog`

 80:   Level: developer

 82:   Note:
 83:   This is a low level routine used by the logging functions in PETSc

 85: .seealso: `PetscEventPerfLogDestroy()`, `PetscStageLogCreate()`
 86: @*/
 87: PetscErrorCode PetscEventPerfLogCreate(PetscEventPerfLog *eventLog)
 88: {
 89:   PetscEventPerfLog l;

 91:   PetscNew(&l);
 92:   l->numEvents = 0;
 93:   l->maxEvents = 100;
 94:   PetscCalloc1(l->maxEvents, &l->eventInfo);
 95:   *eventLog = l;
 96:   return 0;
 97: }

 99: /*@C
100:   PetscEventPerfLogDestroy - This destroys a `PetscEventPerfLog` object.

102:   Not collective

104:   Input Parameter:
105: . eventLog - The `PetscEventPerfLog`

107:   Level: developer

109:   Note:
110:   This is a low level routine used by the logging functions in PETSc

112: .seealso: `PetscEventPerfLogCreate()`
113: @*/
114: PetscErrorCode PetscEventPerfLogDestroy(PetscEventPerfLog eventLog)
115: {
116:   PetscFree(eventLog->eventInfo);
117:   PetscFree(eventLog);
118:   return 0;
119: }

121: /*------------------------------------------------ General Functions -------------------------------------------------*/
122: /*@C
123:   PetscEventPerfInfoClear - This clears a `PetscEventPerfInfo` object.

125:   Not collective

127:   Input Parameter:
128: . eventInfo - The `PetscEventPerfInfo`

130:   Level: developer

132:   Note:
133:   This is a low level routine used by the logging functions in PETSc

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

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

184:   Not collective

186:   Input Parameter:
187: . eventInfo - The input `PetscEventPerfInfo`

189:   Output Parameter:
190: . outInfo   - The output `PetscEventPerfInfo`

192:   Level: developer

194:   Note:
195:   This is a low level routine used by the logging functions in PETSc

197: .seealso: `PetscEventPerfInfoClear()`
198: @*/
199: PetscErrorCode PetscEventPerfInfoCopy(PetscEventPerfInfo *eventInfo, PetscEventPerfInfo *outInfo)
200: {
201:   outInfo->id      = eventInfo->id;
202:   outInfo->active  = eventInfo->active;
203:   outInfo->visible = eventInfo->visible;
204:   return 0;
205: }

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

210:   Not collective

212:   Input Parameters:
213: + eventLog - The `PetscEventPerfLog`
214: - size     - The size

216:   Level: developer

218:   Note:
219:   This is a low level routine used by the logging functions in PETSc

221: .seealso: `PetscEventPerfLogCreate()`
222: @*/
223: PetscErrorCode PetscEventPerfLogEnsureSize(PetscEventPerfLog eventLog, int size)
224: {
225:   PetscEventPerfInfo *eventInfo;

227:   while (size > eventLog->maxEvents) {
228:     PetscCalloc1(eventLog->maxEvents * 2, &eventInfo);
229:     PetscArraycpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents);
230:     PetscFree(eventLog->eventInfo);
231:     eventLog->eventInfo = eventInfo;
232:     eventLog->maxEvents *= 2;
233:   }
234:   while (eventLog->numEvents < size) PetscEventPerfInfoClear(&eventLog->eventInfo[eventLog->numEvents++]);
235:   return 0;
236: }

238: #if defined(PETSC_HAVE_MPE)
239:   #include <mpe.h>
240: PETSC_INTERN PetscErrorCode PetscLogMPEGetRGBColor(const char *[]);
241: PetscErrorCode              PetscLogEventBeginMPE(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
242: {
243:   MPE_Log_event(petsc_stageLog->eventLog->eventInfo[event].mpe_id_begin, 0, NULL);
244:   return 0;
245: }

247: PetscErrorCode PetscLogEventEndMPE(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
248: {
249:   MPE_Log_event(petsc_stageLog->eventLog->eventInfo[event].mpe_id_end, 0, NULL);
250:   return 0;
251: }
252: #endif

254: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
255: /*@C
256:   PetscEventRegLogRegister - Registers an event for logging operations in an application code.

258:   Not Collective

260:   Input Parameters:
261: + eventLog - The `PetscEventLog`
262: . ename    - The name associated with the event
263: - classid   - The classid associated to the class for this event

265:   Output Parameter:
266: . event    - The event

268:   Example of Usage:
269: .vb
270:       int USER_EVENT;
271:       PetscLogDouble user_event_flops;
272:       PetscLogEventRegister("User event name",0,&USER_EVENT);
273:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
274:          [code segment to monitor]
275:          PetscLogFlops(user_event_flops);
276:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
277: .ve

279:   Notes:
280:   PETSc can gather data for use with the utilities Jumpshot
281:   (part of the MPICH distribution).  If PETSc has been compiled
282:   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
283:   MPICH), the user can employ another command line option, -log_mpe,
284:   to create a logfile, "mpe.log", which can be visualized
285:   Jumpshot.

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

289:   Level: developer

291: .seealso: `PetscLogEventBegin()`, `PetscLogEventEnd()`, `PetscLogFlops()`,
292:           `PetscEventLogActivate()`, `PetscEventLogDeactivate()`
293: @*/
294: PetscErrorCode PetscEventRegLogRegister(PetscEventRegLog eventLog, const char ename[], PetscClassId classid, PetscLogEvent *event)
295: {
296:   PetscEventRegInfo *eventInfo;
297:   char              *str;
298:   int                e;

302:   /* Should check classid I think */
303:   e = eventLog->numEvents++;
304:   if (eventLog->numEvents > eventLog->maxEvents) {
305:     PetscCalloc1(eventLog->maxEvents * 2, &eventInfo);
306:     PetscArraycpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents);
307:     PetscFree(eventLog->eventInfo);
308:     eventLog->eventInfo = eventInfo;
309:     eventLog->maxEvents *= 2;
310:   }
311:   PetscStrallocpy(ename, &str);

313:   eventLog->eventInfo[e].name       = str;
314:   eventLog->eventInfo[e].classid    = classid;
315:   eventLog->eventInfo[e].collective = PETSC_TRUE;
316: #if defined(PETSC_HAVE_MPE)
317:   if (PetscLogPLB == PetscLogEventBeginMPE) {
318:     const char *color;
319:     PetscMPIInt rank;
320:     int         beginID, endID;

322:     beginID = MPE_Log_get_event_number();
323:     endID   = MPE_Log_get_event_number();

325:     eventLog->eventInfo[e].mpe_id_begin = beginID;
326:     eventLog->eventInfo[e].mpe_id_end   = endID;

328:     MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
329:     if (rank == 0) {
330:       PetscLogMPEGetRGBColor(&color);
331:       MPE_Describe_state(beginID, endID, str, (char *)color);
332:     }
333:   }
334: #endif
335:   *event = e;
336:   return 0;
337: }

339: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
340: /*@C
341:   PetscEventPerfLogActivate - Indicates that a particular event should be logged.

343:   Not Collective

345:   Input Parameters:
346: + eventLog - The `PetscEventPerfLog`
347: - event    - The event

349:    Usage:
350: .vb
351:       PetscEventPerfLogDeactivate(log, VEC_SetValues);
352:         [code where you do not want to log VecSetValues()]
353:       PetscEventPerfLogActivate(log, VEC_SetValues);
354:         [code where you do want to log VecSetValues()]
355: .ve

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

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

363:   Level: developer

365: .seealso: `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogDeactivatePop()`, `PetscEventPerfLogDeactivatePush()`
366: @*/
367: PetscErrorCode PetscEventPerfLogActivate(PetscEventPerfLog eventLog, PetscLogEvent event)
368: {
369:   eventLog->eventInfo[event].active = PETSC_TRUE;
370:   return 0;
371: }

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

376:   Not Collective

378:   Input Parameters:
379: + eventLog - The `PetscEventPerfLog`
380: - event    - The event

382:    Usage:
383: .vb
384:       PetscEventPerfLogDeactivate(log, VEC_SetValues);
385:         [code where you do not want to log VecSetValues()]
386:       PetscEventPerfLogActivate(log, VEC_SetValues);
387:         [code where you do want to log VecSetValues()]
388: .ve

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

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

396:   Level: developer

398: .seealso: `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivatePop()`, `PetscEventPerfLogDeactivatePush()`
399: @*/
400: PetscErrorCode PetscEventPerfLogDeactivate(PetscEventPerfLog eventLog, PetscLogEvent event)
401: {
402:   eventLog->eventInfo[event].active = PETSC_FALSE;
403:   return 0;
404: }

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

409:   Not Collective

411:   Input Parameters:
412: + eventLog - The `PetscEventPerfLog`
413: - event    - The event

415:    Usage:
416: .vb
417:       PetscEventPerfLogDeactivatePush(log, VEC_SetValues);
418:         [code where you do not want to log VecSetValues()]
419:       PetscEventPerfLogDeactivatePop(log, VEC_SetValues);
420:         [code where you do want to log VecSetValues()]
421: .ve

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

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

429:   Level: developer

431: .seealso: `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivatePop()`
432: @*/
433: PetscErrorCode PetscEventPerfLogDeactivatePush(PetscEventPerfLog eventLog, PetscLogEvent event)
434: {
435:   eventLog->eventInfo[event].depth++;
436:   return 0;
437: }

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

442:   Not Collective

444:   Input Parameters:
445: + eventLog - The `PetscEventPerfLog`
446: - event    - The event

448:    Usage:
449: .vb
450:       PetscEventPerfLogDeactivatePush(log, VEC_SetValues);
451:         [code where you do not want to log VecSetValues()]
452:       PetscEventPerfLogDeactivatePop(log, VEC_SetValues);
453:         [code where you do want to log VecSetValues()]
454: .ve

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

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

462:   Level: developer

464: .seealso: `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivatePush()`
465: @*/
466: PetscErrorCode PetscEventPerfLogDeactivatePop(PetscEventPerfLog eventLog, PetscLogEvent event)
467: {
468:   eventLog->eventInfo[event].depth--;
469:   return 0;
470: }

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

475:   Not Collective

477:   Input Parameters:
478: + eventLog    - The `PetscEventPerfLog`
479: . eventRegLog - The `PetscEventRegLog`
480: - classid      - The class id, for example `MAT_CLASSID`, `SNES_CLASSID`

482:   Level: developer

484:   Note:
485:   This is a low level routine used by the logging functions in PETSc

487: .seealso: `PetscEventPerfLogDeactivateClass()`, `PetscEventPerfLogActivate()`, `PetscEventPerfLogDeactivate()`
488: @*/
489: PetscErrorCode PetscEventPerfLogActivateClass(PetscEventPerfLog eventLog, PetscEventRegLog eventRegLog, PetscClassId classid)
490: {
491:   int e;

493:   for (e = 0; e < eventLog->numEvents; e++) {
494:     int c = eventRegLog->eventInfo[e].classid;
495:     if (c == classid) eventLog->eventInfo[e].active = PETSC_TRUE;
496:   }
497:   return 0;
498: }

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

503:   Not Collective

505:   Input Parameters:
506: + eventLog    - The `PetscEventPerfLog`
507: . eventRegLog - The `PetscEventRegLog`
508: - classid - The class id, for example `MAT_CLASSID`, `SNES_CLASSID`

510:   Level: developer

512:   Note:
513:   This is a low level routine used by the logging functions in PETSc

515: .seealso: `PetscEventPerfLogDeactivateClass()`, `PetscEventPerfLogDeactivate()`, `PetscEventPerfLogActivate()`
516: @*/
517: PetscErrorCode PetscEventPerfLogDeactivateClass(PetscEventPerfLog eventLog, PetscEventRegLog eventRegLog, PetscClassId classid)
518: {
519:   int e;

521:   for (e = 0; e < eventLog->numEvents; e++) {
522:     int c = eventRegLog->eventInfo[e].classid;
523:     if (c == classid) eventLog->eventInfo[e].active = PETSC_FALSE;
524:   }
525:   return 0;
526: }

528: /*------------------------------------------------ Query Functions --------------------------------------------------*/
529: /*@C
530:   PetscEventRegLogGetEvent - This function returns the event id given the event name.

532:   Not Collective

534:   Input Parameters:
535: + eventLog - The `PetscEventRegLog`
536: - name     - The stage name

538:   Output Parameter:
539: . event    - The event id, or -1 if not found

541:   Level: developer

543:   Note:
544:   This is a low level routine used by the logging functions in PETSc

546: .seealso: `PetscEventRegLogRegister()`
547: @*/
548: PetscErrorCode PetscEventRegLogGetEvent(PetscEventRegLog eventLog, const char name[], PetscLogEvent *event)
549: {
550:   PetscBool match;
551:   int       e;

555:   *event = -1;
556:   for (e = 0; e < eventLog->numEvents; e++) {
557:     PetscStrcasecmp(eventLog->eventInfo[e].name, name, &match);
558:     if (match) {
559:       *event = e;
560:       break;
561:     }
562:   }
563:   return 0;
564: }

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

569:   Not Collective

571:   Input Parameters:
572: + eventLog  - The `PetscEventPerfLog`
573: . event     - The event to log
574: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise `PETSC_FALSE` (default is `PETSC_TRUE`)

576:   Database Options:
577: . -log_view - Activates log summary

579:   Level: developer

581:   Note:
582:   This is a low level routine used by the logging functions in PETSc

584: .seealso: `PetscEventPerfLogGetVisible()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
585: @*/
586: PetscErrorCode PetscEventPerfLogSetVisible(PetscEventPerfLog eventLog, PetscLogEvent event, PetscBool isVisible)
587: {
588:   eventLog->eventInfo[event].visible = isVisible;
589:   return 0;
590: }

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

595:   Not Collective

597:   Input Parameters:
598: + eventLog  - The `PetscEventPerfLog`
599: - event     - The event id to log

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

604:   Database Options:
605: . -log_view - Activates log summary

607:   Level: developer

609:   Note:
610:   This is a low level routine used by the logging functions in PETSc

612: .seealso: `PetscEventPerfLogSetVisible()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
613: @*/
614: PetscErrorCode PetscEventPerfLogGetVisible(PetscEventPerfLog eventLog, PetscLogEvent event, PetscBool *isVisible)
615: {
617:   *isVisible = eventLog->eventInfo[event].visible;
618:   return 0;
619: }

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

624:   Input Parameters:
625: + stage - The stage number or `PETSC_DETERMINE` for the current stage
626: - event - The event number

628:   Output Parameters:
629: . info - This structure is filled with the performance information

631:   Level: Intermediate

633:   Note:
634:   This is a low level routine used by the logging functions in PETSc

636: .seealso: `PetscLogEventGetFlops()`
637: @*/
638: PetscErrorCode PetscLogEventGetPerfInfo(int stage, PetscLogEvent event, PetscEventPerfInfo *info)
639: {
640:   PetscStageLog     stageLog;
641:   PetscEventPerfLog eventLog = NULL;

645:   PetscLogGetStageLog(&stageLog);
646:   if (stage < 0) PetscStageLogGetCurrent(stageLog, &stage);
647:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
648:   *info = eventLog->eventInfo[event];
649:   return 0;
650: }

652: PetscErrorCode PetscLogEventGetFlops(PetscLogEvent event, PetscLogDouble *flops)
653: {
654:   PetscStageLog     stageLog;
655:   PetscEventPerfLog eventLog = NULL;
656:   int               stage;

659:   PetscLogGetStageLog(&stageLog);
660:   PetscStageLogGetCurrent(stageLog, &stage);
661:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
662:   *flops = eventLog->eventInfo[event].flops;
663:   return 0;
664: }

666: PetscErrorCode PetscLogEventZeroFlops(PetscLogEvent event)
667: {
668:   PetscStageLog     stageLog;
669:   PetscEventPerfLog eventLog = NULL;
670:   int               stage;

672:   PetscLogGetStageLog(&stageLog);
673:   PetscStageLogGetCurrent(stageLog, &stage);
674:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);

676:   eventLog->eventInfo[event].flops    = 0.0;
677:   eventLog->eventInfo[event].flops2   = 0.0;
678:   eventLog->eventInfo[event].flopsTmp = 0.0;
679:   return 0;
680: }

682: PetscErrorCode PetscLogEventSynchronize(PetscLogEvent event, MPI_Comm comm)
683: {
684:   PetscStageLog     stageLog;
685:   PetscEventRegLog  eventRegLog;
686:   PetscEventPerfLog eventLog = NULL;
687:   int               stage;
688:   PetscLogDouble    time = 0.0;

690:   if (!PetscLogSyncOn || comm == MPI_COMM_NULL) return 0;
691:   PetscLogGetStageLog(&stageLog);
692:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
693:   if (!eventRegLog->eventInfo[event].collective) return 0;
694:   PetscStageLogGetCurrent(stageLog, &stage);
695:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
696:   if (eventLog->eventInfo[event].depth > 0) return 0;

698:   PetscTimeSubtract(&time);
699:   MPI_Barrier(comm);
700:   PetscTimeAdd(&time);
701:   eventLog->eventInfo[event].syncTime += time;
702:   return 0;
703: }

705: #if defined(PETSC_HAVE_CUDA)
706:   #include <nvToolsExt.h>
707: #endif

709: PetscErrorCode PetscLogEventBeginDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
710: {
711:   PetscStageLog     stageLog;
712:   PetscEventPerfLog eventLog = NULL;
713:   int               stage;

715:   PetscLogGetStageLog(&stageLog);
716:   PetscStageLogGetCurrent(stageLog, &stage);
717:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
718:   /* Synchronization */
719:   PetscLogEventSynchronize(event, PetscObjectComm(o1));
720:   /* Check for double counting */
721:   eventLog->eventInfo[event].depth++;
722:   if (eventLog->eventInfo[event].depth > 1) return 0;
723: #if defined(PETSC_HAVE_CUDA)
724:   if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) {
725:     PetscEventRegLog eventRegLog;
726:     PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
727:     nvtxRangePushA(eventRegLog->eventInfo[event].name);
728:   }
729: #endif
730:   /* Log the performance info */
731:   eventLog->eventInfo[event].count++;
732:   eventLog->eventInfo[event].timeTmp = 0.0;
733:   PetscTimeSubtract(&eventLog->eventInfo[event].timeTmp);
734:   eventLog->eventInfo[event].flopsTmp = -petsc_TotalFlops;
735:   eventLog->eventInfo[event].numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
736:   eventLog->eventInfo[event].messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
737:   eventLog->eventInfo[event].numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
738:   if (PetscLogMemory) {
739:     PetscLogDouble usage;
740:     PetscMemoryGetCurrentUsage(&usage);
741:     eventLog->eventInfo[event].memIncrease -= usage;
742:     PetscMallocGetCurrentUsage(&usage);
743:     eventLog->eventInfo[event].mallocSpace -= usage;
744:     PetscMallocGetMaximumUsage(&usage);
745:     eventLog->eventInfo[event].mallocIncrease -= usage;
746:     PetscMallocPushMaximumUsage((int)event);
747:   }
748: #if defined(PETSC_HAVE_DEVICE)
749:   eventLog->eventInfo[event].CpuToGpuCount -= petsc_ctog_ct;
750:   eventLog->eventInfo[event].GpuToCpuCount -= petsc_gtoc_ct;
751:   eventLog->eventInfo[event].CpuToGpuSize -= petsc_ctog_sz;
752:   eventLog->eventInfo[event].GpuToCpuSize -= petsc_gtoc_sz;
753:   eventLog->eventInfo[event].GpuFlops -= petsc_gflops;
754:   eventLog->eventInfo[event].GpuTime -= petsc_gtime;
755: #endif
756:   return 0;
757: }

759: PetscErrorCode PetscLogEventEndDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
760: {
761:   PetscStageLog     stageLog;
762:   PetscEventPerfLog eventLog = NULL;
763:   int               stage;

765:   PetscLogGetStageLog(&stageLog);
766:   PetscStageLogGetCurrent(stageLog, &stage);
767:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
768:   /* Check for double counting */
769:   eventLog->eventInfo[event].depth--;
770:   if (eventLog->eventInfo[event].depth > 0) return 0;
772:   /* Log performance info */
773:   PetscTimeAdd(&eventLog->eventInfo[event].timeTmp);
774:   eventLog->eventInfo[event].time += eventLog->eventInfo[event].timeTmp;
775:   eventLog->eventInfo[event].time2 += eventLog->eventInfo[event].timeTmp * eventLog->eventInfo[event].timeTmp;
776:   eventLog->eventInfo[event].flopsTmp += petsc_TotalFlops;
777:   eventLog->eventInfo[event].flops += eventLog->eventInfo[event].flopsTmp;
778:   eventLog->eventInfo[event].flops2 += eventLog->eventInfo[event].flopsTmp * eventLog->eventInfo[event].flopsTmp;
779:   eventLog->eventInfo[event].numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
780:   eventLog->eventInfo[event].messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
781:   eventLog->eventInfo[event].numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
782:   if (PetscLogMemory) {
783:     PetscLogDouble usage, musage;
784:     PetscMemoryGetCurrentUsage(&usage);   /* the comments below match the column labels printed in PetscLogView_Default() */
785:     eventLog->eventInfo[event].memIncrease += usage; /* RMI */
786:     PetscMallocGetCurrentUsage(&usage);
787:     eventLog->eventInfo[event].mallocSpace += usage; /* Malloc */
788:     PetscMallocPopMaximumUsage((int)event, &musage);
789:     eventLog->eventInfo[event].mallocIncreaseEvent = PetscMax(musage - usage, eventLog->eventInfo[event].mallocIncreaseEvent); /* EMalloc */
790:     PetscMallocGetMaximumUsage(&usage);
791:     eventLog->eventInfo[event].mallocIncrease += usage; /* MMalloc */
792:   }
793: #if defined(PETSC_HAVE_DEVICE)
794:   eventLog->eventInfo[event].CpuToGpuCount += petsc_ctog_ct;
795:   eventLog->eventInfo[event].GpuToCpuCount += petsc_gtoc_ct;
796:   eventLog->eventInfo[event].CpuToGpuSize += petsc_ctog_sz;
797:   eventLog->eventInfo[event].GpuToCpuSize += petsc_gtoc_sz;
798:   eventLog->eventInfo[event].GpuFlops += petsc_gflops;
799:   eventLog->eventInfo[event].GpuTime += petsc_gtime;
800: #endif
801: #if defined(PETSC_HAVE_CUDA)
802:   if (PetscDeviceInitialized(PETSC_DEVICE_CUDA)) nvtxRangePop();
803: #endif
804:   return 0;
805: }

807: PetscErrorCode PetscLogEventBeginComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
808: {
809:   PetscStageLog     stageLog;
810:   PetscEventRegLog  eventRegLog;
811:   PetscEventPerfLog eventPerfLog = NULL;
812:   Action           *tmpAction;
813:   PetscLogDouble    start, end;
814:   PetscLogDouble    curTime;
815:   int               stage;

817:   /* Dynamically enlarge logging structures */
818:   if (petsc_numActions >= petsc_maxActions) {
819:     PetscTime(&start);
820:     PetscCalloc1(petsc_maxActions * 2, &tmpAction);
821:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
822:     PetscFree(petsc_actions);

824:     petsc_actions = tmpAction;
825:     petsc_maxActions *= 2;
826:     PetscTime(&end);
827:     petsc_BaseTime += (end - start);
828:   }
829:   /* Record the event */
830:   PetscLogGetStageLog(&stageLog);
831:   PetscStageLogGetCurrent(stageLog, &stage);
832:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
833:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
834:   PetscTime(&curTime);
835:   if (petsc_logActions) {
836:     petsc_actions[petsc_numActions].time    = curTime - petsc_BaseTime;
837:     petsc_actions[petsc_numActions].action  = ACTIONBEGIN;
838:     petsc_actions[petsc_numActions].event   = event;
839:     petsc_actions[petsc_numActions].classid = eventRegLog->eventInfo[event].classid;
840:     if (o1) petsc_actions[petsc_numActions].id1 = o1->id;
841:     else petsc_actions[petsc_numActions].id1 = -1;
842:     if (o2) petsc_actions[petsc_numActions].id2 = o2->id;
843:     else petsc_actions[petsc_numActions].id2 = -1;
844:     if (o3) petsc_actions[petsc_numActions].id3 = o3->id;
845:     else petsc_actions[petsc_numActions].id3 = -1;
846:     petsc_actions[petsc_numActions].flops = petsc_TotalFlops;

848:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
849:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
850:     petsc_numActions++;
851:   }
852:   /* Check for double counting */
853:   eventPerfLog->eventInfo[event].depth++;
854:   if (eventPerfLog->eventInfo[event].depth > 1) return 0;
855:   /* Log the performance info */
856:   eventPerfLog->eventInfo[event].count++;
857:   eventPerfLog->eventInfo[event].time -= curTime;
858:   eventPerfLog->eventInfo[event].flops -= petsc_TotalFlops;
859:   eventPerfLog->eventInfo[event].numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
860:   eventPerfLog->eventInfo[event].messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
861:   eventPerfLog->eventInfo[event].numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
862:   return 0;
863: }

865: PetscErrorCode PetscLogEventEndComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
866: {
867:   PetscStageLog     stageLog;
868:   PetscEventRegLog  eventRegLog;
869:   PetscEventPerfLog eventPerfLog = NULL;
870:   Action           *tmpAction;
871:   PetscLogDouble    start, end;
872:   PetscLogDouble    curTime;
873:   int               stage;

875:   /* Dynamically enlarge logging structures */
876:   if (petsc_numActions >= petsc_maxActions) {
877:     PetscTime(&start);
878:     PetscCalloc1(petsc_maxActions * 2, &tmpAction);
879:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
880:     PetscFree(petsc_actions);

882:     petsc_actions = tmpAction;
883:     petsc_maxActions *= 2;
884:     PetscTime(&end);
885:     petsc_BaseTime += (end - start);
886:   }
887:   /* Record the event */
888:   PetscLogGetStageLog(&stageLog);
889:   PetscStageLogGetCurrent(stageLog, &stage);
890:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
891:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
892:   PetscTime(&curTime);
893:   if (petsc_logActions) {
894:     petsc_actions[petsc_numActions].time    = curTime - petsc_BaseTime;
895:     petsc_actions[petsc_numActions].action  = ACTIONEND;
896:     petsc_actions[petsc_numActions].event   = event;
897:     petsc_actions[petsc_numActions].classid = eventRegLog->eventInfo[event].classid;
898:     if (o1) petsc_actions[petsc_numActions].id1 = o1->id;
899:     else petsc_actions[petsc_numActions].id1 = -1;
900:     if (o2) petsc_actions[petsc_numActions].id2 = o2->id;
901:     else petsc_actions[petsc_numActions].id2 = -1;
902:     if (o3) petsc_actions[petsc_numActions].id3 = o3->id;
903:     else petsc_actions[petsc_numActions].id3 = -1;
904:     petsc_actions[petsc_numActions].flops = petsc_TotalFlops;

906:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
907:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
908:     petsc_numActions++;
909:   }
910:   /* Check for double counting */
911:   eventPerfLog->eventInfo[event].depth--;
912:   if (eventPerfLog->eventInfo[event].depth > 0) return 0;
914:   /* Log the performance info */
915:   eventPerfLog->eventInfo[event].count++;
916:   eventPerfLog->eventInfo[event].time += curTime;
917:   eventPerfLog->eventInfo[event].flops += petsc_TotalFlops;
918:   eventPerfLog->eventInfo[event].numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
919:   eventPerfLog->eventInfo[event].messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
920:   eventPerfLog->eventInfo[event].numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
921:   return 0;
922: }

924: PetscErrorCode PetscLogEventBeginTrace(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
925: {
926:   PetscStageLog     stageLog;
927:   PetscEventRegLog  eventRegLog;
928:   PetscEventPerfLog eventPerfLog = NULL;
929:   PetscLogDouble    cur_time;
930:   PetscMPIInt       rank;
931:   int               stage, err;

933:   if (!petsc_tracetime) PetscTime(&petsc_tracetime);

935:   petsc_tracelevel++;
936:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
937:   PetscLogGetStageLog(&stageLog);
938:   PetscStageLogGetCurrent(stageLog, &stage);
939:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
940:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
941:   /* Check for double counting */
942:   eventPerfLog->eventInfo[event].depth++;
943:   if (eventPerfLog->eventInfo[event].depth > 1) return 0;
944:   /* Log performance info */
945:   PetscTime(&cur_time);
946:   PetscFPrintf(PETSC_COMM_SELF, petsc_tracefile, "%s[%d] %g Event begin: %s\n", petsc_tracespace, rank, cur_time - petsc_tracetime, eventRegLog->eventInfo[event].name);
947:   PetscStrncpy(petsc_tracespace, petsc_traceblanks, 2 * petsc_tracelevel);

949:   petsc_tracespace[2 * petsc_tracelevel] = 0;

951:   err = fflush(petsc_tracefile);
953:   return 0;
954: }

956: PetscErrorCode PetscLogEventEndTrace(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
957: {
958:   PetscStageLog     stageLog;
959:   PetscEventRegLog  eventRegLog;
960:   PetscEventPerfLog eventPerfLog = NULL;
961:   PetscLogDouble    cur_time;
962:   int               stage, err;
963:   PetscMPIInt       rank;

965:   petsc_tracelevel--;
966:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
967:   PetscLogGetStageLog(&stageLog);
968:   PetscStageLogGetCurrent(stageLog, &stage);
969:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
970:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
971:   /* Check for double counting */
972:   eventPerfLog->eventInfo[event].depth--;
973:   if (eventPerfLog->eventInfo[event].depth > 0) return 0;

976:   /* Log performance info */
977:   if (petsc_tracelevel) PetscStrncpy(petsc_tracespace, petsc_traceblanks, 2 * petsc_tracelevel);
978:   petsc_tracespace[2 * petsc_tracelevel] = 0;
979:   PetscTime(&cur_time);
980:   PetscFPrintf(PETSC_COMM_SELF, petsc_tracefile, "%s[%d] %g Event end: %s\n", petsc_tracespace, rank, cur_time - petsc_tracetime, eventRegLog->eventInfo[event].name);
981:   err = fflush(petsc_tracefile);
983:   return 0;
984: }

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

989:   Not Collective

991:   Input Parameters:
992: + event - The event id to log
993: . n     - The dof index, in [0, 8)
994: - dof   - The number of dofs

996:   Database Options:
997: . -log_view - Activates log summary

999:   Note:
1000:   This is to enable logging of convergence

1002:   Level: developer

1004: .seealso: `PetscLogEventSetError()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
1005: @*/
1006: PetscErrorCode PetscLogEventSetDof(PetscLogEvent event, PetscInt n, PetscLogDouble dof)
1007: {
1008:   PetscStageLog     stageLog;
1009:   PetscEventPerfLog eventLog = NULL;
1010:   int               stage;

1013:   PetscLogGetStageLog(&stageLog);
1014:   PetscStageLogGetCurrent(stageLog, &stage);
1015:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
1016:   eventLog->eventInfo[event].dof[n] = dof;
1017:   return 0;
1018: }

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

1023:   Not Collective

1025:   Input Parameters:
1026: + event - The event id to log
1027: . n     - The error index, in [0, 8)
1028: - error - The error

1030:   Database Options:
1031: . -log_view - Activates log summary

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

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

1039:   Level: developer

1041: .seealso: `PetscLogEventSetDof()`, `PetscEventRegLogRegister()`, `PetscStageLogGetEventLog()`
1042: @*/
1043: PetscErrorCode PetscLogEventSetError(PetscLogEvent event, PetscInt n, PetscLogDouble error)
1044: {
1045:   PetscStageLog     stageLog;
1046:   PetscEventPerfLog eventLog = NULL;
1047:   int               stage;

1050:   PetscLogGetStageLog(&stageLog);
1051:   PetscStageLogGetCurrent(stageLog, &stage);
1052:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
1053:   eventLog->eventInfo[event].errors[n] = error;
1054:   return 0;
1055: }