Actual source code: eventLog.c

  1: /* $Id: eventLog.c,v 1.3 2000/08/16 05:14:09 knepley Exp $ */

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

  7: /* Variables for the tracing logger */
  8: extern FILE          *tracefile;
  9: extern int            tracelevel;
 10: extern char          *traceblanks;
 11: extern char           tracespace[128];
 12: extern PetscLogDouble tracetime;

 14: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
 15: /*
 16:   EventRegLogCreate - This creates a EventRegLog object.

 18:   Not collective

 20:   Input Parameter:
 21: . eventLog - The EventRegLog

 23:   Level: beginner

 25: .keywords: log, event, create
 26: .seealso: EventRegLogDestroy(), StageLogCreate()
 27: */
 28: int EventRegLogCreate(EventRegLog *eventLog) {
 29:   EventRegLog l;
 30:   int         ierr;

 33:   PetscNew(struct _EventRegLog, &l);
 34:   l->numEvents   = 0;
 35:   l->maxEvents   = 100;
 36:   PetscMalloc(l->maxEvents * sizeof(EventRegInfo), &l->eventInfo);
 37:   *eventLog = l;
 38:   return(0);
 39: }

 41: /*
 42:   EventRegLogDestroy - This destroys a EventRegLog object.

 44:   Not collective

 46:   Input Paramter:
 47: . eventLog - The EventRegLog

 49:   Level: beginner

 51: .keywords: log, event, destroy
 52: .seealso: EventRegLogCreate()
 53: */
 54: int EventRegLogDestroy(EventRegLog eventLog) {
 55:   int e;

 59:   for(e = 0; e < eventLog->numEvents; e++) {
 60:     PetscFree(eventLog->eventInfo[e].name);
 61:   }
 62:   PetscFree(eventLog->eventInfo);
 63:   PetscFree(eventLog);
 64:   return(0);
 65: }

 67: /*
 68:   EventPerfLogCreate - This creates a EventPerfLog object.

 70:   Not collective

 72:   Input Parameter:
 73: . eventLog - The EventPerfLog

 75:   Level: beginner

 77: .keywords: log, event, create
 78: .seealso: EventPerfLogDestroy(), StageLogCreate()
 79: */
 80: int EventPerfLogCreate(EventPerfLog *eventLog) {
 81:   EventPerfLog l;
 82:   int          ierr;

 85:   PetscNew(struct _EventPerfLog, &l);
 86:   l->numEvents   = 0;
 87:   l->maxEvents   = 100;
 88:   PetscMalloc(l->maxEvents * sizeof(EventPerfInfo), &l->eventInfo);
 89:   *eventLog = l;
 90:   return(0);
 91: }

 93: /*
 94:   EventPerfLogDestroy - This destroys a EventPerfLog object.

 96:   Not collective

 98:   Input Paramter:
 99: . eventLog - The EventPerfLog

101:   Level: beginner

103: .keywords: log, event, destroy
104: .seealso: EventPerfLogCreate()
105: */
106: int EventPerfLogDestroy(EventPerfLog eventLog) {

110:   PetscFree(eventLog->eventInfo);
111:   PetscFree(eventLog);
112:   return(0);
113: }

115: /*------------------------------------------------ General Functions -------------------------------------------------*/
116: /*
117:   EventPerfInfoClear - This clears a EventPerfInfo object.

119:   Not collective

121:   Input Paramter:
122: . eventInfo - The EventPerfInfo

124:   Level: beginner

126: .keywords: log, event, destroy
127: .seealso: EventPerfLogCreate()
128: */
129: int EventPerfInfoClear(EventPerfInfo *eventInfo) {
131:   eventInfo->id            = -1;
132:   eventInfo->active        = PETSC_TRUE;
133:   eventInfo->visible       = PETSC_TRUE;
134:   eventInfo->depth         = 0;
135:   eventInfo->count         = 0;
136:   eventInfo->flops         = 0.0;
137:   eventInfo->time          = 0.0;
138:   eventInfo->numMessages   = 0.0;
139:   eventInfo->messageLength = 0.0;
140:   eventInfo->numReductions = 0.0;
141:   return(0);
142: }

144: /*
145:   EventPerfLogEnsureSize - This ensures that a EventPerfLog is at least of a certain size.

147:   Not collective

149:   Input Paramters:
150: + eventLog - The EventPerfLog
151: - size     - The size

153:   Level: intermediate

155: .keywords: log, event, size, ensure
156: .seealso: EventPerfLogCreate()
157: */
158: int EventPerfLogEnsureSize(EventPerfLog eventLog, int size) {
159:   EventPerfInfo *eventInfo;
160:   int            ierr;

163:   while(size > eventLog->maxEvents) {
164:     PetscMalloc(eventLog->maxEvents*2 * sizeof(EventPerfInfo), &eventInfo);
165:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventPerfInfo));
166:     PetscFree(eventLog->eventInfo);
167:     eventLog->eventInfo  = eventInfo;
168:     eventLog->maxEvents *= 2;
169:   }
170:   while(eventLog->numEvents < size) {
171:     EventPerfInfoClear(&eventLog->eventInfo[eventLog->numEvents++]);
172:   }
173:   return(0);
174: }

176: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
177: /*@C
178:   EventRegLogRegister - Registers an event for logging operations in an application code.

180:   Not Collective

182:   Input Parameters:
183: + eventLog - The EventLog
184: . ename    - The name associated with the event
185: - cookie   - The cookie associated to the class for this event

187:   Output Parameter:
188: . event    - The event

190:   Example of Usage:
191: .vb
192:       int USER_EVENT;
193:       int user_event_flops;
194:       PetscLogEventRegister(&USER_EVENT,"User event name");
195:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
196:          [code segment to monitor]
197:          PetscLogFlops(user_event_flops);
198:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
199: .ve

201:   Notes: 
202:   PETSc automatically logs library events if the code has been
203:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
204:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
205:   intended for logging user events to supplement this PETSc
206:   information. 

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

215:   Level: intermediate

217: .keywords: log, event, register
218: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
219:           EventLogActivate(), EventLogDeactivate()
220: @*/
221: int EventRegLogRegister(EventRegLog eventLog, const char ename[], int cookie, PetscEvent *event) {
222:   EventRegInfo *eventInfo;
223:   char         *str;
224:   int           e;
225:   int           ierr;

230:   /* Should check cookie I think */
231:   e = eventLog->numEvents++;
232:   if (eventLog->numEvents > eventLog->maxEvents) {
233:     PetscMalloc(eventLog->maxEvents*2 * sizeof(EventRegInfo), &eventInfo);
234:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventRegInfo));
235:     PetscFree(eventLog->eventInfo);
236:     eventLog->eventInfo  = eventInfo;
237:     eventLog->maxEvents *= 2;
238:   }
239:   PetscStrallocpy(ename, &str);
240:   eventLog->eventInfo[e].name   = str;
241:   eventLog->eventInfo[e].cookie = cookie;
242: #if defined(PETSC_HAVE_MPE)
243:   if (UseMPE) {
244:     char *color;
245:     int   rank, beginID, endID;

247:     beginID = MPE_Log_get_event_number();
248:     endID   = MPE_Log_get_event_number();
249:     eventLog->eventInfo[e].mpe_id_begin = beginID;
250:     eventLog->eventInfo[e].mpe_id_end   = endID;
251:     MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
252:     if (!rank) {
253:       PetscLogGetRGBColor(&color);
254:       MPE_Describe_state(beginID, endID, str, color);
255:     }
256:   }
257: #endif
258:   *event = e;
259:   return(0);
260: }

262: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
263: /*@C
264:   EventPerfLogActivate - Indicates that a particular event should be logged.

266:   Not Collective

268:   Input Parameters:
269: + eventLog - The EventPerfLog
270: - event    - The event

272:    Usage:
273: .vb
274:       EventPerfLogDeactivate(log, VEC_SetValues);
275:         [code where you do not want to log VecSetValues()]
276:       EventPerfLogActivate(log, VEC_SetValues);
277:         [code where you do want to log VecSetValues()]
278: .ve 

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

284:   Level: advanced

286: .keywords: log, event, activate
287: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogDeactivate()
288: @*/
289: int EventPerfLogActivate(EventPerfLog eventLog, PetscEvent event) {
291:   eventLog->eventInfo[event].active = PETSC_TRUE;
292:   return(0);
293: }

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

298:   Not Collective

300:   Input Parameters:
301: + eventLog - The EventPerfLog
302: - event    - The event

304:    Usage:
305: .vb
306:       EventPerfLogDeactivate(log, VEC_SetValues);
307:         [code where you do not want to log VecSetValues()]
308:       EventPerfLogActivate(log, VEC_SetValues);
309:         [code where you do want to log VecSetValues()]
310: .ve 

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

316:   Level: advanced

318: .keywords: log, event, activate
319: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogActivate()
320: @*/
321: int EventPerfLogDeactivate(EventPerfLog eventLog, PetscEvent event) {
323:   eventLog->eventInfo[event].active = PETSC_FALSE;
324:   return(0);
325: }

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

330:   Not Collective

332:   Input Parameters:
333: + eventLog    - The EventPerfLog
334: . eventRegLog - The EventRegLog
335: - cookie      - The class id, for example MAT_COOKIE, SNES_COOKIE,

337:   Level: developer

339: .seealso: EventPerfLogDeactivateClass(), EventPerfLogActivate(), EventPerfLogDeactivate()
340: @*/
341: int EventPerfLogActivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, int cookie) {
342:   int e;

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

348:     if (c == cookie) eventLog->eventInfo[e].active = PETSC_TRUE;
349:   }
350:   return(0);
351: }

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

356:   Not Collective

358:   Input Parameters:
359: + eventLog    - The EventPerfLog
360: . eventRegLog - The EventRegLog
361: - cookie - The class id, for example MAT_COOKIE, SNES_COOKIE,

363:   Level: developer

365: .seealso: EventPerfLogDeactivateClass(), EventPerfLogDeactivate(), EventPerfLogActivate()
366: @*/
367: int EventPerfLogDeactivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, int cookie) {
368:   int e;

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

374:     if (c == cookie) eventLog->eventInfo[e].active = PETSC_FALSE;
375:   }
376:   return(0);
377: }

379: /*------------------------------------------------ Query Functions --------------------------------------------------*/
380: /*@C
381:   EventPerfLogSetVisible - This function determines whether an event is printed during PetscLogPrintSummary()

383:   Not Collective

385:   Input Parameters:
386: + eventLog  - The EventPerfLog
387: . event     - The event to log
388: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

390:   Database Options:
391: . -log_summary - Activates log summary

393:   Level: intermediate

395: .keywords: log, visible, event
396: .seealso: EventPerfLogGetVisible(), EventRegLogRegister(), StageLogGetEventLog()
397: @*/
398: int EventPerfLogSetVisible(EventPerfLog eventLog, PetscEvent event, PetscTruth isVisible) {
400:   eventLog->eventInfo[event].visible = isVisible;
401:   return(0);
402: }

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

407:   Not Collective

409:   Input Parameters:
410: + eventLog  - The EventPerfLog
411: - event     - The event id to log

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

416:   Database Options:
417: . -log_summary - Activates log summary

419:   Level: intermediate

421: .keywords: log, visible, event
422: .seealso: EventPerfLogSetVisible(), EventRegLogRegister(), StageLogGetEventLog()
423: @*/
424: int EventPerfLogGetVisible(EventPerfLog eventLog, PetscEvent event, PetscTruth *isVisible) {
427:   *isVisible = eventLog->eventInfo[event].visible;
428:   return(0);
429: }

431: /*------------------------------------------------ Action Functions -------------------------------------------------*/
432: int PetscLogEventBeginDefault(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
433:   StageLog     stageLog;
434:   EventPerfLog eventLog;
435:   int          stage;
436:   int          ierr;

439:   PetscLogGetStageLog(&stageLog);
440:   StageLogGetCurrent(stageLog, &stage);
441:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
442:   /* Check for double counting */
443:   eventLog->eventInfo[event].depth++;
444:   if (eventLog->eventInfo[event].depth > 1) return(0);
445:   /* Log performance info */
446:   eventLog->eventInfo[event].count++;
447:   PetscTimeSubtract(eventLog->eventInfo[event].time);
448:   eventLog->eventInfo[event].flops         -= _TotalFlops;
449:   eventLog->eventInfo[event].numMessages   -= irecv_ct  + isend_ct  + recv_ct  + send_ct;
450:   eventLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
451:   eventLog->eventInfo[event].numReductions -= allreduce_ct;
452:   return(0);
453: }

455: int PetscLogEventEndDefault(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
456:   StageLog     stageLog;
457:   EventPerfLog eventLog;
458:   int          stage;
459:   int          ierr;

462:   PetscLogGetStageLog(&stageLog);
463:   StageLogGetCurrent(stageLog, &stage);
464:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
465:   /* Check for double counting */
466:   eventLog->eventInfo[event].depth--;
467:   if (eventLog->eventInfo[event].depth > 0) {
468:     return(0);
469:   } else if (eventLog->eventInfo[event].depth < 0) {
470:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
471:   }
472:   /* Log performance info */
473:   PetscTimeAdd(eventLog->eventInfo[event].time);
474:   eventLog->eventInfo[event].flops         += _TotalFlops;
475:   eventLog->eventInfo[event].numMessages   += irecv_ct  + isend_ct  + recv_ct  + send_ct;
476:   eventLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
477:   eventLog->eventInfo[event].numReductions += allreduce_ct;
478:   return(0);
479: }

481: int PetscLogEventBeginComplete(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
482:   StageLog       stageLog;
483:   EventRegLog    eventRegLog;
484:   EventPerfLog   eventPerfLog;
485:   Action        *tmpAction;
486:   PetscLogDouble start, end;
487:   PetscLogDouble curTime;
488:   int            stage;
489:   int            ierr;

492:   /* Dynamically enlarge logging structures */
493:   if (numActions >= maxActions) {
494:     PetscTime(start);
495:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
496:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
497:     PetscFree(actions);
498:     actions     = tmpAction;
499:     maxActions *= 2;
500:     PetscTime(end);
501:     BaseTime += (end - start);
502:   }
503:   /* Record the event */
504:   PetscLogGetStageLog(&stageLog);
505:   StageLogGetCurrent(stageLog, &stage);
506:   StageLogGetEventRegLog(stageLog, &eventRegLog);
507:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
508:   PetscTime(curTime);
509:   if (actions != PETSC_NULL) {
510:     actions[numActions].time   = curTime - BaseTime;
511:     actions[numActions].action = ACTIONBEGIN;
512:     actions[numActions].event  = event;
513:     actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
514:     if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
515:     if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
516:     if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
517:     actions[numActions].flops    = _TotalFlops;
518:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
519:     numActions++;
520:   }
521:   /* Check for double counting */
522:   eventPerfLog->eventInfo[event].depth++;
523:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
524:   /* Log the performance info */
525:   eventPerfLog->eventInfo[event].count++;
526:   eventPerfLog->eventInfo[event].time          -= curTime;
527:   eventPerfLog->eventInfo[event].flops         -= _TotalFlops;
528:   eventPerfLog->eventInfo[event].numMessages   -= irecv_ct  + isend_ct  + recv_ct  + send_ct;
529:   eventPerfLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
530:   eventPerfLog->eventInfo[event].numReductions -= allreduce_ct;
531:   return(0);
532: }

534: int PetscLogEventEndComplete(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
535:   StageLog       stageLog;
536:   EventRegLog    eventRegLog;
537:   EventPerfLog   eventPerfLog;
538:   Action        *tmpAction;
539:   PetscLogDouble start, end;
540:   PetscLogDouble curTime;
541:   int            stage;
542:   int            ierr;

545:   /* Dynamically enlarge logging structures */
546:   if (numActions >= maxActions) {
547:     PetscTime(start);
548:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
549:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
550:     PetscFree(actions);
551:     actions     = tmpAction;
552:     maxActions *= 2;
553:     PetscTime(end);
554:     BaseTime += (end - start);
555:   }
556:   /* Record the event */
557:   PetscLogGetStageLog(&stageLog);
558:   StageLogGetCurrent(stageLog, &stage);
559:   StageLogGetEventRegLog(stageLog, &eventRegLog);
560:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
561:   PetscTime(curTime);
562:   if (actions != PETSC_NULL) {
563:     actions[numActions].time   = curTime - BaseTime;
564:     actions[numActions].action = ACTIONEND;
565:     actions[numActions].event  = event;
566:     actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
567:     if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
568:     if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
569:     if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
570:     actions[numActions].flops    = _TotalFlops;
571:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
572:     numActions++;
573:   }
574:   /* Check for double counting */
575:   eventPerfLog->eventInfo[event].depth--;
576:   if (eventPerfLog->eventInfo[event].depth > 0) {
577:     return(0);
578:   } else if (eventPerfLog->eventInfo[event].depth < 0) {
579:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
580:   }
581:   /* Log the performance info */
582:   eventPerfLog->eventInfo[event].count++;
583:   eventPerfLog->eventInfo[event].time          += curTime;
584:   eventPerfLog->eventInfo[event].flops         += _TotalFlops;
585:   eventPerfLog->eventInfo[event].numMessages   += irecv_ct  + isend_ct  + recv_ct  + send_ct;
586:   eventPerfLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
587:   eventPerfLog->eventInfo[event].numReductions += allreduce_ct;
588:   return(0);
589: }

591: int PetscLogEventBeginTrace(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
592:   StageLog       stageLog;
593:   EventRegLog    eventRegLog;
594:   EventPerfLog   eventPerfLog;
595:   PetscLogDouble cur_time;
596:   int            rank, stage;
597:   int            ierr;

600:   if (tracetime == 0.0) {PetscTime(tracetime);}

602:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
603:   PetscLogGetStageLog(&stageLog);
604:   StageLogGetCurrent(stageLog, &stage);
605:   StageLogGetEventRegLog(stageLog, &eventRegLog);
606:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
607:   /* Check for double counting */
608:   eventPerfLog->eventInfo[event].depth++;
609:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
610:   /* Log performance info */
611:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
612:   tracespace[2*tracelevel] = 0;
613:   PetscTime(cur_time);
614:   fprintf(tracefile, "%s[%d] %g Event begin: %sn", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
615:   fflush(tracefile);
616:   tracelevel++;

618:   return(0);
619: }

621: int PetscLogEventEndTrace(PetscEvent event,int t,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4) {
622:   StageLog       stageLog;
623:   EventRegLog    eventRegLog;
624:   EventPerfLog   eventPerfLog;
625:   PetscLogDouble cur_time;
626:   int            rank, stage;
627:   int            ierr;

630:   tracelevel--;
631:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
632:   PetscLogGetStageLog(&stageLog);
633:   StageLogGetCurrent(stageLog, &stage);
634:   StageLogGetEventRegLog(stageLog, &eventRegLog);
635:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
636:   /* Check for double counting */
637:   eventPerfLog->eventInfo[event].depth--;
638:   if (eventPerfLog->eventInfo[event].depth > 0) {
639:     return(0);
640:   } else if (eventPerfLog->eventInfo[event].depth < 0) {
641:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
642:   }
643:   /* Log performance info */
644:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
645:   tracespace[2*tracelevel] = 0;
646:   PetscTime(cur_time);
647:   fprintf(tracefile, "%s[%d] %g Event end: %sn", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
648:   fflush(tracefile);
649:   return(0);
650: }