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 */
 29: int  PETSC_DUMMY_SIZE = 0;
 30: int  PETSC_DUMMY_COUNT = 0;

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

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

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

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

 74: /*---------------------------------------------- General Functions --------------------------------------------------*/
 77: /*@C
 78:   PetscLogDestroy - Destroys the object and event logging data and resets the global counters. 

 80:   Not Collective

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

 86:   Level: developer

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

 97:   PetscFree(actions);
 98:   actions = PETSC_NULL;
 99:   PetscFree(objects);
100:   objects =  PETSC_NULL;
101:   PetscLogSet(PETSC_NULL, PETSC_NULL);

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

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

118:   Not Collective

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

124:   Level: developer

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

137: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
140: PetscErrorCode  PetscLogBegin_Private(void)
141: {
142:   static PetscTruth initialized = PETSC_FALSE;
143:   int               stage;
144:   PetscTruth        opt;
145:   PetscErrorCode    ierr;

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

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

183:   Collective over PETSC_COMM_WORLD

185:   Options Database Keys:
186: + -log_summary - Prints summary of flop and timing information to the 
187:                   screen (for code compiled with PETSC_USE_LOG)
188: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)

190:   Usage:
191: .vb
192:       PetscInitialize(...);
193:       PetscLogBegin();
194:        ... code ...
195:       PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump(); 
196:       PetscFinalize();
197: .ve

199:   Notes:
200:   PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of 
201:   the logging information.

203:   Level: advanced

205: .keywords: log, begin
206: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
207: @*/
208: PetscErrorCode  PetscLogBegin(void)
209: {

213:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
214:   PetscLogBegin_Private();
215:   return(0);
216: }

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

224:   Collective on PETSC_COMM_WORLD

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

229:   Usage:
230: .vb
231:      PetscInitialize(...);
232:      PetscLogAllBegin();
233:      ... code ...
234:      PetscLogDump(filename);
235:      PetscFinalize();
236: .ve

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

243:   Level: advanced

245: .keywords: log, all, begin
246: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
247: @*/
248: PetscErrorCode  PetscLogAllBegin(void)
249: {

253:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
254:   PetscLogBegin_Private();
255:   return(0);
256: }

260: /*@
261:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
262:   begins or ends, the event name is printed.

264:   Collective on PETSC_COMM_WORLD

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

269:   Options Database Key:
270: . -log_trace [filename] - Activates PetscLogTraceBegin()

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

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

280:   Level: intermediate

282: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
283: @*/
284: PetscErrorCode  PetscLogTraceBegin(FILE *file)
285: {

289:   tracefile = file;
290:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
291:   PetscLogBegin_Private();
292:   return(0);
293: }

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

300:   Not Collective

302:   Input Parameter:
303: . flag - PETSC_TRUE if actions are to be logged

305:   Level: intermediate

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

310:   Options Database Keys:
311: . -log_exclude_actions - Turns off actions logging

313: .keywords: log, stage, register
314: .seealso: PetscLogStagePush(), PetscLogStagePop()
315: @*/
316: PetscErrorCode  PetscLogActions(PetscTruth flag)
317: {
319:   logActions = flag;
320:   return(0);
321: }

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

328:   Not Collective

330:   Input Parameter:
331: . flag - PETSC_TRUE if objects are to be logged

333:   Level: intermediate

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

338:   Options Database Keys:
339: . -log_exclude_objects - Turns off objects logging

341: .keywords: log, stage, register
342: .seealso: PetscLogStagePush(), PetscLogStagePop()
343: @*/
344: PetscErrorCode  PetscLogObjects(PetscTruth flag)
345: {
347:   logObjects = flag;
348:   return(0);
349: }

351: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
354: /*@C
355:   PetscLogStageRegister - Attaches a charactor string name to a logging stage.

357:   Not Collective

359:   Input Parameter:
360: . sname - The name to associate with that stage

362:   Output Parameter:
363: . stage - The stage number

365:   Level: intermediate

367: .keywords: log, stage, register
368: .seealso: PetscLogStagePush(), PetscLogStagePop()
369: @*/
370: PetscErrorCode  PetscLogStageRegister(const char sname[],PetscLogStage *stage)
371: {
372:   StageLog       stageLog;
373:   PetscLogEvent  event;

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

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

394:   Not Collective

396:   Input Parameter:
397: . stage - The stage on which to log

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

417:   Level: intermediate

419: .keywords: log, push, stage
420: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
421: @*/
422: PetscErrorCode  PetscLogStagePush(PetscLogStage stage)
423: {
424:   StageLog       stageLog;

428:   PetscLogGetStageLog(&stageLog);
429:   StageLogPush(stageLog, stage);
430:   return(0);
431: }

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

438:   Not Collective

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

455:   Notes:  
456:   Use PetscLogStageRegister() to register a stage.

458:   Level: intermediate

460: .keywords: log, pop, stage
461: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
462: @*/
463: PetscErrorCode  PetscLogStagePop(void)
464: {
465:   StageLog       stageLog;

469:   PetscLogGetStageLog(&stageLog);
470:   StageLogPop(stageLog);
471:   return(0);
472: }

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

479:   Not Collective 

481:   Input Parameters:
482: + stage    - The stage
483: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

485:   Level: intermediate

487: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
488: @*/
489: PetscErrorCode  PetscLogStageSetActive(PetscLogStage stage, PetscTruth isActive)
490: {
491:   StageLog       stageLog;

495:   PetscLogGetStageLog(&stageLog);
496:   StageLogSetActive(stageLog, stage, isActive);
497:   return(0);
498: }

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

505:   Not Collective 

507:   Input Parameter:
508: . stage    - The stage

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

513:   Level: intermediate

515: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
516: @*/
517: PetscErrorCode  PetscLogStageGetActive(PetscLogStage stage, PetscTruth *isActive)
518: {
519:   StageLog       stageLog;

523:   PetscLogGetStageLog(&stageLog);
524:   StageLogGetActive(stageLog, stage, isActive);
525:   return(0);
526: }

530: /*@
531:   PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()

533:   Not Collective 

535:   Input Parameters:
536: + stage     - The stage
537: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

539:   Level: intermediate

541: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
542: @*/
543: PetscErrorCode  PetscLogStageSetVisible(PetscLogStage stage, PetscTruth isVisible)
544: {
545:   StageLog       stageLog;

549:   PetscLogGetStageLog(&stageLog);
550:   StageLogSetVisible(stageLog, stage, isVisible);
551:   return(0);
552: }

556: /*@
557:   PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()

559:   Not Collective 

561:   Input Parameter:
562: . stage     - The stage

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

567:   Level: intermediate

569: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
570: @*/
571: PetscErrorCode  PetscLogStageGetVisible(PetscLogStage stage, PetscTruth *isVisible)
572: {
573:   StageLog       stageLog;

577:   PetscLogGetStageLog(&stageLog);
578:   StageLogGetVisible(stageLog, stage, isVisible);
579:   return(0);
580: }

584: /*@
585:   PetscLogStageGetId - Returns the stage id when given the stage name.

587:   Not Collective 

589:   Input Parameter:
590: . name  - The stage name

592:   Output Parameter:
593: . stage - The stage

595:   Level: intermediate

597: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
598: @*/
599: PetscErrorCode  PetscLogStageGetId(const char name[], PetscLogStage *stage)
600: {
601:   StageLog       stageLog;

605:   PetscLogGetStageLog(&stageLog);
606:   StageLogGetStage(stageLog, name, stage);
607:   return(0);
608: }

610: /*------------------------------------------------ Event Functions --------------------------------------------------*/
613: /*@C
614:   PetscLogEventRegister - Registers an event name for logging operations in an application code. 

616:   Not Collective

618:   Input Parameter:
619: + name   - The name associated with the event
620: - cookie - The cookie associated to the class for this event, obtain either with
621:            PetscCookieRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
622:             
623:   Output Parameter:
624: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

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

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

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

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

658:   Level: intermediate

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

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

684: /*@
685:   PetscLogEventActivate - Indicates that a particular event should be logged.

687:   Not Collective

689:   Input Parameter:
690: . event - The event id

692:   Usage:
693: .vb
694:       PetscLogEventDeactivate(VEC_SetValues);
695:         [code where you do not want to log VecSetValues()]
696:       PetscLogEventActivate(VEC_SetValues);
697:         [code where you do want to log VecSetValues()]
698: .ve 

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

704:   Level: advanced

706: .keywords: log, event, activate
707: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
708: @*/
709: PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
710: {
711:   StageLog       stageLog;
712:   int            stage;

716:   PetscLogGetStageLog(&stageLog);
717:   StageLogGetCurrent(stageLog, &stage);
718:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
719:   return(0);
720: }

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

727:   Not Collective

729:   Input Parameter:
730: . event - The event id

732:   Usage:
733: .vb
734:       PetscLogEventDeactivate(VEC_SetValues);
735:         [code where you do not want to log VecSetValues()]
736:       PetscLogEventActivate(VEC_SetValues);
737:         [code where you do want to log VecSetValues()]
738: .ve 

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

744:   Level: advanced

746: .keywords: log, event, deactivate
747: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
748: @*/
749: PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
750: {
751:   StageLog       stageLog;
752:   int            stage;

756:   PetscLogGetStageLog(&stageLog);
757:   StageLogGetCurrent(stageLog, &stage);
758:   EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
759:   return(0);
760: }

764: /*@
765:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

767:   Not Collective

769:   Input Parameters:
770: + event    - The event id
771: - isActive - The activity flag determining whether the event is logged

773:   Level: advanced

775: .keywords: log, event, activate
776: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
777: @*/
778: PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscTruth isActive)
779: {
780:   StageLog       stageLog;
781:   int            stage;

785:   PetscLogGetStageLog(&stageLog);
786:   for(stage = 0; stage < stageLog->numStages; stage++) {
787:     if (isActive) {
788:       EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
789:     } else {
790:       EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
791:     }
792:   }
793:   return(0);
794: }

798: /*@
799:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

801:   Not Collective

803:   Input Parameter:
804: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

806:   Level: developer

808: .keywords: log, event, activate, class
809: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
810: @*/
811: PetscErrorCode  PetscLogEventActivateClass(PetscCookie cookie)
812: {
813:   StageLog       stageLog;
814:   int            stage;

818:   PetscLogGetStageLog(&stageLog);
819:   StageLogGetCurrent(stageLog, &stage);
820:   EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
821:   return(0);
822: }

826: /*@
827:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

829:   Not Collective

831:   Input Parameter:
832: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

834:   Level: developer

836: .keywords: log, event, deactivate, class
837: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
838: @*/
839: PetscErrorCode  PetscLogEventDeactivateClass(PetscCookie cookie)
840: {
841:   StageLog       stageLog;
842:   int            stage;

846:   PetscLogGetStageLog(&stageLog);
847:   StageLogGetCurrent(stageLog, &stage);
848:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
849:   return(0);
850: }

852: /*MC
853:    PetscLogEventBegin - Logs the beginning of a user event. 

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

859:    Synopsis:
860:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
861:                        PetscObject o4)

863:    Fortran Synopsis:
864:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

866:    Usage:
867: .vb
868:      int USER_EVENT;
869:      int user_event_flops;
870:      PetscLogEventRegister("User event",0,&USER_EVENT);
871:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
872:         [code segment to monitor]
873:         PetscLogFlops(user_event_flops);
874:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
875: .ve

877:    Notes:
878:    You need to register each integer event with the command 
879:    PetscLogEventRegister().  The source code must be compiled with 
880:    -DPETSC_USE_LOG, which is the default.

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

887:    Level: intermediate

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

891: .keywords: log, event, begin
892: M*/

894: /*MC
895:    PetscLogEventEnd - Log the end of a user event.

897:    Input Parameters:
898: +  e - integer associated with the event obtained with PetscLogEventRegister()
899: -  o1,o2,o3,o4 - objects associated with the event, or 0

901:    Synopsis:
902:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
903:                      PetscObject o4)

905:    Fortran Synopsis:
906:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

908:    Usage:
909: .vb
910:      int USER_EVENT;
911:      int user_event_flops;
912:      PetscLogEventRegister("User event",0,&USER_EVENT,);
913:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
914:         [code segment to monitor]
915:         PetscLogFlops(user_event_flops);
916:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
917: .ve

919:    Notes:
920:    You should also register each additional integer event with the command 
921:    PetscLogEventRegister(). Source code must be compiled with 
922:    -DPETSC_USE_LOG, which is the default.

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

929:    Level: intermediate

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

933: .keywords: log, event, end
934: M*/

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

939:    Input Parameters:
940: .  e - integer associated with the event obtained from PetscLogEventRegister()
941: .  o1,o2,o3,o4 - objects associated with the event, or 0
942: .  comm - communicator the barrier takes place over

944:    Synopsis:
945:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
946:                   PetscObject o4,MPI_Comm comm)

948:    Usage:
949: .vb
950:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
951:        MPI_Allreduce()
952:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
953: .ve

955:    Notes:
956:    This is for logging the amount of time spent in a barrier for an event
957:    that requires synchronization. 

959:    Additional Notes:
960:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
961:    VEC_NormComm = VEC_NormBarrier + 1

963:    Level: advanced

965: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
966:           PetscLogEventBarrierEnd()

968: .keywords: log, event, begin, barrier
969: M*/

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

974:    Input Parameters:
975: .  e - integer associated with the event obtained from PetscLogEventRegister()
976: .  o1,o2,o3,o4 - objects associated with the event, or 0
977: .  comm - communicator the barrier takes place over

979:    Synopsis:
980:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
981:                   PetscObject o4,MPI_Comm comm)

983:     Usage:
984: .vb
985:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
986:        MPI_Allreduce()
987:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
988: .ve

990:    Notes:
991:    This is for logging the amount of time spent in a barrier for an event
992:    that requires synchronization. 

994:    Additional Notes:
995:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
996:    VEC_NormComm = VEC_NormBarrier + 1

998:    Level: advanced

1000: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1001:           PetscLogEventBarrierBegin()

1003: .keywords: log, event, begin, barrier
1004: M*/


1007: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1010: /*@C
1011:   PetscLogDump - Dumps logs of objects to a file. This file is intended to 
1012:   be read by petsc/bin/petscview.

1014:   Collective on PETSC_COMM_WORLD

1016:   Input Parameter:
1017: . name - an optional file name

1019:   Options Database Keys:
1020: + -log     - Prints basic log information (for code compiled with PETSC_USE_LOG)
1021: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1022:    
1023:   Usage:
1024: .vb
1025:      PetscInitialize(...);
1026:      PetscLogBegin(); or PetscLogAllBegin(); 
1027:      ... code ...
1028:      PetscLogDump(filename);
1029:      PetscFinalize();
1030: .ve

1032:   Notes:
1033:   The default file name is 
1034: $    Log.<rank>
1035:   where <rank> is the processor number. If no name is specified, 
1036:   this file will be used.

1038:   Level: advanced

1040: .keywords: log, dump
1041: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1042: @*/
1043: PetscErrorCode  PetscLogDump(const char sname[])
1044: {
1045:   StageLog       stageLog;
1046:   EventPerfInfo *eventInfo;
1047:   FILE          *fd;
1048:   char           file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1049:   PetscLogDouble flops, _TotalTime;
1050:   PetscMPIInt    rank;
1051:   int            action, object, curStage;
1052:   PetscLogEvent  event;
1054: 
1056:   /* Calculate the total elapsed time */
1057:   PetscTime(_TotalTime);
1058:   _TotalTime -= BaseTime;
1059:   /* Open log file */
1060:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1061:   if (sname) {
1062:     sprintf(file, "%s.%d", sname, rank);
1063:   } else {
1064:     sprintf(file, "Log.%d", rank);
1065:   }
1066:   PetscFixFilename(file, fname);
1067:   PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1068:   if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1069:   /* Output totals */
1070:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1071:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1072:   /* Output actions */
1073:   if (logActions) {
1074:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1075:     for(action = 0; action < numActions; action++) {
1076:       PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1077:                           actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1078:                           actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1079:     }
1080:   }
1081:   /* Output objects */
1082:   if (logObjects) {
1083:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1084:     for(object = 0; object < numObjects; object++) {
1085:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1086:       if (!objects[object].name[0]) {
1087:         PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1088:       } else {
1089:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1090:       }
1091:       if (objects[object].info[0] != 0) {
1092:         PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1093:       } else {
1094:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1095:       }
1096:     }
1097:   }
1098:   /* Output events */
1099:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1100:   PetscLogGetStageLog(&stageLog);
1101:   StackTop(stageLog->stack, &curStage);
1102:   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1103:   for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1104:     if (eventInfo[event].time != 0.0) {
1105:       flops = eventInfo[event].flops/eventInfo[event].time;
1106:     } else {
1107:       flops = 0.0;
1108:     }
1109:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1110:                         eventInfo[event].flops, eventInfo[event].time, flops);
1111:   }
1112:   PetscFClose(PETSC_COMM_WORLD, fd);
1113:   return(0);
1114: }

1118: /*@C
1119:   PetscLogPrintSummary - Prints a summary of the logging.

1121:   Collective over MPI_Comm

1123:   Input Parameter:
1124: + comm - The MPI communicator (only one processor prints output)
1125: - file - [Optional] The output file name

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

1130:   Usage:
1131: .vb
1132:      PetscInitialize(...);
1133:      PetscLogBegin();
1134:      ... code ...
1135:      PetscLogPrintSummary(MPI_Comm,filename);
1136:      PetscFinalize(...);
1137: .ve

1139:   Notes:
1140:   By default the summary is printed to stdout.

1142:   Level: beginner
1143:    
1144: .keywords: log, dump, print
1145: .seealso: PetscLogBegin(), PetscLogDump()
1146: @*/
1147: PetscErrorCode  PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1148: {
1149:   FILE           *fd = PETSC_STDOUT;
1150:   PetscLogDouble zero = 0.0;
1151:   StageLog       stageLog;
1152:   StageInfo     *stageInfo = PETSC_NULL;
1153:   EventPerfInfo *eventInfo = PETSC_NULL;
1154:   ClassPerfInfo *classInfo;
1155:   char           arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1156:   const char    *name;
1157:   PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1158:   PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1159:   PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1160:   PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1161:   PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1162:   PetscLogDouble min, max, tot, ratio, avg, x, y;
1163:   PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1164:   PetscMPIInt    minCt, maxCt;
1165:   PetscMPIInt    size, rank;
1166:   PetscTruth    *localStageUsed,    *stageUsed;
1167:   PetscTruth    *localStageVisible, *stageVisible;
1168:   int            numStages, localNumEvents, numEvents;
1169:   int            stage, lastStage, oclass;
1170:   PetscLogEvent  event;
1172:   char           version[256];

1175:   MPI_Comm_size(comm, &size);
1176:   MPI_Comm_rank(comm, &rank);
1177:   /* Pop off any stages the user forgot to remove */
1178:   lastStage = 0;
1179:   PetscLogGetStageLog(&stageLog);
1180:   StageLogGetCurrent(stageLog, &stage);
1181:   while (stage >= 0) {
1182:     lastStage = stage;
1183:     StageLogPop(stageLog);
1184:     StageLogGetCurrent(stageLog, &stage);
1185:   }
1186:   /* Get the total elapsed time */
1187:   PetscTime(locTotalTime);  locTotalTime -= BaseTime;
1188:   /* Open the summary file */
1189:   if (filename) {
1190:     PetscFOpen(comm, filename, "w", &fd);
1191:   }

1193:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1194:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1195:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1196:   PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1197:   PetscGetArchType(arch, 10);
1198:   PetscGetHostName(hostname, 64);
1199:   PetscGetUserName(username, 16);
1200:   PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1201:   PetscGetDate(date, 64);
1202:   PetscGetVersion(version,256);
1203:   if (size == 1) {
1204:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1205:   } else {
1206:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1207:   }
1208:   PetscFPrintf(comm, fd, "Using %s\n", version);

1210:   /* Must preserve reduction count before we go on */
1211:   red  = (allreduce_ct + gather_ct + scatter_ct)/((PetscLogDouble) size);

1213:   /* Calculate summary information */
1214:   PetscFPrintf(comm, fd, "\n                         Max       Max/Min        Avg      Total \n");
1215:   /*   Time */
1216:   MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1217:   MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1218:   MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1219:   avg  = (tot)/((PetscLogDouble) size);
1220:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1221:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %10.5f   %5.3e\n", max, ratio, avg);
1222:   TotalTime = tot;
1223:   /*   Objects */
1224:   avg  = (PetscLogDouble) numObjects;
1225:   MPI_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1226:   MPI_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1227:   MPI_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1228:   avg  = (tot)/((PetscLogDouble) size);
1229:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1230:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %10.5f   %5.3e\n", max, ratio, avg);
1231:   /*   Flops */
1232:   MPI_Allreduce(&_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1233:   MPI_Allreduce(&_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1234:   MPI_Allreduce(&_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1235:   avg  = (tot)/((PetscLogDouble) size);
1236:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1237:   PetscFPrintf(comm, fd, "Flops:                %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1238:   TotalFlops = tot;
1239:   /*   Flops/sec -- Must talk to Barry here */
1240:   if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1241:   MPI_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1242:   MPI_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1243:   MPI_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1244:   avg  = (tot)/((PetscLogDouble) size);
1245:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1246:   PetscFPrintf(comm, fd, "Flops/sec:            %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1247:   /*   Memory */
1248:   PetscMallocGetMaximumUsage(&mem);
1249:   if (mem > 0.0) {
1250:     MPI_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1251:     MPI_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1252:     MPI_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1253:     avg  = (tot)/((PetscLogDouble) size);
1254:     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1255:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %10.5f              %5.3e\n", max, ratio, tot);
1256:   }
1257:   /*   Messages */
1258:   mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1259:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1260:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1261:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1262:   avg  = (tot)/((PetscLogDouble) size);
1263:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1264:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1265:   numMessages = tot;
1266:   /*   Message Lengths */
1267:   mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1268:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1269:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1270:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1271:   if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1272:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1273:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1274:   messageLength = tot;
1275:   /*   Reductions */
1276:   MPI_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1277:   MPI_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1278:   MPI_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1279:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1280:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %10.5f\n", max, ratio);
1281:   numReductions = tot;
1282:   PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1283:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1284:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flops\n");

1286:   /* Get total number of stages --
1287:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1288:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1289:        This seems best accomplished by assoicating a communicator with each stage.
1290:   */
1291:   MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1292:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1293:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1294:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1295:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1296:   if (numStages > 0) {
1297:     stageInfo = stageLog->stageInfo;
1298:     for(stage = 0; stage < numStages; stage++) {
1299:       if (stage < stageLog->numStages) {
1300:         localStageUsed[stage]    = stageInfo[stage].used;
1301:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1302:       } else {
1303:         localStageUsed[stage]    = PETSC_FALSE;
1304:         localStageVisible[stage] = PETSC_TRUE;
1305:       }
1306:     }
1307:     MPI_Allreduce(localStageUsed,    stageUsed,    numStages, MPI_INT, MPI_LOR,  comm);
1308:     MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1309:     for(stage = 0; stage < numStages; stage++) {
1310:       if (stageUsed[stage]) {
1311:         PetscFPrintf(comm, fd, "\nSummary of Stages:   ----- Time ------  ----- Flops -----  --- Messages ---  -- Message Lengths --  -- Reductions --\n");
1312:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total   counts   %%Total     Avg         %%Total   counts   %%Total \n");
1313:         break;
1314:       }
1315:     }
1316:     for(stage = 0; stage < numStages; stage++) {
1317:       if (!stageUsed[stage]) continue;
1318:       if (localStageUsed[stage]) {
1319:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1320:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1321:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1322:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1323:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1324:         name = stageInfo[stage].name;
1325:       } else {
1326:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1327:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1328:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1329:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1330:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1331:         name = "";
1332:       }
1333:       mess *= 0.5; messLen *= 0.5; red /= size;
1334:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1335:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1336:       /* Talk to Barry if (stageTime     != 0.0) flops          = (size*flops)/stageTime; else flops          = 0.0; */
1337:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1338:       if (numMessages   != 0.0) avgMessLen     = messLen/numMessages;    else avgMessLen     = 0.0;
1339:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1340:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1341:       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",
1342:                           stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1343:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1344:     }
1345:   }

1347:   PetscFPrintf(comm, fd,
1348:     "\n------------------------------------------------------------------------------------------------------------------------\n");
1349: 
1350:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1351:   PetscFPrintf(comm, fd, "Phase summary info:\n");
1352:   PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");
1353:   PetscFPrintf(comm, fd, "   Time and Flops: Max - maximum over all processors\n");
1354:   PetscFPrintf(comm, fd, "                   Ratio - ratio of maximum to minimum over all processors\n");
1355:   PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");
1356:   PetscFPrintf(comm, fd, "   Avg. len: average message length\n");
1357:   PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");
1358:   PetscFPrintf(comm, fd, "   Global: entire computation\n");
1359:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1360:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flops in this phase\n");
1361:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");
1362:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");
1363:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1364:   PetscFPrintf(comm, fd,
1365:     "------------------------------------------------------------------------------------------------------------------------\n");
1366: 

1368: #if defined(PETSC_USE_DEBUG)
1369:   PetscFPrintf(comm, fd, "\n\n");
1370:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1371:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1372:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1373:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1374:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #\n");
1375:   PetscFPrintf(comm, fd, "      #   To get timing results run config/configure.py        #\n");
1376:   PetscFPrintf(comm, fd, "      #   using --with-debugging=no, the performance will      #\n");
1377:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");
1378:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1379:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1380: #endif
1381: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1382:   PetscFPrintf(comm, fd, "\n\n");
1383:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1384:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1385:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1386:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1387:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #\n");
1388:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #\n");
1389:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #\n");
1390:   PetscFPrintf(comm, fd, "      #   faster, specify --with-fortran-kernels=generic       #\n");
1391:   PetscFPrintf(comm, fd, "      #   when running config/configure.py.                    #\n");
1392:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1393:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1394: #endif

1396:   /* Report events */
1397:   PetscFPrintf(comm, fd,
1398:     "Event                Count      Time (sec)     Flops                             --- Global ---  --- Stage ---   Total\n");
1399: 
1400:   PetscFPrintf(comm, fd,
1401:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s\n");
1402: 
1403:   PetscFPrintf(comm,fd,
1404:     "------------------------------------------------------------------------------------------------------------------------\n");

1406: 
1407:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1408:   for(stage = 0; stage < numStages; stage++) {
1409:     if (!stageVisible[stage]) continue;
1410:     if (localStageUsed[stage]) {
1411:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1412:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1413:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1414:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1415:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1416:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1417:     } else {
1418:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1419:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1420:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1421:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1422:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1423:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1424:     }
1425:     mess *= 0.5; messLen *= 0.5; red /= size;

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

1432:        Problem: If the event did not happen on proc 1, its name will not be available.
1433:        Problem: Event visibility is not implemented
1434:     */
1435:     if (localStageUsed[stage]) {
1436:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1437:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1438:     } else {
1439:       localNumEvents = 0;
1440:     }
1441:     MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1442:     for(event = 0; event < numEvents; event++) {
1443:       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1444:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1445:           flopr = eventInfo[event].flops;
1446:         } else {
1447:           flopr = 0.0;
1448:         }
1449:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1450:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1451:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1452:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1453:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1454:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1455:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1456:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1457:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1458:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1459:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1460:         name = stageLog->eventLog->eventInfo[event].name;
1461:       } else {
1462:         flopr = 0.0;
1463:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1464:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1465:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1466:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1467:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1468:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1469:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1470:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1471:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1472:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1473:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1474:         name = "";
1475:       }
1476:       if (mint < 0.0) {
1477:         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);
1478:         mint = 0;
1479:       }
1480:       if (minf < 0.0) SETERRQ2(PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1481:       totm *= 0.5; totml *= 0.5; totr /= size;
1482: 
1483:       if (maxCt != 0) {
1484:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1485:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1486:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1487:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1488:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1489:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1490:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1491:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1492:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1493:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1494:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1495:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1496:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1497:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1498:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1499:         PetscFPrintf(comm, fd,
1500:           "%-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",
1501:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1502:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1503:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1504:                             flopr/1.0e6);
1505:       }
1506:     }
1507:   }

1509:   /* Memory usage and object creation */
1510:   PetscFPrintf(comm, fd,
1511:     "------------------------------------------------------------------------------------------------------------------------\n");
1512:   PetscFPrintf(comm, fd, "\n");
1513:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

1515:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1516:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1517:      stats for stages local to processor sets.
1518:   */
1519:   /* We should figure out the longest object name here (now 20 characters) */
1520:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions   Memory  Descendants' Mem.\n");
1521:   for(stage = 0; stage < numStages; stage++) {
1522:     if (localStageUsed[stage]) {
1523:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1524:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1525:       for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1526:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1527:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %9d     %g\n", stageLog->classLog->classInfo[oclass].name,
1528:                               classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1529:                               classInfo[oclass].descMem);
1530:         }
1531:       }
1532:     } else {
1533:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1534:     }
1535:   }

1537:   PetscFree(localStageUsed);
1538:   PetscFree(stageUsed);
1539:   PetscFree(localStageVisible);
1540:   PetscFree(stageVisible);

1542:   /* Information unrelated to this particular run */
1543:   PetscFPrintf(comm, fd,
1544:     "========================================================================================================================\n");
1545:   PetscTime(y);
1546:   PetscTime(x);
1547:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1548:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1549:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1550:   /* MPI information */
1551:   if (size > 1) {
1552:     MPI_Status  status;
1553:     PetscMPIInt tag;
1554:     MPI_Comm    newcomm;

1556:     MPI_Barrier(comm);
1557:     PetscTime(x);
1558:     MPI_Barrier(comm);
1559:     MPI_Barrier(comm);
1560:     MPI_Barrier(comm);
1561:     MPI_Barrier(comm);
1562:     MPI_Barrier(comm);
1563:     PetscTime(y);
1564:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1565:     PetscCommDuplicate(comm,&newcomm, &tag);
1566:     MPI_Barrier(comm);
1567:     if (rank) {
1568:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, newcomm, &status);
1569:       MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1570:     } else {
1571:       PetscTime(x);
1572:       MPI_Send(0, 0, MPI_INT, 1,          tag, newcomm);
1573:       MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1574:       PetscTime(y);
1575:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1576:     }
1577:     PetscCommDestroy(&newcomm);
1578:   }
1579:   if (!rank) {
1580:     PetscOptionsPrint(fd);
1581:   }
1582:   /* Machine and compile information */
1583: #if defined(PETSC_USE_FORTRAN_KERNELS)
1584:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1585: #else
1586:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1587: #endif
1588: #if defined(PETSC_USE_SINGLE)
1589:   PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1590: #elif defined(PETSC_USE_LONGDOUBLE)
1591:   PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1592: #elif defined(PETSC_USE_INT)
1593:   PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1594: #endif

1596: #if defined(PETSC_USE_MAT_SINGLE)
1597:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1598: #else
1599:   PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1600: #endif
1601:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1602:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));

1604:   PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1605:   PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1606:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1607:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1608:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1609:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1611:   /* Cleanup */
1612:   PetscFPrintf(comm, fd, "\n");
1613:   PetscFClose(comm, fd);
1614:   StageLogPush(stageLog, lastStage);
1615:   return(0);
1616: }

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

1623:   Collective over MPI_Comm

1625:   Input Parameter:
1626: + comm - The MPI communicator (only one processor prints output)
1627: - file - [Optional] The output file name

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

1632:   Usage:
1633: .vb
1634:      PetscInitialize(...);
1635:      PetscLogBegin();
1636:      ... code ...
1637:      PetscLogPrintDetailed(MPI_Comm,filename);
1638:      PetscFinalize(...);
1639: .ve

1641:   Notes:
1642:   By default the summary is printed to stdout.

1644:   Level: beginner
1645:    
1646: .keywords: log, dump, print
1647: .seealso: PetscLogBegin(), PetscLogDump(), PetscLogPrintSummary()
1648: @*/
1649: PetscErrorCode  PetscLogPrintDetailed(MPI_Comm comm, const char filename[])
1650: {
1651:   FILE          *fd = PETSC_STDOUT;
1652:   StageLog       stageLog;
1653:   StageInfo     *stageInfo = PETSC_NULL;
1654:   EventPerfInfo *eventInfo = PETSC_NULL;
1655:   const char    *name = PETSC_NULL;
1656:   PetscLogDouble TotalTime;
1657:   PetscLogDouble stageTime, flops, flopr, mess, messLen, red;
1658:   PetscLogDouble maxf, totf, maxt, tott, totm, totml, totr = 0.0;
1659:   PetscMPIInt    maxCt;
1660:   PetscMPIInt    size, rank;
1661:   PetscTruth     *stageUsed;
1662:   PetscTruth     *stageVisible;
1663:   int            numStages, numEvents;
1664:   int            stage;
1665:   PetscLogEvent  event;

1669:   MPI_Comm_size(comm, &size);
1670:   MPI_Comm_rank(comm, &rank);
1671:   /* Pop off any stages the user forgot to remove */
1672:   PetscLogGetStageLog(&stageLog);
1673:   StageLogGetCurrent(stageLog, &stage);
1674:   while (stage >= 0) {
1675:     StageLogPop(stageLog);
1676:     StageLogGetCurrent(stageLog, &stage);
1677:   }
1678:   /* Get the total elapsed time */
1679:   PetscTime(TotalTime);  TotalTime -= BaseTime;
1680:   /* Open the summary file */
1681:   if (filename) {
1682:     PetscFOpen(comm, filename, "w", &fd);
1683:   }

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


1690:   numStages = stageLog->numStages;
1691:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1692:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1693:   if (numStages > 0) {
1694:     stageInfo = stageLog->stageInfo;
1695:     for(stage = 0; stage < numStages; stage++) {
1696:       if (stage < stageLog->numStages) {
1697:         stageUsed[stage]    = stageInfo[stage].used;
1698:         stageVisible[stage] = stageInfo[stage].perfInfo.visible;
1699:       } else {
1700:         stageUsed[stage]    = PETSC_FALSE;
1701:         stageVisible[stage] = PETSC_TRUE;
1702:       }
1703:     }
1704:   }

1706:   /* Report events */
1707:   PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flops/sec                          \n");
1708:   PetscFPrintf(comm, fd,"                                                            Mess   Avg len Reduct \n");
1709:   PetscFPrintf(comm,fd,"-----------------------------------------------------------------------------------\n");
1710:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1711:   for(stage = 0; stage < numStages; stage++) {
1712:     if (!stageVisible[stage]) continue;
1713:     if (stageUsed[stage]) {
1714:       PetscSynchronizedFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1715:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1716:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1717:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1718:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1719:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1720:     }
1721:     mess *= 0.5; messLen *= 0.5;

1723:     /* Get total number of events in this stage --
1724:     */
1725:     if (stageUsed[stage]) {
1726:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1727:       numEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1728:     } else {
1729:       numEvents = 0;
1730:     }
1731:     for(event = 0; event < numEvents; event++) {
1732:       if (stageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1733:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1734:           flopr = eventInfo[event].flops/eventInfo[event].time;
1735:         } else {
1736:           flopr = 0.0;
1737:         }
1738:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1739:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1740:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1741:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1742:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1743:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1744:         totr = eventInfo[event].numReductions;
1745:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, PETSC_COMM_SELF);
1746:         name = stageLog->eventLog->eventInfo[event].name;
1747:         totm *= 0.5; totml *= 0.5;
1748:       }
1749: 
1750:       if (maxCt != 0) {
1751:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1752:         PetscSynchronizedFPrintf(comm, fd,"%-16s %7d      %5.4e      %3.2e      %2.1e %2.1e %2.1e\n",name, maxCt,  maxt,  maxf, totm, totml, totr);
1753:       }
1754:     }
1755:   }
1756:   PetscSynchronizedFlush(comm);

1758:   PetscFree(stageUsed);
1759:   PetscFree(stageVisible);

1761:   PetscFClose(comm, fd);
1762:   return(0);
1763: }

1765: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1768: /*@C
1769:    PetscGetFlops - Returns the number of flops used on this processor 
1770:    since the program began. 

1772:    Not Collective

1774:    Output Parameter:
1775:    flops - number of floating point operations 

1777:    Notes:
1778:    A global counter logs all PETSc flop counts.  The user can use
1779:    PetscLogFlops() to increment this counter to include flops for the 
1780:    application code.  

1782:    PETSc automatically logs library events if the code has been
1783:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1784:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1785:    intended for logging user flops to supplement this PETSc
1786:    information.

1788:    Level: intermediate

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

1792: .seealso: PetscGetTime(), PetscLogFlops()
1793: @*/
1794: PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
1795: {
1797:   *flops = _TotalFlops;
1798:   return(0);
1799: }

1803: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
1804: {
1806:   int            fullLength;
1807:   va_list        Argp;

1810:   if (!logObjects) return(0);
1811:   va_start(Argp, format);
1812:   PetscVSNPrintf(objects[obj->id].info, 64,format,&fullLength, Argp);
1813:   va_end(Argp);
1814:   return(0);
1815: }

1819: /*@
1820:   PetscLogGetStageLog - This function returns the default stage logging object.

1822:   Not collective

1824:   Output Parameter:
1825: . stageLog - The default StageLog

1827:   Level: beginner

1829: .keywords: log, stage
1830: .seealso: StageLogCreate()
1831: @*/
1832: PetscErrorCode  PetscLogGetStageLog(StageLog *stageLog)
1833: {
1836:   *stageLog = _stageLog;
1837:   return(0);
1838: }

1840: /*MC
1841:    PetscLogFlops - Adds floating point operations to the global counter.

1843:    Input Parameter:
1844: .  f - flop counter

1846:    Synopsis:
1847:    void PetscLogFlops(int f)

1849:    Usage:
1850: .vb
1851:      int USER_EVENT;
1852:      PetscLogEventRegister("User event",0,&USER_EVENT);
1853:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1854:         [code segment to monitor]
1855:         PetscLogFlops(user_flops)
1856:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1857: .ve

1859:    Notes:
1860:    A global counter logs all PETSc flop counts.  The user can use
1861:    PetscLogFlops() to increment this counter to include flops for the 
1862:    application code.  

1864:    PETSc automatically logs library events if the code has been
1865:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1866:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1867:    intended for logging user flops to supplement this PETSc
1868:    information.

1870:    Level: intermediate

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

1874: .keywords: log, flops, floating point operations
1875: M*/

1877: /*MC
1878:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1879:     to get accurate timings

1881:    Input Parameter:
1882: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1883:            with command line option -preload true or -preload false
1884: -   name - name of first stage (lines of code timed separately with -log_summary) to
1885:            be preloaded

1887:    Synopsis:
1888:    void PreLoadBegin(PetscTruth flag,char *name);

1890:    Usage:
1891: .vb
1892:      PreLoadBegin(PETSC_TRUE,"first stage);
1893:        lines of code
1894:        PreLoadStage("second stage");
1895:        lines of code
1896:      PreLoadEnd();
1897: .ve

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

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

1909:    Level: intermediate

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

1913:    Concepts: preloading
1914:    Concepts: timing^accurate
1915:    Concepts: paging^eliminating effects of


1918: M*/

1920: /*MC
1921:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1922:     to get accurate timings

1924:    Synopsis:
1925:    void PreLoadEnd(void);

1927:    Usage:
1928: .vb
1929:      PreLoadBegin(PETSC_TRUE,"first stage);
1930:        lines of code
1931:        PreLoadStage("second stage");
1932:        lines of code
1933:      PreLoadEnd();
1934: .ve

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

1938:    Level: intermediate

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

1942: M*/

1944: /*MC
1945:    PreLoadStage - Start a new segment of code to be timed separately.
1946:     to get accurate timings

1948:    Synopsis:
1949:    void PreLoadStage(char *name);

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

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

1962:    Level: intermediate

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

1966: M*/

1968: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1971: /*@C
1972:   StackDestroy - This function destroys a stack.

1974:   Not Collective

1976:   Input Parameter:
1977: . stack - The stack

1979:   Level: beginner

1981: .keywords: log, stack, destroy
1982: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1983: @*/
1984: PetscErrorCode StackDestroy(IntStack stack)
1985: {

1989:   PetscFree(stack->stack);
1990:   PetscFree(stack);
1991:   return(0);
1992: }

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

1999:   Not Collective

2001:   Input Parameter:
2002: . stack - The stack

2004:   Output Parameter:
2005: . empty - PETSC_TRUE if the stack is empty

2007:   Level: intermediate

2009: .keywords: log, stack, empty
2010: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
2011: @*/
2012: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
2013: {
2016:   if (stack->top == -1) {
2017:     *empty = PETSC_TRUE;
2018:   } else {
2019:     *empty = PETSC_FALSE;
2020:   }
2021:   return(0);
2022: }

2026: /*@C
2027:   StackTop - This function returns the top of the stack.

2029:   Not Collective

2031:   Input Parameter:
2032: . stack - The stack

2034:   Output Parameter:
2035: . top - The integer on top of the stack

2037:   Level: intermediate

2039: .keywords: log, stack, top
2040: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
2041: @*/
2042: PetscErrorCode StackTop(IntStack stack, int *top)
2043: {
2046:   *top = stack->stack[stack->top];
2047:   return(0);
2048: }

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

2055:   Not Collective

2057:   Input Parameters:
2058: + stack - The stack
2059: - item  - The integer to push

2061:   Level: intermediate

2063: .keywords: log, stack, push
2064: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
2065: @*/
2066: PetscErrorCode StackPush(IntStack stack, int item)
2067: {
2068:   int            *array;

2072:   stack->top++;
2073:   if (stack->top >= stack->max) {
2074:     PetscMalloc(stack->max*2 * sizeof(int), &array);
2075:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2076:     PetscFree(stack->stack);
2077:     stack->stack = array;
2078:     stack->max  *= 2;
2079:   }
2080:   stack->stack[stack->top] = item;
2081:   return(0);
2082: }

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

2089:   Not Collective

2091:   Input Parameter:
2092: . stack - The stack

2094:   Output Parameter:
2095: . item  - The integer popped

2097:   Level: intermediate

2099: .keywords: log, stack, pop
2100: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2101: @*/
2102: PetscErrorCode StackPop(IntStack stack, int *item)
2103: {
2106:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2107:   *item = stack->stack[stack->top--];
2108:   return(0);
2109: }

2113: /*@C
2114:   StackCreate - This function creates a stack.

2116:   Not Collective

2118:   Output Parameter:
2119: . stack - The stack

2121:   Level: beginner

2123: .keywords: log, stack, pop
2124: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2125: @*/
2126: PetscErrorCode StackCreate(IntStack *stack)
2127: {
2128:   IntStack       s;

2133:   PetscNew(struct _n_IntStack, &s);
2134:   s->top = -1;
2135:   s->max = 128;
2136:   PetscMalloc(s->max * sizeof(int), &s->stack);
2137:   PetscMemzero(s->stack, s->max * sizeof(int));
2138:   *stack = s;
2139:   return(0);
2140: }

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

2146: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2147: {
2149:   return(0);
2150: }

2152: #endif /* PETSC_USE_LOG*/


2155: PetscCookie PETSC_LARGEST_COOKIE = PETSC_SMALLEST_COOKIE;
2156: PetscCookie PETSC_OBJECT_COOKIE  = 0;

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

2163:   Not Collective

2165:   Input Parameter:
2166: . name   - The class name
2167:             
2168:   Output Parameter:
2169: . oclass - The class id or cookie

2171:   Level: developer

2173: .keywords: log, class, register

2175: @*/
2176: PetscErrorCode  PetscCookieRegister(const char name[],PetscCookie *oclass )
2177: {
2178: #if defined(PETSC_USE_LOG)
2179:   StageLog       stageLog;
2180:   PetscInt       stage;
2182: #endif

2185:   *oclass = ++PETSC_LARGEST_COOKIE;
2186: #if defined(PETSC_USE_LOG)
2187:   PetscLogGetStageLog(&stageLog);
2188:   ClassRegLogRegister(stageLog->classLog, name, *oclass);
2189:   for(stage = 0; stage < stageLog->numStages; stage++) {
2190:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2191:   }
2192: #endif
2193:   return(0);
2194: }