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: #undef __FUNCT__  
 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: int EventRegLogCreate(EventRegLog *eventLog) {
 31:   EventRegLog l;
 32:   int         ierr;

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

 43: #undef __FUNCT__  
 45: /*@C
 46:   EventRegLogDestroy - This destroys a EventRegLog object.

 48:   Not collective

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

 53:   Level: beginner

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

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

 71: #undef __FUNCT__  
 73: /*@C
 74:   EventPerfLogCreate - This creates a EventPerfLog object.

 76:   Not collective

 78:   Input Parameter:
 79: . eventLog - The EventPerfLog

 81:   Level: beginner

 83: .keywords: log, event, create
 84: .seealso: EventPerfLogDestroy(), StageLogCreate()
 85: @*/
 86: int EventPerfLogCreate(EventPerfLog *eventLog) {
 87:   EventPerfLog l;
 88:   int          ierr;

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

 99: #undef __FUNCT__  
101: /*@C
102:   EventPerfLogDestroy - This destroys a EventPerfLog object.

104:   Not collective

106:   Input Paramter:
107: . eventLog - The EventPerfLog

109:   Level: beginner

111: .keywords: log, event, destroy
112: .seealso: EventPerfLogCreate()
113: @*/
114: int EventPerfLogDestroy(EventPerfLog eventLog) {

118:   PetscFree(eventLog->eventInfo);
119:   PetscFree(eventLog);
120:   return(0);
121: }

123: /*------------------------------------------------ General Functions -------------------------------------------------*/
124: #undef __FUNCT__  
126: /*@C
127:   EventPerfInfoClear - This clears a EventPerfInfo object.

129:   Not collective

131:   Input Paramter:
132: . eventInfo - The EventPerfInfo

134:   Level: beginner

136: .keywords: log, event, destroy
137: .seealso: EventPerfLogCreate()
138: @*/
139: int EventPerfInfoClear(EventPerfInfo *eventInfo) {
141:   eventInfo->id            = -1;
142:   eventInfo->active        = PETSC_TRUE;
143:   eventInfo->visible       = PETSC_TRUE;
144:   eventInfo->depth         = 0;
145:   eventInfo->count         = 0;
146:   eventInfo->flops         = 0.0;
147:   eventInfo->time          = 0.0;
148:   eventInfo->numMessages   = 0.0;
149:   eventInfo->messageLength = 0.0;
150:   eventInfo->numReductions = 0.0;
151:   return(0);
152: }

154: #undef __FUNCT__  
156: /*@C
157:   EventPerfInfoCopy - Copy the activity and visibility data in eventInfo to outInfo

159:   Not collective

161:   Input Paramter:
162: . eventInfo - The input EventPerfInfo

164:   Output Paramter:
165: . outInfo   - The output EventPerfInfo

167:   Level: beginner

169: .keywords: log, event, copy
170: .seealso: EventPerfInfoClear()
171: @*/
172: int EventPerfInfoCopy(EventPerfInfo *eventInfo, EventPerfInfo *outInfo) {
174:   outInfo->id      = eventInfo->id;
175:   outInfo->active  = eventInfo->active;
176:   outInfo->visible = eventInfo->visible;
177:   return(0);
178: }

180: #undef __FUNCT__  
182: /*@C
183:   EventPerfLogEnsureSize - This ensures that a EventPerfLog is at least of a certain size.

185:   Not collective

187:   Input Paramters:
188: + eventLog - The EventPerfLog
189: - size     - The size

191:   Level: intermediate

193: .keywords: log, event, size, ensure
194: .seealso: EventPerfLogCreate()
195: @*/
196: int EventPerfLogEnsureSize(EventPerfLog eventLog, int size) {
197:   EventPerfInfo *eventInfo;
198:   int            ierr;

201:   while(size > eventLog->maxEvents) {
202:     PetscMalloc(eventLog->maxEvents*2 * sizeof(EventPerfInfo), &eventInfo);
203:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventPerfInfo));
204:     PetscFree(eventLog->eventInfo);
205:     eventLog->eventInfo  = eventInfo;
206:     eventLog->maxEvents *= 2;
207:   }
208:   while(eventLog->numEvents < size) {
209:     EventPerfInfoClear(&eventLog->eventInfo[eventLog->numEvents++]);
210:   }
211:   return(0);
212: }

214: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
215: #undef __FUNCT__  
217: /*@C
218:   EventRegLogRegister - Registers an event for logging operations in an application code.

220:   Not Collective

222:   Input Parameters:
223: + eventLog - The EventLog
224: . ename    - The name associated with the event
225: - cookie   - The cookie associated to the class for this event

227:   Output Parameter:
228: . event    - The event

230:   Example of Usage:
231: .vb
232:       int USER_EVENT;
233:       int user_event_flops;
234:       PetscLogEventRegister(&USER_EVENT,"User event name");
235:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
236:          [code segment to monitor]
237:          PetscLogFlops(user_event_flops);
238:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
239: .ve

241:   Notes: 
242:   PETSc automatically logs library events if the code has been
243:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
244:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
245:   intended for logging user events to supplement this PETSc
246:   information. 

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

255:   Level: intermediate

257: .keywords: log, event, register
258: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
259:           EventLogActivate(), EventLogDeactivate()
260: @*/
261: int EventRegLogRegister(EventRegLog eventLog, const char ename[], int cookie, PetscEvent *event) {
262:   EventRegInfo *eventInfo;
263:   char         *str;
264:   int           e;
265:   int           ierr;

270:   /* Should check cookie I think */
271:   e = eventLog->numEvents++;
272:   if (eventLog->numEvents > eventLog->maxEvents) {
273:     PetscMalloc(eventLog->maxEvents*2 * sizeof(EventRegInfo), &eventInfo);
274:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventRegInfo));
275:     PetscFree(eventLog->eventInfo);
276:     eventLog->eventInfo  = eventInfo;
277:     eventLog->maxEvents *= 2;
278:   }
279:   PetscStrallocpy(ename, &str);
280:   eventLog->eventInfo[e].name   = str;
281:   eventLog->eventInfo[e].cookie = cookie;
282: #if defined(PETSC_HAVE_MPE)
283:   if (UseMPE) {
284:     char *color;
285:     int   rank, beginID, endID;

287:     beginID = MPE_Log_get_event_number();
288:     endID   = MPE_Log_get_event_number();
289:     eventLog->eventInfo[e].mpe_id_begin = beginID;
290:     eventLog->eventInfo[e].mpe_id_end   = endID;
291:     MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
292:     if (!rank) {
293:       PetscLogGetRGBColor(&color);
294:       MPE_Describe_state(beginID, endID, str, color);
295:     }
296:   }
297: #endif
298:   *event = e;
299:   return(0);
300: }

302: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
303: #undef __FUNCT__  
305: /*@C
306:   EventPerfLogActivate - Indicates that a particular event should be logged.

308:   Not Collective

310:   Input Parameters:
311: + eventLog - The EventPerfLog
312: - event    - The event

314:    Usage:
315: .vb
316:       EventPerfLogDeactivate(log, VEC_SetValues);
317:         [code where you do not want to log VecSetValues()]
318:       EventPerfLogActivate(log, VEC_SetValues);
319:         [code where you do want to log VecSetValues()]
320: .ve 

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

326:   Level: advanced

328: .keywords: log, event, activate
329: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogDeactivate()
330: @*/
331: int EventPerfLogActivate(EventPerfLog eventLog, PetscEvent event) {
333:   eventLog->eventInfo[event].active = PETSC_TRUE;
334:   return(0);
335: }

337: #undef __FUNCT__  
339: /*@C
340:   EventPerfLogDeactivate - Indicates that a particular event should not be logged.

342:   Not Collective

344:   Input Parameters:
345: + eventLog - The EventPerfLog
346: - event    - The event

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

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

360:   Level: advanced

362: .keywords: log, event, activate
363: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogActivate()
364: @*/
365: int EventPerfLogDeactivate(EventPerfLog eventLog, PetscEvent event) {
367:   eventLog->eventInfo[event].active = PETSC_FALSE;
368:   return(0);
369: }

371: #undef __FUNCT__  
373: /*@C
374:   EventPerfLogActivateClass - Activates event logging for a PETSc object class.

376:   Not Collective

378:   Input Parameters:
379: + eventLog    - The EventPerfLog
380: . eventRegLog - The EventRegLog
381: - cookie      - The class id, for example MAT_COOKIE, SNES_COOKIE,

383:   Level: developer

385: .seealso: EventPerfLogDeactivateClass(), EventPerfLogActivate(), EventPerfLogDeactivate()
386: @*/
387: int EventPerfLogActivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, int cookie) {
388:   int e;

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

394:     if (c == cookie) eventLog->eventInfo[e].active = PETSC_TRUE;
395:   }
396:   return(0);
397: }

399: #undef __FUNCT__  
401: /*@C
402:   EventPerfLogDeactivateClass - Deactivates event logging for a PETSc object class.

404:   Not Collective

406:   Input Parameters:
407: + eventLog    - The EventPerfLog
408: . eventRegLog - The EventRegLog
409: - cookie - The class id, for example MAT_COOKIE, SNES_COOKIE,

411:   Level: developer

413: .seealso: EventPerfLogDeactivateClass(), EventPerfLogDeactivate(), EventPerfLogActivate()
414: @*/
415: int EventPerfLogDeactivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, int cookie) {
416:   int e;

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

422:     if (c == cookie) eventLog->eventInfo[e].active = PETSC_FALSE;
423:   }
424:   return(0);
425: }

427: /*------------------------------------------------ Query Functions --------------------------------------------------*/
428: #undef __FUNCT__  
430: /*@C
431:   EventPerfLogSetVisible - This function determines whether an event is printed during PetscLogPrintSummary()

433:   Not Collective

435:   Input Parameters:
436: + eventLog  - The EventPerfLog
437: . event     - The event to log
438: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

440:   Database Options:
441: . -log_summary - Activates log summary

443:   Level: intermediate

445: .keywords: log, visible, event
446: .seealso: EventPerfLogGetVisible(), EventRegLogRegister(), StageLogGetEventLog()
447: @*/
448: int EventPerfLogSetVisible(EventPerfLog eventLog, PetscEvent event, PetscTruth isVisible) {
450:   eventLog->eventInfo[event].visible = isVisible;
451:   return(0);
452: }

454: #undef __FUNCT__  
456: /*@C
457:   EventPerfLogGetVisible - This function returns whether an event is printed during PetscLogPrintSummary()

459:   Not Collective

461:   Input Parameters:
462: + eventLog  - The EventPerfLog
463: - event     - The event id to log

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

468:   Database Options:
469: . -log_summary - Activates log summary

471:   Level: intermediate

473: .keywords: log, visible, event
474: .seealso: EventPerfLogSetVisible(), EventRegLogRegister(), StageLogGetEventLog()
475: @*/
476: int EventPerfLogGetVisible(EventPerfLog eventLog, PetscEvent event, PetscTruth *isVisible) {
479:   *isVisible = eventLog->eventInfo[event].visible;
480:   return(0);
481: }

483: /*------------------------------------------------ Action Functions -------------------------------------------------*/
484: #undef __FUNCT__  
486: int PetscLogEventBeginDefault(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
487:   StageLog     stageLog;
488:   EventPerfLog eventLog;
489:   int          stage;
490:   int          ierr;

493:   PetscLogGetStageLog(&stageLog);
494:   StageLogGetCurrent(stageLog, &stage);
495:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
496:   /* Check for double counting */
497:   eventLog->eventInfo[event].depth++;
498:   if (eventLog->eventInfo[event].depth > 1) return(0);
499:   /* Log performance info */
500:   eventLog->eventInfo[event].count++;
501:   PetscTimeSubtract(eventLog->eventInfo[event].time);
502:   eventLog->eventInfo[event].flops         -= _TotalFlops;
503:   eventLog->eventInfo[event].numMessages   -= irecv_ct  + isend_ct  + recv_ct  + send_ct;
504:   eventLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
505:   eventLog->eventInfo[event].numReductions -= allreduce_ct;
506:   return(0);
507: }

509: #undef __FUNCT__  
511: int PetscLogEventEndDefault(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
512:   StageLog     stageLog;
513:   EventPerfLog eventLog;
514:   int          stage;
515:   int          ierr;

518:   PetscLogGetStageLog(&stageLog);
519:   StageLogGetCurrent(stageLog, &stage);
520:   StageLogGetEventPerfLog(stageLog, stage, &eventLog);
521:   /* Check for double counting */
522:   eventLog->eventInfo[event].depth--;
523:   if (eventLog->eventInfo[event].depth > 0) {
524:     return(0);
525:   } else if (eventLog->eventInfo[event].depth < 0) {
526:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
527:   }
528:   /* Log performance info */
529:   PetscTimeAdd(eventLog->eventInfo[event].time);
530:   eventLog->eventInfo[event].flops         += _TotalFlops;
531:   eventLog->eventInfo[event].numMessages   += irecv_ct  + isend_ct  + recv_ct  + send_ct;
532:   eventLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
533:   eventLog->eventInfo[event].numReductions += allreduce_ct;
534:   return(0);
535: }

537: #undef __FUNCT__  
539: int PetscLogEventBeginComplete(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
540:   StageLog       stageLog;
541:   EventRegLog    eventRegLog;
542:   EventPerfLog   eventPerfLog;
543:   Action        *tmpAction;
544:   PetscLogDouble start, end;
545:   PetscLogDouble curTime;
546:   int            stage;
547:   int            ierr;

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

592: #undef __FUNCT__  
594: int PetscLogEventEndComplete(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
595:   StageLog       stageLog;
596:   EventRegLog    eventRegLog;
597:   EventPerfLog   eventPerfLog;
598:   Action        *tmpAction;
599:   PetscLogDouble start, end;
600:   PetscLogDouble curTime;
601:   int            stage;
602:   int            ierr;

605:   /* Dynamically enlarge logging structures */
606:   if (numActions >= maxActions) {
607:     PetscTime(start);
608:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
609:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
610:     PetscFree(actions);
611:     actions     = tmpAction;
612:     maxActions *= 2;
613:     PetscTime(end);
614:     BaseTime += (end - start);
615:   }
616:   /* Record the event */
617:   PetscLogGetStageLog(&stageLog);
618:   StageLogGetCurrent(stageLog, &stage);
619:   StageLogGetEventRegLog(stageLog, &eventRegLog);
620:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
621:   PetscTime(curTime);
622:   if (logActions == PETSC_TRUE) {
623:     actions[numActions].time   = curTime - BaseTime;
624:     actions[numActions].action = ACTIONEND;
625:     actions[numActions].event  = event;
626:     actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
627:     if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
628:     if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
629:     if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
630:     actions[numActions].flops    = _TotalFlops;
631:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
632:     numActions++;
633:   }
634:   /* Check for double counting */
635:   eventPerfLog->eventInfo[event].depth--;
636:   if (eventPerfLog->eventInfo[event].depth > 0) {
637:     return(0);
638:   } else if (eventPerfLog->eventInfo[event].depth < 0) {
639:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
640:   }
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: }

651: #undef __FUNCT__  
653: int PetscLogEventBeginTrace(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
654:   StageLog       stageLog;
655:   EventRegLog    eventRegLog;
656:   EventPerfLog   eventPerfLog;
657:   PetscLogDouble cur_time;
658:   int            rank, stage;
659:   int            ierr;

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

664:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
665:   PetscLogGetStageLog(&stageLog);
666:   StageLogGetCurrent(stageLog, &stage);
667:   StageLogGetEventRegLog(stageLog, &eventRegLog);
668:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
669:   /* Check for double counting */
670:   eventPerfLog->eventInfo[event].depth++;
671:   tracelevel++;
672:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
673:   /* Log performance info */
674:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
675:   tracespace[2*tracelevel] = 0;
676:   PetscTime(cur_time);
677:   fprintf(tracefile, "%s[%d] %g Event begin: %sn", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
678:   fflush(tracefile);

680:   return(0);
681: }

683: #undef __FUNCT__  
685: int PetscLogEventEndTrace(PetscEvent event,int t,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4) {
686:   StageLog       stageLog;
687:   EventRegLog    eventRegLog;
688:   EventPerfLog   eventPerfLog;
689:   PetscLogDouble cur_time;
690:   int            rank, stage;
691:   int            ierr;

694:   tracelevel--;
695:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
696:   PetscLogGetStageLog(&stageLog);
697:   StageLogGetCurrent(stageLog, &stage);
698:   StageLogGetEventRegLog(stageLog, &eventRegLog);
699:   StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
700:   /* Check for double counting */
701:   eventPerfLog->eventInfo[event].depth--;
702:   if (eventPerfLog->eventInfo[event].depth > 0) {
703:     return(0);
704:   } else if (eventPerfLog->eventInfo[event].depth < 0 || tracelevel < 0) {
705:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
706:   }
707:   /* Log performance info */
708:   PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
709:   tracespace[2*tracelevel] = 0;
710:   PetscTime(cur_time);
711:   fprintf(tracefile, "%s[%d] %g Event end: %sn", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
712:   fflush(tracefile);
713:   return(0);
714: }