Actual source code: plog.c

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

 22: PetscCookie PETSC_LARGEST_COOKIE = PETSC_COOKIE;
 23: PetscEvent  PETSC_LARGEST_EVENT  = PETSC_EVENT;

 25: #if defined(PETSC_USE_LOG)

 27: /* used in the MPI_XXX() count macros in petsclog.h */
 28: int PETSC_DUMMY = 0,PETSC_DUMMY_SIZE = 0, PETSC_DUMMY_COUNT = 0;

 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 send_ct         = 0.0; /* The number of sends */
 43: PetscLogDouble recv_ct         = 0.0; /* The number of receives */
 44: PetscLogDouble send_len        = 0.0; /* The total length of all sent messages */
 45: PetscLogDouble recv_len        = 0.0; /* The total length of all received messages */
 46: PetscLogDouble isend_ct        = 0.0; /* The number of immediate sends */
 47: PetscLogDouble irecv_ct        = 0.0; /* The number of immediate receives */
 48: PetscLogDouble isend_len       = 0.0; /* The total length of all immediate send messages */
 49: PetscLogDouble irecv_len       = 0.0; /* The total length of all immediate receive messages */
 50: PetscLogDouble wait_ct         = 0.0; /* The number of waits */
 51: PetscLogDouble wait_any_ct     = 0.0; /* The number of anywaits */
 52: PetscLogDouble wait_all_ct     = 0.0; /* The number of waitalls */
 53: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
 54: PetscLogDouble allreduce_ct    = 0.0; /* The number of reductions */

 56: /* Logging functions */
 57: PetscErrorCode (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
 58: PetscErrorCode (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
 59: PetscErrorCode (*_PetscLogPLB)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
 60: PetscErrorCode (*_PetscLogPLE)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;

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

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

 75:   Not Collective

 77:   Notes:
 78:   This routine should not usually be used by programmers. Instead employ 
 79:   PetscLogStagePush() and PetscLogStagePop().

 81:   Level: developer

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

 92:   if (actions) {
 93:     PetscFree(actions);
 94:     actions = PETSC_NULL;
 95:   }
 96:   if (objects) {
 97:     PetscFree(objects);
 98:     objects =  PETSC_NULL;
 99:   }
100:   PetscLogSet(PETSC_NULL, PETSC_NULL);

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

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

117:   Not Collective

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

123:   Level: developer

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

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

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

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

182:   Collective over PETSC_COMM_WORLD

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

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

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

202:   Level: advanced

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

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

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

223:   Collective on PETSC_COMM_WORLD

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

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

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

242:   Level: advanced

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

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

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

263:   Collective on PETSC_COMM_WORLD

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

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

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

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

279:   Level: intermediate

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

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

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

299:   Not Collective

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

304:   Level: intermediate

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

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

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

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

327:   Not Collective

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

332:   Level: intermediate

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

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

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

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

356:   Not Collective

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

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

364:   Level: intermediate

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

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

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

393:   Not Collective

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

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

416:   Level: intermediate

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

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

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

437:   Not Collective

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

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

457:   Level: intermediate

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

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

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

478:   Not Collective 

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

484:   Level: intermediate

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

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

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

504:   Not Collective 

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

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

512:   Level: intermediate

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

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

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

532:   Not Collective 

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

538:   Level: intermediate

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

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

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

558:   Not Collective 

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

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

566:   Level: intermediate

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

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

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

586:   Not Collective 

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

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

594:   Level: intermediate

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

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

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

615:   Not Collective

617:   Input Parameter:
618: + name   - The name associated with the event
619: - cookie - The cookie associated to the class for this event
620:             
621:   Output Parameter:
622: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

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

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

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

649:   Level: intermediate

651: .keywords: log, event, register
652: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
653:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
654:           PetscLogEventActivate(), PetscLogEventDeactivate()
655: @*/
656: PetscErrorCode PetscLogEventRegister(PetscEvent *event, const char name[],PetscCookie cookie)
657: {
658:   StageLog       stageLog;
659:   int            stage;

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

675: /*@
676:   PetscLogEventActivate - Indicates that a particular event should be logged.

678:   Not Collective

680:   Input Parameter:
681: . event - The event id

683:   Usage:
684: .vb
685:       PetscLogEventDeactivate(VEC_SetValues);
686:         [code where you do not want to log VecSetValues()]
687:       PetscLogEventActivate(VEC_SetValues);
688:         [code where you do want to log VecSetValues()]
689: .ve 

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

695:   Level: advanced

697: .keywords: log, event, activate
698: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
699: @*/
700: PetscErrorCode PetscLogEventActivate(PetscEvent event)
701: {
702:   StageLog       stageLog;
703:   int            stage;

707:   PetscLogGetStageLog(&stageLog);
708:   StageLogGetCurrent(stageLog, &stage);
709:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
710:   return(0);
711: }

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

718:   Not Collective

720:   Input Parameter:
721: . event - The event id

723:   Usage:
724: .vb
725:       PetscLogEventDeactivate(VEC_SetValues);
726:         [code where you do not want to log VecSetValues()]
727:       PetscLogEventActivate(VEC_SetValues);
728:         [code where you do want to log VecSetValues()]
729: .ve 

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

735:   Level: advanced

737: .keywords: log, event, deactivate
738: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
739: @*/
740: PetscErrorCode PetscLogEventDeactivate(PetscEvent event)
741: {
742:   StageLog       stageLog;
743:   int            stage;

747:   PetscLogGetStageLog(&stageLog);
748:   StageLogGetCurrent(stageLog, &stage);
749:   EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
750:   return(0);
751: }

755: /*@
756:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

758:   Not Collective

760:   Input Parameters:
761: + event    - The event id
762: - isActive - The activity flag determining whether the event is logged

764:   Level: advanced

766: .keywords: log, event, activate
767: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
768: @*/
769: PetscErrorCode PetscLogEventSetActiveAll(PetscEvent event, PetscTruth isActive)
770: {
771:   StageLog       stageLog;
772:   int            stage;

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

789: /*@
790:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

792:   Not Collective

794:   Input Parameter:
795: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

797:   Level: developer

799: .keywords: log, event, activate, class
800: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
801: @*/
802: PetscErrorCode PetscLogEventActivateClass(PetscCookie cookie)
803: {
804:   StageLog       stageLog;
805:   int            stage;

809:   PetscLogGetStageLog(&stageLog);
810:   StageLogGetCurrent(stageLog, &stage);
811:   EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
812:   return(0);
813: }

817: /*@
818:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

820:   Not Collective

822:   Input Parameter:
823: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

825:   Level: developer

827: .keywords: log, event, deactivate, class
828: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
829: @*/
830: PetscErrorCode PetscLogEventDeactivateClass(PetscCookie cookie)
831: {
832:   StageLog       stageLog;
833:   int            stage;

837:   PetscLogGetStageLog(&stageLog);
838:   StageLogGetCurrent(stageLog, &stage);
839:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
840:   return(0);
841: }

843: /*MC
844:    PetscLogEventBegin - Logs the beginning of a user event. 

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

850:    Synopsis:
851:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
852:                        PetscObject o4)

854:    Fortran Synopsis:
855:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

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

868:    Notes:
869:    You need to register each integer event with the command 
870:    PetscLogEventRegister().  The source code must be compiled with 
871:    -DPETSC_USE_LOG, which is the default.

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

878:    Level: intermediate

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

882: .keywords: log, event, begin
883: M*/

885: /*MC
886:    PetscLogEventEnd - Log the end of a user event.

888:    Input Parameters:
889: +  e - integer associated with the event obtained with PetscLogEventRegister()
890: -  o1,o2,o3,o4 - objects associated with the event, or 0

892:    Synopsis:
893:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
894:                      PetscObject o4)

896:    Fortran Synopsis:
897:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

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

910:    Notes:
911:    You should also register each additional integer event with the command 
912:    PetscLogEventRegister(). Source code must be compiled with 
913:    -DPETSC_USE_LOG, which is the default.

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

920:    Level: intermediate

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

924: .keywords: log, event, end
925: M*/

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

930:    Input Parameters:
931: .  e - integer associated with the event obtained from PetscLogEventRegister()
932: .  o1,o2,o3,o4 - objects associated with the event, or 0
933: .  comm - communicator the barrier takes place over

935:    Synopsis:
936:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
937:                   PetscObject o4,MPI_Comm comm)

939:    Usage:
940: .vb
941:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
942:        MPI_Allreduce()
943:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
944: .ve

946:    Notes:
947:    This is for logging the amount of time spent in a barrier for an event
948:    that requires synchronization. 

950:    Additional Notes:
951:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
952:    VEC_NormComm = VEC_NormBarrier + 1

954:    Level: advanced

956: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
957:           PetscLogEventBarrierEnd()

959: .keywords: log, event, begin, barrier
960: M*/

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

965:    Input Parameters:
966: .  e - integer associated with the event obtained from PetscLogEventRegister()
967: .  o1,o2,o3,o4 - objects associated with the event, or 0
968: .  comm - communicator the barrier takes place over

970:    Synopsis:
971:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
972:                   PetscObject o4,MPI_Comm comm)

974:     Usage:
975: .vb
976:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
977:        MPI_Allreduce()
978:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
979: .ve

981:    Notes:
982:    This is for logging the amount of time spent in a barrier for an event
983:    that requires synchronization. 

985:    Additional Notes:
986:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
987:    VEC_NormComm = VEC_NormBarrier + 1

989:    Level: advanced

991: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
992:           PetscLogEventBarrierBegin()

994: .keywords: log, event, begin, barrier
995: M*/

997: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1000: /*@C
1001:   PetscLogClassRegister - Registers a class name for logging operations in an application code. 

1003:   Not Collective

1005:   Input Parameter:
1006: . name   - The class name
1007:             
1008:   Output Parameter:
1009: . oclass - The class id or cookie

1011:   Level: developer

1013: .keywords: log, class, register
1014: .seealso: ClassLogRegister()
1015: @*/
1016: PetscErrorCode PetscLogClassRegister(PetscCookie *oclass, const char name[])
1017: {
1018:   StageLog       stageLog;
1019:   int            stage;

1023:   *oclass = PETSC_DECIDE;
1024:   PetscLogGetStageLog(&stageLog);
1025:   ClassRegLogRegister(stageLog->classLog, name, oclass);
1026:   for(stage = 0; stage < stageLog->numStages; stage++) {
1027:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
1028:   }
1029:   return(0);
1030: }

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

1039:   Collective on PETSC_COMM_WORLD

1041:   Input Parameter:
1042: . name - an optional file name

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

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

1063:   Level: advanced

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

1139: /*@C
1140:   PetscLogPrintSummary - Prints a summary of the logging.

1142:   Collective over MPI_Comm

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

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

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

1160:   Notes:
1161:   By default the summary is printed to stdout.
1162:   More extensive examination of the log information can be done with 
1163:   PetscLogDump(), which is activated by the option -log or -log_all, in 
1164:   combination with petsc/bin/petscview.

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

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

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

1234:   /* Must preserve reduction count before we go on */
1235:   red  = allreduce_ct/((PetscLogDouble) size);

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

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

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

1393: #if defined(PETSC_USE_BOPT_g)
1394:   PetscFPrintf(comm, fd, "\n\n");
1395:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1396:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1397:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1398:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1399:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #\n");
1400:   PetscFPrintf(comm, fd, "      #   BOPT=<g,g_c++,g_complex>.   To get timing results    #\n");
1401:   PetscFPrintf(comm, fd, "      #   ALWAYS compile your code with an optimized version,  #\n");
1402:   PetscFPrintf(comm, fd, "      #   BOPT=<O,O_c++,O_complex>;  the performance will      #\n");
1403:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");
1404:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1405:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1406: #endif
1407: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1408:   PetscFPrintf(comm, fd, "\n\n");
1409:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1410:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1411:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1412:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1413:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #\n");
1414:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #\n");
1415:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #\n");
1416:   PetscFPrintf(comm, fd, "      #   faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #\n");
1417:   PetscFPrintf(comm, fd, "      #   in base_variables and recompile the PETSc libraries. #\n");
1418:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1419:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1420: #endif

1422:   if (!PetscPreLoadingUsed) {
1423:     PetscFPrintf(comm,fd,"\n\n");
1424:     PetscFPrintf(comm,fd,"      ##########################################################\n");
1425:     PetscFPrintf(comm,fd,"      #                                                        #\n");
1426:     PetscFPrintf(comm,fd,"      #                          WARNING!!!                    #\n");
1427:     PetscFPrintf(comm,fd,"      #                                                        #\n");
1428:     PetscFPrintf(comm,fd,"      #   This code was run without the PreLoadBegin()         #\n");
1429:     PetscFPrintf(comm,fd,"      #   macros. To get timing results we always recommend    #\n");
1430:     PetscFPrintf(comm,fd,"      #   preloading. otherwise timing numbers may be          #\n");
1431:     PetscFPrintf(comm,fd,"      #   meaningless.                                         #\n");
1432:     PetscFPrintf(comm,fd,"      ##########################################################\n\n\n");
1433:   }

1435:   /* Report events */
1436:   PetscFPrintf(comm, fd,
1437:     "Event                Count      Time (sec)     Flops/sec                         --- Global ---  --- Stage ---   Total\n");
1438: 
1439:   PetscFPrintf(comm, fd,
1440:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s\n");
1441: 
1442:   PetscFPrintf(comm,fd,
1443:     "------------------------------------------------------------------------------------------------------------------------\n");

1445: 
1446:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1447:   for(stage = 0; stage < numStages; stage++) {
1448:     if (stageVisible[stage] == PETSC_FALSE) continue;
1449:     if (localStageUsed[stage] == PETSC_TRUE) {
1450:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1451:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1452:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1453:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1454:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1455:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1456:     } else {
1457:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1458:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1459:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1460:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1461:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1462:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1463:     }
1464:     mess *= 0.5; messLen *= 0.5; red /= size;

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

1471:        Problem: If the event did not happen on proc 1, its name will not be available.
1472:        Problem: Event visibility is not implemented
1473:     */
1474:     if (localStageUsed[stage] == PETSC_TRUE) {
1475:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1476:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1477:     } else {
1478:       localNumEvents = 0;
1479:     }
1480:     MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1481:     for(event = 0; event < numEvents; event++) {
1482:       if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1483:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1484:           flopr = eventInfo[event].flops/eventInfo[event].time;
1485:         } else {
1486:           flopr = 0.0;
1487:         }
1488:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1489:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1490:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1491:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1492:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1493:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1494:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1495:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1496:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1497:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1498:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1499:         name = stageLog->eventLog->eventInfo[event].name;
1500:       } else {
1501:         flopr = 0.0;
1502:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1503:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1504:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1505:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1506:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1507:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1508:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1509:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1510:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1511:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1512:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1513:         name = "";
1514:       }
1515:       totm *= 0.5; totml *= 0.5; totr /= size;
1516: 
1517:       if (maxCt != 0) {
1518:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1519:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1520:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1521:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1522:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1523:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1524:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1525:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1526:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1527:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1528:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1529:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1530:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1531:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1532:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1533:         PetscFPrintf(comm, fd,
1534:           "%-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",
1535:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1536:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1537:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1538:                             flopr/1.0e6);
1539: 
1540:       }
1541:     }
1542:   }

1544:   /* Memory usage and object creation */
1545:   PetscFPrintf(comm, fd,
1546:     "------------------------------------------------------------------------------------------------------------------------\n");
1547: 
1548:   PetscFPrintf(comm, fd, "\n");
1549:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

1551:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1552:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1553:      stats for stages local to processor sets.
1554:   */
1555:   /* We should figure out the longest object name here (now 20 characters) */
1556:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions   Memory  Descendants' Mem.\n");
1557:   for(stage = 0; stage < numStages; stage++) {
1558:     if (localStageUsed[stage] == PETSC_TRUE) {
1559:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1560:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1561:       for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1562:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1563:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %9d     %g\n", stageLog->classLog->classInfo[oclass].name,
1564:                               classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1565:                               classInfo[oclass].descMem);
1566: 
1567:         }
1568:       }
1569:     } else {
1570:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1571:     }
1572:   }

1574:   PetscFree(localStageUsed);
1575:   PetscFree(stageUsed);
1576:   PetscFree(localStageVisible);
1577:   PetscFree(stageVisible);

1579:   /* Information unrelated to this particular run */
1580:   PetscFPrintf(comm, fd,
1581:     "========================================================================================================================\n");
1582: 
1583:   PetscTime(y);
1584:   PetscTime(x);
1585:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1586:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1587:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1588:   /* MPI information */
1589:   if (size > 1) {
1590:     MPI_Status status;
1591:     int        tag;

1593:     MPI_Barrier(comm);
1594:     PetscTime(x);
1595:     MPI_Barrier(comm);
1596:     MPI_Barrier(comm);
1597:     MPI_Barrier(comm);
1598:     MPI_Barrier(comm);
1599:     MPI_Barrier(comm);
1600:     PetscTime(y);
1601:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1602:     PetscCommGetNewTag(comm, &tag);
1603:     MPI_Barrier(comm);
1604:     if (rank) {
1605:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, comm, &status);
1606:       MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, comm);
1607:     } else {
1608:       PetscTime(x);
1609:       MPI_Send(0, 0, MPI_INT, 1,          tag, comm);
1610:       MPI_Recv(0, 0, MPI_INT, size-1, tag, comm, &status);
1611:       PetscTime(y);
1612:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1613:     }
1614:   }
1615:   /* Machine and compile information */
1616: #if defined(PETSC_USE_FORTRAN_KERNELS)
1617:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1618: #else
1619:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1620: #endif
1621: #if defined(PETSC_USE_MAT_SINGLE)
1622:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1623: #else
1624:   PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)\n");
1625: #endif
1626:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d",
1627:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1628: 

1630:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1631:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1632:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1633:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

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

1641: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1644: /*@C
1645:    PetscGetFlops - Returns the number of flops used on this processor 
1646:    since the program began. 

1648:    Not Collective

1650:    Output Parameter:
1651:    flops - number of floating point operations 

1653:    Notes:
1654:    A global counter logs all PETSc flop counts.  The user can use
1655:    PetscLogFlops() to increment this counter to include flops for the 
1656:    application code.  

1658:    PETSc automatically logs library events if the code has been
1659:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1660:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1661:    intended for logging user flops to supplement this PETSc
1662:    information.

1664:    Level: intermediate

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

1668: .seealso: PetscGetTime(), PetscLogFlops()
1669: @*/
1670: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1671: {
1673:   *flops = _TotalFlops;
1674:   return(0);
1675: }

1679: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1680: {
1682:   va_list        Argp;

1685:   if (!logObjects) return(0);
1686:   va_start(Argp, format);
1687:   PetscVSNPrintf(objects[obj->id].info, 64,format, Argp);
1688:   va_end(Argp);
1689:   return(0);
1690: }

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

1696: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1697: {
1699:   return(0);
1700: }

1702: #endif /* PETSC_USE_LOG*/

1706: /*@
1707:    PetscGetTime - Returns the current time of day in seconds. This 
1708:    returns wall-clock time.  

1710:    Not Collective

1712:    Output Parameter:
1713: .  v - time counter

1715:    Usage: 
1716: .vb
1717:       PetscLogDouble v1,v2,elapsed_time;
1718:       PetscGetTime(&v1);CHKERR(ierr);
1719:       .... perform some calculation ...
1720:       PetscGetTime(&v2);CHKERR(ierr);
1721:       elapsed_time = v2 - v1;   
1722: .ve

1724:    Notes:
1725:    Since the PETSc libraries incorporate timing of phases and operations, 
1726:    PetscGetTime() is intended only for timing of application codes.  
1727:    The options database commands -log, -log_summary, and -log_all activate
1728:    PETSc library timing.  See the users manual for further details.

1730:    Level: intermediate

1732: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(),  PetscLogStagePush(), 
1733:           PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()

1735: .keywords:  get, time
1736: @*/
1737: PetscErrorCode PetscGetTime(PetscLogDouble *t)
1738: {
1740:   PetscTime(*t);
1741:   return(0);
1742: }

1746: /*@
1747:   PetscLogGetStageLog - This function returns the default stage logging object.

1749:   Not collective

1751:   Output Parameter:
1752: . stageLog - The default StageLog

1754:   Level: beginner

1756: .keywords: log, stage
1757: .seealso: StageLogCreate()
1758: @*/
1759: PetscErrorCode PetscLogGetStageLog(StageLog *stageLog)
1760: {
1763:   *stageLog = _stageLog;
1764:   return(0);
1765: }

1767: /*MC
1768:    PetscLogFlops - Adds floating point operations to the global counter.

1770:    Input Parameter:
1771: .  f - flop counter

1773:    Synopsis:
1774:    void PetscLogFlops(int f)

1776:    Usage:
1777: .vb
1778:      int USER_EVENT;
1779:      PetscLogEventRegister(&USER_EVENT,"User event");
1780:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1781:         [code segment to monitor]
1782:         PetscLogFlops(user_flops)
1783:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1784: .ve

1786:    Notes:
1787:    A global counter logs all PETSc flop counts.  The user can use
1788:    PetscLogFlops() to increment this counter to include flops for the 
1789:    application code.  

1791:    PETSc automatically logs library events if the code has been
1792:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1793:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1794:    intended for logging user flops to supplement this PETSc
1795:    information.

1797:    Level: intermediate

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

1801: .keywords: log, flops, floating point operations
1802: M*/

1804: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1805: PetscTruth PetscPreLoadingOn   = PETSC_FALSE;

1807: /*MC
1808:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1809:     to get accurate timings

1811:    Input Parameter:
1812: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1813:            with command line option -preload true or -preload false
1814: -   name - name of first stage (lines of code timed seperately with -log_summary) to
1815:            be preloaded

1817:    Synopsis:
1818:    void PreLoadBegin(PetscTruth flag,char *name);

1820:    Usage:
1821: .vb
1822:      PreLoadBegin(PETSC_TRUE,"first stage);
1823:        lines of code
1824:        PreLoadStage("second stage");
1825:        lines of code
1826:      PreLoadEnd();
1827: .ve

1829:    Notes: Flags available within the macro. 
1830: +    PetscPreLoadingUsed - true if we are or have done preloading 
1831: .    PetscPreLoadingOn - true if it is CURRENTLY doing preload
1832: .    PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1833: -    PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1834:      The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1835:      and PreLoadEnd()

1837:    Level: intermediate

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

1841:    Concepts: preloading
1842:    Concepts: timing^accurate
1843:    Concepts: paging^eliminating effects of


1846: M*/

1848: /*MC
1849:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1850:     to get accurate timings

1852:    Synopsis:
1853:    void PreLoadEnd(void);

1855:    Usage:
1856: .vb
1857:      PreLoadBegin(PETSC_TRUE,"first stage);
1858:        lines of code
1859:        PreLoadStage("second stage");
1860:        lines of code
1861:      PreLoadEnd();
1862: .ve

1864:    Level: intermediate

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

1868: M*/

1870: /*MC
1871:    PreLoadStage - Start a new segment of code to be timed seperately.
1872:     to get accurate timings

1874:    Synopsis:
1875:    void PreLoadStage(char *name);

1877:    Usage:
1878: .vb
1879:      PreLoadBegin(PETSC_TRUE,"first stage);
1880:        lines of code
1881:        PreLoadStage("second stage");
1882:        lines of code
1883:      PreLoadEnd();
1884: .ve

1886:    Level: intermediate

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

1890: M*/

1892: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1895: /*@C
1896:   StackDestroy - This function destroys a stack.

1898:   Not Collective

1900:   Input Parameter:
1901: . stack - The stack

1903:   Level: beginner

1905: .keywords: log, stack, destroy
1906: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1907: @*/
1908: PetscErrorCode StackDestroy(IntStack stack)
1909: {

1913:   PetscFree(stack->stack);
1914:   PetscFree(stack);
1915:   return(0);
1916: }

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

1923:   Not Collective

1925:   Input Parameter:
1926: . stack - The stack

1928:   Output Parameter:
1929: . empty - PETSC_TRUE if the stack is empty

1931:   Level: intermediate

1933: .keywords: log, stack, empty
1934: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1935: @*/
1936: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
1937: {
1940:   if (stack->top == -1) {
1941:     *empty = PETSC_TRUE;
1942:   } else {
1943:     *empty = PETSC_FALSE;
1944:   }
1945:   return(0);
1946: }

1950: /*@C
1951:   StackTop - This function returns the top of the stack.

1953:   Not Collective

1955:   Input Parameter:
1956: . stack - The stack

1958:   Output Parameter:
1959: . top - The integer on top of the stack

1961:   Level: intermediate

1963: .keywords: log, stack, top
1964: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1965: @*/
1966: PetscErrorCode StackTop(IntStack stack, int *top)
1967: {
1970:   *top = stack->stack[stack->top];
1971:   return(0);
1972: }

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

1979:   Not Collective

1981:   Input Parameters:
1982: + stack - The stack
1983: - item  - The integer to push

1985:   Level: intermediate

1987: .keywords: log, stack, push
1988: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1989: @*/
1990: PetscErrorCode StackPush(IntStack stack, int item)
1991: {
1992:   int            *array;

1996:   stack->top++;
1997:   if (stack->top >= stack->max) {
1998:     PetscMalloc(stack->max*2 * sizeof(int), &array);
1999:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2000:     PetscFree(stack->stack);
2001:     stack->stack = array;
2002:     stack->max  *= 2;
2003:   }
2004:   stack->stack[stack->top] = item;
2005:   return(0);
2006: }

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

2013:   Not Collective

2015:   Input Parameter:
2016: . stack - The stack

2018:   Output Parameter:
2019: . item  - The integer popped

2021:   Level: intermediate

2023: .keywords: log, stack, pop
2024: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2025: @*/
2026: PetscErrorCode StackPop(IntStack stack, int *item)
2027: {
2030:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2031:   *item = stack->stack[stack->top--];
2032:   return(0);
2033: }

2037: /*@C
2038:   StackCreate - This function creates a stack.

2040:   Not Collective

2042:   Output Parameter:
2043: . stack - The stack

2045:   Level: beginner

2047: .keywords: log, stack, pop
2048: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2049: @*/
2050: PetscErrorCode StackCreate(IntStack *stack)
2051: {
2052:   IntStack       s;

2057:   PetscNew(struct _IntStack, &s);
2058:   s->top = -1;
2059:   s->max = 128;
2060:   PetscMalloc(s->max * sizeof(int), &s->stack);
2061:   PetscMemzero(s->stack, s->max * sizeof(int));
2062:   *stack = s;
2063:   return(0);
2064: }