Actual source code: eventlog.c

petsc-3.6.1 2015-08-06
Report Typos and Errors
  2: /*
  3:      This defines part of the private API for logging performance information. It is intended to be used only by the
  4:    PETSc PetscLog...() interface and not elsewhere, nor by users. Hence the prototypes for these functions are NOT
  5:    in the public PETSc include files.

  7: */
  8: #include <petsc/private/logimpl.h>  /*I    "petscsys.h"   I*/

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

 15: /*@C
 16:   EventRegLogCreate - This creates a PetscEventRegLog object.

 18:   Not collective

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

 23:   Level: developer

 25: .keywords: log, event, create
 26: .seealso: EventRegLogDestroy(), PetscStageLogCreate()
 27: @*/
 28: PetscErrorCode EventRegLogCreate(PetscEventRegLog *eventLog)
 29: {
 30:   PetscEventRegLog l;
 31:   PetscErrorCode   ierr;

 34:   PetscNew(&l);
 35:   l->numEvents = 0;
 36:   l->maxEvents = 100;
 37:   PetscMalloc1(l->maxEvents, &l->eventInfo);
 38:   *eventLog    = l;
 39:   return(0);
 40: }

 44: /*@C
 45:   EventRegLogDestroy - This destroys a PetscEventRegLog object.

 47:   Not collective

 49:   Input Paramter:
 50: . eventLog - The PetscEventRegLog

 52:   Level: developer

 54: .keywords: log, event, destroy
 55: .seealso: EventRegLogCreate()
 56: @*/
 57: PetscErrorCode EventRegLogDestroy(PetscEventRegLog eventLog)
 58: {
 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: }

 73: /*@C
 74:   EventPerfLogCreate - This creates a PetscEventPerfLog object.

 76:   Not collective

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

 81:   Level: developer

 83: .keywords: log, event, create
 84: .seealso: EventPerfLogDestroy(), PetscStageLogCreate()
 85: @*/
 86: PetscErrorCode EventPerfLogCreate(PetscEventPerfLog *eventLog)
 87: {
 88:   PetscEventPerfLog l;
 89:   PetscErrorCode    ierr;

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

102: /*@C
103:   EventPerfLogDestroy - This destroys a PetscEventPerfLog object.

105:   Not collective

107:   Input Paramter:
108: . eventLog - The PetscEventPerfLog

110:   Level: developer

112: .keywords: log, event, destroy
113: .seealso: EventPerfLogCreate()
114: @*/
115: PetscErrorCode EventPerfLogDestroy(PetscEventPerfLog eventLog)
116: {

120:   PetscFree(eventLog->eventInfo);
121:   PetscFree(eventLog);
122:   return(0);
123: }

125: /*------------------------------------------------ General Functions -------------------------------------------------*/
128: /*@C
129:   EventPerfInfoClear - This clears a PetscEventPerfInfo object.

131:   Not collective

133:   Input Paramter:
134: . eventInfo - The PetscEventPerfInfo

136:   Level: developer

138: .keywords: log, event, destroy
139: .seealso: EventPerfLogCreate()
140: @*/
141: PetscErrorCode EventPerfInfoClear(PetscEventPerfInfo *eventInfo)
142: {
144:   eventInfo->id            = -1;
145:   eventInfo->active        = PETSC_TRUE;
146:   eventInfo->visible       = PETSC_TRUE;
147:   eventInfo->depth         = 0;
148:   eventInfo->count         = 0;
149:   eventInfo->flops         = 0.0;
150:   eventInfo->flops2        = 0.0;
151:   eventInfo->flopsTmp      = 0.0;
152:   eventInfo->time          = 0.0;
153:   eventInfo->time2         = 0.0;
154:   eventInfo->timeTmp       = 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 PetscEventPerfInfo

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

174:   Level: developer

176: .keywords: log, event, copy
177: .seealso: EventPerfInfoClear()
178: @*/
179: PetscErrorCode EventPerfInfoCopy(PetscEventPerfInfo *eventInfo, PetscEventPerfInfo *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 PetscEventPerfLog is at least of a certain size.

193:   Not collective

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

199:   Level: developer

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

210:   while (size > eventLog->maxEvents) {
211:     PetscMalloc1(eventLog->maxEvents*2, &eventInfo);
212:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(PetscEventPerfInfo));
213:     PetscFree(eventLog->eventInfo);

215:     eventLog->eventInfo  = eventInfo;
216:     eventLog->maxEvents *= 2;
217:   }
218:   while (eventLog->numEvents < size) {
219:     EventPerfInfoClear(&eventLog->eventInfo[eventLog->numEvents++]);
220:   }
221:   return(0);
222: }

224: #if defined(PETSC_HAVE_MPE)
225: #include <mpe.h>
226: PETSC_INTERN PetscErrorCode PetscLogMPEGetRGBColor(const char*[]);
229: PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
230: {
231:   PetscErrorCode    ierr;

234:   MPE_Log_event(petsc_stageLog->eventLog->eventInfo[event].mpe_id_begin,0,NULL);
235:   return(0);
236: }

240: PetscErrorCode PetscLogEventEndMPE(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
241: {
242:   PetscErrorCode    ierr;

245:   MPE_Log_event(petsc_stageLog->eventLog->eventInfo[event].mpe_id_end,0,NULL);
246:   return(0);
247: }
248: #endif

250: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
253: /*@C
254:   EventRegLogRegister - Registers an event for logging operations in an application code.

256:   Not Collective

258:   Input Parameters:
259: + eventLog - The EventLog
260: . ename    - The name associated with the event
261: - classid   - The classid associated to the class for this event

263:   Output Parameter:
264: . event    - The event

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

277:   Notes:
278:   PETSc automatically logs library events if the code has been
279:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
280:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
281:   intended for logging user events to supplement this PETSc
282:   information.

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

291:   Level: developer

293: .keywords: log, event, register
294: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
295:           EventLogActivate(), EventLogDeactivate()
296: @*/
297: PetscErrorCode EventRegLogRegister(PetscEventRegLog eventLog, const char ename[], PetscClassId classid, PetscLogEvent *event)
298: {
299:   PetscEventRegInfo *eventInfo;
300:   char              *str;
301:   int               e;
302:   PetscErrorCode    ierr;

307:   /* Should check classid I think */
308:   e = eventLog->numEvents++;
309:   if (eventLog->numEvents > eventLog->maxEvents) {
310:     PetscMalloc1(eventLog->maxEvents*2, &eventInfo);
311:     PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(PetscEventRegInfo));
312:     PetscFree(eventLog->eventInfo);

314:     eventLog->eventInfo  = eventInfo;
315:     eventLog->maxEvents *= 2;
316:   }
317:   PetscStrallocpy(ename, &str);

319:   eventLog->eventInfo[e].name    = str;
320:   eventLog->eventInfo[e].classid = classid;
321: #if defined(PETSC_HAVE_MPE)
322:   if (PetscLogPLB == PetscLogEventBeginMPE) {
323:     const char  *color;
324:     PetscMPIInt rank;
325:     int         beginID, endID;

327:     beginID = MPE_Log_get_event_number();
328:     endID   = MPE_Log_get_event_number();

330:     eventLog->eventInfo[e].mpe_id_begin = beginID;
331:     eventLog->eventInfo[e].mpe_id_end   = endID;

333:     MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
334:     if (!rank) {
335:       PetscLogMPEGetRGBColor(&color);
336:       MPE_Describe_state(beginID, endID, str, (char*)color);
337:     }
338:   }
339: #endif
340:   *event = e;
341:   return(0);
342: }

344: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
347: /*@C
348:   EventPerfLogActivate - Indicates that a particular event should be logged.

350:   Not Collective

352:   Input Parameters:
353: + eventLog - The PetscEventPerfLog
354: - event    - The event

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

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

368:   Level: developer

370: .keywords: log, event, activate
371: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogDeactivate()
372: @*/
373: PetscErrorCode EventPerfLogActivate(PetscEventPerfLog eventLog, PetscLogEvent event)
374: {
376:   eventLog->eventInfo[event].active = PETSC_TRUE;
377:   return(0);
378: }

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

385:   Not Collective

387:   Input Parameters:
388: + eventLog - The PetscEventPerfLog
389: - event    - The event

391:    Usage:
392: .vb
393:       EventPerfLogDeactivate(log, VEC_SetValues);
394:         [code where you do not want to log VecSetValues()]
395:       EventPerfLogActivate(log, VEC_SetValues);
396:         [code where you do want to log VecSetValues()]
397: .ve

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

403:   Level: developer

405: .keywords: log, event, activate
406: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogActivate()
407: @*/
408: PetscErrorCode EventPerfLogDeactivate(PetscEventPerfLog eventLog, PetscLogEvent event)
409: {
411:   eventLog->eventInfo[event].active = PETSC_FALSE;
412:   return(0);
413: }

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

420:   Not Collective

422:   Input Parameters:
423: + eventLog    - The PetscEventPerfLog
424: . eventRegLog - The PetscEventRegLog
425: - classid      - The class id, for example MAT_CLASSID, SNES_CLASSID,

427:   Level: developer

429: .seealso: EventPerfLogDeactivateClass(), EventPerfLogActivate(), EventPerfLogDeactivate()
430: @*/
431: PetscErrorCode EventPerfLogActivateClass(PetscEventPerfLog eventLog, PetscEventRegLog eventRegLog, PetscClassId classid)
432: {
433:   int e;

436:   for (e = 0; e < eventLog->numEvents; e++) {
437:     int c = eventRegLog->eventInfo[e].classid;
438:     if (c == classid) eventLog->eventInfo[e].active = PETSC_TRUE;
439:   }
440:   return(0);
441: }

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

448:   Not Collective

450:   Input Parameters:
451: + eventLog    - The PetscEventPerfLog
452: . eventRegLog - The PetscEventRegLog
453: - classid - The class id, for example MAT_CLASSID, SNES_CLASSID,

455:   Level: developer

457: .seealso: EventPerfLogDeactivateClass(), EventPerfLogDeactivate(), EventPerfLogActivate()
458: @*/
459: PetscErrorCode EventPerfLogDeactivateClass(PetscEventPerfLog eventLog, PetscEventRegLog eventRegLog, PetscClassId classid)
460: {
461:   int e;

464:   for (e = 0; e < eventLog->numEvents; e++) {
465:     int c = eventRegLog->eventInfo[e].classid;
466:     if (c == classid) eventLog->eventInfo[e].active = PETSC_FALSE;
467:   }
468:   return(0);
469: }

471: /*------------------------------------------------ Query Functions --------------------------------------------------*/
474: /*@C
475:   EventRegLogGetEvent - This function returns the event id given the event name.

477:   Not Collective

479:   Input Parameters:
480: + eventLog - The PetscEventRegLog
481: - name     - The stage name

483:   Output Parameter:
484: . event    - The event id, or -1 if not found

486:   Level: developer

488: .keywords: log, stage
489: .seealso: EventRegLogRegister()
490: @*/
491: PetscErrorCode  EventRegLogGetEvent(PetscEventRegLog eventLog, const char name[], PetscLogEvent *event)
492: {
493:   PetscBool      match;
494:   int            e;

500:   *event = -1;
501:   for (e = 0; e < eventLog->numEvents; e++) {
502:     PetscStrcasecmp(eventLog->eventInfo[e].name, name, &match);
503:     if (match) {
504:       *event = e;
505:       break;
506:     }
507:   }
508:   return(0);
509: }

513: /*@C
514:   EventPerfLogSetVisible - This function determines whether an event is printed during PetscLogView()

516:   Not Collective

518:   Input Parameters:
519: + eventLog  - The PetscEventPerfLog
520: . event     - The event to log
521: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

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

526:   Level: developer

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

540: /*@C
541:   EventPerfLogGetVisible - This function returns whether an event is printed during PetscLogView()

543:   Not Collective

545:   Input Parameters:
546: + eventLog  - The PetscEventPerfLog
547: - event     - The event id to log

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

552:   Database Options:
553: . -log_summary - Activates log summary

555:   Level: developer

557: .keywords: log, visible, event
558: .seealso: EventPerfLogSetVisible(), EventRegLogRegister(), PetscStageLogGetEventLog()
559: @*/
560: PetscErrorCode EventPerfLogGetVisible(PetscEventPerfLog eventLog, PetscLogEvent event, PetscBool  *isVisible)
561: {
564:   *isVisible = eventLog->eventInfo[event].visible;
565:   return(0);
566: }

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

573:   Input Parameters:
574: + stage - The stage number or PETSC_DETERMINE for the current stage
575: - event - The event number

577:   Output Parameters:
578: . info - This structure is filled with the performance information

580:   Level: Intermediate

582: .seealso: PetscLogEventGetFlops()
583: @*/
584: PetscErrorCode PetscLogEventGetPerfInfo(int stage, PetscLogEvent event, PetscEventPerfInfo *info)
585: {
586:   PetscStageLog     stageLog;
587:   PetscEventPerfLog eventLog = NULL;
588:   PetscErrorCode    ierr;

592:   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_summary or PetscLogBegin() before calling this routine");
593:   PetscLogGetStageLog(&stageLog);
594:   if (stage < 0) {PetscStageLogGetCurrent(stageLog, &stage);}
595:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
596:   *info = eventLog->eventInfo[event];
597:   return(0);
598: }

602: PetscErrorCode PetscLogEventGetFlops(PetscLogEvent event, PetscLogDouble *flops)
603: {
604:   PetscStageLog     stageLog;
605:   PetscEventPerfLog eventLog = NULL;
606:   int               stage;
607:   PetscErrorCode    ierr;

610:   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_summary or PetscLogBegin() before calling this routine");
611:   PetscLogGetStageLog(&stageLog);
612:   PetscStageLogGetCurrent(stageLog, &stage);
613:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
614:   *flops = eventLog->eventInfo[event].flops;
615:   return(0);
616: }

620: PetscErrorCode PetscLogEventZeroFlops(PetscLogEvent event)
621: {
622:   PetscStageLog     stageLog;
623:   PetscEventPerfLog eventLog = NULL;
624:   int               stage;
625:   PetscErrorCode    ierr;

628:   PetscLogGetStageLog(&stageLog);
629:   PetscStageLogGetCurrent(stageLog, &stage);
630:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);

632:   eventLog->eventInfo[event].flops    = 0.0;
633:   eventLog->eventInfo[event].flops2   = 0.0;
634:   eventLog->eventInfo[event].flopsTmp = 0.0;
635:   return(0);
636: }

638: #if defined(PETSC_HAVE_PAPI)
639: #include <papi.h>
640: extern int PAPIEventSet;
641: #endif

645: PetscErrorCode PetscLogEventBeginDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
646: {
647:   PetscStageLog     stageLog;
648:   PetscEventPerfLog eventLog = NULL;
649:   int               stage;
650:   PetscErrorCode    ierr;

653:   PetscLogGetStageLog(&stageLog);
654:   PetscStageLogGetCurrent(stageLog, &stage);
655:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
656:   /* Check for double counting */
657:   eventLog->eventInfo[event].depth++;
658:   if (eventLog->eventInfo[event].depth > 1) return(0);
659:   /* Log performance info */
660:   eventLog->eventInfo[event].count++;
661:   eventLog->eventInfo[event].timeTmp = 0.0;
662:   PetscTimeSubtract(&eventLog->eventInfo[event].timeTmp);
663:   eventLog->eventInfo[event].flopsTmp = 0.0;
664: #if defined(PETSC_HAVE_PAPI)
665:   { long_long values[2];
666:     PAPI_read(PAPIEventSet,values);

668:     eventLog->eventInfo[event].flopsTmp -= values[0];
669:     /*    printf("fma %g flops %g\n",(double)values[1],(double)values[0]); */
670:   }
671: #else
672:   eventLog->eventInfo[event].flopsTmp -= petsc_TotalFlops;
673: #endif
674:   eventLog->eventInfo[event].numMessages   -= petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
675:   eventLog->eventInfo[event].messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
676:   eventLog->eventInfo[event].numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
677:   return(0);
678: }

682: PetscErrorCode PetscLogEventEndDefault(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
683: {
684:   PetscStageLog     stageLog;
685:   PetscEventPerfLog eventLog = NULL;
686:   int               stage;
687:   PetscErrorCode    ierr;

690:   PetscLogGetStageLog(&stageLog);
691:   PetscStageLogGetCurrent(stageLog, &stage);
692:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventLog);
693:   /* Check for double counting */
694:   eventLog->eventInfo[event].depth--;
695:   if (eventLog->eventInfo[event].depth > 0) return(0);
696:   else if (eventLog->eventInfo[event].depth < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
697:   /* Log performance info */
698:   PetscTimeAdd(&eventLog->eventInfo[event].timeTmp);
699:   eventLog->eventInfo[event].time  += eventLog->eventInfo[event].timeTmp;
700:   eventLog->eventInfo[event].time2 += eventLog->eventInfo[event].timeTmp*eventLog->eventInfo[event].timeTmp;
701: #if defined(PETSC_HAVE_PAPI)
702:   { long_long values[2];
703:     PAPI_read(PAPIEventSet,values);

705:     eventLog->eventInfo[event].flopsTmp += values[0];
706:     /* printf("fma %g flops %g\n",(double)values[1],(double)values[0]); */
707:   }
708: #else
709:   eventLog->eventInfo[event].flopsTmp += petsc_TotalFlops;
710: #endif
711:   eventLog->eventInfo[event].flops         += eventLog->eventInfo[event].flopsTmp;
712:   eventLog->eventInfo[event].flops2        += eventLog->eventInfo[event].flopsTmp*eventLog->eventInfo[event].flopsTmp;
713:   eventLog->eventInfo[event].numMessages   += petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
714:   eventLog->eventInfo[event].messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
715:   eventLog->eventInfo[event].numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
716:   return(0);
717: }

721: PetscErrorCode PetscLogEventBeginComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
722: {
723:   PetscStageLog     stageLog;
724:   PetscEventRegLog  eventRegLog;
725:   PetscEventPerfLog eventPerfLog = NULL;
726:   Action            *tmpAction;
727:   PetscLogDouble    start, end;
728:   PetscLogDouble    curTime;
729:   int               stage;
730:   PetscErrorCode    ierr;

733:   /* Dynamically enlarge logging structures */
734:   if (petsc_numActions >= petsc_maxActions) {
735:     PetscTime(&start);
736:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
737:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
738:     PetscFree(petsc_actions);

740:     petsc_actions     = tmpAction;
741:     petsc_maxActions *= 2;
742:     PetscTime(&end);
743:     petsc_BaseTime += (end - start);
744:   }
745:   /* Record the event */
746:   PetscLogGetStageLog(&stageLog);
747:   PetscStageLogGetCurrent(stageLog, &stage);
748:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
749:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
750:   PetscTime(&curTime);
751:   if (petsc_logActions) {
752:     petsc_actions[petsc_numActions].time    = curTime - petsc_BaseTime;
753:     petsc_actions[petsc_numActions].action  = ACTIONBEGIN;
754:     petsc_actions[petsc_numActions].event   = event;
755:     petsc_actions[petsc_numActions].classid = eventRegLog->eventInfo[event].classid;
756:     if (o1) petsc_actions[petsc_numActions].id1 = o1->id;
757:     else petsc_actions[petsc_numActions].id1 = -1;
758:     if (o2) petsc_actions[petsc_numActions].id2 = o2->id;
759:     else petsc_actions[petsc_numActions].id2 = -1;
760:     if (o3) petsc_actions[petsc_numActions].id3 = o3->id;
761:     else petsc_actions[petsc_numActions].id3 = -1;
762:     petsc_actions[petsc_numActions].flops = petsc_TotalFlops;

764:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
765:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
766:     petsc_numActions++;
767:   }
768:   /* Check for double counting */
769:   eventPerfLog->eventInfo[event].depth++;
770:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
771:   /* Log the performance info */
772:   eventPerfLog->eventInfo[event].count++;
773:   eventPerfLog->eventInfo[event].time          -= curTime;
774:   eventPerfLog->eventInfo[event].flops         -= petsc_TotalFlops;
775:   eventPerfLog->eventInfo[event].numMessages   -= petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
776:   eventPerfLog->eventInfo[event].messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
777:   eventPerfLog->eventInfo[event].numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
778:   return(0);
779: }

783: PetscErrorCode PetscLogEventEndComplete(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
784: {
785:   PetscStageLog     stageLog;
786:   PetscEventRegLog  eventRegLog;
787:   PetscEventPerfLog eventPerfLog = NULL;
788:   Action            *tmpAction;
789:   PetscLogDouble    start, end;
790:   PetscLogDouble    curTime;
791:   int               stage;
792:   PetscErrorCode    ierr;

795:   /* Dynamically enlarge logging structures */
796:   if (petsc_numActions >= petsc_maxActions) {
797:     PetscTime(&start);
798:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
799:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
800:     PetscFree(petsc_actions);

802:     petsc_actions     = tmpAction;
803:     petsc_maxActions *= 2;
804:     PetscTime(&end);
805:     petsc_BaseTime += (end - start);
806:   }
807:   /* Record the event */
808:   PetscLogGetStageLog(&stageLog);
809:   PetscStageLogGetCurrent(stageLog, &stage);
810:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
811:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
812:   PetscTime(&curTime);
813:   if (petsc_logActions) {
814:     petsc_actions[petsc_numActions].time    = curTime - petsc_BaseTime;
815:     petsc_actions[petsc_numActions].action  = ACTIONEND;
816:     petsc_actions[petsc_numActions].event   = event;
817:     petsc_actions[petsc_numActions].classid = eventRegLog->eventInfo[event].classid;
818:     if (o1) petsc_actions[petsc_numActions].id1 = o1->id;
819:     else petsc_actions[petsc_numActions].id1 = -1;
820:     if (o2) petsc_actions[petsc_numActions].id2 = o2->id;
821:     else petsc_actions[petsc_numActions].id2 = -1;
822:     if (o3) petsc_actions[petsc_numActions].id3 = o3->id;
823:     else petsc_actions[petsc_numActions].id3 = -1;
824:     petsc_actions[petsc_numActions].flops = petsc_TotalFlops;

826:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
827:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
828:     petsc_numActions++;
829:   }
830:   /* Check for double counting */
831:   eventPerfLog->eventInfo[event].depth--;
832:   if (eventPerfLog->eventInfo[event].depth > 0) return(0);
833:   else if (eventPerfLog->eventInfo[event].depth < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
834:   /* Log the performance info */
835:   eventPerfLog->eventInfo[event].count++;
836:   eventPerfLog->eventInfo[event].time          += curTime;
837:   eventPerfLog->eventInfo[event].flops         += petsc_TotalFlops;
838:   eventPerfLog->eventInfo[event].numMessages   += petsc_irecv_ct  + petsc_isend_ct  + petsc_recv_ct  + petsc_send_ct;
839:   eventPerfLog->eventInfo[event].messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
840:   eventPerfLog->eventInfo[event].numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
841:   return(0);
842: }

846: PetscErrorCode PetscLogEventBeginTrace(PetscLogEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
847: {
848:   PetscStageLog     stageLog;
849:   PetscEventRegLog  eventRegLog;
850:   PetscEventPerfLog eventPerfLog = NULL;
851:   PetscLogDouble    cur_time;
852:   PetscMPIInt       rank;
853:   int               stage,err;
854:   PetscErrorCode    ierr;

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

859:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
860:   PetscLogGetStageLog(&stageLog);
861:   PetscStageLogGetCurrent(stageLog, &stage);
862:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
863:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
864:   /* Check for double counting */
865:   eventPerfLog->eventInfo[event].depth++;
866:   petsc_tracelevel++;
867:   if (eventPerfLog->eventInfo[event].depth > 1) return(0);
868:   /* Log performance info */
869:   PetscTime(&cur_time);
870:   PetscFPrintf(PETSC_COMM_SELF,petsc_tracefile, "%s[%d] %g Event begin: %s\n", petsc_tracespace, rank, cur_time-petsc_tracetime, eventRegLog->eventInfo[event].name);
871:   PetscStrncpy(petsc_tracespace, petsc_traceblanks, 2*petsc_tracelevel);

873:   petsc_tracespace[2*petsc_tracelevel] = 0;

875:   err = fflush(petsc_tracefile);
876:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
877:   return(0);
878: }

882: PetscErrorCode PetscLogEventEndTrace(PetscLogEvent event,int t,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
883: {
884:   PetscStageLog     stageLog;
885:   PetscEventRegLog  eventRegLog;
886:   PetscEventPerfLog eventPerfLog = NULL;
887:   PetscLogDouble    cur_time;
888:   int               stage,err;
889:   PetscMPIInt       rank;
890:   PetscErrorCode    ierr;

893:   petsc_tracelevel--;
894:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
895:   PetscLogGetStageLog(&stageLog);
896:   PetscStageLogGetCurrent(stageLog, &stage);
897:   PetscStageLogGetEventRegLog(stageLog, &eventRegLog);
898:   PetscStageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
899:   /* Check for double counting */
900:   eventPerfLog->eventInfo[event].depth--;
901:   if (eventPerfLog->eventInfo[event].depth > 0) return(0);
902:   else if (eventPerfLog->eventInfo[event].depth < 0 || petsc_tracelevel < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");

904:   /* Log performance info */
905:   PetscStrncpy(petsc_tracespace, petsc_traceblanks, 2*petsc_tracelevel);

907:   petsc_tracespace[2*petsc_tracelevel] = 0;
908:   PetscTime(&cur_time);
909:   PetscFPrintf(PETSC_COMM_SELF,petsc_tracefile, "%s[%d] %g Event end: %s\n", petsc_tracespace, rank, cur_time-petsc_tracetime, eventRegLog->eventInfo[event].name);
910:   err  = fflush(petsc_tracefile);
911:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
912:   return(0);
913: }