Actual source code: eventLog.c

  1: #define PETSC_DLL

 3:  #include ../src/sys/plog/plog.h

  5: /* Variables for the tracing logger */

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

 17: /*@C
 18:   EventRegLogCreate - This creates a EventRegLog object.

 20:   Not collective

 22:   Input Parameter:
 23: . eventLog - The EventRegLog

 25:   Level: beginner

 27: .keywords: log, event, create
 28: .seealso: EventRegLogDestroy(), StageLogCreate()
 29: @*/
 30: PetscErrorCode EventRegLogCreate(EventRegLog *eventLog)
 31: {
 32:   EventRegLog l;

 36:   PetscNew(struct _n_EventRegLog, &l);
 37:   l->numEvents   = 0;
 38:   l->maxEvents   = 100;
 39:   PetscMalloc(l->maxEvents * sizeof(EventRegInfo), &l->eventInfo);
 40:   *eventLog = l;
 41:   return(0);
 42: }

 46: /*@C
 47:   EventRegLogDestroy - This destroys a EventRegLog object.

 49:   Not collective

 51:   Input Paramter:
 52: . eventLog - The EventRegLog

 54:   Level: beginner

 56: .keywords: log, event, destroy
 57: .seealso: EventRegLogCreate()
 58: @*/
 59: PetscErrorCode EventRegLogDestroy(EventRegLog eventLog)
 60: {
 61:   int e;

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

 75: /*@C
 76:   EventPerfLogCreate - This creates a EventPerfLog object.

 78:   Not collective

 80:   Input Parameter:
 81: . eventLog - The EventPerfLog

 83:   Level: beginner

 85: .keywords: log, event, create
 86: .seealso: EventPerfLogDestroy(), StageLogCreate()
 87: @*/
 88: PetscErrorCode EventPerfLogCreate(EventPerfLog *eventLog)
 89: {
 90:   EventPerfLog l;

 94:   PetscNew(struct _n_EventPerfLog, &l);
 95:   l->numEvents   = 0;
 96:   l->maxEvents   = 100;
 97:   PetscMalloc(l->maxEvents * sizeof(EventPerfInfo), &l->eventInfo);
 98:   *eventLog = l;
 99:   return(0);
100: }

104: /*@C
105:   EventPerfLogDestroy - This destroys a EventPerfLog object.

107:   Not collective

109:   Input Paramter:
110: . eventLog - The EventPerfLog

112:   Level: beginner

114: .keywords: log, event, destroy
115: .seealso: EventPerfLogCreate()
116: @*/
117: PetscErrorCode EventPerfLogDestroy(EventPerfLog eventLog)
118: {

122:   PetscFree(eventLog->eventInfo);
123:   PetscFree(eventLog);
124:   return(0);
125: }

127: /*------------------------------------------------ General Functions -------------------------------------------------*/
130: /*@C
131:   EventPerfInfoClear - This clears a EventPerfInfo object.

133:   Not collective

135:   Input Paramter:
136: . eventInfo - The EventPerfInfo

138:   Level: beginner

140: .keywords: log, event, destroy
141: .seealso: EventPerfLogCreate()
142: @*/
143: PetscErrorCode EventPerfInfoClear(EventPerfInfo *eventInfo)
144: {
146:   eventInfo->id            = -1;
147:   eventInfo->active        = PETSC_TRUE;
148:   eventInfo->visible       = PETSC_TRUE;
149:   eventInfo->depth         = 0;
150:   eventInfo->count         = 0;
151:   eventInfo->flops         = 0.0;
152:   eventInfo->time          = 0.0;
153:   eventInfo->numMessages   = 0.0;
154:   eventInfo->messageLength = 0.0;
155:   eventInfo->numReductions = 0.0;
156:   return(0);
157: }

161: /*@C
162:   EventPerfInfoCopy - Copy the activity and visibility data in eventInfo to outInfo

164:   Not collective

166:   Input Paramter:
167: . eventInfo - The input EventPerfInfo

169:   Output Paramter:
170: . outInfo   - The output EventPerfInfo

172:   Level: beginner

174: .keywords: log, event, copy
175: .seealso: EventPerfInfoClear()
176: @*/
177: PetscErrorCode EventPerfInfoCopy(EventPerfInfo *eventInfo, EventPerfInfo *outInfo)
178: {
180:   outInfo->id      = eventInfo->id;
181:   outInfo->active  = eventInfo->active;
182:   outInfo->visible = eventInfo->visible;
183:   return(0);
184: }

188: /*@C
189:   EventPerfLogEnsureSize - This ensures that a EventPerfLog is at least of a certain size.

191:   Not collective

193:   Input Paramters:
194: + eventLog - The EventPerfLog
195: - size     - The size

197:   Level: intermediate

199: .keywords: log, event, size, ensure
200: .seealso: EventPerfLogCreate()
201: @*/
202: PetscErrorCode EventPerfLogEnsureSize(EventPerfLog eventLog, int size)
203: {
204:   EventPerfInfo *eventInfo;

208:   while(size > eventLog->maxEvents) {
209:     PetscMalloc(eventLog->maxEvents*2 * sizeof(EventPerfInfo), &eventInfo);
210:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventPerfInfo));
211:     PetscFree(eventLog->eventInfo);
212:     eventLog->eventInfo  = eventInfo;
213:     eventLog->maxEvents *= 2;
214:   }
215:   while(eventLog->numEvents < size) {
216:     EventPerfInfoClear(&eventLog->eventInfo[eventLog->numEvents++]);
217:   }
218:   return(0);
219: }

221: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
224: /*@C
225:   EventRegLogRegister - Registers an event for logging operations in an application code.

227:   Not Collective

229:   Input Parameters:
230: + eventLog - The EventLog
231: . ename    - The name associated with the event
232: - cookie   - The cookie associated to the class for this event

234:   Output Parameter:
235: . event    - The event

237:   Example of Usage:
238: .vb
239:       int USER_EVENT;
240:       PetscLogDouble user_event_flops;
241:       PetscLogEventRegister("User event name",0,&USER_EVENT);
242:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
243:          [code segment to monitor]
244:          PetscLogFlops(user_event_flops);
245:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
246: .ve

248:   Notes: 
249:   PETSc automatically logs library events if the code has been
250:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
251:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
252:   intended for logging user events to supplement this PETSc
253:   information. 

255:   PETSc can gather data for use with the utilities Upshot/Nupshot
256:   (part of the MPICH distribution).  If PETSc has been compiled
257:   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
258:   MPICH), the user can employ another command line option, -log_mpe,
259:   to create a logfile, "mpe.log", which can be visualized
260:   Upshot/Nupshot.

262:   Level: intermediate

264: .keywords: log, event, register
265: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
266:           EventLogActivate(), EventLogDeactivate()
267: @*/
268: PetscErrorCode EventRegLogRegister(EventRegLog eventLog, const char ename[], PetscCookie cookie, PetscLogEvent *event)
269: {
270:   EventRegInfo *eventInfo;
271:   char         *str;
272:   int           e;

278:   /* Should check cookie I think */
279:   e = eventLog->numEvents++;
280:   if (eventLog->numEvents > eventLog->maxEvents) {
281:     PetscMalloc(eventLog->maxEvents*2 * sizeof(EventRegInfo), &eventInfo);
282:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventRegInfo));
283:     PetscFree(eventLog->eventInfo);
284:     eventLog->eventInfo  = eventInfo;
285:     eventLog->maxEvents *= 2;
286:   }
287:   PetscStrallocpy(ename, &str);
288:   eventLog->eventInfo[e].name   = str;
289:   eventLog->eventInfo[e].cookie = cookie;
290: #if defined(PETSC_HAVE_MPE)
291:   if (UseMPE) {
292:     const char  *color;
293:     PetscMPIInt rank;
294:     int         beginID, endID;

296:     beginID = MPE_Log_get_event_number();
297:     endID   = MPE_Log_get_event_number();
298:     eventLog->eventInfo[e].mpe_id_begin = beginID;
299:     eventLog->eventInfo[e].mpe_id_end   = endID;
300:     MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
301:     if (!rank) {
302:       PetscLogGetRGBColor(&color);
303:       MPE_Describe_state(beginID, endID, str, (char*)color);
304:     }
305:   }
306: #endif
307:   *event = e;
308:   return(0);
309: }

311: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
314: /*@C
315:   EventPerfLogActivate - Indicates that a particular event should be logged.

317:   Not Collective

319:   Input Parameters:
320: + eventLog - The EventPerfLog
321: - event    - The event

323:    Usage:
324: .vb
325:       EventPerfLogDeactivate(log, VEC_SetValues);
326:         [code where you do not want to log VecSetValues()]
327:       EventPerfLogActivate(log, VEC_SetValues);
328:         [code where you do want to log VecSetValues()]
329: .ve 

331:   Note:
332:   The event may be either a pre-defined PETSc event (found in 
333:   include/petsclog.h) or an event number obtained with EventRegLogRegister().

335:   Level: advanced

337: .keywords: log, event, activate
338: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogDeactivate()
339: @*/
340: PetscErrorCode EventPerfLogActivate(EventPerfLog eventLog, PetscLogEvent event)
341: {
343:   eventLog->eventInfo[event].active = PETSC_TRUE;
344:   return(0);
345: }

349: /*@C
350:   EventPerfLogDeactivate - Indicates that a particular event should not be logged.

352:   Not Collective

354:   Input Parameters:
355: + eventLog - The EventPerfLog
356: - event    - The event

358:    Usage:
359: .vb
360:       EventPerfLogDeactivate(log, VEC_SetValues);
361:         [code where you do not want to log VecSetValues()]
362:       EventPerfLogActivate(log, VEC_SetValues);
363:         [code where you do want to log VecSetValues()]
364: .ve 

366:   Note:
367:   The event may be either a pre-defined PETSc event (found in 
368:   include/petsclog.h) or an event number obtained with EventRegLogRegister().

370:   Level: advanced

372: .keywords: log, event, activate
373: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogActivate()
374: @*/
375: PetscErrorCode EventPerfLogDeactivate(EventPerfLog eventLog, PetscLogEvent event)
376: {
378:   eventLog->eventInfo[event].active = PETSC_FALSE;
379:   return(0);
380: }

384: /*@C
385:   EventPerfLogActivateClass - Activates event logging for a PETSc object class.

387:   Not Collective

389:   Input Parameters:
390: + eventLog    - The EventPerfLog
391: . eventRegLog - The EventRegLog
392: - cookie      - The class id, for example MAT_COOKIE, SNES_COOKIE,

394:   Level: developer

396: .seealso: EventPerfLogDeactivateClass(), EventPerfLogActivate(), EventPerfLogDeactivate()
397: @*/
398: PetscErrorCode EventPerfLogActivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, PetscCookie cookie)
399: {
400:   int e;

403:   for(e = 0; e < eventLog->numEvents; e++) {
404:     int c = eventRegLog->eventInfo[e].cookie;

406:     if (c == cookie) eventLog->eventInfo[e].active = PETSC_TRUE;
407:   }
408:   return(0);
409: }

413: /*@C
414:   EventPerfLogDeactivateClass - Deactivates event logging for a PETSc object class.

416:   Not Collective

418:   Input Parameters:
419: + eventLog    - The EventPerfLog
420: . eventRegLog - The EventRegLog
421: - cookie - The class id, for example MAT_COOKIE, SNES_COOKIE,

423:   Level: developer

425: .seealso: EventPerfLogDeactivateClass(), EventPerfLogDeactivate(), EventPerfLogActivate()
426: @*/
427: PetscErrorCode EventPerfLogDeactivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, PetscCookie cookie)
428: {
429:   int e;

432:   for(e = 0; e < eventLog->numEvents; e++) {
433:     int c = eventRegLog->eventInfo[e].cookie;

435:     if (c == cookie) eventLog->eventInfo[e].active = PETSC_FALSE;
436:   }
437:   return(0);
438: }

440: /*------------------------------------------------ Query Functions --------------------------------------------------*/
443: /*@
444:   EventRegLogGetEvent - This function returns the event id given the event name.

446:   Not Collective

448:   Input Parameters:
449: + eventLog - The EventRegLog
450: - name     - The stage name

452:   Output Parameter:
453: . event    - The event id

455:   Level: intermediate

457: .keywords: log, stage
458: .seealso: EventRegLogRegister()
459: @*/
460: PetscErrorCode  EventRegLogGetEvent(EventRegLog eventLog, const char name[], PetscLogEvent *event)
461: {
462:   PetscTruth match;
463:   int        e;

469:   *event = -1;
470:   for(e = 0; e < eventLog->numEvents; e++) {
471:     PetscStrcasecmp(eventLog->eventInfo[e].name, name, &match);
472:     if (match) break;
473:   }
474:   if (e == eventLog->numEvents) SETERRQ1(PETSC_ERR_ARG_WRONG, "No event named %s", name);
475:   *event = e;
476:   return(0);
477: }

481: /*@C
482:   EventPerfLogSetVisible - This function determines whether an event is printed during PetscLogPrintSummary()

484:   Not Collective

486:   Input Parameters:
487: + eventLog  - The EventPerfLog
488: . event     - The event to log
489: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

491:   Database Options:
492: . -log_summary - Activates log summary

494:   Level: intermediate

496: .keywords: log, visible, event
497: .seealso: EventPerfLogGetVisible(), EventRegLogRegister(), StageLogGetEventLog()
498: @*/
499: PetscErrorCode EventPerfLogSetVisible(EventPerfLog eventLog, PetscLogEvent event, PetscTruth isVisible)
500: {
502:   eventLog->eventInfo[event].visible = isVisible;
503:   return(0);
504: }

508: /*@C
509:   EventPerfLogGetVisible - This function returns whether an event is printed during PetscLogPrintSummary()

511:   Not Collective

513:   Input Parameters:
514: + eventLog  - The EventPerfLog
515: - event     - The event id to log

517:   Output Parameter:
518: . isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

520:   Database Options:
521: . -log_summary - Activates log summary

523:   Level: intermediate

525: .keywords: log, visible, event
526: .seealso: EventPerfLogSetVisible(), EventRegLogRegister(), StageLogGetEventLog()
527: @*/
528: PetscErrorCode EventPerfLogGetVisible(EventPerfLog eventLog, PetscLogEvent event, PetscTruth *isVisible)
529: {
532:   *isVisible = eventLog->eventInfo[event].visible;
533:   return(0);
534: }

538: PetscErrorCode PetscLogEventGetFlops(PetscLogEvent event, PetscLogDouble *flops)
539: {
540:   StageLog       stageLog;
541:   EventPerfLog   eventLog;
542:   int            stage;

546:   PetscLogGetStageLog(&stageLog);
547:   StageLogGetCurrent(stageLog, &stage);
548:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
549:   *flops = eventLog->eventInfo[event].flops;
550:   return(0);
551: }

555: PetscErrorCode PetscLogEventZeroFlops(PetscLogEvent event)
556: {
557:   StageLog       stageLog;
558:   EventPerfLog   eventLog;
559:   int            stage;

563:   PetscLogGetStageLog(&stageLog);
564:   StageLogGetCurrent(stageLog, &stage);
565:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
566:   eventLog->eventInfo[event].flops = 0.0;
567:   return(0);
568: }

570: #if defined(PETSC_HAVE_CHUD)
571: #include <CHUD/CHUD.h>
572: #endif
573: #if defined(PETSC_HAVE_PAPI)
574: #include "papi.h"
576: #endif

578: /*------------------------------------------------ Action Functions -------------------------------------------------*/
581: PetscErrorCode PetscLogEventBeginDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
582: {
583:   StageLog       stageLog;
584:   EventPerfLog   eventLog;
585:   int            stage;

589:   PetscLogGetStageLog(&stageLog);
590:   StageLogGetCurrent(stageLog, &stage);
591:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
592:   /* Check for double counting */
593:   eventLog->eventInfo[event].depth++;
594:   if (eventLog->eventInfo[event].depth > 1) return(0);
595:   /* Log performance info */
596:   eventLog->eventInfo[event].count++;
597:   PetscTimeSubtract(eventLog->eventInfo[event].time);
598: #if defined(PETSC_HAVE_CHUD)
599:   eventLog->eventInfo[event].flops         -= chudGetPMCEventCount(chudCPU1Dev,PMC_1);
600: #elif defined(PETSC_HAVE_PAPI)
601:   { long_long values[2];
602:     PAPI_read(PAPIEventSet,values);
603:     eventLog->eventInfo[event].flops -= values[0];
604:     /*    printf("fma %g flops %g\n",(double)values[1],(double)values[0]); */
605:   }
606: #else
607:   eventLog->eventInfo[event].flops         -= _TotalFlops;
608: #endif
609:   eventLog->eventInfo[event].numMessages   -= irecv_ct  + isend_ct  + recv_ct  + send_ct;
610:   eventLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
611:   eventLog->eventInfo[event].numReductions -= allreduce_ct;
612:   return(0);
613: }

617: PetscErrorCode PetscLogEventEndDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
618: {
619:   StageLog     stageLog;
620:   EventPerfLog eventLog;
621:   int          stage;

625:   PetscLogGetStageLog(&stageLog);
626:   StageLogGetCurrent(stageLog, &stage);
627:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
628:   /* Check for double counting */
629:   eventLog->eventInfo[event].depth--;
630:   if (eventLog->eventInfo[event].depth > 0) {
631:     return(0);
632:   } else if (eventLog->eventInfo[event].depth < 0) {
633:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
634:   }
635:   /* Log performance info */
636:   PetscTimeAdd(eventLog->eventInfo[event].time);
637: #if defined(PETSC_HAVE_CHUD)
638:   eventLog->eventInfo[event].flops         += chudGetPMCEventCount(chudCPU1Dev,PMC_1);
639: #elif defined(PETSC_HAVE_PAPI)
640:   { long_long values[2];
641:     PAPI_read(PAPIEventSet,values);
642:     eventLog->eventInfo[event].flops += values[0];
643:     /* printf("fma %g flops %g\n",(double)values[1],(double)values[0]); */
644:   }
645: #else
646:   eventLog->eventInfo[event].flops         += _TotalFlops;
647: #endif
648:   eventLog->eventInfo[event].numMessages   += irecv_ct  + isend_ct  + recv_ct  + send_ct;
649:   eventLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
650:   eventLog->eventInfo[event].numReductions += allreduce_ct;
651:   return(0);
652: }

656: PetscErrorCode PetscLogEventBeginComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
657: {
658:   StageLog       stageLog;
659:   EventRegLog    eventRegLog;
660:   EventPerfLog   eventPerfLog;
661:   Action        *tmpAction;
662:   PetscLogDouble start, end;
663:   PetscLogDouble curTime;
664:   int            stage;

668:   /* Dynamically enlarge logging structures */
669:   if (numActions >= maxActions) {
670:     PetscTime(start);
671:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
672:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
673:     PetscFree(actions);
674:     actions     = tmpAction;
675:     maxActions *= 2;
676:     PetscTime(end);
677:     BaseTime += (end - start);
678:   }
679:   /* Record the event */
680:   PetscLogGetStageLog(&stageLog);
681:   StageLogGetCurrent(stageLog, &stage);
682:   StageLogGetEventRegLog(stageLog, &eventRegLog);
683:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
684:   PetscTime(curTime);
685:   if (logActions) {
686:     actions[numActions].time   = curTime - BaseTime;
687:     actions[numActions].action = ACTIONBEGIN;
688:     actions[numActions].event  = event;
689:     actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
690:     if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
691:     if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
692:     if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
693:     actions[numActions].flops    = _TotalFlops;
694:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
695:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
696:     numActions++;
697:   }
698:   /* Check for double counting */
699:   eventPerfLog->eventInfo[event].depth++;
700:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
701:   /* Log the performance info */
702:   eventPerfLog->eventInfo[event].count++;
703:   eventPerfLog->eventInfo[event].time          -= curTime;
704:   eventPerfLog->eventInfo[event].flops         -= _TotalFlops;
705:   eventPerfLog->eventInfo[event].numMessages   -= irecv_ct  + isend_ct  + recv_ct  + send_ct;
706:   eventPerfLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
707:   eventPerfLog->eventInfo[event].numReductions -= allreduce_ct;
708:   return(0);
709: }

713: PetscErrorCode PetscLogEventEndComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
714: {
715:   StageLog       stageLog;
716:   EventRegLog    eventRegLog;
717:   EventPerfLog   eventPerfLog;
718:   Action        *tmpAction;
719:   PetscLogDouble start, end;
720:   PetscLogDouble curTime;
721:   int            stage;

725:   /* Dynamically enlarge logging structures */
726:   if (numActions >= maxActions) {
727:     PetscTime(start);
728:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
729:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
730:     PetscFree(actions);
731:     actions     = tmpAction;
732:     maxActions *= 2;
733:     PetscTime(end);
734:     BaseTime += (end - start);
735:   }
736:   /* Record the event */
737:   PetscLogGetStageLog(&stageLog);
738:   StageLogGetCurrent(stageLog, &stage);
739:   StageLogGetEventRegLog(stageLog, &eventRegLog);
740:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
741:   PetscTime(curTime);
742:   if (logActions) {
743:     actions[numActions].time   = curTime - BaseTime;
744:     actions[numActions].action = ACTIONEND;
745:     actions[numActions].event  = event;
746:     actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
747:     if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
748:     if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
749:     if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
750:     actions[numActions].flops    = _TotalFlops;
751:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
752:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
753:     numActions++;
754:   }
755:   /* Check for double counting */
756:   eventPerfLog->eventInfo[event].depth--;
757:   if (eventPerfLog->eventInfo[event].depth > 0) {
758:     return(0);
759:   } else if (eventPerfLog->eventInfo[event].depth < 0) {
760:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
761:   }
762:   /* Log the performance info */
763:   eventPerfLog->eventInfo[event].count++;
764:   eventPerfLog->eventInfo[event].time          += curTime;
765:   eventPerfLog->eventInfo[event].flops         += _TotalFlops;
766:   eventPerfLog->eventInfo[event].numMessages   += irecv_ct  + isend_ct  + recv_ct  + send_ct;
767:   eventPerfLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
768:   eventPerfLog->eventInfo[event].numReductions += allreduce_ct;
769:   return(0);
770: }

774: PetscErrorCode PetscLogEventBeginTrace(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
775: {
776:   StageLog       stageLog;
777:   EventRegLog    eventRegLog;
778:   EventPerfLog   eventPerfLog;
779:   PetscLogDouble cur_time;
780:   PetscMPIInt    rank;
781:   int            stage,err;

785:   if (!tracetime) {PetscTime(tracetime);}

787:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
788:   PetscLogGetStageLog(&stageLog);
789:   StageLogGetCurrent(stageLog, &stage);
790:   StageLogGetEventRegLog(stageLog, &eventRegLog);
791:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
792:   /* Check for double counting */
793:   eventPerfLog->eventInfo[event].depth++;
794:   tracelevel++;
795:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
796:   /* Log performance info */
797:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
798:   tracespace[2*tracelevel] = 0;
799:   PetscTime(cur_time);
800:   PetscFPrintf(PETSC_COMM_SELF,tracefile, "%s[%d] %g Event begin: %s\n", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
801:   err = fflush(tracefile);
802:   if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");

804:   return(0);
805: }

809: PetscErrorCode PetscLogEventEndTrace(PetscLogEvent event,int t,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
810: {
811:   StageLog       stageLog;
812:   EventRegLog    eventRegLog;
813:   EventPerfLog   eventPerfLog;
814:   PetscLogDouble cur_time;
815:   int            stage,err;
816:   PetscMPIInt    rank;

820:   tracelevel--;
821:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
822:   PetscLogGetStageLog(&stageLog);
823:   StageLogGetCurrent(stageLog, &stage);
824:   StageLogGetEventRegLog(stageLog, &eventRegLog);
825:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
826:   /* Check for double counting */
827:   eventPerfLog->eventInfo[event].depth--;
828:   if (eventPerfLog->eventInfo[event].depth > 0) {
829:     return(0);
830:   } else if (eventPerfLog->eventInfo[event].depth < 0 || tracelevel < 0) {
831:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
832:   }
833:   /* Log performance info */
834:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
835:   tracespace[2*tracelevel] = 0;
836:   PetscTime(cur_time);
837:   PetscFPrintf(PETSC_COMM_SELF,tracefile, "%s[%d] %g Event end: %s\n", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
838:   err = fflush(tracefile);
839:   if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
840:   return(0);
841: }