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_TRUE;
 35: PetscTruth logObjects = PETSC_TRUE;
 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: /*@C
 72:   PetscLogDestroy - Destroys the object and event logging data and resets the global counters. 

 74:   Not Collective

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

 80:   Level: developer

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

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

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

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

113:   Not Collective

115:   Input Parameters:
116: + b - The function called at beginning of event
117: - e - The function called at end of event

119:   Level: developer

121: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
122: @*/
123: int PetscLogSet(int (*b)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
124:             int (*e)(int, int, PetscObject, PetscObject, PetscObject, PetscObject))
125: {
127:   _PetscLogPLB = b;
128:   _PetscLogPLE = e;
129:   return(0);
130: }

132: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
133: int PetscLogBegin_Private(void) {
134:   static int initialized = 0;
135:   int        stage;
136:   PetscTruth opt;
137:   int        ierr;

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

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

171:   Collective over PETSC_COMM_WORLD

173:   Options Database Keys:
174: + -log_summary - Prints summary of flop and timing information to the 
175:                   screen (for code compiled with PETSC_USE_LOG)
176: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)

178:   Usage:
179: .vb
180:       PetscInitialize(...);
181:       PetscLogBegin();
182:        ... code ...
183:       PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump(); 
184:       PetscFinalize();
185: .ve

187:   Notes:
188:   PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of 
189:   the logging information.

191:   Level: advanced

193: .keywords: log, begin
194: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
195: @*/
196: int PetscLogBegin(void)
197: {

201:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
202:   PetscLogBegin_Private();
203:   return(0);
204: }

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

210:   Collective on PETSC_COMM_WORLD

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

215:   Usage:
216: .vb
217:      PetscInitialize(...);
218:      PetscLogAllBegin();
219:      ... code ...
220:      PetscLogDump(filename);
221:      PetscFinalize();
222: .ve

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

229:   Level: advanced

231: .keywords: log, all, begin
232: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
233: @*/
234: int PetscLogAllBegin(void)
235: {

239:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
240:   PetscLogBegin_Private();
241:   return(0);
242: }

244: /*@
245:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
246:   begins or ends, the event name is printed.

248:   Collective on PETSC_COMM_WORLD

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

253:   Options Database Key:
254: . -log_trace [filename] - Activates PetscLogTraceBegin()

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

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

264:   Level: intermediate

266: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
267: @*/
268: int PetscLogTraceBegin(FILE *file)
269: {

273:   tracefile = file;
274:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
275:   PetscLogBegin_Private();
276:   return(0);
277: }

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

282:   Not Collective

284:   Input Parameter:
285: . flag - PETSC_TRUE if actions are to be logged

287:   Level: intermediate

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

292:   Options Database Keys:
293: . -log_exclude_actions - Turns off actions logging

295: .keywords: log, stage, register
296: .seealso: PetscLogStagePush(), PetscLogStagePop()
297: @*/
298: int PetscLogActions(PetscTruth flag) {
300:   logActions = flag;
301:   return(0);
302: }

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

307:   Not Collective

309:   Input Parameter:
310: . flag - PETSC_TRUE if objects are to be logged

312:   Level: intermediate

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

317:   Options Database Keys:
318: . -log_exclude_objects - Turns off objects logging

320: .keywords: log, stage, register
321: .seealso: PetscLogStagePush(), PetscLogStagePop()
322: @*/
323: int PetscLogObjects(PetscTruth flag) {
325:   logObjects = flag;
326:   return(0);
327: }

329: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
330: /*@C
331:   PetscLogStageRegister - Attaches a charactor string name to a logging stage.

333:   Not Collective

335:   Input Parameter:
336: . sname - The name to associate with that stage

338:   Output Parameter:
339: . stage - The stage number

341:   Level: intermediate

343: .keywords: log, stage, register
344: .seealso: PetscLogStagePush(), PetscLogStagePop()
345: @*/
346: int PetscLogStageRegister(int *stage, const char sname[]) {
347:   StageLog stageLog;
348:   int      event;
349:   int      ierr;

352:   PetscLogGetStageLog(&stageLog);
353:   StageLogRegister(stageLog, sname, stage);
354:   /* Copy events already changed in the main stage, this sucks */
355:   EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
356:   for(event = 0; event < stageLog->eventLog->numEvents; event++) {
357:     EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
358:                              &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
359: 
360:   }
361:   ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
362:   return(0);
363: }

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

368:   Not Collective

370:   Input Parameter:
371: . stage - The stage on which to log

373:   Usage:
374:   If the option -log_sumary is used to run the program containing the 
375:   following code, then 2 sets of summary data will be printed during
376:   PetscFinalize().
377: .vb
378:       PetscInitialize(int *argc,char ***args,0,0);
379:       [stage 0 of code]   
380:       PetscLogStagePush(1);
381:       [stage 1 of code]
382:       PetscLogStagePop();
383:       PetscBarrier(...);
384:       [more stage 0 of code]   
385:       PetscFinalize();
386: .ve
387:  
388:   Notes:
389:   Use PetscLogStageRegister() to register a stage.

391:   Level: intermediate

393: .keywords: log, push, stage
394: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
395: @*/
396: int PetscLogStagePush(int stage)
397: {
398:   StageLog stageLog;
399:   int      ierr;

402:   PetscLogGetStageLog(&stageLog);
403:   StageLogPush(stageLog, stage);
404:   return(0);
405: }

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

410:   Not Collective

412:   Usage:
413:   If the option -log_sumary is used to run the program containing the 
414:   following code, then 2 sets of summary data will be printed during
415:   PetscFinalize().
416: .vb
417:       PetscInitialize(int *argc,char ***args,0,0);
418:       [stage 0 of code]   
419:       PetscLogStagePush(1);
420:       [stage 1 of code]
421:       PetscLogStagePop();
422:       PetscBarrier(...);
423:       [more stage 0 of code]   
424:       PetscFinalize();
425: .ve

427:   Notes:  
428:   Use PetscLogStageRegister() to register a stage.

430:   Level: intermediate

432: .keywords: log, pop, stage
433: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
434: @*/
435: int PetscLogStagePop(void)
436: {
437:   StageLog stageLog;
438:   int      ierr;

441:   PetscLogGetStageLog(&stageLog);
442:   StageLogPop(stageLog);
443:   return(0);
444: }

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

449:   Not Collective 

451:   Input Parameters:
452: + stage    - The stage
453: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

455:   Level: intermediate

457: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
458: @*/
459: int PetscLogStageSetActive(int stage, PetscTruth isActive) {
460:   StageLog stageLog;
461:   int      ierr;

464:   PetscLogGetStageLog(&stageLog);
465:   StageLogSetActive(stageLog, stage, isActive);
466:   return(0);
467: }

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

472:   Not Collective 

474:   Input Parameter:
475: . stage    - The stage

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

480:   Level: intermediate

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

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

494: /*@
495:   PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()

497:   Not Collective 

499:   Input Parameters:
500: + stage     - The stage
501: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

503:   Level: intermediate

505: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
506: @*/
507: int PetscLogStageSetVisible(int stage, PetscTruth isVisible)
508: {
509:   StageLog stageLog;
510:   int      ierr;

513:   PetscLogGetStageLog(&stageLog);
514:   StageLogSetVisible(stageLog, stage, isVisible);
515:   return(0);
516: }

518: /*@
519:   PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()

521:   Not Collective 

523:   Input Parameter:
524: . stage     - The stage

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

529:   Level: intermediate

531: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
532: @*/
533: int PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
534: {
535:   StageLog stageLog;
536:   int      ierr;

539:   PetscLogGetStageLog(&stageLog);
540:   StageLogGetVisible(stageLog, stage, isVisible);
541:   return(0);
542: }

544: /*@
545:   PetscLogStageGetId - Returns the stage id when given the stage name.

547:   Not Collective 

549:   Input Parameter:
550: . name  - The stage name

552:   Output Parameter:
553: . stage - The stage

555:   Level: intermediate

557: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
558: @*/
559: int PetscLogStageGetId(const char name[], int *stage)
560: {
561:   StageLog stageLog;
562:   int      ierr;

565:   PetscLogGetStageLog(&stageLog);
566:   StageLogGetStage(stageLog, name, stage);
567:   return(0);
568: }

570: /*------------------------------------------------ Event Functions --------------------------------------------------*/
571: /*@C
572:   PetscLogEventRegister - Registers an event name for logging operations in an application code. 

574:   Not Collective

576:   Input Parameter:
577: + name   - The name associated with the event
578: - cookie - The cookie associated to the class for this event
579:             
580:   Output Parameter:
581: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

583:   Example of Usage:
584: .vb
585:       int USER_EVENT;
586:       int user_event_flops;
587:       PetscLogEventRegister(&USER_EVENT,"User event name");
588:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
589:          [code segment to monitor]
590:          PetscLogFlops(user_event_flops);
591:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
592: .ve

594:   Notes: 
595:   PETSc automatically logs library events if the code has been
596:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
597:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
598:   intended for logging user events to supplement this PETSc
599:   information. 

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

608:   Level: intermediate

610: .keywords: log, event, register
611: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
612:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
613:           PetscLogEventActivate(), PetscLogEventDeactivate()
614: @*/
615: int PetscLogEventRegister(int *event, const char name[],int cookie) {
616:   StageLog stageLog;
617:   int      stage;
618:   int      ierr;

621:   *event = PETSC_DECIDE;
622:   PetscLogGetStageLog(&stageLog);
623:   EventRegLogRegister(stageLog->eventLog, name, cookie, event);
624:   for(stage = 0; stage < stageLog->numStages; stage++) {
625:     EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
626:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
627:   }
628:   return(0);
629: }

631: /*@
632:   PetscLogEventActivate - Indicates that a particular event should be logged.

634:   Not Collective

636:   Input Parameter:
637: . event - The event id

639:   Usage:
640: .vb
641:       PetscLogEventDeactivate(VEC_SetValues);
642:         [code where you do not want to log VecSetValues()]
643:       PetscLogEventActivate(VEC_SetValues);
644:         [code where you do want to log VecSetValues()]
645: .ve 

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

651:   Level: advanced

653: .keywords: log, event, activate
654: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
655: @*/
656: int PetscLogEventActivate(int event) {
657:   StageLog stageLog;
658:   int      stage;
659:   int      ierr;

662:   PetscLogGetStageLog(&stageLog);
663:   StageLogGetCurrent(stageLog, &stage);
664:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
665:   return(0);
666: }

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

671:   Not Collective

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

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

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

688:   Level: advanced

690: .keywords: log, event, deactivate
691: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
692: @*/
693: int PetscLogEventDeactivate(int event) {
694:   StageLog stageLog;
695:   int      stage;
696:   int      ierr;

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

705: /*@
706:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

708:   Not Collective

710:   Input Parameters:
711: + event    - The event id
712: - isActive - The activity flag determining whether the event is logged

714:   Level: advanced

716: .keywords: log, event, activate
717: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
718: @*/
719: int PetscLogEventSetActiveAll(int event, PetscTruth isActive) {
720:   StageLog stageLog;
721:   int      stage;
722:   int      ierr;

725:   PetscLogGetStageLog(&stageLog);
726:   for(stage = 0; stage < stageLog->numStages; stage++) {
727:     if (isActive == PETSC_TRUE) {
728:       EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
729:     } else {
730:       EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
731:     }
732:   }
733:   return(0);
734: }

736: /*@
737:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

739:   Not Collective

741:   Input Parameter:
742: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

744:   Level: developer

746: .keywords: log, event, activate, class
747: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
748: @*/
749: int PetscLogEventActivateClass(int cookie) {
750:   StageLog stageLog;
751:   int      stage;
752:   int      ierr;

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

761: /*@
762:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

764:   Not Collective

766:   Input Parameter:
767: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

769:   Level: developer

771: .keywords: log, event, deactivate, class
772: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
773: @*/
774: int PetscLogEventDeactivateClass(int cookie) {
775:   StageLog stageLog;
776:   int      stage;
777:   int      ierr;

780:   PetscLogGetStageLog(&stageLog);
781:   StageLogGetCurrent(stageLog, &stage);
782:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
783:   return(0);
784: }

786: /*MC
787:    PetscLogEventBegin - Logs the beginning of a user event. 

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

793:    Synopsis:
794:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
795:                        PetscObject o4)

797:    Usage:
798: .vb
799:      int USER_EVENT;
800:      int user_event_flops;
801:      PetscLogEventRegister(&USER_EVENT,"User event");
802:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
803:         [code segment to monitor]
804:         PetscLogFlops(user_event_flops);
805:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
806: .ve

808:    Notes:
809:    You should also register each integer event with the command 
810:    PetscLogEventRegister().  The source code must be compiled with 
811:    -DPETSC_USE_LOG, which is the default.

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

818:    Level: intermediate

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

822: .keywords: log, event, begin
823: M*/

825: /*MC
826:    PetscLogEventEnd - Log the end of a user event.

828:    Input Parameters:
829: +  e - integer associated with the event obtained with PetscLogEventRegister()
830: -  o1,o2,o3,o4 - objects associated with the event, or 0

832:    Synopsis:
833:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
834:                      PetscObject o4)

836:    Usage:
837: .vb
838:      int USER_EVENT;
839:      int user_event_flops;
840:      PetscLogEventRegister(&USER_EVENT,"User event");
841:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
842:         [code segment to monitor]
843:         PetscLogFlops(user_event_flops);
844:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
845: .ve

847:    Notes:
848:    You should also register each additional integer event with the command 
849:    PetscLogEventRegister(). Source code must be compiled with 
850:    -DPETSC_USE_LOG, which is the default.

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

857:    Level: intermediate

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

861: .keywords: log, event, end
862: M*/

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

867:    Input Parameters:
868: .  e - integer associated with the event obtained from PetscLogEventRegister()
869: .  o1,o2,o3,o4 - objects associated with the event, or 0
870: .  comm - communicator the barrier takes place over

872:    Synopsis:
873:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
874:                   PetscObject o4,MPI_Comm comm)

876:    Usage:
877: .vb
878:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
879:        MPI_Allreduce()
880:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
881: .ve

883:    Notes:
884:    This is for logging the amount of time spent in a barrier for an event
885:    that requires synchronization. 

887:    Additional Notes:
888:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
889:    VEC_NormComm = VEC_NormBarrier + 1

891:    Level: advanced

893: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
894:           PetscLogEventBarrierEnd()

896: .keywords: log, event, begin, barrier
897: M*/

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

902:    Input Parameters:
903: .  e - integer associated with the event obtained from PetscLogEventRegister()
904: .  o1,o2,o3,o4 - objects associated with the event, or 0
905: .  comm - communicator the barrier takes place over

907:    Synopsis:
908:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
909:                   PetscObject o4,MPI_Comm comm)

911:     Usage:
912: .vb
913:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
914:        MPI_Allreduce()
915:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
916: .ve

918:    Notes:
919:    This is for logging the amount of time spent in a barrier for an event
920:    that requires synchronization. 

922:    Additional Notes:
923:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
924:    VEC_NormComm = VEC_NormBarrier + 1

926:    Level: advanced

928: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
929:           PetscLogEventBarrierBegin()

931: .keywords: log, event, begin, barrier
932: M*/

934: /*------------------------------------------------ Class Functions --------------------------------------------------*/
935: /*@C
936:   PetscLogClassRegister - Registers a class name for logging operations in an application code. 

938:   Not Collective

940:   Input Parameter:
941: . name   - The class name
942:             
943:   Output Parameter:
944: . oclass - The class id or cookie

946:   Level: developer

948: .keywords: log, class, register
949: .seealso: ClassLogRegister()
950: @*/
951: int PetscLogClassRegister(int *oclass, const char name[])
952: {
953:   StageLog stageLog;
954:   int      ierr;

957:   *oclass = PETSC_DECIDE;
958:   PetscLogGetStageLog(&stageLog);
959:   ClassRegLogRegister(stageLog->classLog, name, oclass);
960:   return(0);
961: }

963: /*------------------------------------------------ Output Functions -------------------------------------------------*/
964: /*@C
965:   PetscLogDump - Dumps logs of objects to a file. This file is intended to 
966:   be read by petsc/bin/petscview.

968:   Collective on PETSC_COMM_WORLD

970:   Input Parameter:
971: . name - an optional file name

973:   Options Database Keys:
974: + -log     - Prints basic log information (for code compiled with PETSC_USE_LOG)
975: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
976:    
977:   Usage:
978: .vb
979:      PetscInitialize(...);
980:      PetscLogBegin(); or PetscLogAllBegin(); 
981:      ... code ...
982:      PetscLogDump(filename);
983:      PetscFinalize();
984: .ve

986:   Notes:
987:   The default file name is 
988: $    Log.<rank>
989:   where <rank> is the processor number. If no name is specified, 
990:   this file will be used.

992:   Level: advanced

994: .keywords: log, dump
995: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
996: @*/
997: int PetscLogDump(const char sname[]) {
998:   StageLog       stageLog;
999:   EventPerfInfo *eventInfo;
1000:   FILE          *fd;
1001:   char           file[64], fname[64];
1002:   PetscLogDouble flops, _TotalTime;
1003:   int            rank, curStage;
1004:   int            action, object, event;
1005:   int            ierr;
1006: 
1008:   /* Calculate the total elapsed time */
1009:   PetscTime(_TotalTime);
1010:   _TotalTime -= BaseTime;
1011:   /* Open log file */
1012:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1013:   if (sname != PETSC_NULL) {
1014:     sprintf(file, "%s.%d", sname, rank);
1015:   } else {
1016:     sprintf(file, "Log.%d", rank);
1017:   }
1018:   PetscFixFilename(file, fname);
1019:   PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1020:   if ((rank == 0) && (fd == PETSC_NULL)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1021:   /* Output totals */
1022:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8en", _TotalFlops, _TotalTime);
1023:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %gn", 0.0);
1024:   /* Output actions */
1025:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %dn", numActions);
1026:   for(action = 0; action < numActions; action++) {
1027:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %gn",
1028:                         actions[action].time, actions[action].action, actions[action].event, actions[action].cookie, actions[action].id1,
1029:                         actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1030:   }
1031:   /* Output objects */
1032:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %dn", numObjects, numObjectsDestroyed);
1033:   for(object = 0; object < numObjects; object++) {
1034:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %dn", objects[object].parent, (int) objects[object].mem);
1035:     if (!objects[object].name[0]) {
1036:       PetscFPrintf(PETSC_COMM_WORLD, fd,"No Namen");
1037:     } else {
1038:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %sn", objects[object].name);
1039:     }
1040:     if (objects[object].info[0] != 0) {
1041:       PetscFPrintf(PETSC_COMM_WORLD, fd, "No Infon");
1042:     } else {
1043:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %sn", objects[object].info);
1044:     }
1045:   }
1046:   /* Output events */
1047:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:n");
1048:   PetscLogGetStageLog(&stageLog);
1049:   StackTop(stageLog->stack, &curStage);
1050:   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1051:   for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1052:     if (eventInfo[event].time != 0.0) {
1053:       flops = eventInfo[event].flops/eventInfo[event].time;
1054:     } else {
1055:       flops = 0.0;
1056:     }
1057:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16gn", event, eventInfo[event].count,
1058:                         eventInfo[event].flops, eventInfo[event].time, flops);
1059:   }
1060:   PetscFClose(PETSC_COMM_WORLD, fd);
1061:   return(0);
1062: }

1064: /*@C
1065:   PetscLogPrintSummary - Prints a summary of the logging.

1067:   Collective over MPI_Comm

1069:   Input Parameter:
1070: + comm - The MPI communicator (only one processor prints output)
1071: - file - [Optional] The output file name

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

1076:   Usage:
1077: .vb
1078:      PetscInitialize(...);
1079:      PetscLogBegin();
1080:      ... code ...
1081:      PetscLogPrintSummary(MPI_Comm,filename);
1082:      PetscFinalize(...);
1083: .ve

1085:   Notes:
1086:   By default the summary is printed to stdout.
1087:   More extensive examination of the log information can be done with 
1088:   PetscLogDump(), which is activated by the option -log or -log_all, in 
1089:   combination with petsc/bin/petscview.

1091:   Level: beginner
1092:    
1093: .keywords: log, dump, print
1094: .seealso: PetscLogBegin(), PetscLogDump()
1095: @*/
1096: int PetscLogPrintSummary(MPI_Comm comm, const char filename[]) {
1097:   FILE          *fd   = stdout;
1098:   PetscScalar    zero = 0.0;
1099:   StageLog       stageLog;
1100:   StageInfo     *stageInfo = PETSC_NULL;
1101:   EventPerfInfo *eventInfo = PETSC_NULL;
1102:   ClassPerfInfo *classInfo;
1103:   char           arch[10], hostname[64], username[16], pname[256], date[64];
1104:   char           *name;
1105:   PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1106:   PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1107:   PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1108:   PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1109:   PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1110:   PetscLogDouble min, max, tot, ratio, avg, x, y;
1111:   PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1112:   int            minCt, maxCt;
1113:   int            numProcs, rank;
1114:   PetscTruth    *localStageUsed,    *stageUsed;
1115:   PetscTruth    *localStageVisible, *stageVisible;
1116:   int            numStages, localNumEvents, numEvents;
1117:   int            stage, event, oclass;
1118:   int            ierr;
1119:   char           version[256];

1122:   MPI_Comm_size(comm, &numProcs);
1123:   MPI_Comm_rank(comm, &rank);
1124:   /* Pop off any stages the user forgot to remove */
1125:   PetscLogGetStageLog(&stageLog);
1126:   StageLogGetCurrent(stageLog, &stage);
1127:   while (stage >= 0) {
1128:     StageLogPop(stageLog);
1129:     StageLogGetCurrent(stageLog, &stage);
1130:   }
1131:   /* Get the total elapsed time */
1132:   PetscTime(locTotalTime);  locTotalTime -= BaseTime;
1133:   /* Open the summary file */
1134:   if (filename != PETSC_NULL) {
1135:     PetscFOpen(comm, filename, "w", &fd);
1136:   }

1138:   PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1139:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***n");
1140:   PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1141:   PetscFPrintf(comm, fd, "n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------nn");
1142:   PetscGetArchType(arch, 10);
1143:   PetscGetHostName(hostname, 64);
1144:   PetscGetUserName(username, 16);
1145:   PetscGetProgramName(pname, 256);
1146:   PetscGetDate(date, 64);
1147:   PetscGetVersion(&version);
1148:   if (numProcs == 1) {
1149:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %sn", pname, arch, hostname, numProcs, username, date);
1150: 
1151:   } else {
1152:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %sn", pname, arch, hostname, numProcs, username, date);
1153: 
1154:   }
1155:   PetscFPrintf(comm, fd, "Using %sn", version);

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

1160:   /* Calculate summary information */
1161:   PetscFPrintf(comm, fd, "n                         Max       Max/Min        Avg      Total n");
1162:   /*   Time */
1163:   MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1164:   MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1165:   MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1166:   avg  = (tot)/((PetscLogDouble) numProcs);
1167:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1168:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %10.5f   %5.3en", max, ratio, avg);
1169:   TotalTime = tot;
1170:   /*   Objects */
1171:   avg  = (PetscLogDouble) numObjects;
1172:   MPI_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1173:   MPI_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1174:   MPI_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1175:   avg  = (tot)/((PetscLogDouble) numProcs);
1176:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1177:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %10.5f   %5.3en", max, ratio, avg);
1178:   /*   Flops */
1179:   MPI_Allreduce(&_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1180:   MPI_Allreduce(&_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1181:   MPI_Allreduce(&_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1182:   avg  = (tot)/((PetscLogDouble) numProcs);
1183:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1184:   PetscFPrintf(comm, fd, "Flops:                %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1185:   TotalFlops = tot;
1186:   /*   Flops/sec -- Must talk to Barry here */
1187:   if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1188:   MPI_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1189:   MPI_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1190:   MPI_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1191:   avg  = (tot)/((PetscLogDouble) numProcs);
1192:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1193:   PetscFPrintf(comm, fd, "Flops/sec:            %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1194:   /*   Memory */
1195:   PetscTrSpace(PETSC_NULL, PETSC_NULL, &mem);
1196:   if (mem > 0.0) {
1197:     MPI_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1198:     MPI_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1199:     MPI_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1200:     avg  = (tot)/((PetscLogDouble) numProcs);
1201:     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1202:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %10.5f              %5.3en", max, ratio, tot);
1203:   }
1204:   /*   Messages */
1205:   mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1206:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1207:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1208:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1209:   avg  = (tot)/((PetscLogDouble) numProcs);
1210:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1211:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1212:   numMessages = tot;
1213:   /*   Message Lengths */
1214:   mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1215:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1216:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1217:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1218:   if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1219:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1220:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1221:   messageLength = tot;
1222:   /*   Reductions */
1223:   MPI_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1224:   MPI_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1225:   MPI_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1226:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1227:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %10.5fn", max, ratio);
1228:   numReductions = tot;
1229:   PetscFPrintf(comm, fd, "nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)n");
1230:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flopsn");
1231:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flopsn");

1233:   /* Get total number of stages --
1234:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1235:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1236:        This seems best accomplished by assoicating a communicator with each stage.
1237:   */
1238:   MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1239:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1240:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1241:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1242:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1243:   if (numStages > 0) {
1244:     stageInfo = stageLog->stageInfo;
1245:     for(stage = 0; stage < numStages; stage++) {
1246:       if (stage < stageLog->numStages) {
1247:         localStageUsed[stage]    = stageInfo[stage].used;
1248:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1249:       } else {
1250:         localStageUsed[stage]    = PETSC_FALSE;
1251:         localStageVisible[stage] = PETSC_TRUE;
1252:       }
1253:     }
1254:     MPI_Allreduce(localStageUsed,    stageUsed,    numStages, MPI_INT, MPI_LOR,  comm);
1255:     MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1256:     for(stage = 0; stage < numStages; stage++) {
1257:       if (stageUsed[stage] == PETSC_TRUE) {
1258:         PetscFPrintf(comm, fd, "nSummary of Stages:   ----- Time ------  ----- Flops -----  --- Messages ---  -- Message Lengths --  -- Reductions --n");
1259:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total   counts   %%Total     Avg         %%Total   counts   %%Total n");
1260:         break;
1261:       }
1262:     }
1263:     for(stage = 0; stage < numStages; stage++) {
1264:       if (stageUsed[stage] == PETSC_FALSE) continue;
1265:       if (localStageUsed[stage] == PETSC_TRUE) {
1266:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1267:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1268:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1269:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1270:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1271:         name = stageInfo[stage].name;
1272:       } else {
1273:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1274:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1275:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1276:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1277:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1278:         name = "";
1279:       }
1280:       mess *= 0.5; messLen *= 0.5; red /= numProcs;
1281:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1282:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1283:       /* Talk to Barry if (stageTime     != 0.0) flops          = (numProcs*flops)/stageTime; else flops          = 0.0; */
1284:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1285:       if (numMessages   != 0.0) avgMessLen     = messLen/numMessages;    else avgMessLen     = 0.0;
1286:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1287:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1288:       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",
1289:                           stage, name, stageTime/numProcs, 100.0*fracTime, flops, 100.0*fracFlops,
1290:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1291: 
1292:     }
1293:   }

1295:   PetscFPrintf(comm, fd,
1296:     "n------------------------------------------------------------------------------------------------------------------------n");
1297: 
1298:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.n");
1299:   PetscFPrintf(comm, fd, "Phase summary info:n");
1300:   PetscFPrintf(comm, fd, "   Count: number of times phase was executedn");
1301:   PetscFPrintf(comm, fd, "   Time and Flops/sec: Max - maximum over all processorsn");
1302:   PetscFPrintf(comm, fd, "                       Ratio - ratio of maximum to minimum over all processorsn");
1303:   PetscFPrintf(comm, fd, "   Mess: number of messages sentn");
1304:   PetscFPrintf(comm, fd, "   Avg. len: average message lengthn");
1305:   PetscFPrintf(comm, fd, "   Reduct: number of global reductionsn");
1306:   PetscFPrintf(comm, fd, "   Global: entire computationn");
1307:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().n");
1308:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flops in this phasen");
1309:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phasen");
1310:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phasen");
1311:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)n");
1312:   PetscFPrintf(comm, fd,
1313:     "------------------------------------------------------------------------------------------------------------------------n");
1314: 

1316: #if defined(PETSC_USE_BOPT_g)
1317:   PetscFPrintf(comm, fd, "nn");
1318:   PetscFPrintf(comm, fd, "      ##########################################################n");
1319:   PetscFPrintf(comm, fd, "      #                                                        #n");
1320:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1321:   PetscFPrintf(comm, fd, "      #                                                        #n");
1322:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #n");
1323:   PetscFPrintf(comm, fd, "      #   BOPT=<g,g_c++,g_complex>.   To get timing results    #n");
1324:   PetscFPrintf(comm, fd, "      #   ALWAYS compile your code with an optimized version,  #n");
1325:   PetscFPrintf(comm, fd, "      #   BOPT=<O,O_c++,O_complex>;  the performance will      #n");
1326:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #n");
1327:   PetscFPrintf(comm, fd, "      #                                                        #n");
1328:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1329: #endif
1330: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1331:   PetscFPrintf(comm, fd, "nn");
1332:   PetscFPrintf(comm, fd, "      ##########################################################n");
1333:   PetscFPrintf(comm, fd, "      #                                                        #n");
1334:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1335:   PetscFPrintf(comm, fd, "      #                                                        #n");
1336:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #n");
1337:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #n");
1338:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #n");
1339:   PetscFPrintf(comm, fd, "      #   faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #n");
1340:   PetscFPrintf(comm, fd, "      #   in base_variables and recompile the PETSc libraries. #n");
1341:   PetscFPrintf(comm, fd, "      #                                                        #n");
1342:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1343: #endif

1345:   if (!PetscPreLoadingUsed) {
1346:     PetscFPrintf(comm,fd,"nn");
1347:     PetscFPrintf(comm,fd,"      ##########################################################n");
1348:     PetscFPrintf(comm,fd,"      #                                                        #n");
1349:     PetscFPrintf(comm,fd,"      #                          WARNING!!!                    #n");
1350:     PetscFPrintf(comm,fd,"      #                                                        #n");
1351:     PetscFPrintf(comm,fd,"      #   This code was run without the PreLoadinBegin()       #n");
1352:     PetscFPrintf(comm,fd,"      #   macros. To get timing results we always recommend    #n");
1353:     PetscFPrintf(comm,fd,"      #   preloading. otherwise timing numbers may be          #n");
1354:     PetscFPrintf(comm,fd,"      #   meaningless.                                         #n");
1355:     PetscFPrintf(comm,fd,"      ##########################################################nnn");
1356:   }

1358:   /* Report events */
1359:   PetscFPrintf(comm, fd,
1360:     "Event                Count      Time (sec)     Flops/sec                         --- Global ---  --- Stage ---   Totaln");
1361: 
1362:   PetscFPrintf(comm, fd,
1363:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/sn");
1364: 
1365:   PetscFPrintf(comm,fd,
1366:     "------------------------------------------------------------------------------------------------------------------------n");

1368: 
1369:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1370:   for(stage = 0; stage < numStages; stage++) {
1371:     if (stageVisible[stage] == PETSC_FALSE) continue;
1372:     if (localStageUsed[stage] == PETSC_TRUE) {
1373:       PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1374:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1375:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1376:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1377:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1378:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1379:     } else {
1380:       PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1381:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1382:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1383:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1384:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1385:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1386:     }
1387:     mess *= 0.5; messLen *= 0.5; red /= numProcs;

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

1394:        Problem: If the event did not happen on proc 1, its name will not be available.
1395:        Problem: Event visibility is not implemented
1396:     */
1397:     if (localStageUsed[stage] == PETSC_TRUE) {
1398:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1399:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1400:     } else {
1401:       localNumEvents = 0;
1402:     }
1403:     MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1404:     for(event = 0; event < numEvents; event++) {
1405:       if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1406:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1407:           flopr = eventInfo[event].flops/eventInfo[event].time;
1408:         } else {
1409:           flopr = 0.0;
1410:         }
1411:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1412:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1413:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1414:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1415:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1416:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1417:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1418:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1419:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1420:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1421:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1422:         name = stageLog->eventLog->eventInfo[event].name;
1423:       } else {
1424:         flopr = 0.0;
1425:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1426:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1427:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1428:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1429:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1430:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1431:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1432:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1433:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1434:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1435:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1436:         name = "";
1437:       }
1438:       totm *= 0.5; totml *= 0.5; totr /= numProcs;
1439: 
1440:       if (maxCt != 0) {
1441:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1442:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1443:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1444:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1445:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1446:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1447:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1448:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1449:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1450:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1451:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1452:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1453:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1454:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1455:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1456:         PetscFPrintf(comm, fd,
1457:           "%-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",
1458:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1459:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1460:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1461:                             flopr/1.0e6);
1462: 
1463:       }
1464:     }
1465:   }

1467:   /* Memory usage and object creation */
1468:   PetscFPrintf(comm, fd,
1469:     "------------------------------------------------------------------------------------------------------------------------n");
1470: 
1471:   PetscFPrintf(comm, fd, "n");
1472:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:nn");

1474:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1475:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1476:      stats for stages local to processor sets.
1477:   */
1478:   /* We should figure out the longest object name here (now 20 characters) */
1479:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions   Memory  Descendants' Mem.n");
1480:   for(stage = 0; stage < numStages; stage++) {
1481:     if (localStageUsed[stage] == PETSC_TRUE) {
1482:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1483:       PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1484:       for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1485:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1486:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %9d     %gn", stageLog->classLog->classInfo[oclass].name,
1487:                               classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1488:                               classInfo[oclass].descMem);
1489: 
1490:         }
1491:       }
1492:     } else {
1493:       PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1494:     }
1495:   }

1497:   PetscFree(localStageUsed);
1498:   PetscFree(stageUsed);
1499:   PetscFree(localStageVisible);
1500:   PetscFree(stageVisible);

1502:   /* Information unrelated to this particular run */
1503:   PetscFPrintf(comm, fd,
1504:     "========================================================================================================================n");
1505: 
1506:   PetscTime(y);
1507:   PetscTime(x);
1508:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1509:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1510:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %gn", (y-x)/10.0);
1511:   /* MPI information */
1512:   if (numProcs > 1) {
1513:     MPI_Status status;
1514:     int        tag;

1516:     MPI_Barrier(comm);
1517:     PetscTime(x);
1518:     MPI_Barrier(comm);
1519:     MPI_Barrier(comm);
1520:     MPI_Barrier(comm);
1521:     MPI_Barrier(comm);
1522:     MPI_Barrier(comm);
1523:     PetscTime(y);
1524:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %gn", (y-x)/5.0);
1525:     PetscCommGetNewTag(comm, &tag);
1526:     MPI_Barrier(comm);
1527:     if (rank) {
1528:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, comm, &status);
1529:       MPI_Send(0, 0, MPI_INT, (rank+1)%numProcs, tag, comm);
1530:     } else {
1531:       PetscTime(x);
1532:       MPI_Send(0, 0, MPI_INT, 1,          tag, comm);
1533:       MPI_Recv(0, 0, MPI_INT, numProcs-1, tag, comm, &status);
1534:       PetscTime(y);
1535:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %gn", (y-x)/numProcs);
1536:     }
1537:   }
1538:   /* Machine and compile information */
1539: #if defined(PETSC_USE_FORTRAN_KERNELS)
1540:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernelsn");
1541: #else
1542:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1543: #endif
1544: #if defined(PETSC_USE_MAT_SINGLE)
1545:   PetscFPrintf(comm, fd, "Compiled with single precision matricesn");
1546: #else
1547:   PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)n");
1548: #endif
1549:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void *) %d",
1550:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1551: 

1553:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1554:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1555:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1556:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1558:   /* Cleanup */
1559:   PetscFPrintf(comm, fd, "n");
1560:   PetscFClose(comm, fd);
1561:   return(0);
1562: }

1564: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1565: /*@C
1566:    PetscGetFlops - Returns the number of flops used on this processor 
1567:    since the program began. 

1569:    Not Collective

1571:    Output Parameter:
1572:    flops - number of floating point operations 

1574:    Notes:
1575:    A global counter logs all PETSc flop counts.  The user can use
1576:    PetscLogFlops() to increment this counter to include flops for the 
1577:    application code.  

1579:    PETSc automatically logs library events if the code has been
1580:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1581:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1582:    intended for logging user flops to supplement this PETSc
1583:    information.

1585:    Level: intermediate

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

1589: .seealso: PetscGetTime(), PetscLogFlops()
1590: @*/
1591: int PetscGetFlops(PetscLogDouble *flops)
1592: {
1594:   *flops = _TotalFlops;
1595:   return(0);
1596: }

1598: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1599: {
1600:   va_list Argp;

1603:   if (logObjects == PETSC_FALSE) return(0);
1604:   va_start(Argp, format);
1605: #if defined(PETSC_HAVE_VPRINTF_CHAR)
1606:   vsprintf(objects[obj->id].info, format, (char *) Argp);
1607: #else
1608:   vsprintf(objects[obj->id].info, format, Argp);
1609: #endif
1610:   va_end(Argp);
1611:   return(0);
1612: }

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

1616: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1617: {
1619:   return(0);
1620: }

1622: #endif /* PETSC_USE_LOG*/

1624: /*@
1625:    PetscGetTime - Returns the current time of day in seconds. This 
1626:    returns wall-clock time.  

1628:    Not Collective

1630:    Output Parameter:
1631: .  v - time counter

1633:    Usage: 
1634: .vb
1635:       PetscLogDouble v1,v2,elapsed_time;
1636:       PetscGetTime(&v1);CHKERR(ierr);
1637:       .... perform some calculation ...
1638:       PetscGetTime(&v2);CHKERR(ierr);
1639:       elapsed_time = v2 - v1;   
1640: .ve

1642:    Notes:
1643:    Since the PETSc libraries incorporate timing of phases and operations, 
1644:    PetscGetTime() is intended only for timing of application codes.  
1645:    The options database commands -log, -log_summary, and -log_all activate
1646:    PETSc library timing.  See the users manual for further details.

1648:    Level: intermediate

1650: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(),  PetscLogStagePush(), 
1651:           PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()

1653: .keywords:  get, time
1654: @*/
1655: int PetscGetTime(PetscLogDouble *t)
1656: {
1658:   PetscTime(*t);
1659:   return(0);
1660: }

1662: /*@
1663:   PetscLogGetStageLog - This function returns the default stage logging object.

1665:   Not collective

1667:   Output Parameter:
1668: . stageLog - The default StageLog

1670:   Level: beginner

1672: .keywords: log, stage
1673: .seealso: StageLogCreate()
1674: @*/
1675: int PetscLogGetStageLog(StageLog *stageLog)
1676: {
1679:   *stageLog = _stageLog;
1680:   return(0);
1681: }

1683: /*MC
1684:    PetscLogFlops - Adds floating point operations to the global counter.

1686:    Input Parameter:
1687: .  f - flop counter

1689:    Synopsis:
1690:    void PetscLogFlops(int f)

1692:    Usage:
1693: .vb
1694:      int USER_EVENT;
1695:      PetscLogEventRegister(&USER_EVENT,"User event");
1696:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1697:         [code segment to monitor]
1698:         PetscLogFlops(user_flops)
1699:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1700: .ve

1702:    Notes:
1703:    A global counter logs all PETSc flop counts.  The user can use
1704:    PetscLogFlops() to increment this counter to include flops for the 
1705:    application code.  

1707:    PETSc automatically logs library events if the code has been
1708:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1709:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1710:    intended for logging user flops to supplement this PETSc
1711:    information.

1713:    Level: intermediate

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

1717: .keywords: log, flops, floating point operations
1718: M*/

1720: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1721: PetscTruth PetscPreLoadingOn   = PETSC_FALSE;

1723: /*MC
1724:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1725:     to get accurate timings

1727:    Input Parameter:
1728: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1729:            with command line option -preload true or -preload false
1730: -   name - name of first stage (lines of code timed seperately with -log_summary) to
1731:            be preloaded

1733:    Synopsis:
1734:    void PreLoadBegin(PetscTruth flag,char *name);

1736:    Usage:
1737: .vb
1738:      PreLoadBegin(PETSC_TRUE,"first stage);
1739:        lines of code
1740:        PreLoadStage("second stage");
1741:        lines of code
1742:      PreLoadEnd();
1743: .ve

1745:    Level: intermediate

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

1749:    Concepts: preloading
1750:    Concepts: timing^accurate
1751:    Concepts: paging^eliminating effects of


1754: M*/

1756: /*MC
1757:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1758:     to get accurate timings

1760:    Synopsis:
1761:    void PreLoadEnd(void);

1763:    Usage:
1764: .vb
1765:      PreLoadBegin(PETSC_TRUE,"first stage);
1766:        lines of code
1767:        PreLoadStage("second stage");
1768:        lines of code
1769:      PreLoadEnd();
1770: .ve

1772:    Level: intermediate

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

1776: M*/

1778: /*MC
1779:    PreLoadStage - Start a new segment of code to be timed seperately.
1780:     to get accurate timings

1782:    Synopsis:
1783:    void PreLoadStage(char *name);

1785:    Usage:
1786: .vb
1787:      PreLoadBegin(PETSC_TRUE,"first stage);
1788:        lines of code
1789:        PreLoadStage("second stage");
1790:        lines of code
1791:      PreLoadEnd();
1792: .ve

1794:    Level: intermediate

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

1798: M*/

1800: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1801: /*@C
1802:   StackDestroy - This function destroys a stack.

1804:   Not Collective

1806:   Input Parameter:
1807: . stack - The stack

1809:   Level: beginner

1811: .keywords: log, stack, destroy
1812: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1813: @*/
1814: int StackDestroy(IntStack stack)
1815: {

1819:   PetscFree(stack->stack);
1820:   PetscFree(stack);
1821:   return(0);
1822: }

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

1827:   Not Collective

1829:   Input Parameter:
1830: . stack - The stack

1832:   Output Parameter:
1833: . empty - PETSC_TRUE if the stack is empty

1835:   Level: intermediate

1837: .keywords: log, stack, empty
1838: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1839: @*/
1840: int StackEmpty(IntStack stack, PetscTruth *empty)
1841: {
1844:   if (stack->top == -1) {
1845:     *empty = PETSC_TRUE;
1846:   } else {
1847:     *empty = PETSC_FALSE;
1848:   }
1849:   return(0);
1850: }

1852: /*@C
1853:   StackTop - This function returns the top of the stack.

1855:   Not Collective

1857:   Input Parameter:
1858: . stack - The stack

1860:   Output Parameter:
1861: . top - The integer on top of the stack

1863:   Level: intermediate

1865: .keywords: log, stack, top
1866: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1867: @*/
1868: int StackTop(IntStack stack, int *top)
1869: {
1872:   *top = stack->stack[stack->top];
1873:   return(0);
1874: }

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

1879:   Not Collective

1881:   Input Parameters:
1882: + stack - The stack
1883: - item  - The integer to push

1885:   Level: intermediate

1887: .keywords: log, stack, push
1888: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1889: @*/
1890: int StackPush(IntStack stack, int item)
1891: {
1892:   int *array;
1893:   int  ierr;

1896:   stack->top++;
1897:   if (stack->top >= stack->max) {
1898:     PetscMalloc(stack->max*2 * sizeof(int), &array);
1899:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1900:     PetscFree(stack->stack);
1901:     stack->stack = array;
1902:     stack->max  *= 2;
1903:   }
1904:   stack->stack[stack->top] = item;
1905:   return(0);
1906: }

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

1911:   Not Collective

1913:   Input Parameter:
1914: . stack - The stack

1916:   Output Parameter:
1917: . item  - The integer popped

1919:   Level: intermediate

1921: .keywords: log, stack, pop
1922: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
1923: @*/
1924: int StackPop(IntStack stack, int *item)
1925: {
1928:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
1929:   *item = stack->stack[stack->top--];
1930:   return(0);
1931: }

1933: /*@C
1934:   StackCreate - This function creates a stack.

1936:   Not Collective

1938:   Output Parameter:
1939: . stack - The stack

1941:   Level: beginner

1943: .keywords: log, stack, pop
1944: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
1945: @*/
1946: int StackCreate(IntStack *stack)
1947: {
1948:   IntStack s;
1949:   int      ierr;

1953:   PetscNew(struct _IntStack, &s);
1954:   s->top = -1;
1955:   s->max = 128;
1956:   PetscMalloc(s->max * sizeof(int), &s->stack);
1957:   PetscMemzero(s->stack, s->max * sizeof(int));
1958:   *stack = s;
1959:   return(0);
1960: }