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: int     numActions = 0, maxActions = 100;
 35: int     numObjects = 0, maxObjects = 100;
 36: int     numObjectsDestroyed = 0;

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

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

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

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

 72:   Not Collective

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

 78:   Level: developer

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

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

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

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

111:   Not Collective

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

117:   Level: developer

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

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

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

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

165:   Collective over PETSC_COMM_WORLD

167:   Options Database Keys:
168: + -log_summary - Prints summary of flop and timing information to the 
169:                   screen (for code compiled with PETSC_USE_LOG)
170: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)

172:   Usage:
173: .vb
174:       PetscInitialize(...);
175:       PetscLogBegin();
176:        ... code ...
177:       PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump(); 
178:       PetscFinalize();
179: .ve

181:   Notes:
182:   PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of 
183:   the logging information.

185:   Level: advanced

187: .keywords: log, begin
188: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
189: @*/
190: int PetscLogBegin(void)
191: {

195:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
196:   PetscLogBegin_Private();
197:   return(0);
198: }

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

204:   Collective on PETSC_COMM_WORLD

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

209:   Usage:
210: .vb
211:      PetscInitialize(...);
212:      PetscLogAllBegin();
213:      ... code ...
214:      PetscLogDump(filename);
215:      PetscFinalize();
216: .ve

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

223:   Level: advanced

225: .keywords: log, all, begin
226: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
227: @*/
228: int PetscLogAllBegin(void)
229: {

233:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
234:   PetscLogBegin_Private();
235:   return(0);
236: }

238: /*@
239:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
240:   begins or ends, the event name is printed.

242:   Collective on PETSC_COMM_WORLD

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

247:   Options Database Key:
248: . -log_trace [filename] - Activates PetscLogTraceBegin()

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

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

258:   Level: intermediate

260: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
261: @*/
262: int PetscLogTraceBegin(FILE *file)
263: {

267:   tracefile = file;
268:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
269:   PetscLogBegin_Private();
270:   return(0);
271: }

273: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
274: /*@C
275:   PetscLogStageRegister - Attaches a charactor string name to a logging stage.

277:   Not Collective

279:   Input Parameter:
280: . sname - The name to associate with that stage

282:   Output Parameter:
283: . stage - The stage number

285:   Level: intermediate

287: .keywords: log, stage, register
288: .seealso: PetscLogStagePush(), PetscLogStagePop()
289: @*/
290: int PetscLogStageRegister(int *stage, const char sname[]) {
291:   StageLog stageLog;
292:   int      ierr;

295:   PetscLogGetStageLog(&stageLog);
296:   StageLogRegister(stageLog, sname, stage);
297:   EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
298:   ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
299:   return(0);
300: }

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

305:   Not Collective

307:   Input Parameter:
308: . stage - The stage on which to log

310:   Usage:
311:   If the option -log_sumary is used to run the program containing the 
312:   following code, then 2 sets of summary data will be printed during
313:   PetscFinalize().
314: .vb
315:       PetscInitialize(int *argc,char ***args,0,0);
316:       [stage 0 of code]   
317:       PetscLogStagePush(1);
318:       [stage 1 of code]
319:       PetscLogStagePop();
320:       PetscBarrier(...);
321:       [more stage 0 of code]   
322:       PetscFinalize();
323: .ve
324:  
325:   Notes:
326:   Use PetscLogStageRegister() to register a stage.

328:   Level: intermediate

330: .keywords: log, push, stage
331: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
332: @*/
333: int PetscLogStagePush(int stage)
334: {
335:   StageLog stageLog;
336:   int      ierr;

339:   PetscLogGetStageLog(&stageLog);
340:   StageLogPush(stageLog, stage);
341:   return(0);
342: }

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

347:   Not Collective

349:   Usage:
350:   If the option -log_sumary is used to run the program containing the 
351:   following code, then 2 sets of summary data will be printed during
352:   PetscFinalize().
353: .vb
354:       PetscInitialize(int *argc,char ***args,0,0);
355:       [stage 0 of code]   
356:       PetscLogStagePush(1);
357:       [stage 1 of code]
358:       PetscLogStagePop();
359:       PetscBarrier(...);
360:       [more stage 0 of code]   
361:       PetscFinalize();
362: .ve

364:   Notes:  
365:   Use PetscLogStageRegister() to register a stage.

367:   Level: intermediate

369: .keywords: log, pop, stage
370: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
371: @*/
372: int PetscLogStagePop(void)
373: {
374:   StageLog stageLog;
375:   int      ierr;

378:   PetscLogGetStageLog(&stageLog);
379:   StageLogPop(stageLog);
380:   return(0);
381: }

383: /*@C
384:   PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().

386:   Not Collective 

388:   Input Parameters:
389: + stage    - The stage
390: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

392:   Level: intermediate

394: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
395: @*/
396: int PetscLogStageSetActive(int stage, PetscTruth isActive) {
397:   StageLog stageLog;
398:   int      ierr;

401:   PetscLogGetStageLog(&stageLog);
402:   StageLogSetActive(stageLog, stage, isActive);
403:   return(0);
404: }

406: /*@C
407:   PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().

409:   Not Collective 

411:   Input Parameter:
412: . stage    - The stage

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

417:   Level: intermediate

419: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
420: @*/
421: int PetscLogStageGetActive(int stage, PetscTruth *isActive) {
422:   StageLog stageLog;
423:   int      ierr;

426:   PetscLogGetStageLog(&stageLog);
427:   StageLogGetActive(stageLog, stage, isActive);
428:   return(0);
429: }

431: /*@C
432:   PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()

434:   Not Collective 

436:   Input Parameters:
437: + stage     - The stage
438: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

440:   Level: intermediate

442: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
443: @*/
444: int PetscLogStageSetVisible(int stage, PetscTruth isVisible)
445: {
446:   StageLog stageLog;
447:   int      ierr;

450:   PetscLogGetStageLog(&stageLog);
451:   StageLogSetVisible(stageLog, stage, isVisible);
452:   return(0);
453: }

455: /*@C
456:   PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()

458:   Not Collective 

460:   Input Parameter:
461: . stage     - The stage

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

466:   Level: intermediate

468: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
469: @*/
470: int PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
471: {
472:   StageLog stageLog;
473:   int      ierr;

476:   PetscLogGetStageLog(&stageLog);
477:   StageLogGetVisible(stageLog, stage, isVisible);
478:   return(0);
479: }

481: /*@C
482:   PetscLogStageGetId - Returns the stage id when given the stage name.

484:   Not Collective 

486:   Input Parameter:
487: . name  - The stage name

489:   Output Parameter:
490: . stage - The stage

492:   Level: intermediate

494: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
495: @*/
496: int PetscLogStageGetId(const char name[], int *stage)
497: {
498:   StageLog stageLog;
499:   int      ierr;

502:   PetscLogGetStageLog(&stageLog);
503:   StageLogGetStage(stageLog, name, stage);
504:   return(0);
505: }

507: /*------------------------------------------------ Event Functions --------------------------------------------------*/
508: /*@C
509:   PetscLogEventRegister - Registers an event name for logging operations in an application code. 

511:   Not Collective

513:   Input Parameter:
514: + name   - The name associated with the event
515: - cookie - The cookie associated to the class for this event
516:             
517:   Output Parameter:
518: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

520:   Example of Usage:
521: .vb
522:       int USER_EVENT;
523:       int user_event_flops;
524:       PetscLogEventRegister(&USER_EVENT,"User event name");
525:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
526:          [code segment to monitor]
527:          PetscLogFlops(user_event_flops);
528:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
529: .ve

531:   Notes: 
532:   PETSc automatically logs library events if the code has been
533:   compiled with -DPETSC_USE_LOG (which is the default) and -log,
534:   -log_summary, or -log_all are specified.  PetscLogEventRegister() is
535:   intended for logging user events to supplement this PETSc
536:   information. 

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

545:   Level: intermediate

547: .keywords: log, event, register
548: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
549:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
550:           PetscLogEventActivate(), PetscLogEventDeactivate()
551: @*/
552: int PetscLogEventRegister(int *event, const char name[],int cookie) {
553:   StageLog stageLog;
554:   int      stage;
555:   int      ierr;

558:   *event = PETSC_DECIDE;
559:   PetscLogGetStageLog(&stageLog);
560:   EventRegLogRegister(stageLog->eventLog, name, cookie, event);
561:   for(stage = 0; stage < stageLog->numStages; stage++) {
562:     EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
563:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
564:   }
565:   return(0);
566: }

568: /*@
569:   PetscLogEventActivate - Indicates that a particular event should be logged.

571:   Not Collective

573:   Input Parameter:
574: . event - The event id

576:   Usage:
577: .vb
578:       PetscLogEventDeactivate(VEC_SetValues);
579:         [code where you do not want to log VecSetValues()]
580:       PetscLogEventActivate(VEC_SetValues);
581:         [code where you do want to log VecSetValues()]
582: .ve 

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

588:   Level: advanced

590: .keywords: log, event, activate
591: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
592: @*/
593: int PetscLogEventActivate(int event) {
594:   StageLog stageLog;
595:   int      stage;
596:   int      ierr;

599:   PetscLogGetStageLog(&stageLog);
600:   StageLogGetCurrent(stageLog, &stage);
601:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
602:   return(0);
603: }

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

608:   Not Collective

610:   Input Parameter:
611: . event - The event id

613:   Usage:
614: .vb
615:       PetscLogEventDeactivate(VEC_SetValues);
616:         [code where you do not want to log VecSetValues()]
617:       PetscLogEventActivate(VEC_SetValues);
618:         [code where you do want to log VecSetValues()]
619: .ve 

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

625:   Level: advanced

627: .keywords: log, event, deactivate
628: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
629: @*/
630: int PetscLogEventDeactivate(int event) {
631:   StageLog stageLog;
632:   int      stage;
633:   int      ierr;

636:   PetscLogGetStageLog(&stageLog);
637:   StageLogGetCurrent(stageLog, &stage);
638:   EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
639:   return(0);
640: }

642: /*@
643:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

645:   Not Collective

647:   Input Parameter:
648: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

650:   Level: developer

652: .keywords: log, event, activate, class
653: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
654: @*/
655: int PetscLogEventActivateClass(int cookie) {
656:   StageLog stageLog;
657:   int      stage;
658:   int      ierr;

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

667: /*@
668:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

670:   Not Collective

672:   Input Parameter:
673: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

675:   Level: developer

677: .keywords: log, event, deactivate, class
678: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
679: @*/
680: int PetscLogEventDeactivateClass(int cookie) {
681:   StageLog stageLog;
682:   int      stage;
683:   int      ierr;

686:   PetscLogGetStageLog(&stageLog);
687:   StageLogGetCurrent(stageLog, &stage);
688:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
689:   return(0);
690: }

692: /*MC
693:    PetscLogEventBegin - Logs the beginning of a user event. 

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

699:    Synopsis:
700:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
701:                        PetscObject o4)

703:    Usage:
704: .vb
705:      int USER_EVENT;
706:      int user_event_flops;
707:      PetscLogEventRegister(&USER_EVENT,"User event");
708:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
709:         [code segment to monitor]
710:         PetscLogFlops(user_event_flops);
711:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
712: .ve

714:    Notes:
715:    You should also register each integer event with the command 
716:    PetscLogEventRegister().  The source code must be compiled with 
717:    -DPETSC_USE_LOG, which is the default.

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

724:    Level: intermediate

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

728: .keywords: log, event, begin
729: M*/

731: /*MC
732:    PetscLogEventEnd - Log the end of a user event.

734:    Input Parameters:
735: +  e - integer associated with the event obtained with PetscLogEventRegister()
736: -  o1,o2,o3,o4 - objects associated with the event, or 0

738:    Synopsis:
739:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
740:                      PetscObject o4)

742:    Usage:
743: .vb
744:      int USER_EVENT;
745:      int user_event_flops;
746:      PetscLogEventRegister(&USER_EVENT,"User event");
747:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
748:         [code segment to monitor]
749:         PetscLogFlops(user_event_flops);
750:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
751: .ve

753:    Notes:
754:    You should also register each additional integer event with the command 
755:    PetscLogEventRegister(). Source code must be compiled with 
756:    -DPETSC_USE_LOG, which is the default.

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

763:    Level: intermediate

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

767: .keywords: log, event, end
768: M*/

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

773:    Input Parameters:
774: .  e - integer associated with the event obtained from PetscLogEventRegister()
775: .  o1,o2,o3,o4 - objects associated with the event, or 0
776: .  comm - communicator the barrier takes place over

778:    Synopsis:
779:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
780:                   PetscObject o4,MPI_Comm comm)

782:    Usage:
783: .vb
784:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
785:        MPI_Allreduce()
786:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
787: .ve

789:    Notes:
790:    This is for logging the amount of time spent in a barrier for an event
791:    that requires synchronization. 

793:    Additional Notes:
794:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
795:    VEC_NormComm = VEC_NormBarrier + 1

797:    Level: advanced

799: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
800:           PetscLogEventBarrierEnd()

802: .keywords: log, event, begin, barrier
803: M*/

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

808:    Input Parameters:
809: .  e - integer associated with the event obtained from PetscLogEventRegister()
810: .  o1,o2,o3,o4 - objects associated with the event, or 0
811: .  comm - communicator the barrier takes place over

813:    Synopsis:
814:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
815:                   PetscObject o4,MPI_Comm comm)

817:     Usage:
818: .vb
819:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
820:        MPI_Allreduce()
821:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
822: .ve

824:    Notes:
825:    This is for logging the amount of time spent in a barrier for an event
826:    that requires synchronization. 

828:    Additional Notes:
829:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
830:    VEC_NormComm = VEC_NormBarrier + 1

832:    Level: advanced

834: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
835:           PetscLogEventBarrierBegin()

837: .keywords: log, event, begin, barrier
838: M*/

840: /*------------------------------------------------ Class Functions --------------------------------------------------*/
841: /*@C
842:   PetscLogClassRegister - Registers a class name for logging operations in an application code. 

844:   Not Collective

846:   Input Parameter:
847: . name   - The class name
848:             
849:   Output Parameter:
850: . oclass - The class id or cookie

852:   Level: developer

854: .keywords: log, class, register
855: .seealso: ClassLogRegister()
856: @*/
857: int PetscLogClassRegister(int *oclass, const char name[])
858: {
859:   StageLog stageLog;
860:   int      ierr;

863:   *oclass = PETSC_DECIDE;
864:   PetscLogGetStageLog(&stageLog);
865:   ClassRegLogRegister(stageLog->classLog, name, oclass);
866:   return(0);
867: }

869: /*------------------------------------------------ Output Functions -------------------------------------------------*/
870: /*@C
871:   PetscLogDump - Dumps logs of objects to a file. This file is intended to 
872:   be read by petsc/bin/petscview.

874:   Collective on PETSC_COMM_WORLD

876:   Input Parameter:
877: . name - an optional file name

879:   Options Database Keys:
880: + -log     - Prints basic log information (for code compiled with PETSC_USE_LOG)
881: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
882:    
883:   Usage:
884: .vb
885:      PetscInitialize(...);
886:      PetscLogBegin(); or PetscLogAllBegin(); 
887:      ... code ...
888:      PetscLogDump(filename);
889:      PetscFinalize();
890: .ve

892:   Notes:
893:   The default file name is 
894: $    Log.<rank>
895:   where <rank> is the processor number. If no name is specified, 
896:   this file will be used.

898:   Level: advanced

900: .keywords: log, dump
901: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
902: @*/
903: int PetscLogDump(const char sname[]) {
904:   StageLog       stageLog;
905:   EventPerfInfo *eventInfo;
906:   FILE          *fd;
907:   char           file[64], fname[64];
908:   PetscLogDouble flops, _TotalTime;
909:   int            rank, curStage;
910:   int            action, object, event;
911:   int            ierr;
912: 
914:   /* Calculate the total elapsed time */
915:   PetscTime(_TotalTime);
916:   _TotalTime -= BaseTime;
917:   /* Open log file */
918:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
919:   if (sname != PETSC_NULL) {
920:     sprintf(file, "%s.%d", sname, rank);
921:   } else {
922:     sprintf(file, "Log.%d", rank);
923:   }
924:   PetscFixFilename(file, fname);
925:   PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
926:   if ((rank == 0) && (fd == PETSC_NULL)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
927:   /* Output totals */
928:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8en", _TotalFlops, _TotalTime);
929:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %gn", 0.0);
930:   /* Output actions */
931:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %dn", numActions);
932:   for(action = 0; action < numActions; action++) {
933:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %gn",
934:                         actions[action].time, actions[action].action, actions[action].event, actions[action].cookie, actions[action].id1,
935:                         actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
936:   }
937:   /* Output objects */
938:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %dn", numObjects, numObjectsDestroyed);
939:   for(object = 0; object < numObjects; object++) {
940:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %dn", objects[object].parent, (int) objects[object].mem);
941:     if (!objects[object].name[0]) {
942:       PetscFPrintf(PETSC_COMM_WORLD, fd,"No Namen");
943:     } else {
944:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %sn", objects[object].name);
945:     }
946:     if (objects[object].info[0] != 0) {
947:       PetscFPrintf(PETSC_COMM_WORLD, fd, "No Infon");
948:     } else {
949:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %sn", objects[object].info);
950:     }
951:   }
952:   /* Output events */
953:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:n");
954:   PetscLogGetStageLog(&stageLog);
955:   StackTop(stageLog->stack, &curStage);
956:   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
957:   for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
958:     if (eventInfo[event].time != 0.0) {
959:       flops = eventInfo[event].flops/eventInfo[event].time;
960:     } else {
961:       flops = 0.0;
962:     }
963:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16gn", event, eventInfo[event].count,
964:                         eventInfo[event].flops, eventInfo[event].time, flops);
965:   }
966:   PetscFClose(PETSC_COMM_WORLD, fd);
967:   return(0);
968: }

970: /*@C
971:   PetscLogPrintSummary - Prints a summary of the logging.

973:   Collective over MPI_Comm

975:   Input Parameter:
976: + comm - The MPI communicator (only one processor prints output)
977: - file - [Optional] The output file name

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

982:   Usage:
983: .vb
984:      PetscInitialize(...);
985:      PetscLogBegin();
986:      ... code ...
987:      PetscLogPrintSummary(MPI_Comm,filename);
988:      PetscFinalize(...);
989: .ve

991:   Notes:
992:   By default the summary is printed to stdout.
993:   More extensive examination of the log information can be done with 
994:   PetscLogDump(), which is activated by the option -log or -log_all, in 
995:   combination with petsc/bin/petscview.

997:   Level: beginner
998:    
999: .keywords: log, dump, print
1000: .seealso: PetscLogBegin(), PetscLogDump()
1001: @*/
1002: int PetscLogPrintSummary(MPI_Comm comm, const char filename[]) {
1003:   FILE          *fd   = stdout;
1004:   PetscScalar    zero = 0.0;
1005:   StageLog       stageLog;
1006:   StageInfo     *stageInfo = PETSC_NULL;
1007:   EventPerfInfo *eventInfo = PETSC_NULL;
1008:   ClassPerfInfo *classInfo;
1009:   char           arch[10], hostname[64], username[16], pname[256], date[64];
1010:   char           *name;
1011:   PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1012:   PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1013:   PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1014:   PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1015:   PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1016:   PetscLogDouble min, max, tot, ratio, avg, x, y;
1017:   PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1018:   int            minCt, maxCt;
1019:   int            numProcs, rank;
1020:   PetscTruth    *localStageUsed,    *stageUsed;
1021:   PetscTruth    *localStageVisible, *stageVisible;
1022:   int            numStages, localNumEvents, numEvents;
1023:   int            stage, event, oclass;
1024:   int            ierr;

1027:   MPI_Comm_size(comm, &numProcs);
1028:   MPI_Comm_rank(comm, &rank);
1029:   /* Pop off any stages the user forgot to remove */
1030:   PetscLogGetStageLog(&stageLog);
1031:   StageLogGetCurrent(stageLog, &stage);
1032:   while (stage >= 0) {
1033:     StageLogPop(stageLog);
1034:     StageLogGetCurrent(stageLog, &stage);
1035:   }
1036:   /* Get the total elapsed time */
1037:   PetscTime(locTotalTime);  locTotalTime -= BaseTime;
1038:   /* Open the summary file */
1039:   if (filename != PETSC_NULL) {
1040:     PetscFOpen(comm, filename, "w", &fd);
1041:   }

1043:   PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1044:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***n");
1045:   PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1046:   PetscFPrintf(comm, fd, "n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------nn");
1047:   PetscGetArchType(arch, 10);
1048:   PetscGetHostName(hostname, 64);
1049:   PetscGetUserName(username, 16);
1050:   PetscGetProgramName(pname, 256);
1051:   PetscGetDate(date, 64);
1052:   if (numProcs == 1) {
1053:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %sn", pname, arch, hostname, numProcs, username, date);
1054: 
1055:   } else {
1056:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %sn", pname, arch, hostname, numProcs, username, date);
1057: 
1058:   }
1059:   PetscFPrintf(comm, fd, "Using %sn", PETSC_VERSION_NUMBER);

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

1064:   /* Calculate summary information */
1065:   PetscFPrintf(comm, fd, "n                         Max       Max/Min        Avg      Total n");
1066:   /*   Time */
1067:   MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1068:   MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1069:   MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1070:   avg  = (tot)/((PetscLogDouble) numProcs);
1071:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1072:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %10.5f   %5.3en", max, ratio, avg);
1073:   TotalTime = tot;
1074:   /*   Objects */
1075:   avg  = (PetscLogDouble) numObjects;
1076:   MPI_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1077:   MPI_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1078:   MPI_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1079:   avg  = (tot)/((PetscLogDouble) numProcs);
1080:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1081:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %10.5f   %5.3en", max, ratio, avg);
1082:   /*   Flops */
1083:   MPI_Allreduce(&_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1084:   MPI_Allreduce(&_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1085:   MPI_Allreduce(&_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1086:   avg  = (tot)/((PetscLogDouble) numProcs);
1087:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1088:   PetscFPrintf(comm, fd, "Flops:                %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1089:   TotalFlops = tot;
1090:   /*   Flops/sec -- Must talk to Barry here */
1091:   if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1092:   MPI_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1093:   MPI_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1094:   MPI_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1095:   avg  = (tot)/((PetscLogDouble) numProcs);
1096:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1097:   PetscFPrintf(comm, fd, "Flops/sec:            %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1098:   /*   Memory */
1099:   PetscTrSpace(PETSC_NULL, PETSC_NULL, &mem);
1100:   if (mem > 0.0) {
1101:     MPI_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1102:     MPI_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1103:     MPI_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1104:     avg  = (tot)/((PetscLogDouble) numProcs);
1105:     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1106:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %10.5f              %5.3en", max, ratio, tot);
1107:   }
1108:   /*   Messages */
1109:   mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1110:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1111:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1112:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1113:   avg  = (tot)/((PetscLogDouble) numProcs);
1114:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1115:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1116:   numMessages = tot;
1117:   /*   Message Lengths */
1118:   mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1119:   MPI_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1120:   MPI_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1121:   MPI_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1122:   if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1123:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1124:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %10.5f   %5.3e  %5.3en", max, ratio, avg, tot);
1125:   messageLength = tot;
1126:   /*   Reductions */
1127:   MPI_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1128:   MPI_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1129:   MPI_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1130:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1131:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %10.5fn", max, ratio);
1132:   numReductions = tot;
1133:   PetscFPrintf(comm, fd, "nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)n");
1134:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flopsn");
1135:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flopsn");

1137:   /* Get total number of stages --
1138:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1139:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1140:        This seems best accomplished by assoicating a communicator with each stage.
1141:   */
1142:   MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1143:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1144:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1145:   PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1146:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1147:   if (numStages > 0) {
1148:     stageInfo = stageLog->stageInfo;
1149:     for(stage = 0; stage < numStages; stage++) {
1150:       if (stage < stageLog->numStages) {
1151:         localStageUsed[stage]    = stageInfo[stage].used;
1152:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1153:       } else {
1154:         localStageUsed[stage]    = PETSC_FALSE;
1155:         localStageVisible[stage] = PETSC_TRUE;
1156:       }
1157:     }
1158:     MPI_Allreduce(localStageUsed,    stageUsed,    numStages, MPI_INT, MPI_LOR,  comm);
1159:     MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1160:     for(stage = 0; stage < numStages; stage++) {
1161:       if (stageUsed[stage] == PETSC_TRUE) {
1162:         PetscFPrintf(comm, fd, "nSummary of Stages:   ----- Time ------  ----- Flops -----  --- Messages ---  -- Message Lengths --  -- Reductions --n");
1163:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total   counts   %%Total     Avg         %%Total   counts   %%Total n");
1164:         break;
1165:       }
1166:     }
1167:     for(stage = 0; stage < numStages; stage++) {
1168:       if (stageUsed[stage] == PETSC_FALSE) continue;
1169:       if (localStageUsed[stage] == PETSC_TRUE) {
1170:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1171:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1172:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1173:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1174:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1175:         name = stageInfo[stage].name;
1176:       } else {
1177:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1178:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1179:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1180:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1181:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1182:         name = "";
1183:       }
1184:       mess *= 0.5; messLen *= 0.5; red /= numProcs;
1185:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1186:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1187:       /* Talk to Barry if (stageTime     != 0.0) flops          = (numProcs*flops)/stageTime; else flops          = 0.0; */
1188:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1189:       if (numMessages   != 0.0) avgMessLen     = messLen/numMessages;    else avgMessLen     = 0.0;
1190:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1191:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1192:       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",
1193:                           stage, name, stageTime/numProcs, 100.0*fracTime, flops, 100.0*fracFlops,
1194:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1195: 
1196:     }
1197:   }

1199:   PetscFPrintf(comm, fd,
1200:     "n------------------------------------------------------------------------------------------------------------------------n");
1201: 
1202:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.n");
1203:   PetscFPrintf(comm, fd, "Phase summary info:n");
1204:   PetscFPrintf(comm, fd, "   Count: number of times phase was executedn");
1205:   PetscFPrintf(comm, fd, "   Time and Flops/sec: Max - maximum over all processorsn");
1206:   PetscFPrintf(comm, fd, "                       Ratio - ratio of maximum to minimum over all processorsn");
1207:   PetscFPrintf(comm, fd, "   Mess: number of messages sentn");
1208:   PetscFPrintf(comm, fd, "   Avg. len: average message lengthn");
1209:   PetscFPrintf(comm, fd, "   Reduct: number of global reductionsn");
1210:   PetscFPrintf(comm, fd, "   Global: entire computationn");
1211:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().n");
1212:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flops in this phasen");
1213:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phasen");
1214:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phasen");
1215:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)n");
1216:   PetscFPrintf(comm, fd,
1217:     "------------------------------------------------------------------------------------------------------------------------n");
1218: 

1220: #if defined(PETSC_USE_BOPT_g)
1221:   PetscFPrintf(comm, fd, "nn");
1222:   PetscFPrintf(comm, fd, "      ##########################################################n");
1223:   PetscFPrintf(comm, fd, "      #                                                        #n");
1224:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1225:   PetscFPrintf(comm, fd, "      #                                                        #n");
1226:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #n");
1227:   PetscFPrintf(comm, fd, "      #   BOPT=<g,g_c++,g_complex>.   To get timing results    #n");
1228:   PetscFPrintf(comm, fd, "      #   ALWAYS compile your code with an optimized version,  #n");
1229:   PetscFPrintf(comm, fd, "      #   BOPT=<O,O_c++,O_complex>;  the performance will      #n");
1230:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #n");
1231:   PetscFPrintf(comm, fd, "      #                                                        #n");
1232:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1233: #endif
1234: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1235:   PetscFPrintf(comm, fd, "nn");
1236:   PetscFPrintf(comm, fd, "      ##########################################################n");
1237:   PetscFPrintf(comm, fd, "      #                                                        #n");
1238:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #n");
1239:   PetscFPrintf(comm, fd, "      #                                                        #n");
1240:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #n");
1241:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #n");
1242:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #n");
1243:   PetscFPrintf(comm, fd, "      #   faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #n");
1244:   PetscFPrintf(comm, fd, "      #   in base_variables and recompile the PETSc libraries. #n");
1245:   PetscFPrintf(comm, fd, "      #                                                        #n");
1246:   PetscFPrintf(comm, fd, "      ##########################################################nnn");
1247: #endif

1249:   if (!PetscPreLoadingUsed) {
1250:     PetscFPrintf(comm,fd,"nn");
1251:     PetscFPrintf(comm,fd,"      ##########################################################n");
1252:     PetscFPrintf(comm,fd,"      #                                                        #n");
1253:     PetscFPrintf(comm,fd,"      #                          WARNING!!!                    #n");
1254:     PetscFPrintf(comm,fd,"      #                                                        #n");
1255:     PetscFPrintf(comm,fd,"      #   This code was run without the PreLoadinBegin()       #n");
1256:     PetscFPrintf(comm,fd,"      #   macros. To get timing results we always recommend    #n");
1257:     PetscFPrintf(comm,fd,"      #   preloading. otherwise timing numbers may be          #n");
1258:     PetscFPrintf(comm,fd,"      #   meaningless.                                         #n");
1259:     PetscFPrintf(comm,fd,"      ##########################################################nnn");
1260:   }

1262:   /* Report events */
1263:   PetscFPrintf(comm, fd,
1264:     "Event                Count      Time (sec)     Flops/sec                         --- Global ---  --- Stage ---   Totaln");
1265: 
1266:   PetscFPrintf(comm, fd,
1267:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/sn");
1268: 
1269:   PetscFPrintf(comm,fd,
1270:     "------------------------------------------------------------------------------------------------------------------------n");

1272: 
1273:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1274:   for(stage = 0; stage < numStages; stage++) {
1275:     if (stageVisible[stage] == PETSC_FALSE) continue;
1276:     if (localStageUsed[stage] == PETSC_TRUE) {
1277:       PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1278:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1279:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1280:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1281:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1282:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1283:     } else {
1284:       PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1285:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1286:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1287:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1288:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1289:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1290:     }
1291:     mess *= 0.5; messLen *= 0.5; red /= numProcs;

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

1298:        Problem: If the event did not happen on proc 1, its name will not be available.
1299:        Problem: Event visibility is not implemented
1300:     */
1301:     if (localStageUsed[stage] == PETSC_TRUE) {
1302:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1303:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1304:     } else {
1305:       localNumEvents = 0;
1306:     }
1307:     MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1308:     for(event = 0; event < numEvents; event++) {
1309:       if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1310:         if (eventInfo[event].count > 0) {
1311:           flopr = eventInfo[event].flops/eventInfo[event].time;
1312:         } else {
1313:           flopr = 0.0;
1314:         }
1315:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1316:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1317:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1318:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1319:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1320:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1321:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1322:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1323:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1324:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1325:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1326:         name = stageLog->eventLog->eventInfo[event].name;
1327:       } else {
1328:         flopr = 0.0;
1329:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1330:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1331:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1332:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1333:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1334:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1335:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1336:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1337:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1338:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1339:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1340:         name = "";
1341:       }
1342:       totm *= 0.5; totml *= 0.5; totr /= numProcs;
1343: 
1344:       if (maxCt != 0) {
1345:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1346:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1347:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1348:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1349:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1350:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1351:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1352:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1353:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1354:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1355:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1356:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1357:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1358:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1359:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1360:         PetscFPrintf(comm, fd,
1361:           "%-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",
1362:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1363:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1364:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1365:                             flopr/1.0e6);
1366: 
1367:       }
1368:     }
1369:   }

1371:   /* Memory usage and object creation */
1372:   PetscFPrintf(comm, fd,
1373:     "------------------------------------------------------------------------------------------------------------------------n");
1374: 
1375:   PetscFPrintf(comm, fd, "n");
1376:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:nn");

1378:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1379:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1380:      stats for stages local to processor sets.
1381:   */
1382:   /* We should figure out the longest object name here (now 20 characters) */
1383:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions   Memory  Descendants' Mem.n");
1384:   for(stage = 0; stage < numStages; stage++) {
1385:     if (localStageUsed[stage] == PETSC_TRUE) {
1386:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1387:       PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1388:       for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1389:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1390:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %9d     %gn", stageLog->classLog->classInfo[oclass].name,
1391:                               classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1392:                               classInfo[oclass].descMem);
1393: 
1394:         }
1395:       }
1396:     } else {
1397:       PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1398:     }
1399:   }

1401:   PetscFree(localStageUsed);
1402:   PetscFree(stageUsed);
1403:   PetscFree(localStageVisible);
1404:   PetscFree(stageVisible);

1406:   /* Information unrelated to this particular run */
1407:   PetscFPrintf(comm, fd,
1408:     "========================================================================================================================n");
1409: 
1410:   PetscTime(y);
1411:   PetscTime(x);
1412:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1413:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1414:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %gn", (y-x)/10.0);
1415:   /* MPI information */
1416:   if (numProcs > 1) {
1417:     MPI_Status status;
1418:     int        tag;

1420:     MPI_Barrier(comm);
1421:     PetscTime(x);
1422:     MPI_Barrier(comm);
1423:     MPI_Barrier(comm);
1424:     MPI_Barrier(comm);
1425:     MPI_Barrier(comm);
1426:     MPI_Barrier(comm);
1427:     PetscTime(y);
1428:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %gn", (y-x)/5.0);
1429:     PetscCommGetNewTag(comm, &tag);
1430:     MPI_Barrier(comm);
1431:     if (rank) {
1432:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, comm, &status);
1433:       MPI_Send(0, 0, MPI_INT, (rank+1)%numProcs, tag, comm);
1434:     } else {
1435:       PetscTime(x);
1436:       MPI_Send(0, 0, MPI_INT, 1,          tag, comm);
1437:       MPI_Recv(0, 0, MPI_INT, numProcs-1, tag, comm, &status);
1438:       PetscTime(y);
1439:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %gn", (y-x)/numProcs);
1440:     }
1441:   }
1442:   /* Machine and compile information */
1443: #if defined(PETSC_USE_FORTRAN_KERNELS)
1444:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1445: #else
1446:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1447: #endif
1448: #if defined(PETSC_USE_MAT_SINGLE)
1449:   PetscFPrintf(comm, fd, "Compiled with single precision matricesn");
1450: #else
1451:   PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)n");
1452: #endif
1453:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void *) %d",
1454:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1455: 

1457:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1458:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1459:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1460:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1462:   /* Cleanup */
1463:   PetscFPrintf(comm, fd, "n");
1464:   PetscFClose(comm, fd);
1465:   return(0);
1466: }

1468: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1469: /*@C
1470:    PetscGetFlops - Returns the number of flops used on this processor 
1471:    since the program began. 

1473:    Not Collective

1475:    Output Parameter:
1476:    flops - number of floating point operations 

1478:    Notes:
1479:    A global counter logs all PETSc flop counts.  The user can use
1480:    PetscLogFlops() to increment this counter to include flops for the 
1481:    application code.  

1483:    PETSc automatically logs library events if the code has been
1484:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1485:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1486:    intended for logging user flops to supplement this PETSc
1487:    information.

1489:    Level: intermediate

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

1493: .seealso: PetscGetTime(), PetscLogFlops()
1494: @*/
1495: int PetscGetFlops(PetscLogDouble *flops)
1496: {
1498:   *flops = _TotalFlops;
1499:   return(0);
1500: }

1502: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1503: {
1504:   va_list Argp;

1507:   if (!objects) return(0);
1508:   va_start(Argp, format);
1509: #if defined(PETSC_HAVE_VPRINTF_CHAR)
1510:   vsprintf(objects[obj->id].info, format, (char *) Argp);
1511: #else
1512:   vsprintf(objects[obj->id].info, format, Argp);
1513: #endif
1514:   va_end(Argp);
1515:   return(0);
1516: }

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

1520: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1521: {
1523:   return(0);
1524: }

1526: #endif /* PETSC_USE_LOG*/

1528: /*@
1529:    PetscGetTime - Returns the current time of day in seconds. This 
1530:    returns wall-clock time.  

1532:    Not Collective

1534:    Output Parameter:
1535: .  v - time counter

1537:    Usage: 
1538: .vb
1539:       PetscLogDouble v1,v2,elapsed_time;
1540:       PetscGetTime(&v1);CHKERR(ierr);
1541:       .... perform some calculation ...
1542:       PetscGetTime(&v2);CHKERR(ierr);
1543:       elapsed_time = v2 - v1;   
1544: .ve

1546:    Notes:
1547:    Since the PETSc libraries incorporate timing of phases and operations, 
1548:    PetscGetTime() is intended only for timing of application codes.  
1549:    The options database commands -log, -log_summary, and -log_all activate
1550:    PETSc library timing.  See the users manual for further details.

1552:    Level: intermediate

1554: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(),  PetscLogStagePush(), 
1555:           PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()

1557: .keywords:  get, time
1558: @*/
1559: int PetscGetTime(PetscLogDouble *t)
1560: {
1562:   PetscTime(*t);
1563:   return(0);
1564: }

1566: /*
1567:   PetscLogGetStageLog - This function returns the default stage logging object.

1569:   Not collective

1571:   Output Parameter:
1572: . stageLog - The default StageLog

1574:   Level: beginner

1576: .keywords: log, stage
1577: .seealso: StageLogCreate()
1578: */
1579: int PetscLogGetStageLog(StageLog *stageLog)
1580: {
1583:   *stageLog = _stageLog;
1584:   return(0);
1585: }

1587: /*MC
1588:    PetscLogFlops - Adds floating point operations to the global counter.

1590:    Input Parameter:
1591: .  f - flop counter

1593:    Synopsis:
1594:    void PetscLogFlops(int f)

1596:    Usage:
1597: .vb
1598:      int USER_EVENT;
1599:      PetscLogEventRegister(&USER_EVENT,"User event");
1600:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1601:         [code segment to monitor]
1602:         PetscLogFlops(user_flops)
1603:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1604: .ve

1606:    Notes:
1607:    A global counter logs all PETSc flop counts.  The user can use
1608:    PetscLogFlops() to increment this counter to include flops for the 
1609:    application code.  

1611:    PETSc automatically logs library events if the code has been
1612:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1613:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1614:    intended for logging user flops to supplement this PETSc
1615:    information.

1617:    Level: intermediate

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

1621: .keywords: log, flops, floating point operations
1622: M*/

1624: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1625: PetscTruth PetscPreLoadingOn   = PETSC_FALSE;

1627: /*MC
1628:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1629:     to get accurate timings

1631:    Input Parameter:
1632: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1633:            with command line option -preload true or -preload false
1634: -   name - name of first stage (lines of code timed seperately with -log_summary) to
1635:            be preloaded

1637:    Synopsis:
1638:    void PreLoadBegin(PetscTruth flag,char *name);

1640:    Usage:
1641: .vb
1642:      PreLoadBegin(PETSC_TRUE,"first stage);
1643:        lines of code
1644:        PreLoadStage("second stage");
1645:        lines of code
1646:      PreLoadEnd();
1647: .ve

1649:    Level: intermediate

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

1653:    Concepts: preloading
1654:    Concepts: timing^accurate
1655:    Concepts: paging^eliminating effects of


1658: M*/

1660: /*MC
1661:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1662:     to get accurate timings

1664:    Synopsis:
1665:    void PreLoadEnd(void);

1667:    Usage:
1668: .vb
1669:      PreLoadBegin(PETSC_TRUE,"first stage);
1670:        lines of code
1671:        PreLoadStage("second stage");
1672:        lines of code
1673:      PreLoadEnd();
1674: .ve

1676:    Level: intermediate

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

1680: M*/

1682: /*MC
1683:    PreLoadStage - Start a new segment of code to be timed seperately.
1684:     to get accurate timings

1686:    Synopsis:
1687:    void PreLoadStage(char *name);

1689:    Usage:
1690: .vb
1691:      PreLoadBegin(PETSC_TRUE,"first stage);
1692:        lines of code
1693:        PreLoadStage("second stage");
1694:        lines of code
1695:      PreLoadEnd();
1696: .ve

1698:    Level: intermediate

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

1702: M*/

1704: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1705: /*@C
1706:   StackDestroy - This function destroys a stack.

1708:   Not Collective

1710:   Input Parameter:
1711: . stack - The stack

1713:   Level: beginner

1715: .keywords: log, stack, destroy
1716: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1717: @*/
1718: int StackDestroy(IntStack stack)
1719: {

1723:   PetscFree(stack->stack);
1724:   PetscFree(stack);
1725:   return(0);
1726: }

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

1731:   Not Collective

1733:   Input Parameter:
1734: . stack - The stack

1736:   Output Parameter:
1737: . empty - PETSC_TRUE if the stack is empty

1739:   Level: intermediate

1741: .keywords: log, stack, empty
1742: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1743: @*/
1744: int StackEmpty(IntStack stack, PetscTruth *empty)
1745: {
1748:   if (stack->top == -1) {
1749:     *empty = PETSC_TRUE;
1750:   } else {
1751:     *empty = PETSC_FALSE;
1752:   }
1753:   return(0);
1754: }

1756: /*@C
1757:   StackTop - This function returns the top of the stack.

1759:   Not Collective

1761:   Input Parameter:
1762: . stack - The stack

1764:   Output Parameter:
1765: . top - The integer on top of the stack

1767:   Level: intermediate

1769: .keywords: log, stack, top
1770: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1771: @*/
1772: int StackTop(IntStack stack, int *top)
1773: {
1776:   *top = stack->stack[stack->top];
1777:   return(0);
1778: }

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

1783:   Not Collective

1785:   Input Parameters:
1786: + stack - The stack
1787: - item  - The integer to push

1789:   Level: intermediate

1791: .keywords: log, stack, push
1792: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1793: @*/
1794: int StackPush(IntStack stack, int item)
1795: {
1796:   int *array;
1797:   int  ierr;

1800:   stack->top++;
1801:   if (stack->top >= stack->max) {
1802:     PetscMalloc(stack->max*2 * sizeof(int), &array);
1803:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1804:     PetscFree(stack->stack);
1805:     stack->stack = array;
1806:     stack->max  *= 2;
1807:   }
1808:   stack->stack[stack->top] = item;
1809:   return(0);
1810: }

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

1815:   Not Collective

1817:   Input Parameter:
1818: . stack - The stack

1820:   Output Parameter:
1821: . item  - The integer popped

1823:   Level: intermediate

1825: .keywords: log, stack, pop
1826: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
1827: @*/
1828: int StackPop(IntStack stack, int *item)
1829: {
1832:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
1833:   *item = stack->stack[stack->top--];
1834:   return(0);
1835: }

1837: /*@C
1838:   StackCreate - This function creates a stack.

1840:   Not Collective

1842:   Output Parameter:
1843: . stack - The stack

1845:   Level: beginner

1847: .keywords: log, stack, pop
1848: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
1849: @*/
1850: int StackCreate(IntStack *stack)
1851: {
1852:   IntStack s;
1853:   int      ierr;

1857:   PetscNew(struct _IntStack, &s);
1858:   s->top = -1;
1859:   s->max = 128;
1860:   PetscMalloc(s->max * sizeof(int), &s->stack);
1861:   PetscMemzero(s->stack, s->max * sizeof(int));
1862:   *stack = s;
1863:   return(0);
1864: }