Actual source code: plog.c

  1: /*$Id: plog.c,v 1.262 2001/08/22 17:59:37 balay Exp $*/
  2: /*
  3:       PETSc code to log object creation and destruction and PETSc events.
  4: */
 5:  #include petsc.h
  6: #include "petscmachineinfo.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) && !defined(__cplusplus)
 17: #include <malloc.h>
 18: #endif
 19: #include "petscfix.h"
 20:  #include src/sys/src/plog/ptime.h
 21:  #include plog.h

 23: int PETSC_LARGEST_COOKIE = PETSC_COOKIE;
 24: int PETSC_LARGEST_EVENT  = PETSC_EVENT;

 26: #if defined(PETSC_USE_LOG)

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

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

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

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

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

 70: /*---------------------------------------------- General Functions --------------------------------------------------*/
 71: #undef __FUNCT__  
 73: /*@C
 74:   PetscLogDestroy - Destroys the object and event logging data and resets the global counters. 

 76:   Not Collective

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

 82:   Level: developer

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

 92:   if (actions != PETSC_NULL) {
 93:     PetscFree(actions);
 94:     actions = PETSC_NULL;
 95:   }
 96:   if (objects != PETSC_NULL) {
 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: }

112: #undef __FUNCT__  
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: int PetscLogSet(int (*b)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
128:             int (*e)(int, int, PetscObject, PetscObject, PetscObject, PetscObject))
129: {
131:   _PetscLogPLB = b;
132:   _PetscLogPLE = e;
133:   return(0);
134: }

136: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
137: #undef __FUNCT__  
139: int PetscLogBegin_Private(void) {
140:   static int initialized = 0;
141:   int        stage;
142:   PetscTruth opt;
143:   int        ierr;

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

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

181:   Collective over PETSC_COMM_WORLD

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

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

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

201:   Level: advanced

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

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

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

222:   Collective on PETSC_COMM_WORLD

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

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

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

241:   Level: advanced

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

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

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

262:   Collective on PETSC_COMM_WORLD

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

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

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

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

278:   Level: intermediate

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

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

293: #undef __FUNCT__
295: /*@
296:   PetscLogActions - Determines whether actions are logged for the graphical viewer.

298:   Not Collective

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

303:   Level: intermediate

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

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

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

320: #undef __FUNCT__
322: /*@
323:   PetscLogObjects - Determines whether objects are logged for the graphical viewer.

325:   Not Collective

327:   Input Parameter:
328: . flag - PETSC_TRUE if objects are to be logged

330:   Level: intermediate

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

335:   Options Database Keys:
336: . -log_exclude_objects - Turns off objects logging

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

347: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
348: #undef __FUNCT__
350: /*@C
351:   PetscLogStageRegister - Attaches a charactor string name to a logging stage.

353:   Not Collective

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

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

361:   Level: intermediate

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

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

385: #undef __FUNCT__  
387: /*@C
388:   PetscLogStagePush - This function pushes a stage on the stack.

390:   Not Collective

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

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

413:   Level: intermediate

415: .keywords: log, push, stage
416: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
417: @*/
418: int PetscLogStagePush(int stage)
419: {
420:   StageLog stageLog;
421:   int      ierr;

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

429: #undef __FUNCT__  
431: /*@C
432:   PetscLogStagePop - This function pops a stage from the stack.

434:   Not Collective

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

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

454:   Level: intermediate

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

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

470: #undef __FUNCT__  
472: /*@
473:   PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().

475:   Not Collective 

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

481:   Level: intermediate

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

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

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

500:   Not Collective 

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

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

508:   Level: intermediate

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

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

522: #undef __FUNCT__  
524: /*@
525:   PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()

527:   Not Collective 

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

533:   Level: intermediate

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

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

548: #undef __FUNCT__  
550: /*@
551:   PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()

553:   Not Collective 

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

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

561:   Level: intermediate

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

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

576: #undef __FUNCT__  
578: /*@
579:   PetscLogStageGetId - Returns the stage id when given the stage name.

581:   Not Collective 

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

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

589:   Level: intermediate

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

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

604: /*------------------------------------------------ Event Functions --------------------------------------------------*/
605: #undef __FUNCT__  
607: /*@C
608:   PetscLogEventRegister - Registers an event name for logging operations in an application code. 

610:   Not Collective

612:   Input Parameter:
613: + name   - The name associated with the event
614: - cookie - The cookie associated to the class for this event
615:             
616:   Output Parameter:
617: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

619:   Example of Usage:
620: .vb
621:       int USER_EVENT;
622:       int user_event_flops;
623:       PetscLogEventRegister(&USER_EVENT,"User event name");
624:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
625:          [code segment to monitor]
626:          PetscLogFlops(user_event_flops);
627:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
628: .ve

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

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

644:   Level: intermediate

646: .keywords: log, event, register
647: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
648:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
649:           PetscLogEventActivate(), PetscLogEventDeactivate()
650: @*/
651: int PetscLogEventRegister(int *event, const char name[],int cookie) {
652:   StageLog stageLog;
653:   int      stage;
654:   int      ierr;

657:   *event = PETSC_DECIDE;
658:   PetscLogGetStageLog(&stageLog);
659:   EventRegLogRegister(stageLog->eventLog, name, cookie, event);
660:   for(stage = 0; stage < stageLog->numStages; stage++) {
661:     EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
662:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
663:   }
664:   return(0);
665: }

667: #undef __FUNCT__  
669: /*@
670:   PetscLogEventActivate - Indicates that a particular event should be logged.

672:   Not Collective

674:   Input Parameter:
675: . event - The event id

677:   Usage:
678: .vb
679:       PetscLogEventDeactivate(VEC_SetValues);
680:         [code where you do not want to log VecSetValues()]
681:       PetscLogEventActivate(VEC_SetValues);
682:         [code where you do want to log VecSetValues()]
683: .ve 

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

689:   Level: advanced

691: .keywords: log, event, activate
692: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
693: @*/
694: int PetscLogEventActivate(int event) {
695:   StageLog stageLog;
696:   int      stage;
697:   int      ierr;

700:   PetscLogGetStageLog(&stageLog);
701:   StageLogGetCurrent(stageLog, &stage);
702:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
703:   return(0);
704: }

706: #undef __FUNCT__  
708: /*@
709:   PetscLogEventDeactivate - Indicates that a particular event should not be logged. 

711:   Not Collective

713:   Input Parameter:
714: . event - The event id

716:   Usage:
717: .vb
718:       PetscLogEventDeactivate(VEC_SetValues);
719:         [code where you do not want to log VecSetValues()]
720:       PetscLogEventActivate(VEC_SetValues);
721:         [code where you do want to log VecSetValues()]
722: .ve 

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

728:   Level: advanced

730: .keywords: log, event, deactivate
731: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
732: @*/
733: int PetscLogEventDeactivate(int event) {
734:   StageLog stageLog;
735:   int      stage;
736:   int      ierr;

739:   PetscLogGetStageLog(&stageLog);
740:   StageLogGetCurrent(stageLog, &stage);
741:   EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
742:   return(0);
743: }

745: #undef __FUNCT__  
747: /*@
748:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

750:   Not Collective

752:   Input Parameters:
753: + event    - The event id
754: - isActive - The activity flag determining whether the event is logged

756:   Level: advanced

758: .keywords: log, event, activate
759: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
760: @*/
761: int PetscLogEventSetActiveAll(int event, PetscTruth isActive) {
762:   StageLog stageLog;
763:   int      stage;
764:   int      ierr;

767:   PetscLogGetStageLog(&stageLog);
768:   for(stage = 0; stage < stageLog->numStages; stage++) {
769:     if (isActive == PETSC_TRUE) {
770:       EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
771:     } else {
772:       EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
773:     }
774:   }
775:   return(0);
776: }

778: #undef __FUNCT__  
780: /*@
781:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

783:   Not Collective

785:   Input Parameter:
786: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

788:   Level: developer

790: .keywords: log, event, activate, class
791: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
792: @*/
793: int PetscLogEventActivateClass(int cookie) {
794:   StageLog stageLog;
795:   int      stage;
796:   int      ierr;

799:   PetscLogGetStageLog(&stageLog);
800:   StageLogGetCurrent(stageLog, &stage);
801:   EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
802:   return(0);
803: }

805: #undef __FUNCT__  
807: /*@
808:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

810:   Not Collective

812:   Input Parameter:
813: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

815:   Level: developer

817: .keywords: log, event, deactivate, class
818: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
819: @*/
820: int PetscLogEventDeactivateClass(int cookie) {
821:   StageLog stageLog;
822:   int      stage;
823:   int      ierr;

826:   PetscLogGetStageLog(&stageLog);
827:   StageLogGetCurrent(stageLog, &stage);
828:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
829:   return(0);
830: }

832: /*MC
833:    PetscLogEventBegin - Logs the beginning of a user event. 

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

839:    Synopsis:
840:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
841:                        PetscObject o4)

843:    Fortran Synopsis:
844:    void PetscLogEventEnd(int e,int ierr)

846:    Usage:
847: .vb
848:      int USER_EVENT;
849:      int user_event_flops;
850:      PetscLogEventRegister(&USER_EVENT,"User event");
851:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
852:         [code segment to monitor]
853:         PetscLogFlops(user_event_flops);
854:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
855: .ve

857:    Notes:
858:    You need to register each integer event with the command 
859:    PetscLogEventRegister().  The source code must be compiled with 
860:    -DPETSC_USE_LOG, which is the default.

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

867:    Level: intermediate

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

871: .keywords: log, event, begin
872: M*/

874: /*MC
875:    PetscLogEventEnd - Log the end of a user event.

877:    Input Parameters:
878: +  e - integer associated with the event obtained with PetscLogEventRegister()
879: -  o1,o2,o3,o4 - objects associated with the event, or 0

881:    Synopsis:
882:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
883:                      PetscObject o4)

885:    Fortran Synopsis:
886:    void PetscLogEventEnd(int e,int ierr)

888:    Usage:
889: .vb
890:      int USER_EVENT;
891:      int user_event_flops;
892:      PetscLogEventRegister(&USER_EVENT,"User event");
893:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
894:         [code segment to monitor]
895:         PetscLogFlops(user_event_flops);
896:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
897: .ve

899:    Notes:
900:    You should also register each additional integer event with the command 
901:    PetscLogEventRegister(). Source code must be compiled with 
902:    -DPETSC_USE_LOG, which is the default.

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

909:    Level: intermediate

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

913: .keywords: log, event, end
914: M*/

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

919:    Input Parameters:
920: .  e - integer associated with the event obtained from PetscLogEventRegister()
921: .  o1,o2,o3,o4 - objects associated with the event, or 0
922: .  comm - communicator the barrier takes place over

924:    Synopsis:
925:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
926:                   PetscObject o4,MPI_Comm comm)

928:    Usage:
929: .vb
930:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
931:        MPI_Allreduce()
932:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
933: .ve

935:    Notes:
936:    This is for logging the amount of time spent in a barrier for an event
937:    that requires synchronization. 

939:    Additional Notes:
940:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
941:    VEC_NormComm = VEC_NormBarrier + 1

943:    Level: advanced

945: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
946:           PetscLogEventBarrierEnd()

948: .keywords: log, event, begin, barrier
949: M*/

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

954:    Input Parameters:
955: .  e - integer associated with the event obtained from PetscLogEventRegister()
956: .  o1,o2,o3,o4 - objects associated with the event, or 0
957: .  comm - communicator the barrier takes place over

959:    Synopsis:
960:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
961:                   PetscObject o4,MPI_Comm comm)

963:     Usage:
964: .vb
965:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
966:        MPI_Allreduce()
967:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
968: .ve

970:    Notes:
971:    This is for logging the amount of time spent in a barrier for an event
972:    that requires synchronization. 

974:    Additional Notes:
975:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
976:    VEC_NormComm = VEC_NormBarrier + 1

978:    Level: advanced

980: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
981:           PetscLogEventBarrierBegin()

983: .keywords: log, event, begin, barrier
984: M*/

986: /*------------------------------------------------ Class Functions --------------------------------------------------*/
987: #undef __FUNCT__  
989: /*@C
990:   PetscLogClassRegister - Registers a class name for logging operations in an application code. 

992:   Not Collective

994:   Input Parameter:
995: . name   - The class name
996:             
997:   Output Parameter:
998: . oclass - The class id or cookie

1000:   Level: developer

1002: .keywords: log, class, register
1003: .seealso: ClassLogRegister()
1004: @*/
1005: int PetscLogClassRegister(int *oclass, const char name[])
1006: {
1007:   StageLog stageLog;
1008:   int      ierr;

1011:   *oclass = PETSC_DECIDE;
1012:   PetscLogGetStageLog(&stageLog);
1013:   ClassRegLogRegister(stageLog->classLog, name, oclass);
1014:   return(0);
1015: }

1017: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1018: #undef __FUNCT__  
1020: /*@C
1021:   PetscLogDump - Dumps logs of objects to a file. This file is intended to 
1022:   be read by petsc/bin/petscview.

1024:   Collective on PETSC_COMM_WORLD

1026:   Input Parameter:
1027: . name - an optional file name

1029:   Options Database Keys:
1030: + -log     - Prints basic log information (for code compiled with PETSC_USE_LOG)
1031: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1032:    
1033:   Usage:
1034: .vb
1035:      PetscInitialize(...);
1036:      PetscLogBegin(); or PetscLogAllBegin(); 
1037:      ... code ...
1038:      PetscLogDump(filename);
1039:      PetscFinalize();
1040: .ve

1042:   Notes:
1043:   The default file name is 
1044: $    Log.<rank>
1045:   where <rank> is the processor number. If no name is specified, 
1046:   this file will be used.

1048:   Level: advanced

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

1120: #undef __FUNCT__  
1122: /*@C
1123:   PetscLogPrintSummary - Prints a summary of the logging.

1125:   Collective over MPI_Comm

1127:   Input Parameter:
1128: + comm - The MPI communicator (only one processor prints output)
1129: - file - [Optional] The output file name

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

1134:   Usage:
1135: .vb
1136:      PetscInitialize(...);
1137:      PetscLogBegin();
1138:      ... code ...
1139:      PetscLogPrintSummary(MPI_Comm,filename);
1140:      PetscFinalize(...);
1141: .ve

1143:   Notes:
1144:   By default the summary is printed to stdout.
1145:   More extensive examination of the log information can be done with 
1146:   PetscLogDump(), which is activated by the option -log or -log_all, in 
1147:   combination with petsc/bin/petscview.

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

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

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

1215:   /* Must preserve reduction count before we go on */
1216:   red  = allreduce_ct/((PetscLogDouble) numProcs);

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

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

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

1374: #if defined(PETSC_USE_BOPT_g)
1375:   PetscFPrintf(comm, fd, "nn");
1376:   PetscFPrintf(comm, fd, "      ##########################################################n");
1377:   PetscFPrintf(comm, fd, "      #                                                        #n");
1378:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1379:   PetscFPrintf(comm, fd, "      #                                                        #n");
1380:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #n");
1381:   PetscFPrintf(comm, fd, "      #   BOPT=<g,g_c++,g_complex>.   To get timing results    #n");
1382:   PetscFPrintf(comm, fd, "      #   ALWAYS compile your code with an optimized version,  #n");
1383:   PetscFPrintf(comm, fd, "      #   BOPT=<O,O_c++,O_complex>;  the performance will      #n");
1384:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #n");
1385:   PetscFPrintf(comm, fd, "      #                                                        #n");
1386:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1387: #endif
1388: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1389:   PetscFPrintf(comm, fd, "nn");
1390:   PetscFPrintf(comm, fd, "      ##########################################################n");
1391:   PetscFPrintf(comm, fd, "      #                                                        #n");
1392:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1393:   PetscFPrintf(comm, fd, "      #                                                        #n");
1394:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #n");
1395:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #n");
1396:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #n");
1397:   PetscFPrintf(comm, fd, "      #   faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #n");
1398:   PetscFPrintf(comm, fd, "      #   in base_variables and recompile the PETSc libraries. #n");
1399:   PetscFPrintf(comm, fd, "      #                                                        #n");
1400:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1401: #endif

1403:   if (!PetscPreLoadingUsed) {
1404:     PetscFPrintf(comm,fd,"nn");
1405:     PetscFPrintf(comm,fd,"      ##########################################################n");
1406:     PetscFPrintf(comm,fd,"      #                                                        #n");
1407:     PetscFPrintf(comm,fd,"      #                          WARNING!!!                    #n");
1408:     PetscFPrintf(comm,fd,"      #                                                        #n");
1409:     PetscFPrintf(comm,fd,"      #   This code was run without the PreLoadBegin()         #n");
1410:     PetscFPrintf(comm,fd,"      #   macros. To get timing results we always recommend    #n");
1411:     PetscFPrintf(comm,fd,"      #   preloading. otherwise timing numbers may be          #n");
1412:     PetscFPrintf(comm,fd,"      #   meaningless.                                         #n");
1413:     PetscFPrintf(comm,fd,"      ##########################################################nnn");
1414:   }

1416:   /* Report events */
1417:   PetscFPrintf(comm, fd,
1418:     "Event                Count      Time (sec)     Flops/sec                         --- Global ---  --- Stage ---   Totaln");
1419: 
1420:   PetscFPrintf(comm, fd,
1421:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/sn");
1422: 
1423:   PetscFPrintf(comm,fd,
1424:     "------------------------------------------------------------------------------------------------------------------------n");

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

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

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

1525:   /* Memory usage and object creation */
1526:   PetscFPrintf(comm, fd,
1527:     "------------------------------------------------------------------------------------------------------------------------n");
1528: 
1529:   PetscFPrintf(comm, fd, "n");
1530:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:nn");

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

1555:   PetscFree(localStageUsed);
1556:   PetscFree(stageUsed);
1557:   PetscFree(localStageVisible);
1558:   PetscFree(stageVisible);

1560:   /* Information unrelated to this particular run */
1561:   PetscFPrintf(comm, fd,
1562:     "========================================================================================================================n");
1563: 
1564:   PetscTime(y);
1565:   PetscTime(x);
1566:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1567:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1568:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %gn", (y-x)/10.0);
1569:   /* MPI information */
1570:   if (numProcs > 1) {
1571:     MPI_Status status;
1572:     int        tag;

1574:     MPI_Barrier(comm);
1575:     PetscTime(x);
1576:     MPI_Barrier(comm);
1577:     MPI_Barrier(comm);
1578:     MPI_Barrier(comm);
1579:     MPI_Barrier(comm);
1580:     MPI_Barrier(comm);
1581:     PetscTime(y);
1582:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %gn", (y-x)/5.0);
1583:     PetscCommGetNewTag(comm, &tag);
1584:     MPI_Barrier(comm);
1585:     if (rank) {
1586:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, comm, &status);
1587:       MPI_Send(0, 0, MPI_INT, (rank+1)%numProcs, tag, comm);
1588:     } else {
1589:       PetscTime(x);
1590:       MPI_Send(0, 0, MPI_INT, 1,          tag, comm);
1591:       MPI_Recv(0, 0, MPI_INT, numProcs-1, tag, comm, &status);
1592:       PetscTime(y);
1593:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %gn", (y-x)/numProcs);
1594:     }
1595:   }
1596:   /* Machine and compile information */
1597: #if defined(PETSC_USE_FORTRAN_KERNELS)
1598:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernelsn");
1599: #else
1600:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1601: #endif
1602: #if defined(PETSC_USE_MAT_SINGLE)
1603:   PetscFPrintf(comm, fd, "Compiled with single precision matricesn");
1604: #else
1605:   PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)n");
1606: #endif
1607:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void *) %d",
1608:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1609: 

1611:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1612:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1613:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1614:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1616:   /* Cleanup */
1617:   PetscFPrintf(comm, fd, "n");
1618:   PetscFClose(comm, fd);
1619:   return(0);
1620: }

1622: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1623: #undef __FUNCT__  
1625: /*@C
1626:    PetscGetFlops - Returns the number of flops used on this processor 
1627:    since the program began. 

1629:    Not Collective

1631:    Output Parameter:
1632:    flops - number of floating point operations 

1634:    Notes:
1635:    A global counter logs all PETSc flop counts.  The user can use
1636:    PetscLogFlops() to increment this counter to include flops for the 
1637:    application code.  

1639:    PETSc automatically logs library events if the code has been
1640:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1641:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1642:    intended for logging user flops to supplement this PETSc
1643:    information.

1645:    Level: intermediate

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

1649: .seealso: PetscGetTime(), PetscLogFlops()
1650: @*/
1651: int PetscGetFlops(PetscLogDouble *flops)
1652: {
1654:   *flops = _TotalFlops;
1655:   return(0);
1656: }

1658: #undef __FUNCT__  
1660: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1661: {
1662:   va_list Argp;

1665:   if (logObjects == PETSC_FALSE) return(0);
1666:   va_start(Argp, format);
1667: #if defined(PETSC_HAVE_VPRINTF_CHAR)
1668:   vsprintf(objects[obj->id].info, format, (char *) Argp);
1669: #else
1670:   vsprintf(objects[obj->id].info, format, Argp);
1671: #endif
1672:   va_end(Argp);
1673:   return(0);
1674: }

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

1678: #undef __FUNCT__  
1680: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1681: {
1683:   return(0);
1684: }

1686: #endif /* PETSC_USE_LOG*/

1688: #undef __FUNCT__  
1690: /*@
1691:    PetscGetTime - Returns the current time of day in seconds. This 
1692:    returns wall-clock time.  

1694:    Not Collective

1696:    Output Parameter:
1697: .  v - time counter

1699:    Usage: 
1700: .vb
1701:       PetscLogDouble v1,v2,elapsed_time;
1702:       PetscGetTime(&v1);CHKERR(ierr);
1703:       .... perform some calculation ...
1704:       PetscGetTime(&v2);CHKERR(ierr);
1705:       elapsed_time = v2 - v1;   
1706: .ve

1708:    Notes:
1709:    Since the PETSc libraries incorporate timing of phases and operations, 
1710:    PetscGetTime() is intended only for timing of application codes.  
1711:    The options database commands -log, -log_summary, and -log_all activate
1712:    PETSc library timing.  See the users manual for further details.

1714:    Level: intermediate

1716: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(),  PetscLogStagePush(), 
1717:           PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()

1719: .keywords:  get, time
1720: @*/
1721: int PetscGetTime(PetscLogDouble *t)
1722: {
1724:   PetscTime(*t);
1725:   return(0);
1726: }

1728: #undef __FUNCT__  
1730: /*@
1731:   PetscLogGetStageLog - This function returns the default stage logging object.

1733:   Not collective

1735:   Output Parameter:
1736: . stageLog - The default StageLog

1738:   Level: beginner

1740: .keywords: log, stage
1741: .seealso: StageLogCreate()
1742: @*/
1743: int PetscLogGetStageLog(StageLog *stageLog)
1744: {
1747:   *stageLog = _stageLog;
1748:   return(0);
1749: }

1751: /*MC
1752:    PetscLogFlops - Adds floating point operations to the global counter.

1754:    Input Parameter:
1755: .  f - flop counter

1757:    Synopsis:
1758:    void PetscLogFlops(int f)

1760:    Usage:
1761: .vb
1762:      int USER_EVENT;
1763:      PetscLogEventRegister(&USER_EVENT,"User event");
1764:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1765:         [code segment to monitor]
1766:         PetscLogFlops(user_flops)
1767:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1768: .ve

1770:    Notes:
1771:    A global counter logs all PETSc flop counts.  The user can use
1772:    PetscLogFlops() to increment this counter to include flops for the 
1773:    application code.  

1775:    PETSc automatically logs library events if the code has been
1776:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1777:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1778:    intended for logging user flops to supplement this PETSc
1779:    information.

1781:    Level: intermediate

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

1785: .keywords: log, flops, floating point operations
1786: M*/

1788: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1789: PetscTruth PetscPreLoadingOn   = PETSC_FALSE;

1791: /*MC
1792:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1793:     to get accurate timings

1795:    Input Parameter:
1796: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1797:            with command line option -preload true or -preload false
1798: -   name - name of first stage (lines of code timed seperately with -log_summary) to
1799:            be preloaded

1801:    Synopsis:
1802:    void PreLoadBegin(PetscTruth flag,char *name);

1804:    Usage:
1805: .vb
1806:      PreLoadBegin(PETSC_TRUE,"first stage);
1807:        lines of code
1808:        PreLoadStage("second stage");
1809:        lines of code
1810:      PreLoadEnd();
1811: .ve

1813:    Level: intermediate

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

1817:    Concepts: preloading
1818:    Concepts: timing^accurate
1819:    Concepts: paging^eliminating effects of


1822: M*/

1824: /*MC
1825:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1826:     to get accurate timings

1828:    Synopsis:
1829:    void PreLoadEnd(void);

1831:    Usage:
1832: .vb
1833:      PreLoadBegin(PETSC_TRUE,"first stage);
1834:        lines of code
1835:        PreLoadStage("second stage");
1836:        lines of code
1837:      PreLoadEnd();
1838: .ve

1840:    Level: intermediate

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

1844: M*/

1846: /*MC
1847:    PreLoadStage - Start a new segment of code to be timed seperately.
1848:     to get accurate timings

1850:    Synopsis:
1851:    void PreLoadStage(char *name);

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

1862:    Level: intermediate

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

1866: M*/

1868: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1869: #undef __FUNCT__  
1871: /*@C
1872:   StackDestroy - This function destroys a stack.

1874:   Not Collective

1876:   Input Parameter:
1877: . stack - The stack

1879:   Level: beginner

1881: .keywords: log, stack, destroy
1882: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1883: @*/
1884: int StackDestroy(IntStack stack)
1885: {

1889:   PetscFree(stack->stack);
1890:   PetscFree(stack);
1891:   return(0);
1892: }

1894: #undef __FUNCT__  
1896: /*@C
1897:   StackEmpty - This function determines whether any items have been pushed.

1899:   Not Collective

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

1904:   Output Parameter:
1905: . empty - PETSC_TRUE if the stack is empty

1907:   Level: intermediate

1909: .keywords: log, stack, empty
1910: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1911: @*/
1912: int StackEmpty(IntStack stack, PetscTruth *empty)
1913: {
1916:   if (stack->top == -1) {
1917:     *empty = PETSC_TRUE;
1918:   } else {
1919:     *empty = PETSC_FALSE;
1920:   }
1921:   return(0);
1922: }

1924: #undef __FUNCT__  
1926: /*@C
1927:   StackTop - This function returns the top of the stack.

1929:   Not Collective

1931:   Input Parameter:
1932: . stack - The stack

1934:   Output Parameter:
1935: . top - The integer on top of the stack

1937:   Level: intermediate

1939: .keywords: log, stack, top
1940: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1941: @*/
1942: int StackTop(IntStack stack, int *top)
1943: {
1946:   *top = stack->stack[stack->top];
1947:   return(0);
1948: }

1950: #undef __FUNCT__  
1952: /*@C
1953:   StackPush - This function pushes an integer on the stack.

1955:   Not Collective

1957:   Input Parameters:
1958: + stack - The stack
1959: - item  - The integer to push

1961:   Level: intermediate

1963: .keywords: log, stack, push
1964: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1965: @*/
1966: int StackPush(IntStack stack, int item)
1967: {
1968:   int *array;
1969:   int  ierr;

1972:   stack->top++;
1973:   if (stack->top >= stack->max) {
1974:     PetscMalloc(stack->max*2 * sizeof(int), &array);
1975:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1976:     PetscFree(stack->stack);
1977:     stack->stack = array;
1978:     stack->max  *= 2;
1979:   }
1980:   stack->stack[stack->top] = item;
1981:   return(0);
1982: }

1984: #undef __FUNCT__  
1986: /*@C
1987:   StackPop - This function pops an integer from the stack.

1989:   Not Collective

1991:   Input Parameter:
1992: . stack - The stack

1994:   Output Parameter:
1995: . item  - The integer popped

1997:   Level: intermediate

1999: .keywords: log, stack, pop
2000: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2001: @*/
2002: int StackPop(IntStack stack, int *item)
2003: {
2006:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2007:   *item = stack->stack[stack->top--];
2008:   return(0);
2009: }

2011: #undef __FUNCT__  
2013: /*@C
2014:   StackCreate - This function creates a stack.

2016:   Not Collective

2018:   Output Parameter:
2019: . stack - The stack

2021:   Level: beginner

2023: .keywords: log, stack, pop
2024: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2025: @*/
2026: int StackCreate(IntStack *stack)
2027: {
2028:   IntStack s;
2029:   int      ierr;

2033:   PetscNew(struct _IntStack, &s);
2034:   s->top = -1;
2035:   s->max = 128;
2036:   PetscMalloc(s->max * sizeof(int), &s->stack);
2037:   PetscMemzero(s->stack, s->max * sizeof(int));
2038:   *stack = s;
2039:   return(0);
2040: }