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      ierr;

351:   PetscLogGetStageLog(&stageLog);
352:   StageLogRegister(stageLog, sname, stage);
353:   EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
354:   ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
355:   return(0);
356: }

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

361:   Not Collective

363:   Input Parameter:
364: . stage - The stage on which to log

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

384:   Level: intermediate

386: .keywords: log, push, stage
387: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
388: @*/
389: int PetscLogStagePush(int stage)
390: {
391:   StageLog stageLog;
392:   int      ierr;

395:   PetscLogGetStageLog(&stageLog);
396:   StageLogPush(stageLog, stage);
397:   return(0);
398: }

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

403:   Not Collective

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

420:   Notes:  
421:   Use PetscLogStageRegister() to register a stage.

423:   Level: intermediate

425: .keywords: log, pop, stage
426: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
427: @*/
428: int PetscLogStagePop(void)
429: {
430:   StageLog stageLog;
431:   int      ierr;

434:   PetscLogGetStageLog(&stageLog);
435:   StageLogPop(stageLog);
436:   return(0);
437: }

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

442:   Not Collective 

444:   Input Parameters:
445: + stage    - The stage
446: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

448:   Level: intermediate

450: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
451: @*/
452: int PetscLogStageSetActive(int stage, PetscTruth isActive) {
453:   StageLog stageLog;
454:   int      ierr;

457:   PetscLogGetStageLog(&stageLog);
458:   StageLogSetActive(stageLog, stage, isActive);
459:   return(0);
460: }

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

465:   Not Collective 

467:   Input Parameter:
468: . stage    - The stage

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

473:   Level: intermediate

475: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
476: @*/
477: int PetscLogStageGetActive(int stage, PetscTruth *isActive) {
478:   StageLog stageLog;
479:   int      ierr;

482:   PetscLogGetStageLog(&stageLog);
483:   StageLogGetActive(stageLog, stage, isActive);
484:   return(0);
485: }

487: /*@
488:   PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()

490:   Not Collective 

492:   Input Parameters:
493: + stage     - The stage
494: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

496:   Level: intermediate

498: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
499: @*/
500: int PetscLogStageSetVisible(int stage, PetscTruth isVisible)
501: {
502:   StageLog stageLog;
503:   int      ierr;

506:   PetscLogGetStageLog(&stageLog);
507:   StageLogSetVisible(stageLog, stage, isVisible);
508:   return(0);
509: }

511: /*@
512:   PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()

514:   Not Collective 

516:   Input Parameter:
517: . stage     - The stage

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

522:   Level: intermediate

524: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
525: @*/
526: int PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
527: {
528:   StageLog stageLog;
529:   int      ierr;

532:   PetscLogGetStageLog(&stageLog);
533:   StageLogGetVisible(stageLog, stage, isVisible);
534:   return(0);
535: }

537: /*@
538:   PetscLogStageGetId - Returns the stage id when given the stage name.

540:   Not Collective 

542:   Input Parameter:
543: . name  - The stage name

545:   Output Parameter:
546: . stage - The stage

548:   Level: intermediate

550: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
551: @*/
552: int PetscLogStageGetId(const char name[], int *stage)
553: {
554:   StageLog stageLog;
555:   int      ierr;

558:   PetscLogGetStageLog(&stageLog);
559:   StageLogGetStage(stageLog, name, stage);
560:   return(0);
561: }

563: /*------------------------------------------------ Event Functions --------------------------------------------------*/
564: /*@C
565:   PetscLogEventRegister - Registers an event name for logging operations in an application code. 

567:   Not Collective

569:   Input Parameter:
570: + name   - The name associated with the event
571: - cookie - The cookie associated to the class for this event
572:             
573:   Output Parameter:
574: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

576:   Example of Usage:
577: .vb
578:       int USER_EVENT;
579:       int user_event_flops;
580:       PetscLogEventRegister(&USER_EVENT,"User event name");
581:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
582:          [code segment to monitor]
583:          PetscLogFlops(user_event_flops);
584:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
585: .ve

587:   Notes: 
588:   PETSc automatically logs library events if the code has been
589:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
590:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
591:   intended for logging user events to supplement this PETSc
592:   information. 

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

601:   Level: intermediate

603: .keywords: log, event, register
604: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
605:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
606:           PetscLogEventActivate(), PetscLogEventDeactivate()
607: @*/
608: int PetscLogEventRegister(int *event, const char name[],int cookie) {
609:   StageLog stageLog;
610:   int      stage;
611:   int      ierr;

614:   *event = PETSC_DECIDE;
615:   PetscLogGetStageLog(&stageLog);
616:   EventRegLogRegister(stageLog->eventLog, name, cookie, event);
617:   for(stage = 0; stage < stageLog->numStages; stage++) {
618:     EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
619:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
620:   }
621:   return(0);
622: }

624: /*@
625:   PetscLogEventActivate - Indicates that a particular event should be logged.

627:   Not Collective

629:   Input Parameter:
630: . event - The event id

632:   Usage:
633: .vb
634:       PetscLogEventDeactivate(VEC_SetValues);
635:         [code where you do not want to log VecSetValues()]
636:       PetscLogEventActivate(VEC_SetValues);
637:         [code where you do want to log VecSetValues()]
638: .ve 

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

644:   Level: advanced

646: .keywords: log, event, activate
647: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
648: @*/
649: int PetscLogEventActivate(int event) {
650:   StageLog stageLog;
651:   int      stage;
652:   int      ierr;

655:   PetscLogGetStageLog(&stageLog);
656:   StageLogGetCurrent(stageLog, &stage);
657:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
658:   return(0);
659: }

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

664:   Not Collective

666:   Input Parameter:
667: . event - The event id

669:   Usage:
670: .vb
671:       PetscLogEventDeactivate(VEC_SetValues);
672:         [code where you do not want to log VecSetValues()]
673:       PetscLogEventActivate(VEC_SetValues);
674:         [code where you do want to log VecSetValues()]
675: .ve 

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

681:   Level: advanced

683: .keywords: log, event, deactivate
684: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
685: @*/
686: int PetscLogEventDeactivate(int event) {
687:   StageLog stageLog;
688:   int      stage;
689:   int      ierr;

692:   PetscLogGetStageLog(&stageLog);
693:   StageLogGetCurrent(stageLog, &stage);
694:   EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
695:   return(0);
696: }

698: /*@
699:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

701:   Not Collective

703:   Input Parameter:
704: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

706:   Level: developer

708: .keywords: log, event, activate, class
709: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
710: @*/
711: int PetscLogEventActivateClass(int cookie) {
712:   StageLog stageLog;
713:   int      stage;
714:   int      ierr;

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

723: /*@
724:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

726:   Not Collective

728:   Input Parameter:
729: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

731:   Level: developer

733: .keywords: log, event, deactivate, class
734: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
735: @*/
736: int PetscLogEventDeactivateClass(int cookie) {
737:   StageLog stageLog;
738:   int      stage;
739:   int      ierr;

742:   PetscLogGetStageLog(&stageLog);
743:   StageLogGetCurrent(stageLog, &stage);
744:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
745:   return(0);
746: }

748: /*MC
749:    PetscLogEventBegin - Logs the beginning of a user event. 

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

755:    Synopsis:
756:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
757:                        PetscObject o4)

759:    Usage:
760: .vb
761:      int USER_EVENT;
762:      int user_event_flops;
763:      PetscLogEventRegister(&USER_EVENT,"User event");
764:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
765:         [code segment to monitor]
766:         PetscLogFlops(user_event_flops);
767:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
768: .ve

770:    Notes:
771:    You should also register each integer event with the command 
772:    PetscLogEventRegister().  The source code must be compiled with 
773:    -DPETSC_USE_LOG, which is the default.

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

780:    Level: intermediate

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

784: .keywords: log, event, begin
785: M*/

787: /*MC
788:    PetscLogEventEnd - Log the end of a user event.

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

794:    Synopsis:
795:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
796:                      PetscObject o4)

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

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

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

819:    Level: intermediate

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

823: .keywords: log, event, end
824: M*/

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

829:    Input Parameters:
830: .  e - integer associated with the event obtained from PetscLogEventRegister()
831: .  o1,o2,o3,o4 - objects associated with the event, or 0
832: .  comm - communicator the barrier takes place over

834:    Synopsis:
835:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
836:                   PetscObject o4,MPI_Comm comm)

838:    Usage:
839: .vb
840:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
841:        MPI_Allreduce()
842:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
843: .ve

845:    Notes:
846:    This is for logging the amount of time spent in a barrier for an event
847:    that requires synchronization. 

849:    Additional Notes:
850:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
851:    VEC_NormComm = VEC_NormBarrier + 1

853:    Level: advanced

855: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
856:           PetscLogEventBarrierEnd()

858: .keywords: log, event, begin, barrier
859: M*/

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

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

869:    Synopsis:
870:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
871:                   PetscObject o4,MPI_Comm comm)

873:     Usage:
874: .vb
875:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
876:        MPI_Allreduce()
877:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
878: .ve

880:    Notes:
881:    This is for logging the amount of time spent in a barrier for an event
882:    that requires synchronization. 

884:    Additional Notes:
885:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
886:    VEC_NormComm = VEC_NormBarrier + 1

888:    Level: advanced

890: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
891:           PetscLogEventBarrierBegin()

893: .keywords: log, event, begin, barrier
894: M*/

896: /*------------------------------------------------ Class Functions --------------------------------------------------*/
897: /*@C
898:   PetscLogClassRegister - Registers a class name for logging operations in an application code. 

900:   Not Collective

902:   Input Parameter:
903: . name   - The class name
904:             
905:   Output Parameter:
906: . oclass - The class id or cookie

908:   Level: developer

910: .keywords: log, class, register
911: .seealso: ClassLogRegister()
912: @*/
913: int PetscLogClassRegister(int *oclass, const char name[])
914: {
915:   StageLog stageLog;
916:   int      ierr;

919:   *oclass = PETSC_DECIDE;
920:   PetscLogGetStageLog(&stageLog);
921:   ClassRegLogRegister(stageLog->classLog, name, oclass);
922:   return(0);
923: }

925: /*------------------------------------------------ Output Functions -------------------------------------------------*/
926: /*@C
927:   PetscLogDump - Dumps logs of objects to a file. This file is intended to 
928:   be read by petsc/bin/petscview.

930:   Collective on PETSC_COMM_WORLD

932:   Input Parameter:
933: . name - an optional file name

935:   Options Database Keys:
936: + -log     - Prints basic log information (for code compiled with PETSC_USE_LOG)
937: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
938:    
939:   Usage:
940: .vb
941:      PetscInitialize(...);
942:      PetscLogBegin(); or PetscLogAllBegin(); 
943:      ... code ...
944:      PetscLogDump(filename);
945:      PetscFinalize();
946: .ve

948:   Notes:
949:   The default file name is 
950: $    Log.<rank>
951:   where <rank> is the processor number. If no name is specified, 
952:   this file will be used.

954:   Level: advanced

956: .keywords: log, dump
957: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
958: @*/
959: int PetscLogDump(const char sname[]) {
960:   StageLog       stageLog;
961:   EventPerfInfo *eventInfo;
962:   FILE          *fd;
963:   char           file[64], fname[64];
964:   PetscLogDouble flops, _TotalTime;
965:   int            rank, curStage;
966:   int            action, object, event;
967:   int            ierr;
968: 
970:   /* Calculate the total elapsed time */
971:   PetscTime(_TotalTime);
972:   _TotalTime -= BaseTime;
973:   /* Open log file */
974:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
975:   if (sname != PETSC_NULL) {
976:     sprintf(file, "%s.%d", sname, rank);
977:   } else {
978:     sprintf(file, "Log.%d", rank);
979:   }
980:   PetscFixFilename(file, fname);
981:   PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
982:   if ((rank == 0) && (fd == PETSC_NULL)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
983:   /* Output totals */
984:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8en", _TotalFlops, _TotalTime);
985:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %gn", 0.0);
986:   /* Output actions */
987:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %dn", numActions);
988:   for(action = 0; action < numActions; action++) {
989:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %gn",
990:                         actions[action].time, actions[action].action, actions[action].event, actions[action].cookie, actions[action].id1,
991:                         actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
992:   }
993:   /* Output objects */
994:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %dn", numObjects, numObjectsDestroyed);
995:   for(object = 0; object < numObjects; object++) {
996:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %dn", objects[object].parent, (int) objects[object].mem);
997:     if (!objects[object].name[0]) {
998:       PetscFPrintf(PETSC_COMM_WORLD, fd,"No Namen");
999:     } else {
1000:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %sn", objects[object].name);
1001:     }
1002:     if (objects[object].info[0] != 0) {
1003:       PetscFPrintf(PETSC_COMM_WORLD, fd, "No Infon");
1004:     } else {
1005:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %sn", objects[object].info);
1006:     }
1007:   }
1008:   /* Output events */
1009:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:n");
1010:   PetscLogGetStageLog(&stageLog);
1011:   StackTop(stageLog->stack, &curStage);
1012:   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1013:   for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1014:     if (eventInfo[event].time != 0.0) {
1015:       flops = eventInfo[event].flops/eventInfo[event].time;
1016:     } else {
1017:       flops = 0.0;
1018:     }
1019:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16gn", event, eventInfo[event].count,
1020:                         eventInfo[event].flops, eventInfo[event].time, flops);
1021:   }
1022:   PetscFClose(PETSC_COMM_WORLD, fd);
1023:   return(0);
1024: }

1026: /*@C
1027:   PetscLogPrintSummary - Prints a summary of the logging.

1029:   Collective over MPI_Comm

1031:   Input Parameter:
1032: + comm - The MPI communicator (only one processor prints output)
1033: - file - [Optional] The output file name

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

1038:   Usage:
1039: .vb
1040:      PetscInitialize(...);
1041:      PetscLogBegin();
1042:      ... code ...
1043:      PetscLogPrintSummary(MPI_Comm,filename);
1044:      PetscFinalize(...);
1045: .ve

1047:   Notes:
1048:   By default the summary is printed to stdout.
1049:   More extensive examination of the log information can be done with 
1050:   PetscLogDump(), which is activated by the option -log or -log_all, in 
1051:   combination with petsc/bin/petscview.

1053:   Level: beginner
1054:    
1055: .keywords: log, dump, print
1056: .seealso: PetscLogBegin(), PetscLogDump()
1057: @*/
1058: int PetscLogPrintSummary(MPI_Comm comm, const char filename[]) {
1059:   FILE          *fd   = stdout;
1060:   PetscScalar    zero = 0.0;
1061:   StageLog       stageLog;
1062:   StageInfo     *stageInfo = PETSC_NULL;
1063:   EventPerfInfo *eventInfo = PETSC_NULL;
1064:   ClassPerfInfo *classInfo;
1065:   char           arch[10], hostname[64], username[16], pname[256], date[64];
1066:   char           *name;
1067:   PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1068:   PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1069:   PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1070:   PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1071:   PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1072:   PetscLogDouble min, max, tot, ratio, avg, x, y;
1073:   PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1074:   int            minCt, maxCt;
1075:   int            numProcs, rank;
1076:   PetscTruth    *localStageUsed,    *stageUsed;
1077:   PetscTruth    *localStageVisible, *stageVisible;
1078:   int            numStages, localNumEvents, numEvents;
1079:   int            stage, event, oclass;
1080:   int            ierr;
1081:   char           version[256];

1084:   MPI_Comm_size(comm, &numProcs);
1085:   MPI_Comm_rank(comm, &rank);
1086:   /* Pop off any stages the user forgot to remove */
1087:   PetscLogGetStageLog(&stageLog);
1088:   StageLogGetCurrent(stageLog, &stage);
1089:   while (stage >= 0) {
1090:     StageLogPop(stageLog);
1091:     StageLogGetCurrent(stageLog, &stage);
1092:   }
1093:   /* Get the total elapsed time */
1094:   PetscTime(locTotalTime);  locTotalTime -= BaseTime;
1095:   /* Open the summary file */
1096:   if (filename != PETSC_NULL) {
1097:     PetscFOpen(comm, filename, "w", &fd);
1098:   }

1100:   PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1101:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***n");
1102:   PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1103:   PetscFPrintf(comm, fd, "n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------nn");
1104:   PetscGetArchType(arch, 10);
1105:   PetscGetHostName(hostname, 64);
1106:   PetscGetUserName(username, 16);
1107:   PetscGetProgramName(pname, 256);
1108:   PetscGetDate(date, 64);
1109:   PetscGetVersion(&version);
1110:   if (numProcs == 1) {
1111:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %sn", pname, arch, hostname, numProcs, username, date);
1112: 
1113:   } else {
1114:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %sn", pname, arch, hostname, numProcs, username, date);
1115: 
1116:   }
1117:   PetscFPrintf(comm, fd, "Using %sn", version);

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

1122:   /* Calculate summary information */
1123:   PetscFPrintf(comm, fd, "n                         Max       Max/Min        Avg      Total n");
1124:   /*   Time */
1125:   MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1126:   MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1127:   MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1128:   avg  = (tot)/((PetscLogDouble) numProcs);
1129:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1130:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %10.5f   %5.3en", max, ratio, avg);
1131:   TotalTime = tot;
1132:   /*   Objects */
1133:   avg  = (PetscLogDouble) numObjects;
1134:   MPI_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1135:   MPI_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1136:   MPI_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1137:   avg  = (tot)/((PetscLogDouble) numProcs);
1138:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1139:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %10.5f   %5.3en", max, ratio, avg);
1140:   /*   Flops */
1141:   MPI_Allreduce(&_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1142:   MPI_Allreduce(&_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1143:   MPI_Allreduce(&_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1144:   avg  = (tot)/((PetscLogDouble) numProcs);
1145:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1146:   PetscFPrintf(comm, fd, "Flops:                %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1147:   TotalFlops = tot;
1148:   /*   Flops/sec -- Must talk to Barry here */
1149:   if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1150:   MPI_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1151:   MPI_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1152:   MPI_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1153:   avg  = (tot)/((PetscLogDouble) numProcs);
1154:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1155:   PetscFPrintf(comm, fd, "Flops/sec:            %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1156:   /*   Memory */
1157:   PetscTrSpace(PETSC_NULL, PETSC_NULL, &mem);
1158:   if (mem > 0.0) {
1159:     MPI_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1160:     MPI_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1161:     MPI_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1162:     avg  = (tot)/((PetscLogDouble) numProcs);
1163:     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1164:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %10.5f              %5.3en", max, ratio, tot);
1165:   }
1166:   /*   Messages */
1167:   mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1168:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1169:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1170:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1171:   avg  = (tot)/((PetscLogDouble) numProcs);
1172:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1173:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1174:   numMessages = tot;
1175:   /*   Message Lengths */
1176:   mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1177:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1178:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1179:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1180:   if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1181:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1182:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1183:   messageLength = tot;
1184:   /*   Reductions */
1185:   MPI_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1186:   MPI_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1187:   MPI_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1188:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1189:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %10.5fn", max, ratio);
1190:   numReductions = tot;
1191:   PetscFPrintf(comm, fd, "nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)n");
1192:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flopsn");
1193:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flopsn");

1195:   /* Get total number of stages --
1196:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1197:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1198:        This seems best accomplished by assoicating a communicator with each stage.
1199:   */
1200:   MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1201:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1202:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1203:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1204:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1205:   if (numStages > 0) {
1206:     stageInfo = stageLog->stageInfo;
1207:     for(stage = 0; stage < numStages; stage++) {
1208:       if (stage < stageLog->numStages) {
1209:         localStageUsed[stage]    = stageInfo[stage].used;
1210:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1211:       } else {
1212:         localStageUsed[stage]    = PETSC_FALSE;
1213:         localStageVisible[stage] = PETSC_TRUE;
1214:       }
1215:     }
1216:     MPI_Allreduce(localStageUsed,    stageUsed,    numStages, MPI_INT, MPI_LOR,  comm);
1217:     MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1218:     for(stage = 0; stage < numStages; stage++) {
1219:       if (stageUsed[stage] == PETSC_TRUE) {
1220:         PetscFPrintf(comm, fd, "nSummary of Stages:   ----- Time ------  ----- Flops -----  --- Messages ---  -- Message Lengths --  -- Reductions --n");
1221:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total   counts   %%Total     Avg         %%Total   counts   %%Total n");
1222:         break;
1223:       }
1224:     }
1225:     for(stage = 0; stage < numStages; stage++) {
1226:       if (stageUsed[stage] == PETSC_FALSE) continue;
1227:       if (localStageUsed[stage] == PETSC_TRUE) {
1228:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1229:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1230:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1231:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1232:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1233:         name = stageInfo[stage].name;
1234:       } else {
1235:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1236:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1237:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1238:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1239:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1240:         name = "";
1241:       }
1242:       mess *= 0.5; messLen *= 0.5; red /= numProcs;
1243:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1244:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1245:       /* Talk to Barry if (stageTime     != 0.0) flops          = (numProcs*flops)/stageTime; else flops          = 0.0; */
1246:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1247:       if (numMessages   != 0.0) avgMessLen     = messLen/numMessages;    else avgMessLen     = 0.0;
1248:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1249:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1250:       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",
1251:                           stage, name, stageTime/numProcs, 100.0*fracTime, flops, 100.0*fracFlops,
1252:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1253: 
1254:     }
1255:   }

1257:   PetscFPrintf(comm, fd,
1258:     "n------------------------------------------------------------------------------------------------------------------------n");
1259: 
1260:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.n");
1261:   PetscFPrintf(comm, fd, "Phase summary info:n");
1262:   PetscFPrintf(comm, fd, "   Count: number of times phase was executedn");
1263:   PetscFPrintf(comm, fd, "   Time and Flops/sec: Max - maximum over all processorsn");
1264:   PetscFPrintf(comm, fd, "                       Ratio - ratio of maximum to minimum over all processorsn");
1265:   PetscFPrintf(comm, fd, "   Mess: number of messages sentn");
1266:   PetscFPrintf(comm, fd, "   Avg. len: average message lengthn");
1267:   PetscFPrintf(comm, fd, "   Reduct: number of global reductionsn");
1268:   PetscFPrintf(comm, fd, "   Global: entire computationn");
1269:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().n");
1270:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flops in this phasen");
1271:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phasen");
1272:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phasen");
1273:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)n");
1274:   PetscFPrintf(comm, fd,
1275:     "------------------------------------------------------------------------------------------------------------------------n");
1276: 

1278: #if defined(PETSC_USE_BOPT_g)
1279:   PetscFPrintf(comm, fd, "nn");
1280:   PetscFPrintf(comm, fd, "      ##########################################################n");
1281:   PetscFPrintf(comm, fd, "      #                                                        #n");
1282:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1283:   PetscFPrintf(comm, fd, "      #                                                        #n");
1284:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #n");
1285:   PetscFPrintf(comm, fd, "      #   BOPT=<g,g_c++,g_complex>.   To get timing results    #n");
1286:   PetscFPrintf(comm, fd, "      #   ALWAYS compile your code with an optimized version,  #n");
1287:   PetscFPrintf(comm, fd, "      #   BOPT=<O,O_c++,O_complex>;  the performance will      #n");
1288:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #n");
1289:   PetscFPrintf(comm, fd, "      #                                                        #n");
1290:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1291: #endif
1292: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1293:   PetscFPrintf(comm, fd, "nn");
1294:   PetscFPrintf(comm, fd, "      ##########################################################n");
1295:   PetscFPrintf(comm, fd, "      #                                                        #n");
1296:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1297:   PetscFPrintf(comm, fd, "      #                                                        #n");
1298:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #n");
1299:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #n");
1300:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #n");
1301:   PetscFPrintf(comm, fd, "      #   faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #n");
1302:   PetscFPrintf(comm, fd, "      #   in base_variables and recompile the PETSc libraries. #n");
1303:   PetscFPrintf(comm, fd, "      #                                                        #n");
1304:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1305: #endif

1307:   if (!PetscPreLoadingUsed) {
1308:     PetscFPrintf(comm,fd,"nn");
1309:     PetscFPrintf(comm,fd,"      ##########################################################n");
1310:     PetscFPrintf(comm,fd,"      #                                                        #n");
1311:     PetscFPrintf(comm,fd,"      #                          WARNING!!!                    #n");
1312:     PetscFPrintf(comm,fd,"      #                                                        #n");
1313:     PetscFPrintf(comm,fd,"      #   This code was run without the PreLoadinBegin()       #n");
1314:     PetscFPrintf(comm,fd,"      #   macros. To get timing results we always recommend    #n");
1315:     PetscFPrintf(comm,fd,"      #   preloading. otherwise timing numbers may be          #n");
1316:     PetscFPrintf(comm,fd,"      #   meaningless.                                         #n");
1317:     PetscFPrintf(comm,fd,"      ##########################################################nnn");
1318:   }

1320:   /* Report events */
1321:   PetscFPrintf(comm, fd,
1322:     "Event                Count      Time (sec)     Flops/sec                         --- Global ---  --- Stage ---   Totaln");
1323: 
1324:   PetscFPrintf(comm, fd,
1325:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/sn");
1326: 
1327:   PetscFPrintf(comm,fd,
1328:     "------------------------------------------------------------------------------------------------------------------------n");

1330: 
1331:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1332:   for(stage = 0; stage < numStages; stage++) {
1333:     if (stageVisible[stage] == PETSC_FALSE) continue;
1334:     if (localStageUsed[stage] == PETSC_TRUE) {
1335:       PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1336:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1337:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1338:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1339:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1340:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1341:     } else {
1342:       PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1343:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1344:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1345:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1346:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1348:     }
1349:     mess *= 0.5; messLen *= 0.5; red /= numProcs;

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

1356:        Problem: If the event did not happen on proc 1, its name will not be available.
1357:        Problem: Event visibility is not implemented
1358:     */
1359:     if (localStageUsed[stage] == PETSC_TRUE) {
1360:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1361:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1362:     } else {
1363:       localNumEvents = 0;
1364:     }
1365:     MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1366:     for(event = 0; event < numEvents; event++) {
1367:       if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1368:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1369:           flopr = eventInfo[event].flops/eventInfo[event].time;
1370:         } else {
1371:           flopr = 0.0;
1372:         }
1373:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1374:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1375:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1376:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1377:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1378:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1379:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1380:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1381:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1382:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1383:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1384:         name = stageLog->eventLog->eventInfo[event].name;
1385:       } else {
1386:         flopr = 0.0;
1387:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1388:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1389:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1390:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1391:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1392:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1393:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1394:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1395:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1396:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1397:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1398:         name = "";
1399:       }
1400:       totm *= 0.5; totml *= 0.5; totr /= numProcs;
1401: 
1402:       if (maxCt != 0) {
1403:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1404:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1405:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1406:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1407:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1408:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1409:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1410:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1411:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1412:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1413:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1414:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1415:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1416:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1417:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1418:         PetscFPrintf(comm, fd,
1419:           "%-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",
1420:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1421:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1422:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1423:                             flopr/1.0e6);
1424: 
1425:       }
1426:     }
1427:   }

1429:   /* Memory usage and object creation */
1430:   PetscFPrintf(comm, fd,
1431:     "------------------------------------------------------------------------------------------------------------------------n");
1432: 
1433:   PetscFPrintf(comm, fd, "n");
1434:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:nn");

1436:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1437:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1438:      stats for stages local to processor sets.
1439:   */
1440:   /* We should figure out the longest object name here (now 20 characters) */
1441:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions   Memory  Descendants' Mem.n");
1442:   for(stage = 0; stage < numStages; stage++) {
1443:     if (localStageUsed[stage] == PETSC_TRUE) {
1444:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1445:       PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1446:       for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1447:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1448:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %9d     %gn", stageLog->classLog->classInfo[oclass].name,
1449:                               classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1450:                               classInfo[oclass].descMem);
1451: 
1452:         }
1453:       }
1454:     } else {
1455:       PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1456:     }
1457:   }

1459:   PetscFree(localStageUsed);
1460:   PetscFree(stageUsed);
1461:   PetscFree(localStageVisible);
1462:   PetscFree(stageVisible);

1464:   /* Information unrelated to this particular run */
1465:   PetscFPrintf(comm, fd,
1466:     "========================================================================================================================n");
1467: 
1468:   PetscTime(y);
1469:   PetscTime(x);
1470:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1471:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1472:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %gn", (y-x)/10.0);
1473:   /* MPI information */
1474:   if (numProcs > 1) {
1475:     MPI_Status status;
1476:     int        tag;

1478:     MPI_Barrier(comm);
1479:     PetscTime(x);
1480:     MPI_Barrier(comm);
1481:     MPI_Barrier(comm);
1482:     MPI_Barrier(comm);
1483:     MPI_Barrier(comm);
1484:     MPI_Barrier(comm);
1485:     PetscTime(y);
1486:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %gn", (y-x)/5.0);
1487:     PetscCommGetNewTag(comm, &tag);
1488:     MPI_Barrier(comm);
1489:     if (rank) {
1490:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, comm, &status);
1491:       MPI_Send(0, 0, MPI_INT, (rank+1)%numProcs, tag, comm);
1492:     } else {
1493:       PetscTime(x);
1494:       MPI_Send(0, 0, MPI_INT, 1,          tag, comm);
1495:       MPI_Recv(0, 0, MPI_INT, numProcs-1, tag, comm, &status);
1496:       PetscTime(y);
1497:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %gn", (y-x)/numProcs);
1498:     }
1499:   }
1500:   /* Machine and compile information */
1501: #if defined(PETSC_USE_FORTRAN_KERNELS)
1502:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernelsn");
1503: #else
1504:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1505: #endif
1506: #if defined(PETSC_USE_MAT_SINGLE)
1507:   PetscFPrintf(comm, fd, "Compiled with single precision matricesn");
1508: #else
1509:   PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)n");
1510: #endif
1511:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void *) %d",
1512:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1513: 

1515:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1516:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1517:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1518:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1520:   /* Cleanup */
1521:   PetscFPrintf(comm, fd, "n");
1522:   PetscFClose(comm, fd);
1523:   return(0);
1524: }

1526: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1527: /*@C
1528:    PetscGetFlops - Returns the number of flops used on this processor 
1529:    since the program began. 

1531:    Not Collective

1533:    Output Parameter:
1534:    flops - number of floating point operations 

1536:    Notes:
1537:    A global counter logs all PETSc flop counts.  The user can use
1538:    PetscLogFlops() to increment this counter to include flops for the 
1539:    application code.  

1541:    PETSc automatically logs library events if the code has been
1542:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1543:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1544:    intended for logging user flops to supplement this PETSc
1545:    information.

1547:    Level: intermediate

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

1551: .seealso: PetscGetTime(), PetscLogFlops()
1552: @*/
1553: int PetscGetFlops(PetscLogDouble *flops)
1554: {
1556:   *flops = _TotalFlops;
1557:   return(0);
1558: }

1560: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1561: {
1562:   va_list Argp;

1565:   if (logObjects == PETSC_FALSE) return(0);
1566:   va_start(Argp, format);
1567: #if defined(PETSC_HAVE_VPRINTF_CHAR)
1568:   vsprintf(objects[obj->id].info, format, (char *) Argp);
1569: #else
1570:   vsprintf(objects[obj->id].info, format, Argp);
1571: #endif
1572:   va_end(Argp);
1573:   return(0);
1574: }

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

1578: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1579: {
1581:   return(0);
1582: }

1584: #endif /* PETSC_USE_LOG*/

1586: /*@
1587:    PetscGetTime - Returns the current time of day in seconds. This 
1588:    returns wall-clock time.  

1590:    Not Collective

1592:    Output Parameter:
1593: .  v - time counter

1595:    Usage: 
1596: .vb
1597:       PetscLogDouble v1,v2,elapsed_time;
1598:       PetscGetTime(&v1);CHKERR(ierr);
1599:       .... perform some calculation ...
1600:       PetscGetTime(&v2);CHKERR(ierr);
1601:       elapsed_time = v2 - v1;   
1602: .ve

1604:    Notes:
1605:    Since the PETSc libraries incorporate timing of phases and operations, 
1606:    PetscGetTime() is intended only for timing of application codes.  
1607:    The options database commands -log, -log_summary, and -log_all activate
1608:    PETSc library timing.  See the users manual for further details.

1610:    Level: intermediate

1612: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(),  PetscLogStagePush(), 
1613:           PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()

1615: .keywords:  get, time
1616: @*/
1617: int PetscGetTime(PetscLogDouble *t)
1618: {
1620:   PetscTime(*t);
1621:   return(0);
1622: }

1624: /*@
1625:   PetscLogGetStageLog - This function returns the default stage logging object.

1627:   Not collective

1629:   Output Parameter:
1630: . stageLog - The default StageLog

1632:   Level: beginner

1634: .keywords: log, stage
1635: .seealso: StageLogCreate()
1636: @*/
1637: int PetscLogGetStageLog(StageLog *stageLog)
1638: {
1641:   *stageLog = _stageLog;
1642:   return(0);
1643: }

1645: /*MC
1646:    PetscLogFlops - Adds floating point operations to the global counter.

1648:    Input Parameter:
1649: .  f - flop counter

1651:    Synopsis:
1652:    void PetscLogFlops(int f)

1654:    Usage:
1655: .vb
1656:      int USER_EVENT;
1657:      PetscLogEventRegister(&USER_EVENT,"User event");
1658:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1659:         [code segment to monitor]
1660:         PetscLogFlops(user_flops)
1661:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1662: .ve

1664:    Notes:
1665:    A global counter logs all PETSc flop counts.  The user can use
1666:    PetscLogFlops() to increment this counter to include flops for the 
1667:    application code.  

1669:    PETSc automatically logs library events if the code has been
1670:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1671:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1672:    intended for logging user flops to supplement this PETSc
1673:    information.

1675:    Level: intermediate

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

1679: .keywords: log, flops, floating point operations
1680: M*/

1682: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1683: PetscTruth PetscPreLoadingOn   = PETSC_FALSE;

1685: /*MC
1686:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1687:     to get accurate timings

1689:    Input Parameter:
1690: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1691:            with command line option -preload true or -preload false
1692: -   name - name of first stage (lines of code timed seperately with -log_summary) to
1693:            be preloaded

1695:    Synopsis:
1696:    void PreLoadBegin(PetscTruth flag,char *name);

1698:    Usage:
1699: .vb
1700:      PreLoadBegin(PETSC_TRUE,"first stage);
1701:        lines of code
1702:        PreLoadStage("second stage");
1703:        lines of code
1704:      PreLoadEnd();
1705: .ve

1707:    Level: intermediate

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

1711:    Concepts: preloading
1712:    Concepts: timing^accurate
1713:    Concepts: paging^eliminating effects of


1716: M*/

1718: /*MC
1719:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1720:     to get accurate timings

1722:    Synopsis:
1723:    void PreLoadEnd(void);

1725:    Usage:
1726: .vb
1727:      PreLoadBegin(PETSC_TRUE,"first stage);
1728:        lines of code
1729:        PreLoadStage("second stage");
1730:        lines of code
1731:      PreLoadEnd();
1732: .ve

1734:    Level: intermediate

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

1738: M*/

1740: /*MC
1741:    PreLoadStage - Start a new segment of code to be timed seperately.
1742:     to get accurate timings

1744:    Synopsis:
1745:    void PreLoadStage(char *name);

1747:    Usage:
1748: .vb
1749:      PreLoadBegin(PETSC_TRUE,"first stage);
1750:        lines of code
1751:        PreLoadStage("second stage");
1752:        lines of code
1753:      PreLoadEnd();
1754: .ve

1756:    Level: intermediate

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

1760: M*/

1762: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1763: /*@C
1764:   StackDestroy - This function destroys a stack.

1766:   Not Collective

1768:   Input Parameter:
1769: . stack - The stack

1771:   Level: beginner

1773: .keywords: log, stack, destroy
1774: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1775: @*/
1776: int StackDestroy(IntStack stack)
1777: {

1781:   PetscFree(stack->stack);
1782:   PetscFree(stack);
1783:   return(0);
1784: }

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

1789:   Not Collective

1791:   Input Parameter:
1792: . stack - The stack

1794:   Output Parameter:
1795: . empty - PETSC_TRUE if the stack is empty

1797:   Level: intermediate

1799: .keywords: log, stack, empty
1800: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1801: @*/
1802: int StackEmpty(IntStack stack, PetscTruth *empty)
1803: {
1806:   if (stack->top == -1) {
1807:     *empty = PETSC_TRUE;
1808:   } else {
1809:     *empty = PETSC_FALSE;
1810:   }
1811:   return(0);
1812: }

1814: /*@C
1815:   StackTop - This function returns the top of the stack.

1817:   Not Collective

1819:   Input Parameter:
1820: . stack - The stack

1822:   Output Parameter:
1823: . top - The integer on top of the stack

1825:   Level: intermediate

1827: .keywords: log, stack, top
1828: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1829: @*/
1830: int StackTop(IntStack stack, int *top)
1831: {
1834:   *top = stack->stack[stack->top];
1835:   return(0);
1836: }

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

1841:   Not Collective

1843:   Input Parameters:
1844: + stack - The stack
1845: - item  - The integer to push

1847:   Level: intermediate

1849: .keywords: log, stack, push
1850: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1851: @*/
1852: int StackPush(IntStack stack, int item)
1853: {
1854:   int *array;
1855:   int  ierr;

1858:   stack->top++;
1859:   if (stack->top >= stack->max) {
1860:     PetscMalloc(stack->max*2 * sizeof(int), &array);
1861:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1862:     PetscFree(stack->stack);
1863:     stack->stack = array;
1864:     stack->max  *= 2;
1865:   }
1866:   stack->stack[stack->top] = item;
1867:   return(0);
1868: }

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

1873:   Not Collective

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

1878:   Output Parameter:
1879: . item  - The integer popped

1881:   Level: intermediate

1883: .keywords: log, stack, pop
1884: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
1885: @*/
1886: int StackPop(IntStack stack, int *item)
1887: {
1890:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
1891:   *item = stack->stack[stack->top--];
1892:   return(0);
1893: }

1895: /*@C
1896:   StackCreate - This function creates a stack.

1898:   Not Collective

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

1903:   Level: beginner

1905: .keywords: log, stack, pop
1906: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
1907: @*/
1908: int StackCreate(IntStack *stack)
1909: {
1910:   IntStack s;
1911:   int      ierr;

1915:   PetscNew(struct _IntStack, &s);
1916:   s->top = -1;
1917:   s->max = 128;
1918:   PetscMalloc(s->max * sizeof(int), &s->stack);
1919:   PetscMemzero(s->stack, s->max * sizeof(int));
1920:   *stack = s;
1921:   return(0);
1922: }