Actual source code: plog.c

  1: #define PETSC_DLL
  2: /*
  3:       PETSc code to log object creation and destruction and PETSc events.
  4: */
 5:  #include petsc.h
 6:  #include petsctime.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)
 17: #include <malloc.h>
 18: #endif
 19: #include "petscfix.h"
 20:  #include plog.h

 22: PetscLogEvent  PETSC_LARGEST_EVENT  = PETSC_EVENT;

 24: #if defined(PETSC_USE_LOG)
 25: #include "petscmachineinfo.h"
 26: #include "petscconfiginfo.h"

 28: /* used in the MPI_XXX() count macros in petsclog.h */

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

 39: /* Global counters */
 40: PetscLogDouble  BaseTime        = 0.0;
 41: PetscLogDouble  _TotalFlops     = 0.0; /* The number of flops */
 42: PetscLogDouble  petsc_tmp_flops = 0.0; /* The incremental 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 */
 56: PetscLogDouble  gather_ct       = 0.0; /* The number of gathers and gathervs */
 57: PetscLogDouble  scatter_ct      = 0.0; /* The number of scatters and scattervs */

 59: /* Logging functions */
 60: PetscErrorCode  (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
 61: PetscErrorCode  (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
 62: PetscErrorCode  (*_PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
 63: PetscErrorCode  (*_PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;

 65: /* Tracing event logging variables */
 66: FILE          *tracefile       = PETSC_NULL;
 67: int            tracelevel      = 0;
 68: const char    *traceblanks     = "                                                                                                    ";
 69: char           tracespace[128] = " ";
 70: PetscLogDouble tracetime       = 0.0;
 71: PetscTruth PetscLogBegin_PrivateCalled = PETSC_FALSE;

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

 79:   Not Collective

 81:   Notes:
 82:   This routine should not usually be used by programmers. Instead employ 
 83:   PetscLogStagePush() and PetscLogStagePop().

 85:   Level: developer

 87: .keywords: log, destroy
 88: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
 89: @*/
 90: PetscErrorCode  PetscLogDestroy(void)
 91: {
 92:   StageLog       stageLog;

 96:   PetscFree(actions);
 97:   actions = PETSC_NULL;
 98:   PetscFree(objects);
 99:   objects =  PETSC_NULL;
100:   PetscLogSet(PETSC_NULL, PETSC_NULL);

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

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

117:   Not Collective

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

123:   Level: developer

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

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

146:   if (PetscLogBegin_PrivateCalled) return(0);
147:   PetscLogBegin_PrivateCalled = PETSC_TRUE;

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

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

182:   Collective over PETSC_COMM_WORLD

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

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

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

202:   Level: advanced

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

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

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

223:   Collective on PETSC_COMM_WORLD

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

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

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

242:   Level: advanced

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

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

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

263:   Collective on PETSC_COMM_WORLD

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

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

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

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

279:   Level: intermediate

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

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

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

299:   Not Collective

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

304:   Level: intermediate

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

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

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

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

327:   Not Collective

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

332:   Level: intermediate

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

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

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

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

356:   Not Collective

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

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

364:   Level: intermediate

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

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

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

393:   Not Collective

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

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

416:   Level: intermediate

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

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

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

437:   Not Collective

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

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

457:   Level: intermediate

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

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

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

478:   Not Collective 

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

484:   Level: intermediate

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

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

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

504:   Not Collective 

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

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

512:   Level: intermediate

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

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

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

532:   Not Collective 

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

538:   Level: intermediate

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

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

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

558:   Not Collective 

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

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

566:   Level: intermediate

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

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

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

586:   Not Collective 

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

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

594:   Level: intermediate

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

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

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

615:   Not Collective

617:   Input Parameter:
618: + name   - The name associated with the event
619: - cookie - The cookie associated to the class for this event, obtain either with
620:            PetscCookieRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
621:             
622:   Output Parameter:
623: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

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

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

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

652:   The cookie is associated with each event so that classes of events
653:   can be disabled simultaneously, such as all matrix events. The user
654:   can either use an existing cookie, such as MAT_COOKIE, or create
655:   their own as shown in the example.

657:   Level: intermediate

659: .keywords: log, event, register
660: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
661:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
662:           PetscLogEventActivate(), PetscLogEventDeactivate(), PetscCookieRegister()
663: @*/
664: PetscErrorCode  PetscLogEventRegister(const char name[],PetscCookie cookie,PetscLogEvent *event)
665: {
666:   StageLog       stageLog;
667:   int            stage;

671:   *event = PETSC_DECIDE;
672:   PetscLogGetStageLog(&stageLog);
673:   EventRegLogRegister(stageLog->eventLog, name, cookie, event);
674:   for(stage = 0; stage < stageLog->numStages; stage++) {
675:     EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
676:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
677:   }
678:   return(0);
679: }

683: /*@
684:   PetscLogEventActivate - Indicates that a particular event should be logged.

686:   Not Collective

688:   Input Parameter:
689: . event - The event id

691:   Usage:
692: .vb
693:       PetscLogEventDeactivate(VEC_SetValues);
694:         [code where you do not want to log VecSetValues()]
695:       PetscLogEventActivate(VEC_SetValues);
696:         [code where you do want to log VecSetValues()]
697: .ve 

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

703:   Level: advanced

705: .keywords: log, event, activate
706: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
707: @*/
708: PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
709: {
710:   StageLog       stageLog;
711:   int            stage;

715:   PetscLogGetStageLog(&stageLog);
716:   StageLogGetCurrent(stageLog, &stage);
717:   EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
718:   return(0);
719: }

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

726:   Not Collective

728:   Input Parameter:
729: . event - The event id

731:   Usage:
732: .vb
733:       PetscLogEventDeactivate(VEC_SetValues);
734:         [code where you do not want to log VecSetValues()]
735:       PetscLogEventActivate(VEC_SetValues);
736:         [code where you do want to log VecSetValues()]
737: .ve 

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

743:   Level: advanced

745: .keywords: log, event, deactivate
746: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
747: @*/
748: PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
749: {
750:   StageLog       stageLog;
751:   int            stage;

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

763: /*@
764:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

766:   Not Collective

768:   Input Parameters:
769: + event    - The event id
770: - isActive - The activity flag determining whether the event is logged

772:   Level: advanced

774: .keywords: log, event, activate
775: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
776: @*/
777: PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscTruth isActive)
778: {
779:   StageLog       stageLog;
780:   int            stage;

784:   PetscLogGetStageLog(&stageLog);
785:   for(stage = 0; stage < stageLog->numStages; stage++) {
786:     if (isActive) {
787:       EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
788:     } else {
789:       EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
790:     }
791:   }
792:   return(0);
793: }

797: /*@
798:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

800:   Not Collective

802:   Input Parameter:
803: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

805:   Level: developer

807: .keywords: log, event, activate, class
808: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
809: @*/
810: PetscErrorCode  PetscLogEventActivateClass(PetscCookie cookie)
811: {
812:   StageLog       stageLog;
813:   int            stage;

817:   PetscLogGetStageLog(&stageLog);
818:   StageLogGetCurrent(stageLog, &stage);
819:   EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
820:   return(0);
821: }

825: /*@
826:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

828:   Not Collective

830:   Input Parameter:
831: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.

833:   Level: developer

835: .keywords: log, event, deactivate, class
836: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
837: @*/
838: PetscErrorCode  PetscLogEventDeactivateClass(PetscCookie cookie)
839: {
840:   StageLog       stageLog;
841:   int            stage;

845:   PetscLogGetStageLog(&stageLog);
846:   StageLogGetCurrent(stageLog, &stage);
847:   EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
848:   return(0);
849: }

851: /*MC
852:    PetscLogEventBegin - Logs the beginning of a user event. 

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

858:    Synopsis:
859:    void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
860:                        PetscObject o4)

862:    Fortran Synopsis:
863:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

865:    Usage:
866: .vb
867:      int USER_EVENT;
868:      int user_event_flops;
869:      PetscLogEventRegister("User event",0,&USER_EVENT);
870:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
871:         [code segment to monitor]
872:         PetscLogFlops(user_event_flops);
873:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
874: .ve

876:    Notes:
877:    You need to register each integer event with the command 
878:    PetscLogEventRegister().  The source code must be compiled with 
879:    -DPETSC_USE_LOG, which is the default.

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

886:    Level: intermediate

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

890: .keywords: log, event, begin
891: M*/

893: /*MC
894:    PetscLogEventEnd - Log the end of a user event.

896:    Input Parameters:
897: +  e - integer associated with the event obtained with PetscLogEventRegister()
898: -  o1,o2,o3,o4 - objects associated with the event, or 0

900:    Synopsis:
901:    void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
902:                      PetscObject o4)

904:    Fortran Synopsis:
905:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

907:    Usage:
908: .vb
909:      int USER_EVENT;
910:      int user_event_flops;
911:      PetscLogEventRegister("User event",0,&USER_EVENT,);
912:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
913:         [code segment to monitor]
914:         PetscLogFlops(user_event_flops);
915:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
916: .ve

918:    Notes:
919:    You should also register each additional integer event with the command 
920:    PetscLogEventRegister(). Source code must be compiled with 
921:    -DPETSC_USE_LOG, which is the default.

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

928:    Level: intermediate

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

932: .keywords: log, event, end
933: M*/

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

938:    Input Parameters:
939: .  e - integer associated with the event obtained from PetscLogEventRegister()
940: .  o1,o2,o3,o4 - objects associated with the event, or 0
941: .  comm - communicator the barrier takes place over

943:    Synopsis:
944:    void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
945:                   PetscObject o4,MPI_Comm comm)

947:    Usage:
948: .vb
949:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
950:        MPI_Allreduce()
951:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
952: .ve

954:    Notes:
955:    This is for logging the amount of time spent in a barrier for an event
956:    that requires synchronization. 

958:    Additional Notes:
959:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
960:    VEC_NormComm = VEC_NormBarrier + 1

962:    Level: advanced

964: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
965:           PetscLogEventBarrierEnd()

967: .keywords: log, event, begin, barrier
968: M*/

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

973:    Input Parameters:
974: .  e - integer associated with the event obtained from PetscLogEventRegister()
975: .  o1,o2,o3,o4 - objects associated with the event, or 0
976: .  comm - communicator the barrier takes place over

978:    Synopsis:
979:    void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
980:                   PetscObject o4,MPI_Comm comm)

982:     Usage:
983: .vb
984:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
985:        MPI_Allreduce()
986:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
987: .ve

989:    Notes:
990:    This is for logging the amount of time spent in a barrier for an event
991:    that requires synchronization. 

993:    Additional Notes:
994:    Synchronization events always come in pairs; for example, VEC_NormBarrier and 
995:    VEC_NormComm = VEC_NormBarrier + 1

997:    Level: advanced

999: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1000:           PetscLogEventBarrierBegin()

1002: .keywords: log, event, begin, barrier
1003: M*/

1007: /*@C
1008:   PetscLogEventGetId - Returns the event id when given the event name.

1010:   Not Collective 

1012:   Input Parameter:
1013: . name  - The event name

1015:   Output Parameter:
1016: . event - The event

1018:   Level: intermediate

1020: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1021: @*/
1022: PetscErrorCode  PetscLogEventGetId(const char name[], PetscLogEvent *event)
1023: {
1024:   StageLog       stageLog;

1028:   PetscLogGetStageLog(&stageLog);
1029:   EventRegLogGetEvent(stageLog->eventLog, name, event);
1030:   return(0);
1031: }


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

1041:   Collective on PETSC_COMM_WORLD

1043:   Input Parameter:
1044: . name - an optional file name

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

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

1065:   Level: advanced

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

1145: /*@C
1146:   PetscLogPrintSummary - Prints a summary of the logging.

1148:   Collective over MPI_Comm

1150:   Input Parameter:
1151: + comm - The MPI communicator (only one processor prints output)
1152: - file - [Optional] The output file name

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

1157:   Usage:
1158: .vb
1159:      PetscInitialize(...);
1160:      PetscLogBegin();
1161:      ... code ...
1162:      PetscLogPrintSummary(MPI_Comm,filename);
1163:      PetscFinalize(...);
1164: .ve

1166:   Notes:
1167:   By default the summary is printed to stdout.

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

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

1220:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1221:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1222:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1223:   PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1224:   PetscGetArchType(arch, 10);
1225:   PetscGetHostName(hostname, 64);
1226:   PetscGetUserName(username, 16);
1227:   PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1228:   PetscGetDate(date, 64);
1229:   PetscGetVersion(version,256);
1230:   if (size == 1) {
1231:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1232:   } else {
1233:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1234:   }
1235:   PetscFPrintf(comm, fd, "Using %s\n", version);

1237:   /* Must preserve reduction count before we go on */
1238:   red  = allreduce_ct + gather_ct + scatter_ct;

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

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

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

1395: #if defined(PETSC_USE_DEBUG)
1396:   PetscFPrintf(comm, fd, "\n\n");
1397:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1398:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1399:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1400:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1401:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #\n");
1402:   PetscFPrintf(comm, fd, "      #   To get timing results run config/configure.py        #\n");
1403:   PetscFPrintf(comm, fd, "      #   using --with-debugging=no, the performance will      #\n");
1404:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");
1405:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1406:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1407: #endif
1408: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1409:   PetscFPrintf(comm, fd, "\n\n");
1410:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1411:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1412:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1413:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1414:   PetscFPrintf(comm, fd, "      #   The code for various complex numbers numerical       #\n");
1415:   PetscFPrintf(comm, fd, "      #   kernels uses C++, which generally is not well        #\n");
1416:   PetscFPrintf(comm, fd, "      #   optimized.  For performance that is about 4-5 times  #\n");
1417:   PetscFPrintf(comm, fd, "      #   faster, specify --with-fortran-kernels=generic       #\n");
1418:   PetscFPrintf(comm, fd, "      #   when running config/configure.py.                    #\n");
1419:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1420:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1421: #endif

1423:   /* Report events */
1424:   PetscFPrintf(comm, fd,
1425:     "Event                Count      Time (sec)     Flops                             --- Global ---  --- Stage ---   Total\n");
1426: 
1427:   PetscFPrintf(comm, fd,
1428:     "                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s\n");
1429: 
1430:   PetscFPrintf(comm,fd,
1431:     "------------------------------------------------------------------------------------------------------------------------\n");

1433: 
1434:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1435:   for(stage = 0; stage < numStages; stage++) {
1436:     if (!stageVisible[stage]) continue;
1437:     if (localStageUsed[stage]) {
1438:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1439:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1440:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1441:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1442:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1443:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1444:     } else {
1445:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1446:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1447:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1448:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1449:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1450:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1451:     }
1452:     mess *= 0.5; messLen *= 0.5; red /= size;

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

1459:        Problem: If the event did not happen on proc 1, its name will not be available.
1460:        Problem: Event visibility is not implemented
1461:     */
1462:     if (localStageUsed[stage]) {
1463:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1464:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1465:     } else {
1466:       localNumEvents = 0;
1467:     }
1468:     MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1469:     for(event = 0; event < numEvents; event++) {
1470:       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1471:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1472:           flopr = eventInfo[event].flops;
1473:         } else {
1474:           flopr = 0.0;
1475:         }
1476:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1477:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1478:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1479:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1480:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1481:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1482:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1483:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1484:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1485:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1486:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1487:         name = stageLog->eventLog->eventInfo[event].name;
1488:       } else {
1489:         flopr = 0.0;
1490:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1491:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1492:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1493:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1494:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1495:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1496:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1497:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1498:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1499:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1500:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1501:         name = "";
1502:       }
1503:       if (mint < 0.0) {
1504:         PetscFPrintf(comm, fd, "WARNING!!! Minimum time %g over all processors for %s is negative! This happens\n on some machines whose times cannot handle too rapid calls.!\n artificially changing minimum to zero.\n",mint,name);
1505:         mint = 0;
1506:       }
1507:       if (minf < 0.0) SETERRQ2(PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1508:       totm *= 0.5; totml *= 0.5; totr /= size;
1509: 
1510:       if (maxCt != 0) {
1511:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1512:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1513:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1514:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1515:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1516:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1517:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1518:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1519:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1520:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1521:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1522:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1523:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1524:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1525:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1526:         PetscFPrintf(comm, fd,
1527:           "%-16s %7d%4.1f %5.4e%4.1f %3.2e%4.1f %2.1e %2.1e %2.1e%3.0f%3.0f%3.0f%3.0f%3.0f %3.0f%3.0f%3.0f%3.0f%3.0f %5.0f\n",
1528:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1529:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1530:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1531:                             flopr/1.0e6);
1532:       }
1533:     }
1534:   }

1536:   /* Memory usage and object creation */
1537:   PetscFPrintf(comm, fd,
1538:     "------------------------------------------------------------------------------------------------------------------------\n");
1539:   PetscFPrintf(comm, fd, "\n");
1540:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

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

1564:   PetscFree(localStageUsed);
1565:   PetscFree(stageUsed);
1566:   PetscFree(localStageVisible);
1567:   PetscFree(stageVisible);

1569:   /* Information unrelated to this particular run */
1570:   PetscFPrintf(comm, fd,
1571:     "========================================================================================================================\n");
1572:   PetscTime(y);
1573:   PetscTime(x);
1574:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1575:   PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1576:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1577:   /* MPI information */
1578:   if (size > 1) {
1579:     MPI_Status  status;
1580:     PetscMPIInt tag;
1581:     MPI_Comm    newcomm;

1583:     MPI_Barrier(comm);
1584:     PetscTime(x);
1585:     MPI_Barrier(comm);
1586:     MPI_Barrier(comm);
1587:     MPI_Barrier(comm);
1588:     MPI_Barrier(comm);
1589:     MPI_Barrier(comm);
1590:     PetscTime(y);
1591:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1592:     PetscCommDuplicate(comm,&newcomm, &tag);
1593:     MPI_Barrier(comm);
1594:     if (rank) {
1595:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, newcomm, &status);
1596:       MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1597:     } else {
1598:       PetscTime(x);
1599:       MPI_Send(0, 0, MPI_INT, 1,          tag, newcomm);
1600:       MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1601:       PetscTime(y);
1602:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1603:     }
1604:     PetscCommDestroy(&newcomm);
1605:   }
1606:   if (!rank) {
1607:     PetscOptionsPrint(fd);
1608:   }
1609:   /* Machine and compile information */
1610: #if defined(PETSC_USE_FORTRAN_KERNELS)
1611:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1612: #else
1613:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1614: #endif
1615: #if defined(PETSC_USE_SINGLE)
1616:   PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1617: #elif defined(PETSC_USE_LONGDOUBLE)
1618:   PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1619: #elif defined(PETSC_USE_INT)
1620:   PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1621: #endif

1623: #if defined(PETSC_USE_MAT_SINGLE)
1624:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1625: #else
1626:   PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1627: #endif
1628:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1629:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));

1631:   PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1632:   PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1633:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1634:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1635:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1636:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1638:   /* Cleanup */
1639:   PetscFPrintf(comm, fd, "\n");
1640:   PetscFClose(comm, fd);
1641:   StageLogPush(stageLog, lastStage);
1642:   return(0);
1643: }

1647: /*@C
1648:   PetscLogPrintDetailed - Each process prints the times for its own events

1650:   Collective over MPI_Comm

1652:   Input Parameter:
1653: + comm - The MPI communicator (only one processor prints output)
1654: - file - [Optional] The output file name

1656:   Options Database Keys:
1657: . -log_summary_detailed - Prints summary of log information (for code compiled with PETSC_USE_LOG)

1659:   Usage:
1660: .vb
1661:      PetscInitialize(...);
1662:      PetscLogBegin();
1663:      ... code ...
1664:      PetscLogPrintDetailed(MPI_Comm,filename);
1665:      PetscFinalize(...);
1666: .ve

1668:   Notes:
1669:   By default the summary is printed to stdout.

1671:   Level: beginner
1672:    
1673: .keywords: log, dump, print
1674: .seealso: PetscLogBegin(), PetscLogDump(), PetscLogPrintSummary()
1675: @*/
1676: PetscErrorCode  PetscLogPrintDetailed(MPI_Comm comm, const char filename[])
1677: {
1678:   FILE          *fd = PETSC_STDOUT;
1679:   StageLog       stageLog;
1680:   StageInfo     *stageInfo = PETSC_NULL;
1681:   EventPerfInfo *eventInfo = PETSC_NULL;
1682:   const char    *name = PETSC_NULL;
1683:   PetscLogDouble TotalTime;
1684:   PetscLogDouble stageTime, flops, flopr, mess, messLen, red;
1685:   PetscLogDouble maxf, totf, maxt, tott, totm, totml, totr = 0.0;
1686:   PetscMPIInt    maxCt;
1687:   PetscMPIInt    size, rank;
1688:   PetscTruth     *stageUsed;
1689:   PetscTruth     *stageVisible;
1690:   int            numStages, numEvents;
1691:   int            stage;
1692:   PetscLogEvent  event;

1696:   MPI_Comm_size(comm, &size);
1697:   MPI_Comm_rank(comm, &rank);
1698:   /* Pop off any stages the user forgot to remove */
1699:   PetscLogGetStageLog(&stageLog);
1700:   StageLogGetCurrent(stageLog, &stage);
1701:   while (stage >= 0) {
1702:     StageLogPop(stageLog);
1703:     StageLogGetCurrent(stageLog, &stage);
1704:   }
1705:   /* Get the total elapsed time */
1706:   PetscTime(TotalTime);  TotalTime -= BaseTime;
1707:   /* Open the summary file */
1708:   if (filename) {
1709:     PetscFOpen(comm, filename, "w", &fd);
1710:   }

1712:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1713:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1714:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");


1717:   numStages = stageLog->numStages;
1718:   PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1719:   PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1720:   if (numStages > 0) {
1721:     stageInfo = stageLog->stageInfo;
1722:     for(stage = 0; stage < numStages; stage++) {
1723:       if (stage < stageLog->numStages) {
1724:         stageUsed[stage]    = stageInfo[stage].used;
1725:         stageVisible[stage] = stageInfo[stage].perfInfo.visible;
1726:       } else {
1727:         stageUsed[stage]    = PETSC_FALSE;
1728:         stageVisible[stage] = PETSC_TRUE;
1729:       }
1730:     }
1731:   }

1733:   /* Report events */
1734:   PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flops/sec                          \n");
1735:   PetscFPrintf(comm, fd,"                                                            Mess   Avg len Reduct \n");
1736:   PetscFPrintf(comm,fd,"-----------------------------------------------------------------------------------\n");
1737:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1738:   for(stage = 0; stage < numStages; stage++) {
1739:     if (!stageVisible[stage]) continue;
1740:     if (stageUsed[stage]) {
1741:       PetscSynchronizedFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1742:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1743:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1744:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1745:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1746:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1747:     }
1748:     mess *= 0.5; messLen *= 0.5;

1750:     /* Get total number of events in this stage --
1751:     */
1752:     if (stageUsed[stage]) {
1753:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1754:       numEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1755:     } else {
1756:       numEvents = 0;
1757:     }
1758:     for(event = 0; event < numEvents; event++) {
1759:       if (stageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1760:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1761:           flopr = eventInfo[event].flops/eventInfo[event].time;
1762:         } else {
1763:           flopr = 0.0;
1764:         }
1765:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1766:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1767:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1768:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1769:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1770:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1771:         totr = eventInfo[event].numReductions;
1772:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, PETSC_COMM_SELF);
1773:         name = stageLog->eventLog->eventInfo[event].name;
1774:         totm *= 0.5; totml *= 0.5;
1775:       }
1776: 
1777:       if (maxCt != 0) {
1778:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1779:         PetscSynchronizedFPrintf(comm, fd,"%-16s %7d      %5.4e      %3.2e      %2.1e %2.1e %2.1e\n",name, maxCt,  maxt,  maxf, totm, totml, totr);
1780:       }
1781:     }
1782:   }
1783:   PetscSynchronizedFlush(comm);

1785:   PetscFree(stageUsed);
1786:   PetscFree(stageVisible);

1788:   PetscFClose(comm, fd);
1789:   return(0);
1790: }

1792: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1795: /*@C
1796:    PetscGetFlops - Returns the number of flops used on this processor 
1797:    since the program began. 

1799:    Not Collective

1801:    Output Parameter:
1802:    flops - number of floating point operations 

1804:    Notes:
1805:    A global counter logs all PETSc flop counts.  The user can use
1806:    PetscLogFlops() to increment this counter to include flops for the 
1807:    application code.  

1809:    PETSc automatically logs library events if the code has been
1810:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1811:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1812:    intended for logging user flops to supplement this PETSc
1813:    information.

1815:    Level: intermediate

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

1819: .seealso: PetscGetTime(), PetscLogFlops()
1820: @*/
1821: PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
1822: {
1824:   *flops = _TotalFlops;
1825:   return(0);
1826: }

1830: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
1831: {
1833:   int            fullLength;
1834:   va_list        Argp;

1837:   if (!logObjects) return(0);
1838:   va_start(Argp, format);
1839:   PetscVSNPrintf(objects[obj->id].info, 64,format,&fullLength, Argp);
1840:   va_end(Argp);
1841:   return(0);
1842: }

1846: /*@
1847:   PetscLogGetStageLog - This function returns the default stage logging object.

1849:   Not collective

1851:   Output Parameter:
1852: . stageLog - The default StageLog

1854:   Level: beginner

1856: .keywords: log, stage
1857: .seealso: StageLogCreate()
1858: @*/
1859: PetscErrorCode  PetscLogGetStageLog(StageLog *stageLog)
1860: {
1863:   *stageLog = _stageLog;
1864:   return(0);
1865: }

1867: /*MC
1868:    PetscLogFlops - Adds floating point operations to the global counter.

1870:    Input Parameter:
1871: .  f - flop counter

1873:    Synopsis:
1874:    void PetscLogFlops(int f)

1876:    Usage:
1877: .vb
1878:      int USER_EVENT;
1879:      PetscLogEventRegister("User event",0,&USER_EVENT);
1880:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1881:         [code segment to monitor]
1882:         PetscLogFlops(user_flops)
1883:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1884: .ve

1886:    Notes:
1887:    A global counter logs all PETSc flop counts.  The user can use
1888:    PetscLogFlops() to increment this counter to include flops for the 
1889:    application code.  

1891:    PETSc automatically logs library events if the code has been
1892:    compiled with -DPETSC_USE_LOG (which is the default), and -log,
1893:    -log_summary, or -log_all are specified.  PetscLogFlops() is
1894:    intended for logging user flops to supplement this PETSc
1895:    information.

1897:    Level: intermediate

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

1901: .keywords: log, flops, floating point operations
1902: M*/

1904: /*MC
1905:    PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1906:     to get accurate timings

1908:    Input Parameter:
1909: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1910:            with command line option -preload true or -preload false
1911: -   name - name of first stage (lines of code timed separately with -log_summary) to
1912:            be preloaded

1914:    Synopsis:
1915:    void PreLoadBegin(PetscTruth flag,char *name);

1917:    Usage:
1918: .vb
1919:      PreLoadBegin(PETSC_TRUE,"first stage);
1920:        lines of code
1921:        PreLoadStage("second stage");
1922:        lines of code
1923:      PreLoadEnd();
1924: .ve

1926:    Notes: Only works in C/C++, not Fortran

1928:      Flags available within the macro. 
1929: +    PetscPreLoadingUsed - true if we are or have done preloading 
1930: .    PetscPreLoadingOn - true if it is CURRENTLY doing preload
1931: .    PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1932: -    PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1933:      The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1934:      and PreLoadEnd()

1936:    Level: intermediate

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

1940:    Concepts: preloading
1941:    Concepts: timing^accurate
1942:    Concepts: paging^eliminating effects of


1945: M*/

1947: /*MC
1948:    PreLoadEnd - End a segment of code that may be preloaded (run twice)
1949:     to get accurate timings

1951:    Synopsis:
1952:    void PreLoadEnd(void);

1954:    Usage:
1955: .vb
1956:      PreLoadBegin(PETSC_TRUE,"first stage);
1957:        lines of code
1958:        PreLoadStage("second stage");
1959:        lines of code
1960:      PreLoadEnd();
1961: .ve

1963:    Notes: only works in C/C++ not fortran

1965:    Level: intermediate

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

1969: M*/

1971: /*MC
1972:    PreLoadStage - Start a new segment of code to be timed separately.
1973:     to get accurate timings

1975:    Synopsis:
1976:    void PreLoadStage(char *name);

1978:    Usage:
1979: .vb
1980:      PreLoadBegin(PETSC_TRUE,"first stage);
1981:        lines of code
1982:        PreLoadStage("second stage");
1983:        lines of code
1984:      PreLoadEnd();
1985: .ve

1987:    Notes: only works in C/C++ not fortran

1989:    Level: intermediate

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

1993: M*/

1995: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1998: /*@C
1999:   StackDestroy - This function destroys a stack.

2001:   Not Collective

2003:   Input Parameter:
2004: . stack - The stack

2006:   Level: beginner

2008: .keywords: log, stack, destroy
2009: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
2010: @*/
2011: PetscErrorCode StackDestroy(IntStack stack)
2012: {

2016:   PetscFree(stack->stack);
2017:   PetscFree(stack);
2018:   return(0);
2019: }

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

2026:   Not Collective

2028:   Input Parameter:
2029: . stack - The stack

2031:   Output Parameter:
2032: . empty - PETSC_TRUE if the stack is empty

2034:   Level: intermediate

2036: .keywords: log, stack, empty
2037: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
2038: @*/
2039: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
2040: {
2043:   if (stack->top == -1) {
2044:     *empty = PETSC_TRUE;
2045:   } else {
2046:     *empty = PETSC_FALSE;
2047:   }
2048:   return(0);
2049: }

2053: /*@C
2054:   StackTop - This function returns the top of the stack.

2056:   Not Collective

2058:   Input Parameter:
2059: . stack - The stack

2061:   Output Parameter:
2062: . top - The integer on top of the stack

2064:   Level: intermediate

2066: .keywords: log, stack, top
2067: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
2068: @*/
2069: PetscErrorCode StackTop(IntStack stack, int *top)
2070: {
2073:   *top = stack->stack[stack->top];
2074:   return(0);
2075: }

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

2082:   Not Collective

2084:   Input Parameters:
2085: + stack - The stack
2086: - item  - The integer to push

2088:   Level: intermediate

2090: .keywords: log, stack, push
2091: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
2092: @*/
2093: PetscErrorCode StackPush(IntStack stack, int item)
2094: {
2095:   int            *array;

2099:   stack->top++;
2100:   if (stack->top >= stack->max) {
2101:     PetscMalloc(stack->max*2 * sizeof(int), &array);
2102:     PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2103:     PetscFree(stack->stack);
2104:     stack->stack = array;
2105:     stack->max  *= 2;
2106:   }
2107:   stack->stack[stack->top] = item;
2108:   return(0);
2109: }

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

2116:   Not Collective

2118:   Input Parameter:
2119: . stack - The stack

2121:   Output Parameter:
2122: . item  - The integer popped

2124:   Level: intermediate

2126: .keywords: log, stack, pop
2127: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2128: @*/
2129: PetscErrorCode StackPop(IntStack stack, int *item)
2130: {
2133:   if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2134:   *item = stack->stack[stack->top--];
2135:   return(0);
2136: }

2140: /*@C
2141:   StackCreate - This function creates a stack.

2143:   Not Collective

2145:   Output Parameter:
2146: . stack - The stack

2148:   Level: beginner

2150: .keywords: log, stack, pop
2151: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2152: @*/
2153: PetscErrorCode StackCreate(IntStack *stack)
2154: {
2155:   IntStack       s;

2160:   PetscNew(struct _n_IntStack, &s);
2161:   s->top = -1;
2162:   s->max = 128;
2163:   PetscMalloc(s->max * sizeof(int), &s->stack);
2164:   PetscMemzero(s->stack, s->max * sizeof(int));
2165:   *stack = s;
2166:   return(0);
2167: }

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

2173: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2174: {
2176:   return(0);
2177: }

2179: #endif /* PETSC_USE_LOG*/


2182: PetscCookie PETSC_LARGEST_COOKIE = PETSC_SMALLEST_COOKIE;
2183: PetscCookie PETSC_OBJECT_COOKIE  = 0;

2187: /*@C
2188:   PetscCookieRegister - Registers a new class name for objects and logging operations in an application code. 

2190:   Not Collective

2192:   Input Parameter:
2193: . name   - The class name
2194:             
2195:   Output Parameter:
2196: . oclass - The class id or cookie

2198:   Level: developer

2200: .keywords: log, class, register

2202: @*/
2203: PetscErrorCode  PetscCookieRegister(const char name[],PetscCookie *oclass )
2204: {
2205: #if defined(PETSC_USE_LOG)
2206:   StageLog       stageLog;
2207:   PetscInt       stage;
2209: #endif

2212:   *oclass = ++PETSC_LARGEST_COOKIE;
2213: #if defined(PETSC_USE_LOG)
2214:   PetscLogGetStageLog(&stageLog);
2215:   ClassRegLogRegister(stageLog->classLog, name, *oclass);
2216:   for(stage = 0; stage < stageLog->numStages; stage++) {
2217:     ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2218:   }
2219: #endif
2220:   return(0);
2221: }