Actual source code: plog.c

petsc-master 2016-12-03
Report Typos and Errors

  2: /*
  3:       PETSc code to log object creation and destruction and PETSc events.

  5:       This provides the public API used by the rest of PETSc and by users.

  7:       These routines use a private API that is not used elsewhere in PETSc and is not
  8:       accessible to users. The private API is defined in logimpl.h and the utils directory.

 10: */
 11:  #include <petsc/private/logimpl.h>
 12:  #include <petsctime.h>
 13:  #include <petscviewer.h>

 15: PetscErrorCode PetscLogObjectParent(PetscObject p,PetscObject c)
 16: {
 17:   if (!c || !p) return 0;
 18:   c->parent   = p;
 19:   c->parentid = p->id;
 20:   return 0;
 21: }

 23: /*@C
 24:    PetscLogObjectMemory - Adds to an object a count of additional amount of memory that is used by the object.

 26:    Not collective.

 28:    Input Parameters:
 29: +  obj  - the PETSc object
 30: -  mem  - the amount of memory that is being added to the object

 32:    Level: developer

 34:    Developer Notes: Currently we do not always do a good job of associating all memory allocations with an object. 

 36: .seealso: PetscFinalize(), PetscInitializeFortran(), PetscGetArgs(), PetscInitializeNoArguments()

 38: @*/
 39: PetscErrorCode PetscLogObjectMemory(PetscObject p,PetscLogDouble m)
 40: {
 41:   if (!p) return 0;
 42:   p->mem += m;
 43:   return 0;
 44: }

 46: PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT;

 48: #if defined(PETSC_USE_LOG)
 49: #include <petscmachineinfo.h>
 50: #include <petscconfiginfo.h>

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

 54: /* Action and object logging variables */
 55: Action    *petsc_actions            = NULL;
 56: Object    *petsc_objects            = NULL;
 57: PetscBool petsc_logActions          = PETSC_FALSE;
 58: PetscBool petsc_logObjects          = PETSC_FALSE;
 59: int       petsc_numActions          = 0, petsc_maxActions = 100;
 60: int       petsc_numObjects          = 0, petsc_maxObjects = 100;
 61: int       petsc_numObjectsDestroyed = 0;

 63: /* Global counters */
 64: PetscLogDouble petsc_BaseTime        = 0.0;
 65: PetscLogDouble petsc_TotalFlops      = 0.0;  /* The number of flops */
 66: PetscLogDouble petsc_tmp_flops       = 0.0;  /* The incremental number of flops */
 67: PetscLogDouble petsc_send_ct         = 0.0;  /* The number of sends */
 68: PetscLogDouble petsc_recv_ct         = 0.0;  /* The number of receives */
 69: PetscLogDouble petsc_send_len        = 0.0;  /* The total length of all sent messages */
 70: PetscLogDouble petsc_recv_len        = 0.0;  /* The total length of all received messages */
 71: PetscLogDouble petsc_isend_ct        = 0.0;  /* The number of immediate sends */
 72: PetscLogDouble petsc_irecv_ct        = 0.0;  /* The number of immediate receives */
 73: PetscLogDouble petsc_isend_len       = 0.0;  /* The total length of all immediate send messages */
 74: PetscLogDouble petsc_irecv_len       = 0.0;  /* The total length of all immediate receive messages */
 75: PetscLogDouble petsc_wait_ct         = 0.0;  /* The number of waits */
 76: PetscLogDouble petsc_wait_any_ct     = 0.0;  /* The number of anywaits */
 77: PetscLogDouble petsc_wait_all_ct     = 0.0;  /* The number of waitalls */
 78: PetscLogDouble petsc_sum_of_waits_ct = 0.0;  /* The total number of waits */
 79: PetscLogDouble petsc_allreduce_ct    = 0.0;  /* The number of reductions */
 80: PetscLogDouble petsc_gather_ct       = 0.0;  /* The number of gathers and gathervs */
 81: PetscLogDouble petsc_scatter_ct      = 0.0;  /* The number of scatters and scattervs */

 83: /* Logging functions */
 84: PetscErrorCode (*PetscLogPHC)(PetscObject) = NULL;
 85: PetscErrorCode (*PetscLogPHD)(PetscObject) = NULL;
 86: PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
 87: PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;

 89: /* Tracing event logging variables */
 90: FILE             *petsc_tracefile            = NULL;
 91: int              petsc_tracelevel            = 0;
 92: const char       *petsc_traceblanks          = "                                                                                                    ";
 93: char             petsc_tracespace[128]       = " ";
 94: PetscLogDouble   petsc_tracetime             = 0.0;
 95: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

 97: /*---------------------------------------------- General Functions --------------------------------------------------*/
100: /*@C
101:   PetscLogDestroy - Destroys the object and event logging data and resets the global counters.

103:   Not Collective

105:   Notes:
106:   This routine should not usually be used by programmers. Instead employ
107:   PetscLogStagePush() and PetscLogStagePop().

109:   Level: developer

111: .keywords: log, destroy
112: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogStagePush(), PlogStagePop()
113: @*/
114: PetscErrorCode  PetscLogDestroy(void)
115: {
116:   PetscStageLog  stageLog;

120:   PetscFree(petsc_actions);
121:   PetscFree(petsc_objects);
122:   PetscLogSet(NULL, NULL);

124:   /* Resetting phase */
125:   PetscLogGetStageLog(&stageLog);
126:   PetscStageLogDestroy(stageLog);

128:   petsc_TotalFlops            = 0.0;
129:   petsc_numActions            = 0;
130:   petsc_numObjects            = 0;
131:   petsc_numObjectsDestroyed   = 0;
132:   petsc_maxActions            = 100;
133:   petsc_maxObjects            = 100;
134:   petsc_actions               = NULL;
135:   petsc_objects               = NULL;
136:   petsc_logActions            = PETSC_FALSE;
137:   petsc_logObjects            = PETSC_FALSE;
138:   petsc_BaseTime              = 0.0;
139:   petsc_TotalFlops            = 0.0;
140:   petsc_tmp_flops             = 0.0;
141:   petsc_send_ct               = 0.0;
142:   petsc_recv_ct               = 0.0;
143:   petsc_send_len              = 0.0;
144:   petsc_recv_len              = 0.0;
145:   petsc_isend_ct              = 0.0;
146:   petsc_irecv_ct              = 0.0;
147:   petsc_isend_len             = 0.0;
148:   petsc_irecv_len             = 0.0;
149:   petsc_wait_ct               = 0.0;
150:   petsc_wait_any_ct           = 0.0;
151:   petsc_wait_all_ct           = 0.0;
152:   petsc_sum_of_waits_ct       = 0.0;
153:   petsc_allreduce_ct          = 0.0;
154:   petsc_gather_ct             = 0.0;
155:   petsc_scatter_ct            = 0.0;
156:   PETSC_LARGEST_EVENT         = PETSC_EVENT;
157:   PetscLogPHC                 = NULL;
158:   PetscLogPHD                 = NULL;
159:   petsc_tracefile             = NULL;
160:   petsc_tracelevel            = 0;
161:   petsc_traceblanks           = "                                                                                                    ";
162:   petsc_tracespace[0]         = ' '; petsc_tracespace[1] = 0;
163:   petsc_tracetime             = 0.0;
164:   PETSC_LARGEST_CLASSID       = PETSC_SMALLEST_CLASSID;
165:   PETSC_OBJECT_CLASSID        = 0;
166:   petsc_stageLog              = 0;
167:   PetscLogInitializeCalled = PETSC_FALSE;
168:   return(0);
169: }

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

176:   Not Collective

178:   Input Parameters:
179: + b - The function called at beginning of event
180: - e - The function called at end of event

182:   Level: developer

184: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
185: @*/
186: PetscErrorCode  PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
187:                             PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
188: {
190:   PetscLogPLB = b;
191:   PetscLogPLE = e;
192:   return(0);
193: }

195: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
198: /*
199:     The data structures for logging are always created even if no logging is turned on. This is so events etc can
200:   be registered in the code before the actually logging is turned on.
201:  */
202: PetscErrorCode  PetscLogInitialize(void)
203: {
204:   int            stage;
205:   PetscBool      opt;

209:   if (PetscLogInitializeCalled) return(0);
210:   PetscLogInitializeCalled = PETSC_TRUE;

212:   PetscOptionsHasName(NULL,NULL, "-log_exclude_actions", &opt);
213:   if (opt) petsc_logActions = PETSC_FALSE;
214:   PetscOptionsHasName(NULL,NULL, "-log_exclude_objects", &opt);
215:   if (opt) petsc_logObjects = PETSC_FALSE;
216:   if (petsc_logActions) {
217:     PetscMalloc1(petsc_maxActions, &petsc_actions);
218:   }
219:   if (petsc_logObjects) {
220:     PetscMalloc1(petsc_maxObjects, &petsc_objects);
221:   }
222:   PetscLogPHC = PetscLogObjCreateDefault;
223:   PetscLogPHD = PetscLogObjDestroyDefault;
224:   /* Setup default logging structures */
225:   PetscStageLogCreate(&petsc_stageLog);
226:   PetscStageLogRegister(petsc_stageLog, "Main Stage", &stage);

228:   /* All processors sync here for more consistent logging */
229:   MPI_Barrier(PETSC_COMM_WORLD);
230:   PetscTime(&petsc_BaseTime);
231:   PetscLogStagePush(stage);
232:   return(0);
233: }

237: /*@C
238:   PetscLogDefaultBegin - Turns on logging of objects and events. This logs flop
239:   rates and object creation and should not slow programs down too much.
240:   This routine may be called more than once.

242:   Logically Collective over PETSC_COMM_WORLD

244:   Options Database Keys:
245: . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
246:                   screen (for code configured with --with-log=1 (which is the default))

248:   Usage:
249: .vb
250:       PetscInitialize(...);
251:       PetscLogDefaultBegin();
252:        ... code ...
253:       PetscLogView(viewer); or PetscLogDump();
254:       PetscFinalize();
255: .ve

257:   Notes:
258:   PetscLogView(viewer) or PetscLogDump() actually cause the printing of
259:   the logging information.

261:   Level: advanced

263: .keywords: log, begin
264: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogTraceBegin()
265: @*/
266: PetscErrorCode  PetscLogDefaultBegin(void)
267: {

271:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
272:   return(0);
273: }

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

281:   Logically Collective on PETSC_COMM_WORLD

283:   Options Database Keys:
284: . -log_all - Prints extensive log information

286:   Usage:
287: .vb
288:      PetscInitialize(...);
289:      PetscLogAllBegin();
290:      ... code ...
291:      PetscLogDump(filename);
292:      PetscFinalize();
293: .ve

295:   Notes:
296:   A related routine is PetscLogDefaultBegin() (with the options key -log), which is
297:   intended for production runs since it logs only flop rates and object
298:   creation (and shouldn't significantly slow the programs).

300:   Level: advanced

302: .keywords: log, all, begin
303: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogTraceBegin()
304: @*/
305: PetscErrorCode  PetscLogAllBegin(void)
306: {

310:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
311:   return(0);
312: }

316: /*@
317:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
318:   begins or ends, the event name is printed.

320:   Logically Collective on PETSC_COMM_WORLD

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

325:   Options Database Key:
326: . -log_trace [filename] - Activates PetscLogTraceBegin()

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

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

336:   Level: intermediate

338: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogDefaultBegin()
339: @*/
340: PetscErrorCode  PetscLogTraceBegin(FILE *file)
341: {

345:   petsc_tracefile = file;

347:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
348:   return(0);
349: }

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

356:   Not Collective

358:   Input Parameter:
359: . flag - PETSC_TRUE if actions are to be logged

361:   Level: intermediate

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

366:   Options Database Keys:
367: . -log_exclude_actions - Turns off actions logging

369: .keywords: log, stage, register
370: .seealso: PetscLogStagePush(), PetscLogStagePop()
371: @*/
372: PetscErrorCode  PetscLogActions(PetscBool flag)
373: {
375:   petsc_logActions = flag;
376:   return(0);
377: }

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

384:   Not Collective

386:   Input Parameter:
387: . flag - PETSC_TRUE if objects are to be logged

389:   Level: intermediate

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

394:   Options Database Keys:
395: . -log_exclude_objects - Turns off objects logging

397: .keywords: log, stage, register
398: .seealso: PetscLogStagePush(), PetscLogStagePop()
399: @*/
400: PetscErrorCode  PetscLogObjects(PetscBool flag)
401: {
403:   petsc_logObjects = flag;
404:   return(0);
405: }

407: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
410: /*@C
411:   PetscLogStageRegister - Attaches a charactor string name to a logging stage.

413:   Not Collective

415:   Input Parameter:
416: . sname - The name to associate with that stage

418:   Output Parameter:
419: . stage - The stage number

421:   Level: intermediate

423: .keywords: log, stage, register
424: .seealso: PetscLogStagePush(), PetscLogStagePop()
425: @*/
426: PetscErrorCode  PetscLogStageRegister(const char sname[],PetscLogStage *stage)
427: {
428:   PetscStageLog  stageLog;
429:   PetscLogEvent  event;

433:   PetscLogGetStageLog(&stageLog);
434:   PetscStageLogRegister(stageLog, sname, stage);
435:   /* Copy events already changed in the main stage, this sucks */
436:   PetscEventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
437:   for (event = 0; event < stageLog->eventLog->numEvents; event++) {
438:     PetscEventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],&stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
439:   }
440:   PetscClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
441:   return(0);
442: }

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

449:   Not Collective

451:   Input Parameter:
452: . stage - The stage on which to log

454:   Usage:
455:   If the option -log_sumary is used to run the program containing the
456:   following code, then 2 sets of summary data will be printed during
457:   PetscFinalize().
458: .vb
459:       PetscInitialize(int *argc,char ***args,0,0);
460:       [stage 0 of code]
461:       PetscLogStagePush(1);
462:       [stage 1 of code]
463:       PetscLogStagePop();
464:       PetscBarrier(...);
465:       [more stage 0 of code]
466:       PetscFinalize();
467: .ve

469:   Notes:
470:   Use PetscLogStageRegister() to register a stage.

472:   Level: intermediate

474: .keywords: log, push, stage
475: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
476: @*/
477: PetscErrorCode  PetscLogStagePush(PetscLogStage stage)
478: {
479:   PetscStageLog  stageLog;

483:   PetscLogGetStageLog(&stageLog);
484:   PetscStageLogPush(stageLog, stage);
485:   return(0);
486: }

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

493:   Not Collective

495:   Usage:
496:   If the option -log_sumary is used to run the program containing the
497:   following code, then 2 sets of summary data will be printed during
498:   PetscFinalize().
499: .vb
500:       PetscInitialize(int *argc,char ***args,0,0);
501:       [stage 0 of code]
502:       PetscLogStagePush(1);
503:       [stage 1 of code]
504:       PetscLogStagePop();
505:       PetscBarrier(...);
506:       [more stage 0 of code]
507:       PetscFinalize();
508: .ve

510:   Notes:
511:   Use PetscLogStageRegister() to register a stage.

513:   Level: intermediate

515: .keywords: log, pop, stage
516: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
517: @*/
518: PetscErrorCode  PetscLogStagePop(void)
519: {
520:   PetscStageLog  stageLog;

524:   PetscLogGetStageLog(&stageLog);
525:   PetscStageLogPop(stageLog);
526:   return(0);
527: }

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

534:   Not Collective

536:   Input Parameters:
537: + stage    - The stage
538: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

540:   Level: intermediate

542: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
543: @*/
544: PetscErrorCode  PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
545: {
546:   PetscStageLog  stageLog;

550:   PetscLogGetStageLog(&stageLog);
551:   PetscStageLogSetActive(stageLog, stage, isActive);
552:   return(0);
553: }

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

560:   Not Collective

562:   Input Parameter:
563: . stage    - The stage

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

568:   Level: intermediate

570: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
571: @*/
572: PetscErrorCode  PetscLogStageGetActive(PetscLogStage stage, PetscBool  *isActive)
573: {
574:   PetscStageLog  stageLog;

578:   PetscLogGetStageLog(&stageLog);
579:   PetscStageLogGetActive(stageLog, stage, isActive);
580:   return(0);
581: }

585: /*@
586:   PetscLogStageSetVisible - Determines stage visibility in PetscLogView()

588:   Not Collective

590:   Input Parameters:
591: + stage     - The stage
592: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

594:   Level: intermediate

596: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
597: @*/
598: PetscErrorCode  PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
599: {
600:   PetscStageLog  stageLog;

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

611: /*@
612:   PetscLogStageGetVisible - Returns stage visibility in PetscLogView()

614:   Not Collective

616:   Input Parameter:
617: . stage     - The stage

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

622:   Level: intermediate

624: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
625: @*/
626: PetscErrorCode  PetscLogStageGetVisible(PetscLogStage stage, PetscBool  *isVisible)
627: {
628:   PetscStageLog  stageLog;

632:   PetscLogGetStageLog(&stageLog);
633:   PetscStageLogGetVisible(stageLog, stage, isVisible);
634:   return(0);
635: }

639: /*@C
640:   PetscLogStageGetId - Returns the stage id when given the stage name.

642:   Not Collective

644:   Input Parameter:
645: . name  - The stage name

647:   Output Parameter:
648: . stage - The stage, , or -1 if no stage with that name exists

650:   Level: intermediate

652: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
653: @*/
654: PetscErrorCode  PetscLogStageGetId(const char name[], PetscLogStage *stage)
655: {
656:   PetscStageLog  stageLog;

660:   PetscLogGetStageLog(&stageLog);
661:   PetscStageLogGetStage(stageLog, name, stage);
662:   return(0);
663: }

665: /*------------------------------------------------ Event Functions --------------------------------------------------*/
668: /*@C
669:   PetscLogEventRegister - Registers an event name for logging operations in an application code.

671:   Not Collective

673:   Input Parameter:
674: + name   - The name associated with the event
675: - classid - The classid associated to the class for this event, obtain either with
676:            PetscClassIdRegister() or use a predefined one such as KSP_CLASSID, SNES_CLASSID, the predefined ones
677:            are only available in C code

679:   Output Parameter:
680: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().

682:   Example of Usage:
683: .vb
684:       PetscLogEvent USER_EVENT;
685:       PetscClassId classid;
686:       PetscLogDouble user_event_flops;
687:       PetscClassIdRegister("class name",&classid);
688:       PetscLogEventRegister("User event name",classid,&USER_EVENT);
689:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
690:          [code segment to monitor]
691:          PetscLogFlops(user_event_flops);
692:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
693: .ve

695:   Notes:
696:   PETSc automatically logs library events if the code has been
697:   configured with --with-log (which is the default) and
698:   -log_view or -log_all is specified.  PetscLogEventRegister() is
699:   intended for logging user events to supplement this PETSc
700:   information.

702:   PETSc can gather data for use with the utilities Jumpshot
703:   (part of the MPICH distribution).  If PETSc has been compiled
704:   with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
705:   MPICH), the user can employ another command line option, -log_mpe,
706:   to create a logfile, "mpe.log", which can be visualized
707:   Jumpshot.

709:   The classid is associated with each event so that classes of events
710:   can be disabled simultaneously, such as all matrix events. The user
711:   can either use an existing classid, such as MAT_CLASSID, or create
712:   their own as shown in the example.

714:   If an existing event with the same name exists, its event handle is
715:   returned instead of creating a new event.

717:   Level: intermediate

719: .keywords: log, event, register
720: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
721:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
722:           PetscLogEventActivate(), PetscLogEventDeactivate(), PetscClassIdRegister()
723: @*/
724: PetscErrorCode  PetscLogEventRegister(const char name[],PetscClassId classid,PetscLogEvent *event)
725: {
726:   PetscStageLog  stageLog;
727:   int            stage;

731:   *event = PETSC_DECIDE;
732:   PetscLogGetStageLog(&stageLog);
733:   PetscEventRegLogGetEvent(stageLog->eventLog, name, event);
734:   if (*event > 0) return(0);
735:   PetscEventRegLogRegister(stageLog->eventLog, name, classid, event);
736:   for (stage = 0; stage < stageLog->numStages; stage++) {
737:     PetscEventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
738:     PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
739:   }
740:   return(0);
741: }

745: /*@
746:   PetscLogEventActivate - Indicates that a particular event should be logged.

748:   Not Collective

750:   Input Parameter:
751: . event - The event id

753:   Usage:
754: .vb
755:       PetscLogEventDeactivate(VEC_SetValues);
756:         [code where you do not want to log VecSetValues()]
757:       PetscLogEventActivate(VEC_SetValues);
758:         [code where you do want to log VecSetValues()]
759: .ve

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

765:   Level: advanced

767: .keywords: log, event, activate
768: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
769: @*/
770: PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
771: {
772:   PetscStageLog  stageLog;
773:   int            stage;

777:   PetscLogGetStageLog(&stageLog);
778:   PetscStageLogGetCurrent(stageLog, &stage);
779:   PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
780:   return(0);
781: }

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

788:   Not Collective

790:   Input Parameter:
791: . event - The event id

793:   Usage:
794: .vb
795:       PetscLogEventDeactivate(VEC_SetValues);
796:         [code where you do not want to log VecSetValues()]
797:       PetscLogEventActivate(VEC_SetValues);
798:         [code where you do want to log VecSetValues()]
799: .ve

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

805:   Level: advanced

807: .keywords: log, event, deactivate
808: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
809: @*/
810: PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
811: {
812:   PetscStageLog  stageLog;
813:   int            stage;

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

825: /*@
826:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

828:   Not Collective

830:   Input Parameters:
831: + event    - The event id
832: - isActive - The activity flag determining whether the event is logged

834:   Level: advanced

836: .keywords: log, event, activate
837: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
838: @*/
839: PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
840: {
841:   PetscStageLog  stageLog;
842:   int            stage;

846:   PetscLogGetStageLog(&stageLog);
847:   for (stage = 0; stage < stageLog->numStages; stage++) {
848:     if (isActive) {
849:       PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
850:     } else {
851:       PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
852:     }
853:   }
854:   return(0);
855: }

859: /*@
860:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

862:   Not Collective

864:   Input Parameter:
865: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

867:   Level: developer

869: .keywords: log, event, activate, class
870: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
871: @*/
872: PetscErrorCode  PetscLogEventActivateClass(PetscClassId classid)
873: {
874:   PetscStageLog  stageLog;
875:   int            stage;

879:   PetscLogGetStageLog(&stageLog);
880:   PetscStageLogGetCurrent(stageLog, &stage);
881:   PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
882:   return(0);
883: }

887: /*@
888:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

890:   Not Collective

892:   Input Parameter:
893: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

895:   Level: developer

897: .keywords: log, event, deactivate, class
898: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
899: @*/
900: PetscErrorCode  PetscLogEventDeactivateClass(PetscClassId classid)
901: {
902:   PetscStageLog  stageLog;
903:   int            stage;

907:   PetscLogGetStageLog(&stageLog);
908:   PetscStageLogGetCurrent(stageLog, &stage);
909:   PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
910:   return(0);
911: }

913: /*MC
914:    PetscLogEventBegin - Logs the beginning of a user event.

916:    Synopsis:
917:    #include <petsclog.h>
918:    PetscErrorCode PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)

920:    Not Collective

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


927:    Fortran Synopsis:
928:    void PetscLogEventBegin(int e,PetscErrorCode ierr)

930:    Usage:
931: .vb
932:      PetscLogEvent USER_EVENT;
933:      PetscLogDouble user_event_flops;
934:      PetscLogEventRegister("User event",0,&USER_EVENT);
935:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
936:         [code segment to monitor]
937:         PetscLogFlops(user_event_flops);
938:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
939: .ve

941:    Notes:
942:    You need to register each integer event with the command
943:    PetscLogEventRegister().

945:    Level: intermediate

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

949: .keywords: log, event, begin
950: M*/

952: /*MC
953:    PetscLogEventEnd - Log the end of a user event.

955:    Synopsis:
956:    #include <petsclog.h>
957:    PetscErrorCode PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)

959:    Not Collective

961:    Input Parameters:
962: +  e - integer associated with the event obtained with PetscLogEventRegister()
963: -  o1,o2,o3,o4 - objects associated with the event, or 0


966:    Fortran Synopsis:
967:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

969:    Usage:
970: .vb
971:      PetscLogEvent USER_EVENT;
972:      PetscLogDouble user_event_flops;
973:      PetscLogEventRegister("User event",0,&USER_EVENT,);
974:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
975:         [code segment to monitor]
976:         PetscLogFlops(user_event_flops);
977:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
978: .ve

980:    Notes:
981:    You should also register each additional integer event with the command
982:    PetscLogEventRegister().

984:    Level: intermediate

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

988: .keywords: log, event, end
989: M*/

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

994:    Synopsis:
995:    #include <petsclog.h>
996:    PetscErrorCode PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)

998:    Not Collective

1000:    Input Parameters:
1001: .  e - integer associated with the event obtained from PetscLogEventRegister()
1002: .  o1,o2,o3,o4 - objects associated with the event, or 0
1003: .  comm - communicator the barrier takes place over


1006:    Usage:
1007: .vb
1008:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1009:        MPIU_Allreduce()
1010:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1011: .ve

1013:    Notes:
1014:    This is for logging the amount of time spent in a barrier for an event
1015:    that requires synchronization.

1017:    Additional Notes:
1018:    Synchronization events always come in pairs; for example, VEC_NormBarrier and
1019:    VEC_NormComm = VEC_NormBarrier + 1

1021:    Level: advanced

1023: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1024:           PetscLogEventBarrierEnd()

1026: .keywords: log, event, begin, barrier
1027: M*/

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

1032:    Synopsis:
1033:    #include <petsclog.h>
1034:    PetscErrorCode PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)

1036:    Logically Collective on MPI_Comm

1038:    Input Parameters:
1039: .  e - integer associated with the event obtained from PetscLogEventRegister()
1040: .  o1,o2,o3,o4 - objects associated with the event, or 0
1041: .  comm - communicator the barrier takes place over


1044:     Usage:
1045: .vb
1046:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1047:        MPIU_Allreduce()
1048:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1049: .ve

1051:    Notes:
1052:    This is for logging the amount of time spent in a barrier for an event
1053:    that requires synchronization.

1055:    Additional Notes:
1056:    Synchronization events always come in pairs; for example, VEC_NormBarrier and
1057:    VEC_NormComm = VEC_NormBarrier + 1

1059:    Level: advanced

1061: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1062:           PetscLogEventBarrierBegin()

1064: .keywords: log, event, begin, barrier
1065: M*/

1069: /*@C
1070:   PetscLogEventGetId - Returns the event id when given the event name.

1072:   Not Collective

1074:   Input Parameter:
1075: . name  - The event name

1077:   Output Parameter:
1078: . event - The event, or -1 if no event with that name exists

1080:   Level: intermediate

1082: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1083: @*/
1084: PetscErrorCode  PetscLogEventGetId(const char name[], PetscLogEvent *event)
1085: {
1086:   PetscStageLog  stageLog;

1090:   PetscLogGetStageLog(&stageLog);
1091:   PetscEventRegLogGetEvent(stageLog->eventLog, name, event);
1092:   return(0);
1093: }


1096: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1099: /*@C
1100:   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1101:   be read by bin/petscview. This program no longer exists.

1103:   Collective on PETSC_COMM_WORLD

1105:   Input Parameter:
1106: . name - an optional file name

1108:   Usage:
1109: .vb
1110:      PetscInitialize(...);
1111:      PetscLogDefaultBegin(); or PetscLogAllBegin();
1112:      ... code ...
1113:      PetscLogDump(filename);
1114:      PetscFinalize();
1115: .ve

1117:   Notes:
1118:   The default file name is
1119: $    Log.<rank>
1120:   where <rank> is the processor number. If no name is specified,
1121:   this file will be used.

1123:   Level: advanced

1125: .keywords: log, dump
1126: .seealso: PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogView()
1127: @*/
1128: PetscErrorCode  PetscLogDump(const char sname[])
1129: {
1130:   PetscStageLog      stageLog;
1131:   PetscEventPerfInfo *eventInfo;
1132:   FILE               *fd;
1133:   char               file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1134:   PetscLogDouble     flops, _TotalTime;
1135:   PetscMPIInt        rank;
1136:   int                action, object, curStage;
1137:   PetscLogEvent      event;
1138:   PetscErrorCode     ierr;

1141:   /* Calculate the total elapsed time */
1142:   PetscTime(&_TotalTime);
1143:   _TotalTime -= petsc_BaseTime;
1144:   /* Open log file */
1145:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1146:   if (sname) sprintf(file, "%s.%d", sname, rank);
1147:   else sprintf(file, "Log.%d", rank);
1148:   PetscFixFilename(file, fname);
1149:   PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1150:   if ((!rank) && (!fd)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1151:   /* Output totals */
1152:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", petsc_TotalFlops, _TotalTime);
1153:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1154:   /* Output actions */
1155:   if (petsc_logActions) {
1156:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", petsc_numActions);
1157:     for (action = 0; action < petsc_numActions; action++) {
1158:       PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1159:                           petsc_actions[action].time, petsc_actions[action].action, (int)petsc_actions[action].event, (int)petsc_actions[action].classid, petsc_actions[action].id1,
1160:                           petsc_actions[action].id2, petsc_actions[action].id3, petsc_actions[action].flops, petsc_actions[action].mem, petsc_actions[action].maxmem);
1161:     }
1162:   }
1163:   /* Output objects */
1164:   if (petsc_logObjects) {
1165:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", petsc_numObjects, petsc_numObjectsDestroyed);
1166:     for (object = 0; object < petsc_numObjects; object++) {
1167:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", petsc_objects[object].parent, (int) petsc_objects[object].mem);
1168:       if (!petsc_objects[object].name[0]) {
1169:         PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1170:       } else {
1171:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", petsc_objects[object].name);
1172:       }
1173:       if (petsc_objects[object].info[0] != 0) {
1174:         PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1175:       } else {
1176:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", petsc_objects[object].info);
1177:       }
1178:     }
1179:   }
1180:   /* Output events */
1181:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1182:   PetscLogGetStageLog(&stageLog);
1183:   PetscIntStackTop(stageLog->stack, &curStage);
1184:   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1185:   for (event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1186:     if (eventInfo[event].time != 0.0) flops = eventInfo[event].flops/eventInfo[event].time;
1187:     else flops = 0.0;
1188:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1189:                         eventInfo[event].flops, eventInfo[event].time, flops);
1190:   }
1191:   PetscFClose(PETSC_COMM_WORLD, fd);
1192:   return(0);
1193: }

1197: /*
1198:   PetscLogView_Detailed - Each process prints the times for its own events

1200: */
1201: PetscErrorCode  PetscLogView_Detailed(PetscViewer viewer)
1202: {
1203:   MPI_Comm           comm       = PetscObjectComm((PetscObject) viewer);
1204:   PetscEventPerfInfo *eventInfo = NULL;
1205:   PetscLogDouble     locTotalTime, numRed, maxMem;
1206:   PetscStageLog      stageLog;
1207:   int                numStages,numEvents,stage,event;
1208:   PetscMPIInt        rank,size;
1209:   PetscErrorCode     ierr;

1212:   MPI_Comm_size(comm, &size);
1213:   MPI_Comm_rank(comm, &rank);
1214:   /* Must preserve reduction count before we go on */
1215:   numRed = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1216:   /* Get the total elapsed time */
1217:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1218:   PetscViewerASCIIPrintf(viewer,"numProcs   = %d\n",size);
1219:   PetscViewerASCIIPrintf(viewer,"LocalTimes = {}\n");
1220:   PetscViewerASCIIPrintf(viewer,"LocalFlops = {}\n");
1221:   PetscViewerASCIIPrintf(viewer,"LocalMessageLens = {}\n");
1222:   PetscViewerASCIIPrintf(viewer,"LocalMessages = {}\n");
1223:   PetscViewerASCIIPrintf(viewer,"LocalReductions = {}\n");
1224:   PetscViewerASCIIPrintf(viewer,"LocalObjects = {}\n");
1225:   PetscViewerASCIIPrintf(viewer,"LocalMemory = {}\n");
1226:   PetscLogGetStageLog(&stageLog);
1227:   MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1228:   PetscViewerASCIIPrintf(viewer,"Stages = {}\n");
1229:   for (stage=0; stage<numStages; stage++) {
1230:     PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"] = {}\n",stageLog->stageInfo[stage].name);
1231:     PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"summary\"] = {}\n",stageLog->stageInfo[stage].name);
1232:     MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1233:     for (event = 0; event < numEvents; event++) {
1234:       PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"%s\"] = {}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name);
1235:     }
1236:   }
1237:   PetscViewerASCIIPushSynchronized(viewer);
1238:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalTimes[%d] = %g\n",rank,locTotalTime);
1239:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalFlops[%d] = %g\n",rank,petsc_TotalFlops);
1240:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessageLens[%d] = %g\n",rank,(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len));
1241:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessages[%d] = %g\n",rank,(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct));
1242:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalReductions[%d] = %g\n",rank,numRed);
1243:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalObjects[%d] = %g\n",rank,petsc_numObjects);
1244:   PetscMallocGetMaximumUsage(&maxMem);
1245:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalMemory[%d] = %g\n",rank,maxMem);
1246:   PetscViewerFlush(viewer);
1247:   for (stage=0; stage<numStages; stage++) {
1248:     PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"summary\"][%d] = {\"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flops\" : %g}\n",
1249:                                               stageLog->stageInfo[stage].name,rank,
1250:                                               stageLog->stageInfo[stage].perfInfo.time,stageLog->stageInfo[stage].perfInfo.numMessages,stageLog->stageInfo[stage].perfInfo.messageLength,
1251:                                               stageLog->stageInfo[stage].perfInfo.numReductions,stageLog->stageInfo[stage].perfInfo.flops);
1252:     MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1253:     for (event = 0; event < numEvents; event++) {
1254:       eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1255:       PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"%s\"][%d] = {\"count\" : %D, \"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flops\" : %g}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name,rank,
1256:                                                 eventInfo[event].count, eventInfo[event].time,eventInfo[event].numMessages, eventInfo[event].messageLength,
1257:                                                 eventInfo[event].numReductions,eventInfo[event].flops);
1258:     }
1259:   }
1260:   PetscViewerFlush(viewer);
1261:   PetscViewerASCIIPopSynchronized(viewer);
1262:   return(0);
1263: }

1267: static PetscErrorCode PetscLogViewWarnDebugging(MPI_Comm comm,FILE *fd)
1268: {
1269: #if defined(PETSC_USE_DEBUG)

1273:   PetscFPrintf(comm, fd, "\n\n");
1274:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1275:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1276:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1277:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1278:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #\n");
1279:   PetscFPrintf(comm, fd, "      #   To get timing results run ./configure                #\n");
1280:   PetscFPrintf(comm, fd, "      #   using --with-debugging=no, the performance will      #\n");
1281:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");
1282:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1283:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1284:   return(0);
1285: #else
1286:   return 0;
1287: #endif
1288: }

1292: PetscErrorCode  PetscLogView_Default(PetscViewer viewer)
1293: {
1294:   FILE               *fd;
1295:   PetscLogDouble     zero       = 0.0;
1296:   PetscStageLog      stageLog;
1297:   PetscStageInfo     *stageInfo = NULL;
1298:   PetscEventPerfInfo *eventInfo = NULL;
1299:   PetscClassPerfInfo *classInfo;
1300:   char               arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
1301:   const char         *name;
1302:   PetscLogDouble     locTotalTime, TotalTime, TotalFlops;
1303:   PetscLogDouble     numMessages, messageLength, avgMessLen, numReductions;
1304:   PetscLogDouble     stageTime, flops, flopr, mem, mess, messLen, red;
1305:   PetscLogDouble     fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1306:   PetscLogDouble     fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1307:   PetscLogDouble     min, max, tot, ratio, avg, x, y;
1308:   PetscLogDouble     minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1309:   PetscMPIInt        minCt, maxCt;
1310:   PetscMPIInt        size, rank;
1311:   PetscBool          *localStageUsed,    *stageUsed;
1312:   PetscBool          *localStageVisible, *stageVisible;
1313:   int                numStages, localNumEvents, numEvents;
1314:   int                stage, oclass;
1315:   PetscLogEvent      event;
1316:   PetscErrorCode     ierr;
1317:   char               version[256];
1318:   MPI_Comm           comm;

1321:   PetscObjectGetComm((PetscObject)viewer,&comm);
1322:   PetscViewerASCIIGetPointer(viewer,&fd);
1323:   MPI_Comm_size(comm, &size);
1324:   MPI_Comm_rank(comm, &rank);
1325:   /* Get the total elapsed time */
1326:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;

1328:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1329:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1330:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1331:   PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1332:   PetscLogViewWarnDebugging(comm,fd);
1333:   PetscGetArchType(arch,sizeof(arch));
1334:   PetscGetHostName(hostname,sizeof(hostname));
1335:   PetscGetUserName(username,sizeof(username));
1336:   PetscGetProgramName(pname,sizeof(pname));
1337:   PetscGetDate(date,sizeof(date));
1338:   PetscGetVersion(version,sizeof(version));
1339:   if (size == 1) {
1340:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1341:   } else {
1342:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1343:   }

1345:   PetscFPrintf(comm, fd, "Using %s\n", version);

1347:   /* Must preserve reduction count before we go on */
1348:   red = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;

1350:   /* Calculate summary information */
1351:   PetscFPrintf(comm, fd, "\n                         Max       Max/Min        Avg      Total \n");
1352:   /*   Time */
1353:   MPIU_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1354:   MPIU_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1355:   MPIU_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1356:   avg  = (tot)/((PetscLogDouble) size);
1357:   if (min != 0.0) ratio = max/min;
1358:   else ratio = 0.0;
1359:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %10.5f   %5.3e\n", max, ratio, avg);
1360:   TotalTime = tot;
1361:   /*   Objects */
1362:   avg  = (PetscLogDouble) petsc_numObjects;
1363:   MPIU_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1364:   MPIU_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1365:   MPIU_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1366:   avg  = (tot)/((PetscLogDouble) size);
1367:   if (min != 0.0) ratio = max/min;
1368:   else ratio = 0.0;
1369:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %10.5f   %5.3e\n", max, ratio, avg);
1370:   /*   Flops */
1371:   MPIU_Allreduce(&petsc_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1372:   MPIU_Allreduce(&petsc_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1373:   MPIU_Allreduce(&petsc_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1374:   avg  = (tot)/((PetscLogDouble) size);
1375:   if (min != 0.0) ratio = max/min;
1376:   else ratio = 0.0;
1377:   PetscFPrintf(comm, fd, "Flops:                %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1378:   TotalFlops = tot;
1379:   /*   Flops/sec -- Must talk to Barry here */
1380:   if (locTotalTime != 0.0) flops = petsc_TotalFlops/locTotalTime;
1381:   else flops = 0.0;
1382:   MPIU_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1383:   MPIU_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1384:   MPIU_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1385:   avg  = (tot)/((PetscLogDouble) size);
1386:   if (min != 0.0) ratio = max/min;
1387:   else ratio = 0.0;
1388:   PetscFPrintf(comm, fd, "Flops/sec:            %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1389:   /*   Memory */
1390:   PetscMallocGetMaximumUsage(&mem);
1391:   if (mem > 0.0) {
1392:     MPIU_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1393:     MPIU_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1394:     MPIU_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1395:     avg  = (tot)/((PetscLogDouble) size);
1396:     if (min != 0.0) ratio = max/min;
1397:     else ratio = 0.0;
1398:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %10.5f              %5.3e\n", max, ratio, tot);
1399:   }
1400:   /*   Messages */
1401:   mess = 0.5*(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct);
1402:   MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1403:   MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1404:   MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1405:   avg  = (tot)/((PetscLogDouble) size);
1406:   if (min != 0.0) ratio = max/min;
1407:   else ratio = 0.0;
1408:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1409:   numMessages = tot;
1410:   /*   Message Lengths */
1411:   mess = 0.5*(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len);
1412:   MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1413:   MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1414:   MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1415:   if (numMessages != 0) avg = (tot)/(numMessages);
1416:   else avg = 0.0;
1417:   if (min != 0.0) ratio = max/min;
1418:   else ratio = 0.0;
1419:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %10.5f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1420:   messageLength = tot;
1421:   /*   Reductions */
1422:   MPIU_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1423:   MPIU_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1424:   MPIU_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1425:   if (min != 0.0) ratio = max/min;
1426:   else ratio = 0.0;
1427:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %10.5f\n", max, ratio);
1428:   numReductions = red; /* wrong because uses count from process zero */
1429:   PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1430:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1431:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flops\n");

1433:   /* Get total number of stages --
1434:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1435:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1436:        This seems best accomplished by assoicating a communicator with each stage.
1437:   */
1438:   PetscLogGetStageLog(&stageLog);
1439:   MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1440:   PetscMalloc1(numStages, &localStageUsed);
1441:   PetscMalloc1(numStages, &stageUsed);
1442:   PetscMalloc1(numStages, &localStageVisible);
1443:   PetscMalloc1(numStages, &stageVisible);
1444:   if (numStages > 0) {
1445:     stageInfo = stageLog->stageInfo;
1446:     for (stage = 0; stage < numStages; stage++) {
1447:       if (stage < stageLog->numStages) {
1448:         localStageUsed[stage]    = stageInfo[stage].used;
1449:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1450:       } else {
1451:         localStageUsed[stage]    = PETSC_FALSE;
1452:         localStageVisible[stage] = PETSC_TRUE;
1453:       }
1454:     }
1455:     MPIU_Allreduce(localStageUsed,    stageUsed,    numStages, MPIU_BOOL, MPI_LOR,  comm);
1456:     MPIU_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);
1457:     for (stage = 0; stage < numStages; stage++) {
1458:       if (stageUsed[stage]) {
1459:         PetscFPrintf(comm, fd, "\nSummary of Stages:   ----- Time ------  ----- Flops -----  --- Messages ---  -- Message Lengths --  -- Reductions --\n");
1460:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total   counts   %%Total     Avg         %%Total   counts   %%Total \n");
1461:         break;
1462:       }
1463:     }
1464:     for (stage = 0; stage < numStages; stage++) {
1465:       if (!stageUsed[stage]) continue;
1466:       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1467:       if (localStageUsed[stage]) {
1468:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1469:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1470:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1471:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1472:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1473:         name = stageInfo[stage].name;
1474:       } else {
1475:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1476:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1477:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1478:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1479:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1480:         name = "";
1481:       }
1482:       mess *= 0.5; messLen *= 0.5; red /= size;
1483:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1484:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1485:       /* Talk to Barry if (stageTime     != 0.0) flops          = (size*flops)/stageTime; else flops          = 0.0; */
1486:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1487:       if (numMessages   != 0.0) avgMessLen     = messLen/numMessages;    else avgMessLen     = 0.0;
1488:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1489:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1490:       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",
1491:                           stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1492:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1493:     }
1494:   }

1496:   PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");
1497:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1498:   PetscFPrintf(comm, fd, "Phase summary info:\n");
1499:   PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");
1500:   PetscFPrintf(comm, fd, "   Time and Flops: Max - maximum over all processors\n");
1501:   PetscFPrintf(comm, fd, "                   Ratio - ratio of maximum to minimum over all processors\n");
1502:   PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");
1503:   PetscFPrintf(comm, fd, "   Avg. len: average message length (bytes)\n");
1504:   PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");
1505:   PetscFPrintf(comm, fd, "   Global: entire computation\n");
1506:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1507:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flops in this phase\n");
1508:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");
1509:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");
1510:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1511:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");

1513:   PetscLogViewWarnDebugging(comm,fd);

1515:   /* Report events */
1516:   PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flops                             --- Global ---  --- Stage ---   Total\n");
1517:   PetscFPrintf(comm, fd,"                   Max Ratio  Max     Ratio   Max  Ratio  Mess   Avg len Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s\n");
1518:   PetscFPrintf(comm,fd,"------------------------------------------------------------------------------------------------------------------------\n");

1520:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1521:   for (stage = 0; stage < numStages; stage++) {
1522:     if (!stageVisible[stage]) continue;
1523:     /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1524:     if (localStageUsed[stage]) {
1525:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1526:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1527:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1528:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1529:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1530:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1531:     } else {
1532:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1533:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1534:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1535:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1536:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1537:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1538:     }
1539:     mess *= 0.5; messLen *= 0.5; red /= size;

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

1546:        Problem: If the event did not happen on proc 1, its name will not be available.
1547:        Problem: Event visibility is not implemented
1548:     */
1549:     if (localStageUsed[stage]) {
1550:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1551:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1552:     } else localNumEvents = 0;
1553:     MPIU_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1554:     for (event = 0; event < numEvents; event++) {
1555:       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1556:       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1557:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops;
1558:         else flopr = 0.0;

1560:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1561:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1562:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1563:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1564:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1565:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1566:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1567:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1568:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1569:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1570:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1571:         name = stageLog->eventLog->eventInfo[event].name;
1572:       } else {
1573:         flopr = 0.0;
1574:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1575:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1576:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1577:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1578:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1579:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1580:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1581:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1582:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1583:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1584:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1585:         name  = "";
1586:       }
1587:       if (mint < 0.0) {
1588:         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);
1589:         mint = 0;
1590:       }
1591:       if (minf < 0.0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1592:       totm *= 0.5; totml *= 0.5; totr /= size;

1594:       if (maxCt != 0) {
1595:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1596:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1597:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1598:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1599:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1600:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1601:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1602:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1603:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1604:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1605:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1606:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1607:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1608:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1609:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1610:         if (fracStageTime > 1.00)  PetscFPrintf(comm, fd,"Warning -- total time of event greater than time of entire stage -- something is wrong with the timer\n");
1611:         PetscFPrintf(comm, fd,
1612:           "%-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",
1613:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1614:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1615:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1616:                             PetscAbsReal(flopr/1.0e6));
1617:       }
1618:     }
1619:   }

1621:   /* Memory usage and object creation */
1622:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");
1623:   PetscFPrintf(comm, fd, "\n");
1624:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

1626:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1627:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1628:      stats for stages local to processor sets.
1629:   */
1630:   /* We should figure out the longest object name here (now 20 characters) */
1631:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions     Memory  Descendants' Mem.\n");
1632:   PetscFPrintf(comm, fd, "Reports information only for process 0.\n");
1633:   for (stage = 0; stage < numStages; stage++) {
1634:     if (localStageUsed[stage]) {
1635:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1636:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1637:       for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1638:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1639:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %11.0f     %g\n", stageLog->classLog->classInfo[oclass].name,
1640:                               classInfo[oclass].creations, classInfo[oclass].destructions, classInfo[oclass].mem,
1641:                               classInfo[oclass].descMem);
1642:         }
1643:       }
1644:     } else {
1645:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1646:     }
1647:   }

1649:   PetscFree(localStageUsed);
1650:   PetscFree(stageUsed);
1651:   PetscFree(localStageVisible);
1652:   PetscFree(stageVisible);

1654:   /* Information unrelated to this particular run */
1655:   PetscFPrintf(comm, fd, "========================================================================================================================\n");
1656:   PetscTime(&y);
1657:   PetscTime(&x);
1658:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1659:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1660:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1661:   /* MPI information */
1662:   if (size > 1) {
1663:     MPI_Status  status;
1664:     PetscMPIInt tag;
1665:     MPI_Comm    newcomm;

1667:     MPI_Barrier(comm);
1668:     PetscTime(&x);
1669:     MPI_Barrier(comm);
1670:     MPI_Barrier(comm);
1671:     MPI_Barrier(comm);
1672:     MPI_Barrier(comm);
1673:     MPI_Barrier(comm);
1674:     PetscTime(&y);
1675:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1676:     PetscCommDuplicate(comm,&newcomm, &tag);
1677:     MPI_Barrier(comm);
1678:     if (rank) {
1679:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, newcomm, &status);
1680:       MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1681:     } else {
1682:       PetscTime(&x);
1683:       MPI_Send(0, 0, MPI_INT, 1,          tag, newcomm);
1684:       MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1685:       PetscTime(&y);
1686:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1687:     }
1688:     PetscCommDestroy(&newcomm);
1689:   }
1690:   PetscOptionsView(NULL,viewer);

1692:   /* Machine and compile information */
1693: #if defined(PETSC_USE_FORTRAN_KERNELS)
1694:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1695: #else
1696:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1697: #endif
1698: #if defined(PETSC_USE_REAL_SINGLE)
1699:   PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1700: #elif defined(PETSC_USE_LONGDOUBLE)
1701:   PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1702: #endif

1704: #if defined(PETSC_USE_REAL_MAT_SINGLE)
1705:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1706: #else
1707:   PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1708: #endif
1709:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1710:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));

1712:   PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1713:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1714:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1715:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1716:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1718:   /* Cleanup */
1719:   PetscFPrintf(comm, fd, "\n");
1720:   PetscLogViewWarnDebugging(comm,fd);
1721:   return(0);
1722: }

1724: PetscErrorCode  PetscLogView_Nested(PetscViewer);

1728: /*@C
1729:   PetscLogView - Prints a summary of the logging.

1731:   Collective over MPI_Comm

1733:   Input Parameter:
1734: .  viewer - an ASCII viewer

1736:   Options Database Keys:
1737: +  -log_view [:filename] - Prints summary of log information
1738: .  -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1739: .  -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format, use a browser to open this file, for example on
1740:              Apple MacOS systems use open -a Safari filename.xml
1741: .  -log_all - Saves a file Log.rank for each MPI process with details of each step of the computation
1742: -  -log_trace [filename] - Displays a trace of what each process is doing

1744:   Notes:
1745:   It is possible to control the logging programatically but we recommend using the options database approach whenever possible
1746:   By default the summary is printed to stdout.

1748:   Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()

1750:   If PETSc is configured with --with-logging=0 then this functionality is not available

1752:   The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij  MARITIME  RESEARCH  INSTITUTE  NETHERLANDS

1754:   Level: beginner

1756: .keywords: log, dump, print
1757: .seealso: PetscLogDefaultBegin(), PetscLogDump()
1758: @*/
1759: PetscErrorCode  PetscLogView(PetscViewer viewer)
1760: {
1761:   PetscErrorCode    ierr;
1762:   PetscBool         isascii;
1763:   PetscViewerFormat format;
1764:   int               stage, lastStage;
1765:   PetscStageLog     stageLog;

1768:   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_summary or PetscLogDefaultBegin() before calling this routine");
1769:   /* Pop off any stages the user forgot to remove */
1770:   lastStage = 0;
1771:   PetscLogGetStageLog(&stageLog);
1772:   PetscStageLogGetCurrent(stageLog, &stage);
1773:   while (stage >= 0) {
1774:     lastStage = stage;
1775:     PetscStageLogPop(stageLog);
1776:     PetscStageLogGetCurrent(stageLog, &stage);
1777:   }
1778:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
1779:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
1780:   PetscViewerGetFormat(viewer,&format);
1781:   if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
1782:     PetscLogView_Default(viewer);
1783:   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1784:     PetscLogView_Detailed(viewer);
1785:   } else if (format == PETSC_VIEWER_ASCII_XML) {
1786:     PetscLogView_Nested(viewer);
1787:   }
1788:   PetscStageLogPush(stageLog, lastStage);
1789:   return(0);
1790: }

1794: /*@C
1795:   PetscLogViewFromOptions - Processes command line options to determine if/how a PetscLog is to be viewed. 

1797:   Collective on PETSC_COMM_WORLD

1799:   Not normally called by user

1801:   Level: intermediate

1803: @*/
1804: PetscErrorCode PetscLogViewFromOptions(void)
1805: {
1806:   PetscErrorCode    ierr;
1807:   PetscViewer       viewer;
1808:   PetscBool         flg;
1809:   PetscViewerFormat format;

1812:   PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,"-log_view",&viewer,&format,&flg);
1813:   if (flg) {
1814:     PetscViewerPushFormat(viewer,format);
1815:     PetscLogView(viewer);
1816:     PetscViewerPopFormat(viewer);
1817:     PetscViewerDestroy(&viewer);
1818:   }
1819:   return(0);
1820: }



1824: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1827: /*@C
1828:    PetscGetFlops - Returns the number of flops used on this processor
1829:    since the program began.

1831:    Not Collective

1833:    Output Parameter:
1834:    flops - number of floating point operations

1836:    Notes:
1837:    A global counter logs all PETSc flop counts.  The user can use
1838:    PetscLogFlops() to increment this counter to include flops for the
1839:    application code.

1841:    Level: intermediate

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

1845: .seealso: PetscTime(), PetscLogFlops()
1846: @*/
1847: PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
1848: {
1850:   *flops = petsc_TotalFlops;
1851:   return(0);
1852: }

1856: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
1857: {
1859:   size_t         fullLength;
1860:   va_list        Argp;

1863:   if (!petsc_logObjects) return(0);
1864:   va_start(Argp, format);
1865:   PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);
1866:   va_end(Argp);
1867:   return(0);
1868: }


1871: /*MC
1872:    PetscLogFlops - Adds floating point operations to the global counter.

1874:    Synopsis:
1875:    #include <petsclog.h>
1876:    PetscErrorCode PetscLogFlops(PetscLogDouble f)

1878:    Not Collective

1880:    Input Parameter:
1881: .  f - flop counter


1884:    Usage:
1885: .vb
1886:      PetscLogEvent USER_EVENT;
1887:      PetscLogEventRegister("User event",0,&USER_EVENT);
1888:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1889:         [code segment to monitor]
1890:         PetscLogFlops(user_flops)
1891:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1892: .ve

1894:    Notes:
1895:    A global counter logs all PETSc flop counts.  The user can use
1896:    PetscLogFlops() to increment this counter to include flops for the
1897:    application code.

1899:    Level: intermediate

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

1903: .keywords: log, flops, floating point operations
1904: M*/

1906: /*MC
1907:    PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1908:     to get accurate timings

1910:    Synopsis:
1911:    #include <petsclog.h>
1912:    void PetscPreLoadBegin(PetscBool  flag,char *name);

1914:    Not Collective

1916:    Input Parameter:
1917: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1918:            with command line option -preload true or -preload false
1919: -   name - name of first stage (lines of code timed separately with -log_summary) to
1920:            be preloaded

1922:    Usage:
1923: .vb
1924:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
1925:        lines of code
1926:        PetscPreLoadStage("second stage");
1927:        lines of code
1928:      PetscPreLoadEnd();
1929: .ve

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

1933:      Flags available within the macro.
1934: +    PetscPreLoadingUsed - true if we are or have done preloading
1935: .    PetscPreLoadingOn - true if it is CURRENTLY doing preload
1936: .    PetscPreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1937: -    PetscPreLoadMax - number of times it will do the computation, only one when preloading is turned on
1938:      The first two variables are available throughout the program, the second two only between the PetscPreLoadBegin()
1939:      and PetscPreLoadEnd()

1941:    Level: intermediate

1943: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadEnd(), PetscPreLoadStage()

1945:    Concepts: preloading
1946:    Concepts: timing^accurate
1947:    Concepts: paging^eliminating effects of


1950: M*/

1952: /*MC
1953:    PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
1954:     to get accurate timings

1956:    Synopsis:
1957:    #include <petsclog.h>
1958:    void PetscPreLoadEnd(void);

1960:    Not Collective

1962:    Usage:
1963: .vb
1964:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
1965:        lines of code
1966:        PetscPreLoadStage("second stage");
1967:        lines of code
1968:      PetscPreLoadEnd();
1969: .ve

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

1973:    Level: intermediate

1975: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadStage()

1977: M*/

1979: /*MC
1980:    PetscPreLoadStage - Start a new segment of code to be timed separately.
1981:     to get accurate timings

1983:    Synopsis:
1984:    #include <petsclog.h>
1985:    void PetscPreLoadStage(char *name);

1987:    Not Collective

1989:    Usage:
1990: .vb
1991:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
1992:        lines of code
1993:        PetscPreLoadStage("second stage");
1994:        lines of code
1995:      PetscPreLoadEnd();
1996: .ve

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

2000:    Level: intermediate

2002: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd()

2004: M*/


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

2011: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2012: {
2014:   return(0);
2015: }

2017: #endif /* PETSC_USE_LOG*/


2020: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2021: PetscClassId PETSC_OBJECT_CLASSID  = 0;

2025: /*@C
2026:   PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.

2028:   Not Collective

2030:   Input Parameter:
2031: . name   - The class name

2033:   Output Parameter:
2034: . oclass - The class id or classid

2036:   Level: developer

2038: .keywords: log, class, register

2040: @*/
2041: PetscErrorCode  PetscClassIdRegister(const char name[],PetscClassId *oclass)
2042: {
2043: #if defined(PETSC_USE_LOG)
2044:   PetscStageLog  stageLog;
2045:   PetscInt       stage;
2047: #endif

2050:   *oclass = ++PETSC_LARGEST_CLASSID;
2051: #if defined(PETSC_USE_LOG)
2052:   PetscLogGetStageLog(&stageLog);
2053:   PetscClassRegLogRegister(stageLog->classLog, name, *oclass);
2054:   for (stage = 0; stage < stageLog->numStages; stage++) {
2055:     PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2056:   }
2057: #endif
2058:   return(0);
2059: }

2061: #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2062: #include <mpe.h>

2064: PetscBool PetscBeganMPE = PETSC_FALSE;

2066: PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2067: PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);

2071: /*@C
2072:    PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files
2073:    and slows the program down.

2075:    Collective over PETSC_COMM_WORLD

2077:    Options Database Keys:
2078: . -log_mpe - Prints extensive log information

2080:    Notes:
2081:    A related routine is PetscLogDefaultBegin() (with the options key -log_summary), which is
2082:    intended for production runs since it logs only flop rates and object
2083:    creation (and should not significantly slow the programs).

2085:    Level: advanced

2087:    Concepts: logging^MPE
2088:    Concepts: logging^message passing

2090: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2091:           PetscLogEventDeactivate()
2092: @*/
2093: PetscErrorCode  PetscLogMPEBegin(void)
2094: {

2098:   /* Do MPE initialization */
2099:   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2100:     PetscInfo(0,"Initializing MPE.\n");
2101:     MPE_Init_log();

2103:     PetscBeganMPE = PETSC_TRUE;
2104:   } else {
2105:     PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");
2106:   }
2107:   PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);
2108:   return(0);
2109: }

2113: /*@C
2114:    PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.

2116:    Collective over PETSC_COMM_WORLD

2118:    Level: advanced

2120: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2121: @*/
2122: PetscErrorCode  PetscLogMPEDump(const char sname[])
2123: {
2124:   char           name[PETSC_MAX_PATH_LEN];

2128:   if (PetscBeganMPE) {
2129:     PetscInfo(0,"Finalizing MPE.\n");
2130:     if (sname) {
2131:       PetscStrcpy(name,sname);
2132:     } else {
2133:       PetscGetProgramName(name,PETSC_MAX_PATH_LEN);
2134:     }
2135:     MPE_Finish_log(name);
2136:   } else {
2137:     PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");
2138:   }
2139:   return(0);
2140: }

2142: #define PETSC_RGB_COLORS_MAX 39
2143: static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2144:   "OliveDrab:      ",
2145:   "BlueViolet:     ",
2146:   "CadetBlue:      ",
2147:   "CornflowerBlue: ",
2148:   "DarkGoldenrod:  ",
2149:   "DarkGreen:      ",
2150:   "DarkKhaki:      ",
2151:   "DarkOliveGreen: ",
2152:   "DarkOrange:     ",
2153:   "DarkOrchid:     ",
2154:   "DarkSeaGreen:   ",
2155:   "DarkSlateGray:  ",
2156:   "DarkTurquoise:  ",
2157:   "DeepPink:       ",
2158:   "DarkKhaki:      ",
2159:   "DimGray:        ",
2160:   "DodgerBlue:     ",
2161:   "GreenYellow:    ",
2162:   "HotPink:        ",
2163:   "IndianRed:      ",
2164:   "LavenderBlush:  ",
2165:   "LawnGreen:      ",
2166:   "LemonChiffon:   ",
2167:   "LightCoral:     ",
2168:   "LightCyan:      ",
2169:   "LightPink:      ",
2170:   "LightSalmon:    ",
2171:   "LightSlateGray: ",
2172:   "LightYellow:    ",
2173:   "LimeGreen:      ",
2174:   "MediumPurple:   ",
2175:   "MediumSeaGreen: ",
2176:   "MediumSlateBlue:",
2177:   "MidnightBlue:   ",
2178:   "MintCream:      ",
2179:   "MistyRose:      ",
2180:   "NavajoWhite:    ",
2181:   "NavyBlue:       ",
2182:   "OliveDrab:      "
2183: };

2187: /*@C
2188:   PetscLogMPEGetRGBColor - This routine returns a rgb color useable with PetscLogEventRegister()

2190:   Not collective. Maybe it should be?

2192:   Output Parameter
2193: . str - character string representing the color

2195:   Level: developer

2197: .keywords: log, mpe , color
2198: .seealso: PetscLogEventRegister
2199: @*/
2200: PetscErrorCode  PetscLogMPEGetRGBColor(const char *str[])
2201: {
2202:   static int idx = 0;

2205:   *str = PetscLogMPERGBColors[idx];
2206:   idx  = (idx + 1)% PETSC_RGB_COLORS_MAX;
2207:   return(0);
2208: }

2210: #endif /* PETSC_USE_LOG && PETSC_HAVE_MPE */