Actual source code: plog.c

  1: #define PETSC_DLL
  2: /*
  3:       PETSc code to log object creation and destruction and PETSc events.
  4: */
 5:  #include petsc.h
 6:  #include petsctime.h
  7: #if defined(PETSC_HAVE_MPE)
  8: #include "mpe.h"
  9: #endif
 10: #include <stdarg.h>
 11: #include <sys/types.h>
 12:  #include petscsys.h
 13: #if defined(PETSC_HAVE_STDLIB_H)
 14: #include <stdlib.h>
 15: #endif
 16: #if defined(PETSC_HAVE_MALLOC_H)
 17: #include <malloc.h>
 18: #endif
 19: #include "petscfix.h"
 20:  #include plog.h

 22: PetscLogEvent  PETSC_LARGEST_EVENT  = PETSC_EVENT;

 24: #if defined(PETSC_USE_LOG)
 25: #include "petscmachineinfo.h"
 26: #include "petscconfiginfo.h"

 28: /* used in the MPI_XXX() count macros in petsclog.h */

 30: /* Action and object logging variables */
 31: Action    *actions    = PETSC_NULL;
 32: Object    *objects    = PETSC_NULL;
 33: PetscTruth logActions = PETSC_FALSE;
 34: PetscTruth logObjects = PETSC_FALSE;
 35: int        numActions = 0, maxActions = 100;
 36: int        numObjects = 0, maxObjects = 100;
 37: int        numObjectsDestroyed = 0;

 39: /* Global counters */
 40: PetscLogDouble  BaseTime        = 0.0;
 41: PetscLogDouble  _TotalFlops     = 0.0; /* The number of flops */
 42: PetscLogDouble  petsc_tmp_flops = 0.0; /* The incremental number of flops */
 43: PetscLogDouble  send_ct         = 0.0; /* The number of sends */
 44: PetscLogDouble  recv_ct         = 0.0; /* The number of receives */
 45: PetscLogDouble  send_len        = 0.0; /* The total length of all sent messages */
 46: PetscLogDouble  recv_len        = 0.0; /* The total length of all received messages */
 47: PetscLogDouble  isend_ct        = 0.0; /* The number of immediate sends */
 48: PetscLogDouble  irecv_ct        = 0.0; /* The number of immediate receives */
 49: PetscLogDouble  isend_len       = 0.0; /* The total length of all immediate send messages */
 50: PetscLogDouble  irecv_len       = 0.0; /* The total length of all immediate receive messages */
 51: PetscLogDouble  wait_ct         = 0.0; /* The number of waits */
 52: PetscLogDouble  wait_any_ct     = 0.0; /* The number of anywaits */
 53: PetscLogDouble  wait_all_ct     = 0.0; /* The number of waitalls */
 54: PetscLogDouble  sum_of_waits_ct = 0.0; /* The total number of waits */
 55: PetscLogDouble  allreduce_ct    = 0.0; /* The number of reductions */
 56: PetscLogDouble  gather_ct       = 0.0; /* The number of gathers and gathervs */
 57: PetscLogDouble  scatter_ct      = 0.0; /* The number of scatters and scattervs */

 59: /* Logging functions */
 60: PetscErrorCode  (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
 61: PetscErrorCode  (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
 62: PetscErrorCode  (*_PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
 63: PetscErrorCode  (*_PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;

 65: /* Tracing event logging variables */
 66: FILE          *tracefile       = PETSC_NULL;
 67: int            tracelevel      = 0;
 68: const char    *traceblanks     = "                                                                                                    ";
 69: char           tracespace[128] = " ";
 70: PetscLogDouble tracetime       = 0.0;

 72: /*---------------------------------------------- General Functions --------------------------------------------------*/
 75: /*@C
 76:   PetscLogDestroy - Destroys the object and event logging data and resets the global counters. 

 78:   Not Collective

 80:   Notes:
 81:   This routine should not usually be used by programmers. Instead employ 
 82:   PetscLogStagePush() and PetscLogStagePop().

 84:   Level: developer

 86: .keywords: log, destroy
 87: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
 88: @*/
 89: PetscErrorCode  PetscLogDestroy(void)
 90: {
 91:   StageLog       stageLog;

 95:   PetscFree(actions);
 96:   actions = PETSC_NULL;
 97:   PetscFree(objects);
 98:   objects =  PETSC_NULL;
 99:   PetscLogSet(PETSC_NULL, PETSC_NULL);

101:   /* Resetting phase */
102:   PetscLogGetStageLog(&stageLog);
103:   StageLogDestroy(stageLog);
104:   _TotalFlops         = 0.0;
105:   numActions          = 0;
106:   numObjects          = 0;
107:   numObjectsDestroyed = 0;
108:   return(0);
109: }

113: /*@C
114:   PetscLogSet - Sets the logging functions called at the beginning and ending of every event.

116:   Not Collective

118:   Input Parameters:
119: + b - The function called at beginning of event
120: - e - The function called at end of event

122:   Level: developer

124: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
125: @*/
126: PetscErrorCode  PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
127:             PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
128: {
130:   _PetscLogPLB = b;
131:   _PetscLogPLE = e;
132:   return(0);
133: }

135: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
138: PetscErrorCode  PetscLogBegin_Private(void)
139: {
140:   int               stage;
141:   PetscTruth        opt;
142:   PetscErrorCode    ierr;

145:   PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
146:   if (opt) {
147:     logActions = PETSC_FALSE;
148:   }
149:   PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
150:   if (opt) {
151:     logObjects = PETSC_FALSE;
152:   }
153:   if (logActions) {
154:     PetscMalloc(maxActions * sizeof(Action), &actions);
155:   }
156:   if (logObjects) {
157:     PetscMalloc(maxObjects * sizeof(Object), &objects);
158:   }
159:   _PetscLogPHC = PetscLogObjCreateDefault;
160:   _PetscLogPHD = PetscLogObjDestroyDefault;
161:   /* Setup default logging structures */
162:   StageLogCreate(&_stageLog);
163:   StageLogRegister(_stageLog, "Main Stage", &stage);
164:   /* All processors sync here for more consistent logging */
165:   MPI_Barrier(PETSC_COMM_WORLD);
166:   PetscTime(BaseTime);
167:   PetscLogStagePush(stage);
168:   return(0);
169: }

173: /*@C
174:   PetscLogBegin - Turns on logging of objects and events. This logs flop
175:   rates and object creation and should not slow programs down too much.
176:   This routine may be called more than once.

178:   Collective over PETSC_COMM_WORLD

180:   Options Database Keys:
181: + -log_summary - Prints summary of flop and timing information to the 
182:                   screen (for code compiled with PETSC_USE_LOG)
183: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)

185:   Usage:
186: .vb
187:       PetscInitialize(...);
188:       PetscLogBegin();
189:        ... code ...
190:       PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump(); 
191:       PetscFinalize();
192: .ve

194:   Notes:
195:   PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of 
196:   the logging information.

198:   Level: advanced

200: .keywords: log, begin
201: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
202: @*/
203: PetscErrorCode  PetscLogBegin(void)
204: {

208:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
209:   PetscLogBegin_Private();
210:   return(0);
211: }

215: /*@C
216:   PetscLogAllBegin - Turns on extensive logging of objects and events. Logs 
217:   all events. This creates large log files and slows the program down.

219:   Collective on PETSC_COMM_WORLD

221:   Options Database Keys:
222: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)

224:   Usage:
225: .vb
226:      PetscInitialize(...);
227:      PetscLogAllBegin();
228:      ... code ...
229:      PetscLogDump(filename);
230:      PetscFinalize();
231: .ve

233:   Notes:
234:   A related routine is PetscLogBegin (with the options key -log), which is 
235:   intended for production runs since it logs only flop rates and object
236:   creation (and shouldn't significantly slow the programs).

238:   Level: advanced

240: .keywords: log, all, begin
241: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
242: @*/
243: PetscErrorCode  PetscLogAllBegin(void)
244: {

248:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
249:   PetscLogBegin_Private();
250:   return(0);
251: }

255: /*@
256:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
257:   begins or ends, the event name is printed.

259:   Collective on PETSC_COMM_WORLD

261:   Input Parameter:
262: . file - The file to print trace in (e.g. stdout)

264:   Options Database Key:
265: . -log_trace [filename] - Activates PetscLogTraceBegin()

267:   Notes:
268:   PetscLogTraceBegin() prints the processor number, the execution time (sec),
269:   then "Event begin:" or "Event end:" followed by the event name.

271:   PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
272:   to determine where a program is hanging without running in the 
273:   debugger.  Can be used in conjunction with the -info option. 

275:   Level: intermediate

277: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
278: @*/
279: PetscErrorCode  PetscLogTraceBegin(FILE *file)
280: {

284:   tracefile = file;
285:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
286:   PetscLogBegin_Private();
287:   return(0);
288: }

292: /*@
293:   PetscLogActions - Determines whether actions are logged for the graphical viewer.

295:   Not Collective

297:   Input Parameter:
298: . flag - PETSC_TRUE if actions are to be logged

300:   Level: intermediate

302:   Note: Logging of actions continues to consume more memory as the program
303:   runs. Long running programs should consider turning this feature off.

305:   Options Database Keys:
306: . -log_exclude_actions - Turns off actions logging

308: .keywords: log, stage, register
309: .seealso: PetscLogStagePush(), PetscLogStagePop()
310: @*/
311: PetscErrorCode  PetscLogActions(PetscTruth flag)
312: {
314:   logActions = flag;
315:   return(0);
316: }

320: /*@
321:   PetscLogObjects - Determines whether objects are logged for the graphical viewer.

323:   Not Collective

325:   Input Parameter:
326: . flag - PETSC_TRUE if objects are to be logged

328:   Level: intermediate

330:   Note: Logging of objects continues to consume more memory as the program
331:   runs. Long running programs should consider turning this feature off.

333:   Options Database Keys:
334: . -log_exclude_objects - Turns off objects logging

336: .keywords: log, stage, register
337: .seealso: PetscLogStagePush(), PetscLogStagePop()
338: @*/
339: PetscErrorCode  PetscLogObjects(PetscTruth flag)
340: {
342:   logObjects = flag;
343:   return(0);
344: }

346: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
349: /*@C
350:   PetscLogStageRegister - Attaches a charactor string name to a logging stage.

352:   Not Collective

354:   Input Parameter:
355: . sname - The name to associate with that stage

357:   Output Parameter:
358: . stage - The stage number

360:   Level: intermediate

362: .keywords: log, stage, register
363: .seealso: PetscLogStagePush(), PetscLogStagePop()
364: @*/
365: PetscErrorCode  PetscLogStageRegister(const char sname[],PetscLogStage *stage)
366: {
367:   StageLog       stageLog;
368:   PetscLogEvent  event;

372:   PetscLogGetStageLog(&stageLog);
373:   StageLogRegister(stageLog, sname, stage);
374:   /* Copy events already changed in the main stage, this sucks */
375:   EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
376:   for(event = 0; event < stageLog->eventLog->numEvents; event++) {
377:     EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
378:                              &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
379:   }
380:   ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
381:   return(0);
382: }

386: /*@C
387:   PetscLogStagePush - This function pushes a stage on the stack.

389:   Not Collective

391:   Input Parameter:
392: . stage - The stage on which to log

394:   Usage:
395:   If the option -log_sumary is used to run the program containing the 
396:   following code, then 2 sets of summary data will be printed during
397:   PetscFinalize().
398: .vb
399:       PetscInitialize(int *argc,char ***args,0,0);
400:       [stage 0 of code]   
401:       PetscLogStagePush(1);
402:       [stage 1 of code]
403:       PetscLogStagePop();
404:       PetscBarrier(...);
405:       [more stage 0 of code]   
406:       PetscFinalize();
407: .ve
408:  
409:   Notes:
410:   Use PetscLogStageRegister() to register a stage.

412:   Level: intermediate

414: .keywords: log, push, stage
415: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
416: @*/
417: PetscErrorCode  PetscLogStagePush(PetscLogStage stage)
418: {
419:   StageLog       stageLog;

423:   PetscLogGetStageLog(&stageLog);
424:   StageLogPush(stageLog, stage);
425:   return(0);
426: }

430: /*@C
431:   PetscLogStagePop - This function pops a stage from the stack.

433:   Not Collective

435:   Usage:
436:   If the option -log_sumary is used to run the program containing the 
437:   following code, then 2 sets of summary data will be printed during
438:   PetscFinalize().
439: .vb
440:       PetscInitialize(int *argc,char ***args,0,0);
441:       [stage 0 of code]   
442:       PetscLogStagePush(1);
443:       [stage 1 of code]
444:       PetscLogStagePop();
445:       PetscBarrier(...);
446:       [more stage 0 of code]   
447:       PetscFinalize();
448: .ve

450:   Notes:  
451:   Use PetscLogStageRegister() to register a stage.

453:   Level: intermediate

455: .keywords: log, pop, stage
456: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
457: @*/
458: PetscErrorCode  PetscLogStagePop(void)
459: {
460:   StageLog       stageLog;

464:   PetscLogGetStageLog(&stageLog);
465:   StageLogPop(stageLog);
466:   return(0);
467: }

471: /*@
472:   PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().

474:   Not Collective 

476:   Input Parameters:
477: + stage    - The stage
478: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

480:   Level: intermediate

482: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
483: @*/
484: PetscErrorCode  PetscLogStageSetActive(PetscLogStage stage, PetscTruth isActive)
485: {
486:   StageLog       stageLog;

490:   PetscLogGetStageLog(&stageLog);
491:   StageLogSetActive(stageLog, stage, isActive);
492:   return(0);
493: }

497: /*@
498:   PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().

500:   Not Collective 

502:   Input Parameter:
503: . stage    - The stage

505:   Output Parameter:
506: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

508:   Level: intermediate

510: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
511: @*/
512: PetscErrorCode  PetscLogStageGetActive(PetscLogStage stage, PetscTruth *isActive)
513: {
514:   StageLog       stageLog;

518:   PetscLogGetStageLog(&stageLog);
519:   StageLogGetActive(stageLog, stage, isActive);
520:   return(0);
521: }

525: /*@
526:   PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()

528:   Not Collective 

530:   Input Parameters:
531: + stage     - The stage
532: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

534:   Level: intermediate

536: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
537: @*/
538: PetscErrorCode  PetscLogStageSetVisible(PetscLogStage stage, PetscTruth isVisible)
539: {
540:   StageLog       stageLog;

544:   PetscLogGetStageLog(&stageLog);
545:   StageLogSetVisible(stageLog, stage, isVisible);
546:   return(0);
547: }

551: /*@
552:   PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()

554:   Not Collective 

556:   Input Parameter:
557: . stage     - The stage

559:   Output Parameter:
560: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

562:   Level: intermediate

564: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
565: @*/
566: PetscErrorCode  PetscLogStageGetVisible(PetscLogStage stage, PetscTruth *isVisible)
567: {
568:   StageLog       stageLog;

572:   PetscLogGetStageLog(&stageLog);
573:   StageLogGetVisible(stageLog, stage, isVisible);
574:   return(0);
575: }

579: /*@C
580:   PetscLogStageGetId - Returns the stage id when given the stage name.

582:   Not Collective 

584:   Input Parameter:
585: . name  - The stage name

587:   Output Parameter:
588: . stage - The stage

590:   Level: intermediate

592: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
593: @*/
594: PetscErrorCode  PetscLogStageGetId(const char name[], PetscLogStage *stage)
595: {
596:   StageLog       stageLog;

600:   PetscLogGetStageLog(&stageLog);
601:   StageLogGetStage(stageLog, name, stage);
602:   return(0);
603: }

605: /*------------------------------------------------ Event Functions --------------------------------------------------*/
608: /*@C
609:   PetscLogEventRegister - Registers an event name for logging operations in an application code. 

611:   Not Collective

613:   Input Parameter:
614: + name   - The name associated with the event
615: - cookie - The cookie associated to the class for this event, obtain either with
616:            PetscCookieRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
617:             
618:   Output Parameter:
619: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

621:   Example of Usage:
622: .vb
623:       PetscLogEvent USER_EVENT;
624:       PetscCookie cookie;
625:       int user_event_flops;
626:       PetscCookieRegister("class name",&cookie);
627:       PetscLogEventRegister("User event name",cookie,&USER_EVENT);
628:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
629:          [code segment to monitor]
630:          PetscLogFlops(user_event_flops);
631:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
632: .ve

634:   Notes: 
635:   PETSc automatically logs library events if the code has been
636:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
637:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
638:   intended for logging user events to supplement this PETSc
639:   information. 

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

648:   The cookie is associated with each event so that classes of events
649:   can be disabled simultaneously, such as all matrix events. The user
650:   can either use an existing cookie, such as MAT_COOKIE, or create
651:   their own as shown in the example.

653:   Level: intermediate

655: .keywords: log, event, register
656: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
657:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
658:           PetscLogEventActivate(), PetscLogEventDeactivate(), PetscCookieRegister()
659: @*/
660: PetscErrorCode  PetscLogEventRegister(const char name[],PetscCookie cookie,PetscLogEvent *event)
661: {
662:   StageLog       stageLog;
663:   int            stage;

667:   *event = PETSC_DECIDE;
668:   PetscLogGetStageLog(&stageLog);
669:   EventRegLogRegister(stageLog->eventLog, name, cookie, event);
670:   for(stage = 0; stage < stageLog->numStages; stage++) {
671:     EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
672:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
673:   }
674:   return(0);
675: }

679: /*@
680:   PetscLogEventActivate - Indicates that a particular event should be logged.

682:   Not Collective

684:   Input Parameter:
685: . event - The event id

687:   Usage:
688: .vb
689:       PetscLogEventDeactivate(VEC_SetValues);
690:         [code where you do not want to log VecSetValues()]
691:       PetscLogEventActivate(VEC_SetValues);
692:         [code where you do want to log VecSetValues()]
693: .ve 

695:   Note:
696:   The event may be either a pre-defined PETSc event (found in include/petsclog.h)
697:   or an event number obtained with PetscLogEventRegister().

699:   Level: advanced

701: .keywords: log, event, activate
702: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
703: @*/
704: PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
705: {
706:   StageLog       stageLog;
707:   int            stage;

711:   PetscLogGetStageLog(&stageLog);
712:   StageLogGetCurrent(stageLog, &stage);
713:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
714:   return(0);
715: }

719: /*@
720:   PetscLogEventDeactivate - Indicates that a particular event should not be logged. 

722:   Not Collective

724:   Input Parameter:
725: . event - The event id

727:   Usage:
728: .vb
729:       PetscLogEventDeactivate(VEC_SetValues);
730:         [code where you do not want to log VecSetValues()]
731:       PetscLogEventActivate(VEC_SetValues);
732:         [code where you do want to log VecSetValues()]
733: .ve 

735:   Note: 
736:   The event may be either a pre-defined PETSc event (found in
737:   include/petsclog.h) or an event number obtained with PetscLogEventRegister()).

739:   Level: advanced

741: .keywords: log, event, deactivate
742: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
743: @*/
744: PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
745: {
746:   StageLog       stageLog;
747:   int            stage;

751:   PetscLogGetStageLog(&stageLog);
752:   StageLogGetCurrent(stageLog, &stage);
753:   EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
754:   return(0);
755: }

759: /*@
760:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

762:   Not Collective

764:   Input Parameters:
765: + event    - The event id
766: - isActive - The activity flag determining whether the event is logged

768:   Level: advanced

770: .keywords: log, event, activate
771: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
772: @*/
773: PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscTruth isActive)
774: {
775:   StageLog       stageLog;
776:   int            stage;

780:   PetscLogGetStageLog(&stageLog);
781:   for(stage = 0; stage < stageLog->numStages; stage++) {
782:     if (isActive) {
783:       EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
784:     } else {
785:       EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
786:     }
787:   }
788:   return(0);
789: }

793: /*@
794:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

796:   Not Collective

798:   Input Parameter:
799: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

801:   Level: developer

803: .keywords: log, event, activate, class
804: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
805: @*/
806: PetscErrorCode  PetscLogEventActivateClass(PetscCookie cookie)
807: {
808:   StageLog       stageLog;
809:   int            stage;

813:   PetscLogGetStageLog(&stageLog);
814:   StageLogGetCurrent(stageLog, &stage);
815:   EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
816:   return(0);
817: }

821: /*@
822:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

824:   Not Collective

826:   Input Parameter:
827: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

829:   Level: developer

831: .keywords: log, event, deactivate, class
832: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
833: @*/
834: PetscErrorCode  PetscLogEventDeactivateClass(PetscCookie cookie)
835: {
836:   StageLog       stageLog;
837:   int            stage;

841:   PetscLogGetStageLog(&stageLog);
842:   StageLogGetCurrent(stageLog, &stage);
843:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
844:   return(0);
845: }

847: /*MC
848:    PetscLogEventBegin - Logs the beginning of a user event. 

850:    Input Parameters:
851: +  e - integer associated with the event obtained from PetscLogEventRegister()
852: -  o1,o2,o3,o4 - objects associated with the event, or 0

854:    Synopsis:
855:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
856:                        PetscObject o4)

858:    Fortran Synopsis:
859:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

861:    Usage:
862: .vb
863:      int USER_EVENT;
864:      int user_event_flops;
865:      PetscLogEventRegister("User event",0,&USER_EVENT);
866:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
867:         [code segment to monitor]
868:         PetscLogFlops(user_event_flops);
869:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
870: .ve

872:    Notes:
873:    You need to register each integer event with the command 
874:    PetscLogEventRegister().  The source code must be compiled with 
875:    -DPETSC_USE_LOG, which is the default.

877:    PETSc automatically logs library events if the code has been
878:    compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
879:    specified.  PetscLogEventBegin() is intended for logging user events
880:    to supplement this PETSc information.

882:    Level: intermediate

884: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()

886: .keywords: log, event, begin
887: M*/

889: /*MC
890:    PetscLogEventEnd - Log the end of a user event.

892:    Input Parameters:
893: +  e - integer associated with the event obtained with PetscLogEventRegister()
894: -  o1,o2,o3,o4 - objects associated with the event, or 0

896:    Synopsis:
897:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
898:                      PetscObject o4)

900:    Fortran Synopsis:
901:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

903:    Usage:
904: .vb
905:      int USER_EVENT;
906:      int user_event_flops;
907:      PetscLogEventRegister("User event",0,&USER_EVENT,);
908:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
909:         [code segment to monitor]
910:         PetscLogFlops(user_event_flops);
911:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
912: .ve

914:    Notes:
915:    You should also register each additional integer event with the command 
916:    PetscLogEventRegister(). Source code must be compiled with 
917:    -DPETSC_USE_LOG, which is the default.

919:    PETSc automatically logs library events if the code has been
920:    compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
921:    specified.  PetscLogEventEnd() is intended for logging user events
922:    to supplement this PETSc information.

924:    Level: intermediate

926: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()

928: .keywords: log, event, end
929: M*/

931: /*MC
932:    PetscLogEventBarrierBegin - Logs the time in a barrier before an event.

934:    Input Parameters:
935: .  e - integer associated with the event obtained from PetscLogEventRegister()
936: .  o1,o2,o3,o4 - objects associated with the event, or 0
937: .  comm - communicator the barrier takes place over

939:    Synopsis:
940:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
941:                   PetscObject o4,MPI_Comm comm)

943:    Usage:
944: .vb
945:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
946:        MPI_Allreduce()
947:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
948: .ve

950:    Notes:
951:    This is for logging the amount of time spent in a barrier for an event
952:    that requires synchronization. 

954:    Additional Notes:
955:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
956:    VEC_NormComm = VEC_NormBarrier + 1

958:    Level: advanced

960: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
961:           PetscLogEventBarrierEnd()

963: .keywords: log, event, begin, barrier
964: M*/

966: /*MC
967:    PetscLogEventBarrierEnd - Logs the time in a barrier before an event.

969:    Input Parameters:
970: .  e - integer associated with the event obtained from PetscLogEventRegister()
971: .  o1,o2,o3,o4 - objects associated with the event, or 0
972: .  comm - communicator the barrier takes place over

974:    Synopsis:
975:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
976:                   PetscObject o4,MPI_Comm comm)

978:     Usage:
979: .vb
980:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
981:        MPI_Allreduce()
982:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
983: .ve

985:    Notes:
986:    This is for logging the amount of time spent in a barrier for an event
987:    that requires synchronization. 

989:    Additional Notes:
990:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
991:    VEC_NormComm = VEC_NormBarrier + 1

993:    Level: advanced

995: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
996:           PetscLogEventBarrierBegin()

998: .keywords: log, event, begin, barrier
999: M*/

1003: /*@C
1004:   PetscLogEventGetId - Returns the event id when given the event name.

1006:   Not Collective 

1008:   Input Parameter:
1009: . name  - The event name

1011:   Output Parameter:
1012: . event - The event

1014:   Level: intermediate

1016: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1017: @*/
1018: PetscErrorCode  PetscLogEventGetId(const char name[], PetscLogEvent *event)
1019: {
1020:   StageLog       stageLog;

1024:   PetscLogGetStageLog(&stageLog);
1025:   EventRegLogGetEvent(stageLog->eventLog, name, event);
1026:   return(0);
1027: }


1030: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1033: /*@C
1034:   PetscLogDump - Dumps logs of objects to a file. This file is intended to 
1035:   be read by petsc/bin/petscview.

1037:   Collective on PETSC_COMM_WORLD

1039:   Input Parameter:
1040: . name - an optional file name

1042:   Options Database Keys:
1043: + -log     - Prints basic log information (for code compiled with PETSC_USE_LOG)
1044: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1045:    
1046:   Usage:
1047: .vb
1048:      PetscInitialize(...);
1049:      PetscLogBegin(); or PetscLogAllBegin(); 
1050:      ... code ...
1051:      PetscLogDump(filename);
1052:      PetscFinalize();
1053: .ve

1055:   Notes:
1056:   The default file name is 
1057: $    Log.<rank>
1058:   where <rank> is the processor number. If no name is specified, 
1059:   this file will be used.

1061:   Level: advanced

1063: .keywords: log, dump
1064: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1065: @*/
1066: PetscErrorCode  PetscLogDump(const char sname[])
1067: {
1068:   StageLog       stageLog;
1069:   EventPerfInfo *eventInfo;
1070:   FILE          *fd;
1071:   char           file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1072:   PetscLogDouble flops, _TotalTime;
1073:   PetscMPIInt    rank;
1074:   int            action, object, curStage;
1075:   PetscLogEvent  event;
1077: 
1079:   /* Calculate the total elapsed time */
1080:   PetscTime(_TotalTime);
1081:   _TotalTime -= BaseTime;
1082:   /* Open log file */
1083:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1084:   if (sname) {
1085:     sprintf(file, "%s.%d", sname, rank);
1086:   } else {
1087:     sprintf(file, "Log.%d", rank);
1088:   }
1089:   PetscFixFilename(file, fname);
1090:   PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1091:   if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1092:   /* Output totals */
1093:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1094:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1095:   /* Output actions */
1096:   if (logActions) {
1097:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1098:     for(action = 0; action < numActions; action++) {
1099:       PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1100:                           actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1101:                           actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1102:     }
1103:   }
1104:   /* Output objects */
1105:   if (logObjects) {
1106:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1107:     for(object = 0; object < numObjects; object++) {
1108:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1109:       if (!objects[object].name[0]) {
1110:         PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1111:       } else {
1112:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1113:       }
1114:       if (objects[object].info[0] != 0) {
1115:         PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1116:       } else {
1117:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1118:       }
1119:     }
1120:   }
1121:   /* Output events */
1122:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1123:   PetscLogGetStageLog(&stageLog);
1124:   StackTop(stageLog->stack, &curStage);
1125:   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1126:   for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1127:     if (eventInfo[event].time != 0.0) {
1128:       flops = eventInfo[event].flops/eventInfo[event].time;
1129:     } else {
1130:       flops = 0.0;
1131:     }
1132:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1133:                         eventInfo[event].flops, eventInfo[event].time, flops);
1134:   }
1135:   PetscFClose(PETSC_COMM_WORLD, fd);
1136:   return(0);
1137: }

1141: /*@C
1142:   PetscLogPrintSummary - Prints a summary of the logging.

1144:   Collective over MPI_Comm

1146:   Input Parameter:
1147: + comm - The MPI communicator (only one processor prints output)
1148: - file - [Optional] The output file name

1150:   Options Database Keys:
1151: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)

1153:   Usage:
1154: .vb
1155:      PetscInitialize(...);
1156:      PetscLogBegin();
1157:      ... code ...
1158:      PetscLogPrintSummary(MPI_Comm,filename);
1159:      PetscFinalize(...);
1160: .ve

1162:   Notes:
1163:   By default the summary is printed to stdout.

1165:   Level: beginner
1166:    
1167: .keywords: log, dump, print
1168: .seealso: PetscLogBegin(), PetscLogDump()
1169: @*/
1170: PetscErrorCode  PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1171: {
1172:   FILE           *fd = PETSC_STDOUT;
1173:   PetscLogDouble zero = 0.0;
1174:   StageLog       stageLog;
1175:   StageInfo     *stageInfo = PETSC_NULL;
1176:   EventPerfInfo *eventInfo = PETSC_NULL;
1177:   ClassPerfInfo *classInfo;
1178:   char           arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1179:   const char    *name;
1180:   PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1181:   PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1182:   PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1183:   PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1184:   PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1185:   PetscLogDouble min, max, tot, ratio, avg, x, y;
1186:   PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1187:   PetscMPIInt    minCt, maxCt;
1188:   PetscMPIInt    size, rank;
1189:   PetscTruth    *localStageUsed,    *stageUsed;
1190:   PetscTruth    *localStageVisible, *stageVisible;
1191:   int            numStages, localNumEvents, numEvents;
1192:   int            stage, lastStage, oclass;
1193:   PetscLogEvent  event;
1195:   char           version[256];

1198:   MPI_Comm_size(comm, &size);
1199:   MPI_Comm_rank(comm, &rank);
1200:   /* Pop off any stages the user forgot to remove */
1201:   lastStage = 0;
1202:   PetscLogGetStageLog(&stageLog);
1203:   StageLogGetCurrent(stageLog, &stage);
1204:   while (stage >= 0) {
1205:     lastStage = stage;
1206:     StageLogPop(stageLog);
1207:     StageLogGetCurrent(stageLog, &stage);
1208:   }
1209:   /* Get the total elapsed time */
1210:   PetscTime(locTotalTime);  locTotalTime -= BaseTime;
1211:   /* Open the summary file */
1212:   if (filename) {
1213:     PetscFOpen(comm, filename, "w", &fd);
1214:   }

1216:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1217:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1218:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1219:   PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1220:   PetscGetArchType(arch, 10);
1221:   PetscGetHostName(hostname, 64);
1222:   PetscGetUserName(username, 16);
1223:   PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1224:   PetscGetDate(date, 64);
1225:   PetscGetVersion(version,256);
1226:   if (size == 1) {
1227:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1228:   } else {
1229:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1230:   }
1231:   PetscFPrintf(comm, fd, "Using %s\n", version);

1233:   /* Must preserve reduction count before we go on */
1234:   red  = allreduce_ct + gather_ct + scatter_ct;

1236:   /* Calculate summary information */
1237:   PetscFPrintf(comm, fd, "\n                         Max       Max/Min        Avg      Total \n");
1238:   /*   Time */
1239:   MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1240:   MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1241:   MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1242:   avg  = (tot)/((PetscLogDouble) size);
1243:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1244:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %10.5f   %5.3e\n", max, ratio, avg);
1245:   TotalTime = tot;
1246:   /*   Objects */
1247:   avg  = (PetscLogDouble) numObjects;
1248:   MPI_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1249:   MPI_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1250:   MPI_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1251:   avg  = (tot)/((PetscLogDouble) size);
1252:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1253:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %10.5f   %5.3e\n", max, ratio, avg);
1254:   /*   Flops */
1255:   MPI_Allreduce(&_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1256:   MPI_Allreduce(&_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1257:   MPI_Allreduce(&_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1258:   avg  = (tot)/((PetscLogDouble) size);
1259:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1260:   PetscFPrintf(comm, fd, "Flops:                %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1261:   TotalFlops = tot;
1262:   /*   Flops/sec -- Must talk to Barry here */
1263:   if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1264:   MPI_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1265:   MPI_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1266:   MPI_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1267:   avg  = (tot)/((PetscLogDouble) size);
1268:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1269:   PetscFPrintf(comm, fd, "Flops/sec:            %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1270:   /*   Memory */
1271:   PetscMallocGetMaximumUsage(&mem);
1272:   if (mem > 0.0) {
1273:     MPI_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1274:     MPI_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1275:     MPI_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1276:     avg  = (tot)/((PetscLogDouble) size);
1277:     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1278:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %10.5f              %5.3e\n", max, ratio, tot);
1279:   }
1280:   /*   Messages */
1281:   mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1282:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1283:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1284:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1285:   avg  = (tot)/((PetscLogDouble) size);
1286:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1287:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1288:   numMessages = tot;
1289:   /*   Message Lengths */
1290:   mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1291:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1292:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1293:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1294:   if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1295:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1296:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1297:   messageLength = tot;
1298:   /*   Reductions */
1299:   MPI_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1300:   MPI_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1301:   MPI_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1302:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1303:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %10.5f\n", max, ratio);
1304:   numReductions = red; /* wrong because uses count from process zero */
1305:   PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1306:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1307:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flops\n");

1309:   /* Get total number of stages --
1310:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1311:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1312:        This seems best accomplished by assoicating a communicator with each stage.
1313:   */
1314:   MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1315:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1316:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1317:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1318:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1319:   if (numStages > 0) {
1320:     stageInfo = stageLog->stageInfo;
1321:     for(stage = 0; stage < numStages; stage++) {
1322:       if (stage < stageLog->numStages) {
1323:         localStageUsed[stage]    = stageInfo[stage].used;
1324:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1325:       } else {
1326:         localStageUsed[stage]    = PETSC_FALSE;
1327:         localStageVisible[stage] = PETSC_TRUE;
1328:       }
1329:     }
1330:     MPI_Allreduce(localStageUsed,    stageUsed,    numStages, MPI_INT, MPI_LOR,  comm);
1331:     MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1332:     for(stage = 0; stage < numStages; stage++) {
1333:       if (stageUsed[stage]) {
1334:         PetscFPrintf(comm, fd, "\nSummary of Stages:   ----- Time ------  ----- Flops -----  --- Messages ---  -- Message Lengths --  -- Reductions --\n");
1335:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total   counts   %%Total     Avg         %%Total   counts   %%Total \n");
1336:         break;
1337:       }
1338:     }
1339:     for(stage = 0; stage < numStages; stage++) {
1340:       if (!stageUsed[stage]) continue;
1341:       if (localStageUsed[stage]) {
1342:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1343:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1344:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1345:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1346:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347:         name = stageInfo[stage].name;
1348:       } else {
1349:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1350:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1351:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1352:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1353:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1354:         name = "";
1355:       }
1356:       mess *= 0.5; messLen *= 0.5; red /= size;
1357:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1358:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1359:       /* Talk to Barry if (stageTime     != 0.0) flops          = (size*flops)/stageTime; else flops          = 0.0; */
1360:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1361:       if (numMessages   != 0.0) avgMessLen     = messLen/numMessages;    else avgMessLen     = 0.0;
1362:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1363:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1364:       PetscFPrintf(comm, fd, "%2d: %15s: %6.4e %5.1f%%  %6.4e %5.1f%%  %5.3e %5.1f%%  %5.3e      %5.1f%%  %5.3e %5.1f%% \n",
1365:                           stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1366:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1367:     }
1368:   }

1370:   PetscFPrintf(comm, fd,
1371:     "\n------------------------------------------------------------------------------------------------------------------------\n");
1372: 
1373:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1374:   PetscFPrintf(comm, fd, "Phase summary info:\n");
1375:   PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");
1376:   PetscFPrintf(comm, fd, "   Time and Flops: Max - maximum over all processors\n");
1377:   PetscFPrintf(comm, fd, "                   Ratio - ratio of maximum to minimum over all processors\n");
1378:   PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");
1379:   PetscFPrintf(comm, fd, "   Avg. len: average message length\n");
1380:   PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");
1381:   PetscFPrintf(comm, fd, "   Global: entire computation\n");
1382:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1383:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flops in this phase\n");
1384:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");
1385:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");
1386:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1387:   PetscFPrintf(comm, fd,
1388:     "------------------------------------------------------------------------------------------------------------------------\n");
1389: 

1391: #if defined(PETSC_USE_DEBUG)
1392:   PetscFPrintf(comm, fd, "\n\n");
1393:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1394:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1395:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1396:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1397:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #\n");
1398:   PetscFPrintf(comm, fd, "      #   To get timing results run config/configure.py        #\n");
1399:   PetscFPrintf(comm, fd, "      #   using --with-debugging=no, the performance will      #\n");
1400:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");
1401:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1402:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1403: #endif
1404: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1405:   PetscFPrintf(comm, fd, "\n\n");
1406:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1407:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1408:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1409:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1410:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #\n");
1411:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #\n");
1412:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #\n");
1413:   PetscFPrintf(comm, fd, "      #   faster, specify --with-fortran-kernels=generic       #\n");
1414:   PetscFPrintf(comm, fd, "      #   when running config/configure.py.                    #\n");
1415:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1416:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1417: #endif

1419:   /* Report events */
1420:   PetscFPrintf(comm, fd,
1421:     "Event                Count      Time (sec)     Flops                             --- Global ---  --- Stage ---   Total\n");
1422: 
1423:   PetscFPrintf(comm, fd,
1424:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s\n");
1425: 
1426:   PetscFPrintf(comm,fd,
1427:     "------------------------------------------------------------------------------------------------------------------------\n");

1429: 
1430:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1431:   for(stage = 0; stage < numStages; stage++) {
1432:     if (!stageVisible[stage]) continue;
1433:     if (localStageUsed[stage]) {
1434:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1435:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1436:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1437:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1438:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1439:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1440:     } else {
1441:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1442:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1443:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1444:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1445:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1446:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1447:     }
1448:     mess *= 0.5; messLen *= 0.5; red /= size;

1450:     /* Get total number of events in this stage --
1451:        Currently, a single processor can register more events than another, but events must all be registered in order,
1452:        just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1453:        on the event ID. This seems best accomplished by assoicating a communicator with each stage.

1455:        Problem: If the event did not happen on proc 1, its name will not be available.
1456:        Problem: Event visibility is not implemented
1457:     */
1458:     if (localStageUsed[stage]) {
1459:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1460:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1461:     } else {
1462:       localNumEvents = 0;
1463:     }
1464:     MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1465:     for(event = 0; event < numEvents; event++) {
1466:       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1467:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1468:           flopr = eventInfo[event].flops;
1469:         } else {
1470:           flopr = 0.0;
1471:         }
1472:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1473:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1474:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1475:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1476:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1477:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1478:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1479:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1480:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1481:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1482:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1483:         name = stageLog->eventLog->eventInfo[event].name;
1484:       } else {
1485:         flopr = 0.0;
1486:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1487:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1488:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1489:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1490:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1491:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1492:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1493:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1494:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1495:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1496:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1497:         name = "";
1498:       }
1499:       if (mint < 0.0) {
1500:         PetscFPrintf(comm, fd, "WARNING!!! Minimum time %g over all processors for %s is negative! This happens\n on some machines whose times cannot handle too rapid calls.!\n artificially changing minimum to zero.\n",mint,name);
1501:         mint = 0;
1502:       }
1503:       if (minf < 0.0) SETERRQ2(PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1504:       totm *= 0.5; totml *= 0.5; totr /= size;
1505: 
1506:       if (maxCt != 0) {
1507:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1508:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1509:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1510:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1511:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1512:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1513:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1514:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1515:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1516:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1517:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1518:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1519:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1520:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1521:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1522:         PetscFPrintf(comm, fd,
1523:           "%-16s %7d%4.1f %5.4e%4.1f %3.2e%4.1f %2.1e %2.1e %2.1e%3.0f%3.0f%3.0f%3.0f%3.0f %3.0f%3.0f%3.0f%3.0f%3.0f %5.0f\n",
1524:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1525:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1526:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1527:                             flopr/1.0e6);
1528:       }
1529:     }
1530:   }

1532:   /* Memory usage and object creation */
1533:   PetscFPrintf(comm, fd,
1534:     "------------------------------------------------------------------------------------------------------------------------\n");
1535:   PetscFPrintf(comm, fd, "\n");
1536:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

1538:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1539:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1540:      stats for stages local to processor sets.
1541:   */
1542:   /* We should figure out the longest object name here (now 20 characters) */
1543:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions   Memory  Descendants' Mem.\n");
1544:   for(stage = 0; stage < numStages; stage++) {
1545:     if (localStageUsed[stage]) {
1546:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1547:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1548:       for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1549:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1550:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %9d     %g\n", stageLog->classLog->classInfo[oclass].name,
1551:                               classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1552:                               classInfo[oclass].descMem);
1553:         }
1554:       }
1555:     } else {
1556:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1557:     }
1558:   }

1560:   PetscFree(localStageUsed);
1561:   PetscFree(stageUsed);
1562:   PetscFree(localStageVisible);
1563:   PetscFree(stageVisible);

1565:   /* Information unrelated to this particular run */
1566:   PetscFPrintf(comm, fd,
1567:     "========================================================================================================================\n");
1568:   PetscTime(y);
1569:   PetscTime(x);
1570:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1571:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1572:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1573:   /* MPI information */
1574:   if (size > 1) {
1575:     MPI_Status  status;
1576:     PetscMPIInt tag;
1577:     MPI_Comm    newcomm;

1579:     MPI_Barrier(comm);
1580:     PetscTime(x);
1581:     MPI_Barrier(comm);
1582:     MPI_Barrier(comm);
1583:     MPI_Barrier(comm);
1584:     MPI_Barrier(comm);
1585:     MPI_Barrier(comm);
1586:     PetscTime(y);
1587:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1588:     PetscCommDuplicate(comm,&newcomm, &tag);
1589:     MPI_Barrier(comm);
1590:     if (rank) {
1591:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, newcomm, &status);
1592:       MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1593:     } else {
1594:       PetscTime(x);
1595:       MPI_Send(0, 0, MPI_INT, 1,          tag, newcomm);
1596:       MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1597:       PetscTime(y);
1598:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1599:     }
1600:     PetscCommDestroy(&newcomm);
1601:   }
1602:   if (!rank) {
1603:     PetscOptionsPrint(fd);
1604:   }
1605:   /* Machine and compile information */
1606: #if defined(PETSC_USE_FORTRAN_KERNELS)
1607:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1608: #else
1609:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1610: #endif
1611: #if defined(PETSC_USE_SINGLE)
1612:   PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1613: #elif defined(PETSC_USE_LONGDOUBLE)
1614:   PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1615: #elif defined(PETSC_USE_INT)
1616:   PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1617: #endif

1619: #if defined(PETSC_USE_MAT_SINGLE)
1620:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1621: #else
1622:   PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1623: #endif
1624:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1625:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));

1627:   PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1628:   PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1629:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1630:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1631:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1632:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1634:   /* Cleanup */
1635:   PetscFPrintf(comm, fd, "\n");
1636:   PetscFClose(comm, fd);
1637:   StageLogPush(stageLog, lastStage);
1638:   return(0);
1639: }

1643: /*@C
1644:   PetscLogPrintDetailed - Each process prints the times for its own events

1646:   Collective over MPI_Comm

1648:   Input Parameter:
1649: + comm - The MPI communicator (only one processor prints output)
1650: - file - [Optional] The output file name

1652:   Options Database Keys:
1653: . -log_summary_detailed - Prints summary of log information (for code compiled with PETSC_USE_LOG)

1655:   Usage:
1656: .vb
1657:      PetscInitialize(...);
1658:      PetscLogBegin();
1659:      ... code ...
1660:      PetscLogPrintDetailed(MPI_Comm,filename);
1661:      PetscFinalize(...);
1662: .ve

1664:   Notes:
1665:   By default the summary is printed to stdout.

1667:   Level: beginner
1668:    
1669: .keywords: log, dump, print
1670: .seealso: PetscLogBegin(), PetscLogDump(), PetscLogPrintSummary()
1671: @*/
1672: PetscErrorCode  PetscLogPrintDetailed(MPI_Comm comm, const char filename[])
1673: {
1674:   FILE          *fd = PETSC_STDOUT;
1675:   StageLog       stageLog;
1676:   StageInfo     *stageInfo = PETSC_NULL;
1677:   EventPerfInfo *eventInfo = PETSC_NULL;
1678:   const char    *name = PETSC_NULL;
1679:   PetscLogDouble TotalTime;
1680:   PetscLogDouble stageTime, flops, flopr, mess, messLen, red;
1681:   PetscLogDouble maxf, totf, maxt, tott, totm, totml, totr = 0.0;
1682:   PetscMPIInt    maxCt;
1683:   PetscMPIInt    size, rank;
1684:   PetscTruth     *stageUsed;
1685:   PetscTruth     *stageVisible;
1686:   int            numStages, numEvents;
1687:   int            stage;
1688:   PetscLogEvent  event;

1692:   MPI_Comm_size(comm, &size);
1693:   MPI_Comm_rank(comm, &rank);
1694:   /* Pop off any stages the user forgot to remove */
1695:   PetscLogGetStageLog(&stageLog);
1696:   StageLogGetCurrent(stageLog, &stage);
1697:   while (stage >= 0) {
1698:     StageLogPop(stageLog);
1699:     StageLogGetCurrent(stageLog, &stage);
1700:   }
1701:   /* Get the total elapsed time */
1702:   PetscTime(TotalTime);  TotalTime -= BaseTime;
1703:   /* Open the summary file */
1704:   if (filename) {
1705:     PetscFOpen(comm, filename, "w", &fd);
1706:   }

1708:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1709:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1710:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");


1713:   numStages = stageLog->numStages;
1714:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1715:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1716:   if (numStages > 0) {
1717:     stageInfo = stageLog->stageInfo;
1718:     for(stage = 0; stage < numStages; stage++) {
1719:       if (stage < stageLog->numStages) {
1720:         stageUsed[stage]    = stageInfo[stage].used;
1721:         stageVisible[stage] = stageInfo[stage].perfInfo.visible;
1722:       } else {
1723:         stageUsed[stage]    = PETSC_FALSE;
1724:         stageVisible[stage] = PETSC_TRUE;
1725:       }
1726:     }
1727:   }

1729:   /* Report events */
1730:   PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flops/sec                          \n");
1731:   PetscFPrintf(comm, fd,"                                                            Mess   Avg len Reduct \n");
1732:   PetscFPrintf(comm,fd,"-----------------------------------------------------------------------------------\n");
1733:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1734:   for(stage = 0; stage < numStages; stage++) {
1735:     if (!stageVisible[stage]) continue;
1736:     if (stageUsed[stage]) {
1737:       PetscSynchronizedFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1738:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1739:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1740:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1741:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1742:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1743:     }
1744:     mess *= 0.5; messLen *= 0.5;

1746:     /* Get total number of events in this stage --
1747:     */
1748:     if (stageUsed[stage]) {
1749:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1750:       numEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1751:     } else {
1752:       numEvents = 0;
1753:     }
1754:     for(event = 0; event < numEvents; event++) {
1755:       if (stageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1756:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1757:           flopr = eventInfo[event].flops/eventInfo[event].time;
1758:         } else {
1759:           flopr = 0.0;
1760:         }
1761:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1762:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1763:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1764:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1765:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1766:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1767:         totr = eventInfo[event].numReductions;
1768:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, PETSC_COMM_SELF);
1769:         name = stageLog->eventLog->eventInfo[event].name;
1770:         totm *= 0.5; totml *= 0.5;
1771:       }
1772: 
1773:       if (maxCt != 0) {
1774:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1775:         PetscSynchronizedFPrintf(comm, fd,"%-16s %7d      %5.4e      %3.2e      %2.1e %2.1e %2.1e\n",name, maxCt,  maxt,  maxf, totm, totml, totr);
1776:       }
1777:     }
1778:   }
1779:   PetscSynchronizedFlush(comm);

1781:   PetscFree(stageUsed);
1782:   PetscFree(stageVisible);

1784:   PetscFClose(comm, fd);
1785:   return(0);
1786: }

1788: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1791: /*@C
1792:    PetscGetFlops - Returns the number of flops used on this processor 
1793:    since the program began. 

1795:    Not Collective

1797:    Output Parameter:
1798:    flops - number of floating point operations 

1800:    Notes:
1801:    A global counter logs all PETSc flop counts.  The user can use
1802:    PetscLogFlops() to increment this counter to include flops for the 
1803:    application code.  

1805:    PETSc automatically logs library events if the code has been
1806:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1807:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1808:    intended for logging user flops to supplement this PETSc
1809:    information.

1811:    Level: intermediate

1813: .keywords: log, flops, floating point operations

1815: .seealso: PetscGetTime(), PetscLogFlops()
1816: @*/
1817: PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
1818: {
1820:   *flops = _TotalFlops;
1821:   return(0);
1822: }

1826: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
1827: {
1829:   int            fullLength;
1830:   va_list        Argp;

1833:   if (!logObjects) return(0);
1834:   va_start(Argp, format);
1835:   PetscVSNPrintf(objects[obj->id].info, 64,format,&fullLength, Argp);
1836:   va_end(Argp);
1837:   return(0);
1838: }

1842: /*@
1843:   PetscLogGetStageLog - This function returns the default stage logging object.

1845:   Not collective

1847:   Output Parameter:
1848: . stageLog - The default StageLog

1850:   Level: beginner

1852: .keywords: log, stage
1853: .seealso: StageLogCreate()
1854: @*/
1855: PetscErrorCode  PetscLogGetStageLog(StageLog *stageLog)
1856: {
1859:   *stageLog = _stageLog;
1860:   return(0);
1861: }

1863: /*MC
1864:    PetscLogFlops - Adds floating point operations to the global counter.

1866:    Input Parameter:
1867: .  f - flop counter

1869:    Synopsis:
1870:    void PetscLogFlops(int f)

1872:    Usage:
1873: .vb
1874:      int USER_EVENT;
1875:      PetscLogEventRegister("User event",0,&USER_EVENT);
1876:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1877:         [code segment to monitor]
1878:         PetscLogFlops(user_flops)
1879:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1880: .ve

1882:    Notes:
1883:    A global counter logs all PETSc flop counts.  The user can use
1884:    PetscLogFlops() to increment this counter to include flops for the 
1885:    application code.  

1887:    PETSc automatically logs library events if the code has been
1888:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1889:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1890:    intended for logging user flops to supplement this PETSc
1891:    information.

1893:    Level: intermediate

1895: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()

1897: .keywords: log, flops, floating point operations
1898: M*/

1900: /*MC
1901:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1902:     to get accurate timings

1904:    Input Parameter:
1905: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1906:            with command line option -preload true or -preload false
1907: -   name - name of first stage (lines of code timed separately with -log_summary) to
1908:            be preloaded

1910:    Synopsis:
1911:    void PreLoadBegin(PetscTruth flag,char *name);

1913:    Usage:
1914: .vb
1915:      PreLoadBegin(PETSC_TRUE,"first stage);
1916:        lines of code
1917:        PreLoadStage("second stage");
1918:        lines of code
1919:      PreLoadEnd();
1920: .ve

1922:    Notes: Only works in C/C++, not Fortran

1924:      Flags available within the macro. 
1925: +    PetscPreLoadingUsed - true if we are or have done preloading 
1926: .    PetscPreLoadingOn - true if it is CURRENTLY doing preload
1927: .    PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1928: -    PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1929:      The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1930:      and PreLoadEnd()

1932:    Level: intermediate

1934: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()

1936:    Concepts: preloading
1937:    Concepts: timing^accurate
1938:    Concepts: paging^eliminating effects of


1941: M*/

1943: /*MC
1944:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1945:     to get accurate timings

1947:    Synopsis:
1948:    void PreLoadEnd(void);

1950:    Usage:
1951: .vb
1952:      PreLoadBegin(PETSC_TRUE,"first stage);
1953:        lines of code
1954:        PreLoadStage("second stage");
1955:        lines of code
1956:      PreLoadEnd();
1957: .ve

1959:    Notes: only works in C/C++ not fortran

1961:    Level: intermediate

1963: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()

1965: M*/

1967: /*MC
1968:    PreLoadStage - Start a new segment of code to be timed separately.
1969:     to get accurate timings

1971:    Synopsis:
1972:    void PreLoadStage(char *name);

1974:    Usage:
1975: .vb
1976:      PreLoadBegin(PETSC_TRUE,"first stage);
1977:        lines of code
1978:        PreLoadStage("second stage");
1979:        lines of code
1980:      PreLoadEnd();
1981: .ve

1983:    Notes: only works in C/C++ not fortran

1985:    Level: intermediate

1987: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()

1989: M*/

1991: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1994: /*@C
1995:   StackDestroy - This function destroys a stack.

1997:   Not Collective

1999:   Input Parameter:
2000: . stack - The stack

2002:   Level: beginner

2004: .keywords: log, stack, destroy
2005: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
2006: @*/
2007: PetscErrorCode StackDestroy(IntStack stack)
2008: {

2012:   PetscFree(stack->stack);
2013:   PetscFree(stack);
2014:   return(0);
2015: }

2019: /*@C
2020:   StackEmpty - This function determines whether any items have been pushed.

2022:   Not Collective

2024:   Input Parameter:
2025: . stack - The stack

2027:   Output Parameter:
2028: . empty - PETSC_TRUE if the stack is empty

2030:   Level: intermediate

2032: .keywords: log, stack, empty
2033: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
2034: @*/
2035: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
2036: {
2039:   if (stack->top == -1) {
2040:     *empty = PETSC_TRUE;
2041:   } else {
2042:     *empty = PETSC_FALSE;
2043:   }
2044:   return(0);
2045: }

2049: /*@C
2050:   StackTop - This function returns the top of the stack.

2052:   Not Collective

2054:   Input Parameter:
2055: . stack - The stack

2057:   Output Parameter:
2058: . top - The integer on top of the stack

2060:   Level: intermediate

2062: .keywords: log, stack, top
2063: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
2064: @*/
2065: PetscErrorCode StackTop(IntStack stack, int *top)
2066: {
2069:   *top = stack->stack[stack->top];
2070:   return(0);
2071: }

2075: /*@C
2076:   StackPush - This function pushes an integer on the stack.

2078:   Not Collective

2080:   Input Parameters:
2081: + stack - The stack
2082: - item  - The integer to push

2084:   Level: intermediate

2086: .keywords: log, stack, push
2087: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
2088: @*/
2089: PetscErrorCode StackPush(IntStack stack, int item)
2090: {
2091:   int            *array;

2095:   stack->top++;
2096:   if (stack->top >= stack->max) {
2097:     PetscMalloc(stack->max*2 * sizeof(int), &array);
2098:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2099:     PetscFree(stack->stack);
2100:     stack->stack = array;
2101:     stack->max  *= 2;
2102:   }
2103:   stack->stack[stack->top] = item;
2104:   return(0);
2105: }

2109: /*@C
2110:   StackPop - This function pops an integer from the stack.

2112:   Not Collective

2114:   Input Parameter:
2115: . stack - The stack

2117:   Output Parameter:
2118: . item  - The integer popped

2120:   Level: intermediate

2122: .keywords: log, stack, pop
2123: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2124: @*/
2125: PetscErrorCode StackPop(IntStack stack, int *item)
2126: {
2129:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2130:   *item = stack->stack[stack->top--];
2131:   return(0);
2132: }

2136: /*@C
2137:   StackCreate - This function creates a stack.

2139:   Not Collective

2141:   Output Parameter:
2142: . stack - The stack

2144:   Level: beginner

2146: .keywords: log, stack, pop
2147: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2148: @*/
2149: PetscErrorCode StackCreate(IntStack *stack)
2150: {
2151:   IntStack       s;

2156:   PetscNew(struct _n_IntStack, &s);
2157:   s->top = -1;
2158:   s->max = 128;
2159:   PetscMalloc(s->max * sizeof(int), &s->stack);
2160:   PetscMemzero(s->stack, s->max * sizeof(int));
2161:   *stack = s;
2162:   return(0);
2163: }

2165: #else /* end of -DPETSC_USE_LOG section */

2169: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2170: {
2172:   return(0);
2173: }

2175: #endif /* PETSC_USE_LOG*/


2178: PetscCookie PETSC_LARGEST_COOKIE = PETSC_SMALLEST_COOKIE;
2179: PetscCookie PETSC_OBJECT_COOKIE  = 0;

2183: /*@C
2184:   PetscCookieRegister - Registers a new class name for objects and logging operations in an application code. 

2186:   Not Collective

2188:   Input Parameter:
2189: . name   - The class name
2190:             
2191:   Output Parameter:
2192: . oclass - The class id or cookie

2194:   Level: developer

2196: .keywords: log, class, register

2198: @*/
2199: PetscErrorCode  PetscCookieRegister(const char name[],PetscCookie *oclass )
2200: {
2201: #if defined(PETSC_USE_LOG)
2202:   StageLog       stageLog;
2203:   PetscInt       stage;
2205: #endif

2208:   *oclass = ++PETSC_LARGEST_COOKIE;
2209: #if defined(PETSC_USE_LOG)
2210:   PetscLogGetStageLog(&stageLog);
2211:   ClassRegLogRegister(stageLog->classLog, name, *oclass);
2212:   for(stage = 0; stage < stageLog->numStages; stage++) {
2213:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2214:   }
2215: #endif
2216:   return(0);
2217: }