Actual source code: eventLog.c

  1: #define PETSC_DLL

 3:  #include petsc.h
 4:  #include petsctime.h
 5:  #include ../src/sys/plog/plog.h

  7: /* Variables for the tracing logger */

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

 19: /*@C
 20:   EventRegLogCreate - This creates a EventRegLog object.

 22:   Not collective

 24:   Input Parameter:
 25: . eventLog - The EventRegLog

 27:   Level: beginner

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

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

 48: /*@C
 49:   EventRegLogDestroy - This destroys a EventRegLog object.

 51:   Not collective

 53:   Input Paramter:
 54: . eventLog - The EventRegLog

 56:   Level: beginner

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

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

 77: /*@C
 78:   EventPerfLogCreate - This creates a EventPerfLog object.

 80:   Not collective

 82:   Input Parameter:
 83: . eventLog - The EventPerfLog

 85:   Level: beginner

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

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

106: /*@C
107:   EventPerfLogDestroy - This destroys a EventPerfLog object.

109:   Not collective

111:   Input Paramter:
112: . eventLog - The EventPerfLog

114:   Level: beginner

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

124:   PetscFree(eventLog->eventInfo);
125:   PetscFree(eventLog);
126:   return(0);
127: }

129: /*------------------------------------------------ General Functions -------------------------------------------------*/
132: /*@C
133:   EventPerfInfoClear - This clears a EventPerfInfo object.

135:   Not collective

137:   Input Paramter:
138: . eventInfo - The EventPerfInfo

140:   Level: beginner

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

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

166:   Not collective

168:   Input Paramter:
169: . eventInfo - The input EventPerfInfo

171:   Output Paramter:
172: . outInfo   - The output EventPerfInfo

174:   Level: beginner

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

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

193:   Not collective

195:   Input Paramters:
196: + eventLog - The EventPerfLog
197: - size     - The size

199:   Level: intermediate

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

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

223: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
226: /*@C
227:   EventRegLogRegister - Registers an event for logging operations in an application code.

229:   Not Collective

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

236:   Output Parameter:
237: . event    - The event

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

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

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

264:   Level: intermediate

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

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

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

313: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
316: /*@C
317:   EventPerfLogActivate - Indicates that a particular event should be logged.

319:   Not Collective

321:   Input Parameters:
322: + eventLog - The EventPerfLog
323: - event    - The event

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

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

337:   Level: advanced

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

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

354:   Not Collective

356:   Input Parameters:
357: + eventLog - The EventPerfLog
358: - event    - The event

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

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

372:   Level: advanced

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

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

389:   Not Collective

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

396:   Level: developer

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

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

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

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

418:   Not Collective

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

425:   Level: developer

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

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

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

442: /*------------------------------------------------ Query Functions --------------------------------------------------*/
445: /*@
446:   EventRegLogGetEvent - This function returns the event id given the event name.

448:   Not Collective

450:   Input Parameters:
451: + eventLog - The EventRegLog
452: - name     - The stage name

454:   Output Parameter:
455: . event    - The event id

457:   Level: intermediate

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

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

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

486:   Not Collective

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

493:   Database Options:
494: . -log_summary - Activates log summary

496:   Level: intermediate

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

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

513:   Not Collective

515:   Input Parameters:
516: + eventLog  - The EventPerfLog
517: - event     - The event id to log

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

522:   Database Options:
523: . -log_summary - Activates log summary

525:   Level: intermediate

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

538: /*------------------------------------------------ Action Functions -------------------------------------------------*/
541: PetscErrorCode PetscLogEventBeginDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
542: {
543:   StageLog       stageLog;
544:   EventPerfLog   eventLog;
545:   int            stage;

549:   PetscLogGetStageLog(&stageLog);
550:   StageLogGetCurrent(stageLog, &stage);
551:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
552:   /* Check for double counting */
553:   eventLog->eventInfo[event].depth++;
554:   if (eventLog->eventInfo[event].depth > 1) return(0);
555:   /* Log performance info */
556:   eventLog->eventInfo[event].count++;
557:   PetscTimeSubtract(eventLog->eventInfo[event].time);
558:   eventLog->eventInfo[event].flops         -= _TotalFlops;
559:   eventLog->eventInfo[event].numMessages   -= irecv_ct  + isend_ct  + recv_ct  + send_ct;
560:   eventLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
561:   eventLog->eventInfo[event].numReductions -= allreduce_ct;
562:   return(0);
563: }

567: PetscErrorCode PetscLogEventEndDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
568: {
569:   StageLog     stageLog;
570:   EventPerfLog eventLog;
571:   int          stage;

575:   PetscLogGetStageLog(&stageLog);
576:   StageLogGetCurrent(stageLog, &stage);
577:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
578:   /* Check for double counting */
579:   eventLog->eventInfo[event].depth--;
580:   if (eventLog->eventInfo[event].depth > 0) {
581:     return(0);
582:   } else if (eventLog->eventInfo[event].depth < 0) {
583:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
584:   }
585:   /* Log performance info */
586:   PetscTimeAdd(eventLog->eventInfo[event].time);
587:   eventLog->eventInfo[event].flops         += _TotalFlops;
588:   eventLog->eventInfo[event].numMessages   += irecv_ct  + isend_ct  + recv_ct  + send_ct;
589:   eventLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
590:   eventLog->eventInfo[event].numReductions += allreduce_ct;
591:   return(0);
592: }

596: PetscErrorCode PetscLogEventBeginComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
597: {
598:   StageLog       stageLog;
599:   EventRegLog    eventRegLog;
600:   EventPerfLog   eventPerfLog;
601:   Action        *tmpAction;
602:   PetscLogDouble start, end;
603:   PetscLogDouble curTime;
604:   int            stage;

608:   /* Dynamically enlarge logging structures */
609:   if (numActions >= maxActions) {
610:     PetscTime(start);
611:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
612:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
613:     PetscFree(actions);
614:     actions     = tmpAction;
615:     maxActions *= 2;
616:     PetscTime(end);
617:     BaseTime += (end - start);
618:   }
619:   /* Record the event */
620:   PetscLogGetStageLog(&stageLog);
621:   StageLogGetCurrent(stageLog, &stage);
622:   StageLogGetEventRegLog(stageLog, &eventRegLog);
623:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
624:   PetscTime(curTime);
625:   if (logActions) {
626:     actions[numActions].time   = curTime - BaseTime;
627:     actions[numActions].action = ACTIONBEGIN;
628:     actions[numActions].event  = event;
629:     actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
630:     if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
631:     if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
632:     if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
633:     actions[numActions].flops    = _TotalFlops;
634:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
635:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
636:     numActions++;
637:   }
638:   /* Check for double counting */
639:   eventPerfLog->eventInfo[event].depth++;
640:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
641:   /* Log the performance info */
642:   eventPerfLog->eventInfo[event].count++;
643:   eventPerfLog->eventInfo[event].time          -= curTime;
644:   eventPerfLog->eventInfo[event].flops         -= _TotalFlops;
645:   eventPerfLog->eventInfo[event].numMessages   -= irecv_ct  + isend_ct  + recv_ct  + send_ct;
646:   eventPerfLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
647:   eventPerfLog->eventInfo[event].numReductions -= allreduce_ct;
648:   return(0);
649: }

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

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

714: PetscErrorCode PetscLogEventBeginTrace(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
715: {
716:   StageLog       stageLog;
717:   EventRegLog    eventRegLog;
718:   EventPerfLog   eventPerfLog;
719:   PetscLogDouble cur_time;
720:   PetscMPIInt    rank;
721:   int            stage,err;

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

727:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
728:   PetscLogGetStageLog(&stageLog);
729:   StageLogGetCurrent(stageLog, &stage);
730:   StageLogGetEventRegLog(stageLog, &eventRegLog);
731:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
732:   /* Check for double counting */
733:   eventPerfLog->eventInfo[event].depth++;
734:   tracelevel++;
735:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
736:   /* Log performance info */
737:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
738:   tracespace[2*tracelevel] = 0;
739:   PetscTime(cur_time);
740:   PetscFPrintf(PETSC_COMM_SELF,tracefile, "%s[%d] %g Event begin: %s\n", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
741:   err = fflush(tracefile);
742:   if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");

744:   return(0);
745: }

749: PetscErrorCode PetscLogEventEndTrace(PetscLogEvent event,int t,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
750: {
751:   StageLog       stageLog;
752:   EventRegLog    eventRegLog;
753:   EventPerfLog   eventPerfLog;
754:   PetscLogDouble cur_time;
755:   int            stage,err;
756:   PetscMPIInt    rank;

760:   tracelevel--;
761:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
762:   PetscLogGetStageLog(&stageLog);
763:   StageLogGetCurrent(stageLog, &stage);
764:   StageLogGetEventRegLog(stageLog, &eventRegLog);
765:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
766:   /* Check for double counting */
767:   eventPerfLog->eventInfo[event].depth--;
768:   if (eventPerfLog->eventInfo[event].depth > 0) {
769:     return(0);
770:   } else if (eventPerfLog->eventInfo[event].depth < 0 || tracelevel < 0) {
771:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
772:   }
773:   /* Log performance info */
774:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
775:   tracespace[2*tracelevel] = 0;
776:   PetscTime(cur_time);
777:   PetscFPrintf(PETSC_COMM_SELF,tracefile, "%s[%d] %g Event end: %s\n", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
778:   err = fflush(tracefile);
779:   if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
780:   return(0);
781: }