Actual source code: plog.c

petsc-master 2016-08-29
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: #if defined(PETSC_HAVE_PAPI)
196: #include <papi.h>
197: int PAPIEventSet = PAPI_NULL;
198: #endif

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

214:   if (PetscLogInitializeCalled) return(0);
215:   PetscLogInitializeCalled = PETSC_TRUE;

217:   PetscOptionsHasName(NULL,NULL, "-log_exclude_actions", &opt);
218:   if (opt) petsc_logActions = PETSC_FALSE;
219:   PetscOptionsHasName(NULL,NULL, "-log_exclude_objects", &opt);
220:   if (opt) petsc_logObjects = PETSC_FALSE;
221:   if (petsc_logActions) {
222:     PetscMalloc1(petsc_maxActions, &petsc_actions);
223:   }
224:   if (petsc_logObjects) {
225:     PetscMalloc1(petsc_maxObjects, &petsc_objects);
226:   }
227:   PetscLogPHC = PetscLogObjCreateDefault;
228:   PetscLogPHD = PetscLogObjDestroyDefault;
229:   /* Setup default logging structures */
230:   PetscStageLogCreate(&petsc_stageLog);
231:   PetscStageLogRegister(petsc_stageLog, "Main Stage", &stage);
232: #if defined(PETSC_HAVE_PAPI)
233:   PAPI_library_init(PAPI_VER_CURRENT);
234:   if (ierr != PAPI_VER_CURRENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot initialize PAPI");
235:   PAPI_query_event(PAPI_FP_INS);
236:   PAPI_create_eventset(&PAPIEventSet);
237:   PAPI_add_event(PAPIEventSet,PAPI_FP_INS);
238:   PAPI_start(PAPIEventSet);
239: #endif

241:   /* All processors sync here for more consistent logging */
242:   MPI_Barrier(PETSC_COMM_WORLD);
243:   PetscTime(&petsc_BaseTime);
244:   PetscLogStagePush(stage);
245:   return(0);
246: }

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

255:   Logically Collective over PETSC_COMM_WORLD

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

261:   Usage:
262: .vb
263:       PetscInitialize(...);
264:       PetscLogDefaultBegin();
265:        ... code ...
266:       PetscLogView(viewer); or PetscLogDump();
267:       PetscFinalize();
268: .ve

270:   Notes:
271:   PetscLogView(viewer) or PetscLogDump() actually cause the printing of
272:   the logging information.

274:   Level: advanced

276: .keywords: log, begin
277: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogTraceBegin()
278: @*/
279: PetscErrorCode  PetscLogDefaultBegin(void)
280: {

284:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
285:   return(0);
286: }

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

294:   Logically Collective on PETSC_COMM_WORLD

296:   Options Database Keys:
297: . -log_all - Prints extensive log information

299:   Usage:
300: .vb
301:      PetscInitialize(...);
302:      PetscLogAllBegin();
303:      ... code ...
304:      PetscLogDump(filename);
305:      PetscFinalize();
306: .ve

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

313:   Level: advanced

315: .keywords: log, all, begin
316: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogTraceBegin()
317: @*/
318: PetscErrorCode  PetscLogAllBegin(void)
319: {

323:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
324:   return(0);
325: }

329: /*@
330:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
331:   begins or ends, the event name is printed.

333:   Logically Collective on PETSC_COMM_WORLD

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

338:   Options Database Key:
339: . -log_trace [filename] - Activates PetscLogTraceBegin()

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

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

349:   Level: intermediate

351: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogDefaultBegin()
352: @*/
353: PetscErrorCode  PetscLogTraceBegin(FILE *file)
354: {

358:   petsc_tracefile = file;

360:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
361:   return(0);
362: }

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

369:   Not Collective

371:   Input Parameter:
372: . flag - PETSC_TRUE if actions are to be logged

374:   Level: intermediate

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

379:   Options Database Keys:
380: . -log_exclude_actions - Turns off actions logging

382: .keywords: log, stage, register
383: .seealso: PetscLogStagePush(), PetscLogStagePop()
384: @*/
385: PetscErrorCode  PetscLogActions(PetscBool flag)
386: {
388:   petsc_logActions = flag;
389:   return(0);
390: }

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

397:   Not Collective

399:   Input Parameter:
400: . flag - PETSC_TRUE if objects are to be logged

402:   Level: intermediate

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

407:   Options Database Keys:
408: . -log_exclude_objects - Turns off objects logging

410: .keywords: log, stage, register
411: .seealso: PetscLogStagePush(), PetscLogStagePop()
412: @*/
413: PetscErrorCode  PetscLogObjects(PetscBool flag)
414: {
416:   petsc_logObjects = flag;
417:   return(0);
418: }

420: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
423: /*@C
424:   PetscLogStageRegister - Attaches a charactor string name to a logging stage.

426:   Not Collective

428:   Input Parameter:
429: . sname - The name to associate with that stage

431:   Output Parameter:
432: . stage - The stage number

434:   Level: intermediate

436: .keywords: log, stage, register
437: .seealso: PetscLogStagePush(), PetscLogStagePop()
438: @*/
439: PetscErrorCode  PetscLogStageRegister(const char sname[],PetscLogStage *stage)
440: {
441:   PetscStageLog  stageLog;
442:   PetscLogEvent  event;

446:   PetscLogGetStageLog(&stageLog);
447:   PetscStageLogRegister(stageLog, sname, stage);
448:   /* Copy events already changed in the main stage, this sucks */
449:   PetscEventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
450:   for (event = 0; event < stageLog->eventLog->numEvents; event++) {
451:     PetscEventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],&stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
452:   }
453:   PetscClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
454:   return(0);
455: }

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

462:   Not Collective

464:   Input Parameter:
465: . stage - The stage on which to log

467:   Usage:
468:   If the option -log_sumary is used to run the program containing the
469:   following code, then 2 sets of summary data will be printed during
470:   PetscFinalize().
471: .vb
472:       PetscInitialize(int *argc,char ***args,0,0);
473:       [stage 0 of code]
474:       PetscLogStagePush(1);
475:       [stage 1 of code]
476:       PetscLogStagePop();
477:       PetscBarrier(...);
478:       [more stage 0 of code]
479:       PetscFinalize();
480: .ve

482:   Notes:
483:   Use PetscLogStageRegister() to register a stage.

485:   Level: intermediate

487: .keywords: log, push, stage
488: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
489: @*/
490: PetscErrorCode  PetscLogStagePush(PetscLogStage stage)
491: {
492:   PetscStageLog  stageLog;

496:   PetscLogGetStageLog(&stageLog);
497:   PetscStageLogPush(stageLog, stage);
498:   return(0);
499: }

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

506:   Not Collective

508:   Usage:
509:   If the option -log_sumary is used to run the program containing the
510:   following code, then 2 sets of summary data will be printed during
511:   PetscFinalize().
512: .vb
513:       PetscInitialize(int *argc,char ***args,0,0);
514:       [stage 0 of code]
515:       PetscLogStagePush(1);
516:       [stage 1 of code]
517:       PetscLogStagePop();
518:       PetscBarrier(...);
519:       [more stage 0 of code]
520:       PetscFinalize();
521: .ve

523:   Notes:
524:   Use PetscLogStageRegister() to register a stage.

526:   Level: intermediate

528: .keywords: log, pop, stage
529: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
530: @*/
531: PetscErrorCode  PetscLogStagePop(void)
532: {
533:   PetscStageLog  stageLog;

537:   PetscLogGetStageLog(&stageLog);
538:   PetscStageLogPop(stageLog);
539:   return(0);
540: }

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

547:   Not Collective

549:   Input Parameters:
550: + stage    - The stage
551: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

553:   Level: intermediate

555: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
556: @*/
557: PetscErrorCode  PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
558: {
559:   PetscStageLog  stageLog;

563:   PetscLogGetStageLog(&stageLog);
564:   PetscStageLogSetActive(stageLog, stage, isActive);
565:   return(0);
566: }

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

573:   Not Collective

575:   Input Parameter:
576: . stage    - The stage

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

581:   Level: intermediate

583: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
584: @*/
585: PetscErrorCode  PetscLogStageGetActive(PetscLogStage stage, PetscBool  *isActive)
586: {
587:   PetscStageLog  stageLog;

591:   PetscLogGetStageLog(&stageLog);
592:   PetscStageLogGetActive(stageLog, stage, isActive);
593:   return(0);
594: }

598: /*@
599:   PetscLogStageSetVisible - Determines stage visibility in PetscLogView()

601:   Not Collective

603:   Input Parameters:
604: + stage     - The stage
605: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

607:   Level: intermediate

609: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
610: @*/
611: PetscErrorCode  PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
612: {
613:   PetscStageLog  stageLog;

617:   PetscLogGetStageLog(&stageLog);
618:   PetscStageLogSetVisible(stageLog, stage, isVisible);
619:   return(0);
620: }

624: /*@
625:   PetscLogStageGetVisible - Returns stage visibility in PetscLogView()

627:   Not Collective

629:   Input Parameter:
630: . stage     - The stage

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

635:   Level: intermediate

637: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
638: @*/
639: PetscErrorCode  PetscLogStageGetVisible(PetscLogStage stage, PetscBool  *isVisible)
640: {
641:   PetscStageLog  stageLog;

645:   PetscLogGetStageLog(&stageLog);
646:   PetscStageLogGetVisible(stageLog, stage, isVisible);
647:   return(0);
648: }

652: /*@C
653:   PetscLogStageGetId - Returns the stage id when given the stage name.

655:   Not Collective

657:   Input Parameter:
658: . name  - The stage name

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

663:   Level: intermediate

665: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
666: @*/
667: PetscErrorCode  PetscLogStageGetId(const char name[], PetscLogStage *stage)
668: {
669:   PetscStageLog  stageLog;

673:   PetscLogGetStageLog(&stageLog);
674:   PetscStageLogGetStage(stageLog, name, stage);
675:   return(0);
676: }

678: /*------------------------------------------------ Event Functions --------------------------------------------------*/
681: /*@C
682:   PetscLogEventRegister - Registers an event name for logging operations in an application code.

684:   Not Collective

686:   Input Parameter:
687: + name   - The name associated with the event
688: - classid - The classid associated to the class for this event, obtain either with
689:            PetscClassIdRegister() or use a predefined one such as KSP_CLASSID, SNES_CLASSID, the predefined ones
690:            are only available in C code

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

695:   Example of Usage:
696: .vb
697:       PetscLogEvent USER_EVENT;
698:       PetscClassId classid;
699:       PetscLogDouble user_event_flops;
700:       PetscClassIdRegister("class name",&classid);
701:       PetscLogEventRegister("User event name",classid,&USER_EVENT);
702:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
703:          [code segment to monitor]
704:          PetscLogFlops(user_event_flops);
705:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
706: .ve

708:   Notes:
709:   PETSc automatically logs library events if the code has been
710:   configured with --with-log (which is the default) and
711:   -log_view or -log_all is specified.  PetscLogEventRegister() is
712:   intended for logging user events to supplement this PETSc
713:   information.

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

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

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

730:   Level: intermediate

732: .keywords: log, event, register
733: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
734:           PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
735:           PetscLogEventActivate(), PetscLogEventDeactivate(), PetscClassIdRegister()
736: @*/
737: PetscErrorCode  PetscLogEventRegister(const char name[],PetscClassId classid,PetscLogEvent *event)
738: {
739:   PetscStageLog  stageLog;
740:   int            stage;

744:   *event = PETSC_DECIDE;
745:   PetscLogGetStageLog(&stageLog);
746:   PetscEventRegLogGetEvent(stageLog->eventLog, name, event);
747:   if (*event > 0) return(0);
748:   PetscEventRegLogRegister(stageLog->eventLog, name, classid, event);
749:   for (stage = 0; stage < stageLog->numStages; stage++) {
750:     PetscEventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
751:     PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
752:   }
753:   return(0);
754: }

758: /*@
759:   PetscLogEventActivate - Indicates that a particular event should be logged.

761:   Not Collective

763:   Input Parameter:
764: . event - The event id

766:   Usage:
767: .vb
768:       PetscLogEventDeactivate(VEC_SetValues);
769:         [code where you do not want to log VecSetValues()]
770:       PetscLogEventActivate(VEC_SetValues);
771:         [code where you do want to log VecSetValues()]
772: .ve

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

778:   Level: advanced

780: .keywords: log, event, activate
781: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
782: @*/
783: PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
784: {
785:   PetscStageLog  stageLog;
786:   int            stage;

790:   PetscLogGetStageLog(&stageLog);
791:   PetscStageLogGetCurrent(stageLog, &stage);
792:   PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
793:   return(0);
794: }

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

801:   Not Collective

803:   Input Parameter:
804: . event - The event id

806:   Usage:
807: .vb
808:       PetscLogEventDeactivate(VEC_SetValues);
809:         [code where you do not want to log VecSetValues()]
810:       PetscLogEventActivate(VEC_SetValues);
811:         [code where you do want to log VecSetValues()]
812: .ve

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

818:   Level: advanced

820: .keywords: log, event, deactivate
821: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
822: @*/
823: PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
824: {
825:   PetscStageLog  stageLog;
826:   int            stage;

830:   PetscLogGetStageLog(&stageLog);
831:   PetscStageLogGetCurrent(stageLog, &stage);
832:   PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
833:   return(0);
834: }

838: /*@
839:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

841:   Not Collective

843:   Input Parameters:
844: + event    - The event id
845: - isActive - The activity flag determining whether the event is logged

847:   Level: advanced

849: .keywords: log, event, activate
850: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
851: @*/
852: PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
853: {
854:   PetscStageLog  stageLog;
855:   int            stage;

859:   PetscLogGetStageLog(&stageLog);
860:   for (stage = 0; stage < stageLog->numStages; stage++) {
861:     if (isActive) {
862:       PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
863:     } else {
864:       PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
865:     }
866:   }
867:   return(0);
868: }

872: /*@
873:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

875:   Not Collective

877:   Input Parameter:
878: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

880:   Level: developer

882: .keywords: log, event, activate, class
883: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
884: @*/
885: PetscErrorCode  PetscLogEventActivateClass(PetscClassId classid)
886: {
887:   PetscStageLog  stageLog;
888:   int            stage;

892:   PetscLogGetStageLog(&stageLog);
893:   PetscStageLogGetCurrent(stageLog, &stage);
894:   PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
895:   return(0);
896: }

900: /*@
901:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

903:   Not Collective

905:   Input Parameter:
906: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

908:   Level: developer

910: .keywords: log, event, deactivate, class
911: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
912: @*/
913: PetscErrorCode  PetscLogEventDeactivateClass(PetscClassId classid)
914: {
915:   PetscStageLog  stageLog;
916:   int            stage;

920:   PetscLogGetStageLog(&stageLog);
921:   PetscStageLogGetCurrent(stageLog, &stage);
922:   PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
923:   return(0);
924: }

926: /*MC
927:    PetscLogEventBegin - Logs the beginning of a user event.

929:    Synopsis:
930:    #include <petsclog.h>
931:    PetscErrorCode PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)

933:    Not Collective

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


940:    Fortran Synopsis:
941:    void PetscLogEventBegin(int e,PetscErrorCode ierr)

943:    Usage:
944: .vb
945:      PetscLogEvent USER_EVENT;
946:      PetscLogDouble user_event_flops;
947:      PetscLogEventRegister("User event",0,&USER_EVENT);
948:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
949:         [code segment to monitor]
950:         PetscLogFlops(user_event_flops);
951:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
952: .ve

954:    Notes:
955:    You need to register each integer event with the command
956:    PetscLogEventRegister().

958:    Level: intermediate

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

962: .keywords: log, event, begin
963: M*/

965: /*MC
966:    PetscLogEventEnd - Log the end of a user event.

968:    Synopsis:
969:    #include <petsclog.h>
970:    PetscErrorCode PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)

972:    Not Collective

974:    Input Parameters:
975: +  e - integer associated with the event obtained with PetscLogEventRegister()
976: -  o1,o2,o3,o4 - objects associated with the event, or 0


979:    Fortran Synopsis:
980:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

982:    Usage:
983: .vb
984:      PetscLogEvent USER_EVENT;
985:      PetscLogDouble user_event_flops;
986:      PetscLogEventRegister("User event",0,&USER_EVENT,);
987:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
988:         [code segment to monitor]
989:         PetscLogFlops(user_event_flops);
990:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
991: .ve

993:    Notes:
994:    You should also register each additional integer event with the command
995:    PetscLogEventRegister().

997:    Level: intermediate

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

1001: .keywords: log, event, end
1002: M*/

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

1007:    Synopsis:
1008:    #include <petsclog.h>
1009:    PetscErrorCode PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)

1011:    Not Collective

1013:    Input Parameters:
1014: .  e - integer associated with the event obtained from PetscLogEventRegister()
1015: .  o1,o2,o3,o4 - objects associated with the event, or 0
1016: .  comm - communicator the barrier takes place over


1019:    Usage:
1020: .vb
1021:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1022:        MPIU_Allreduce()
1023:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1024: .ve

1026:    Notes:
1027:    This is for logging the amount of time spent in a barrier for an event
1028:    that requires synchronization.

1030:    Additional Notes:
1031:    Synchronization events always come in pairs; for example, VEC_NormBarrier and
1032:    VEC_NormComm = VEC_NormBarrier + 1

1034:    Level: advanced

1036: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1037:           PetscLogEventBarrierEnd()

1039: .keywords: log, event, begin, barrier
1040: M*/

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

1045:    Synopsis:
1046:    #include <petsclog.h>
1047:    PetscErrorCode PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)

1049:    Logically Collective on MPI_Comm

1051:    Input Parameters:
1052: .  e - integer associated with the event obtained from PetscLogEventRegister()
1053: .  o1,o2,o3,o4 - objects associated with the event, or 0
1054: .  comm - communicator the barrier takes place over


1057:     Usage:
1058: .vb
1059:      PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1060:        MPIU_Allreduce()
1061:      PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1062: .ve

1064:    Notes:
1065:    This is for logging the amount of time spent in a barrier for an event
1066:    that requires synchronization.

1068:    Additional Notes:
1069:    Synchronization events always come in pairs; for example, VEC_NormBarrier and
1070:    VEC_NormComm = VEC_NormBarrier + 1

1072:    Level: advanced

1074: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1075:           PetscLogEventBarrierBegin()

1077: .keywords: log, event, begin, barrier
1078: M*/

1082: /*@C
1083:   PetscLogEventGetId - Returns the event id when given the event name.

1085:   Not Collective

1087:   Input Parameter:
1088: . name  - The event name

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

1093:   Level: intermediate

1095: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1096: @*/
1097: PetscErrorCode  PetscLogEventGetId(const char name[], PetscLogEvent *event)
1098: {
1099:   PetscStageLog  stageLog;

1103:   PetscLogGetStageLog(&stageLog);
1104:   PetscEventRegLogGetEvent(stageLog->eventLog, name, event);
1105:   return(0);
1106: }


1109: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1112: /*@C
1113:   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1114:   be read by bin/petscview. This program no longer exists.

1116:   Collective on PETSC_COMM_WORLD

1118:   Input Parameter:
1119: . name - an optional file name

1121:   Usage:
1122: .vb
1123:      PetscInitialize(...);
1124:      PetscLogDefaultBegin(); or PetscLogAllBegin();
1125:      ... code ...
1126:      PetscLogDump(filename);
1127:      PetscFinalize();
1128: .ve

1130:   Notes:
1131:   The default file name is
1132: $    Log.<rank>
1133:   where <rank> is the processor number. If no name is specified,
1134:   this file will be used.

1136:   Level: advanced

1138: .keywords: log, dump
1139: .seealso: PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogView()
1140: @*/
1141: PetscErrorCode  PetscLogDump(const char sname[])
1142: {
1143:   PetscStageLog      stageLog;
1144:   PetscEventPerfInfo *eventInfo;
1145:   FILE               *fd;
1146:   char               file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1147:   PetscLogDouble     flops, _TotalTime;
1148:   PetscMPIInt        rank;
1149:   int                action, object, curStage;
1150:   PetscLogEvent      event;
1151:   PetscErrorCode     ierr;

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

1210: /*
1211:   PetscLogView_Detailed - Each process prints the times for its own events

1213: */
1214: PetscErrorCode  PetscLogView_Detailed(PetscViewer viewer)
1215: {
1216:   MPI_Comm           comm       = PetscObjectComm((PetscObject) viewer);
1217:   PetscEventPerfInfo *eventInfo = NULL;
1218:   PetscLogDouble     locTotalTime, numRed, maxMem;
1219:   PetscStageLog      stageLog;
1220:   int                numStages,numEvents,stage,event;
1221:   PetscMPIInt        rank,size;
1222:   PetscErrorCode     ierr;

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

1280: static PetscErrorCode PetscLogViewWarnDebugging(MPI_Comm comm,FILE *fd)
1281: {
1282: #if defined(PETSC_USE_DEBUG)

1286:   PetscFPrintf(comm, fd, "\n\n");
1287:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1288:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1289:   PetscFPrintf(comm, fd, "      #                          WARNING!!!                    #\n");
1290:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1291:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option,      #\n");
1292:   PetscFPrintf(comm, fd, "      #   To get timing results run ./configure                #\n");
1293:   PetscFPrintf(comm, fd, "      #   using --with-debugging=no, the performance will      #\n");
1294:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");
1295:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1296:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1297:   return(0);
1298: #else
1299:   return 0;
1300: #endif
1301: }

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

1334:   PetscObjectGetComm((PetscObject)viewer,&comm);
1335:   PetscViewerASCIIGetPointer(viewer,&fd);
1336:   MPI_Comm_size(comm, &size);
1337:   MPI_Comm_rank(comm, &rank);
1338:   /* Get the total elapsed time */
1339:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;

1341:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1342:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1343:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1344:   PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1345:   PetscLogViewWarnDebugging(comm,fd);
1346:   PetscGetArchType(arch,sizeof(arch));
1347:   PetscGetHostName(hostname,sizeof(hostname));
1348:   PetscGetUserName(username,sizeof(username));
1349:   PetscGetProgramName(pname,sizeof(pname));
1350:   PetscGetDate(date,sizeof(date));
1351:   PetscGetVersion(version,sizeof(version));
1352:   if (size == 1) {
1353:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1354:   } else {
1355:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1356:   }

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

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

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

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

1509:   PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");
1510:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1511:   PetscFPrintf(comm, fd, "Phase summary info:\n");
1512:   PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");
1513:   PetscFPrintf(comm, fd, "   Time and Flops: Max - maximum over all processors\n");
1514:   PetscFPrintf(comm, fd, "                   Ratio - ratio of maximum to minimum over all processors\n");
1515:   PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");
1516:   PetscFPrintf(comm, fd, "   Avg. len: average message length (bytes)\n");
1517:   PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");
1518:   PetscFPrintf(comm, fd, "   Global: entire computation\n");
1519:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1520:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flops in this phase\n");
1521:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");
1522:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");
1523:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1524:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");

1526:   PetscLogViewWarnDebugging(comm,fd);

1528:   /* Report events */
1529:   PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flops                             --- Global ---  --- Stage ---   Total\n");
1530:   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");
1531:   PetscFPrintf(comm,fd,"------------------------------------------------------------------------------------------------------------------------\n");

1533:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1534:   for (stage = 0; stage < numStages; stage++) {
1535:     if (!stageVisible[stage]) continue;
1536:     /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1537:     if (localStageUsed[stage]) {
1538:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1539:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1540:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1541:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1542:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1543:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1544:     } else {
1545:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1546:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1547:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1548:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1549:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1550:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1551:     }
1552:     mess *= 0.5; messLen *= 0.5; red /= size;

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

1559:        Problem: If the event did not happen on proc 1, its name will not be available.
1560:        Problem: Event visibility is not implemented
1561:     */
1562:     if (localStageUsed[stage]) {
1563:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1564:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1565:     } else localNumEvents = 0;
1566:     MPIU_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1567:     for (event = 0; event < numEvents; event++) {
1568:       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1569:       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1570:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops;
1571:         else flopr = 0.0;

1573:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1574:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1575:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1576:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1577:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1578:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1579:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1580:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1581:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1582:         MPI_Allreduce(&eventInfo[event].count,         &minCt, 1, MPI_INT,             MPI_MIN, comm);
1583:         MPI_Allreduce(&eventInfo[event].count,         &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1584:         name = stageLog->eventLog->eventInfo[event].name;
1585:       } else {
1586:         flopr = 0.0;
1587:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1588:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1589:         MPI_Allreduce(&zero,                           &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1590:         MPI_Allreduce(&zero,                           &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1591:         MPI_Allreduce(&zero,                           &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1592:         MPI_Allreduce(&zero,                           &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1593:         MPI_Allreduce(&zero,                           &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1594:         MPI_Allreduce(&zero,                           &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1595:         MPI_Allreduce(&zero,                           &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1596:         MPI_Allreduce(&ierr,                           &minCt, 1, MPI_INT,             MPI_MIN, comm);
1597:         MPI_Allreduce(&ierr,                           &maxCt, 1, MPI_INT,             MPI_MAX, comm);
1598:         name  = "";
1599:       }
1600:       if (mint < 0.0) {
1601:         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);
1602:         mint = 0;
1603:       }
1604:       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);
1605:       totm *= 0.5; totml *= 0.5; totr /= size;

1607:       if (maxCt != 0) {
1608:         if (minCt         != 0)   ratCt            = ((PetscLogDouble) maxCt)/minCt; else ratCt            = 0.0;
1609:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1610:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1611:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1612:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1613:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1614:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1615:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1616:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1617:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1618:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1619:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1620:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1621:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1622:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1623:         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");
1624:         PetscFPrintf(comm, fd,
1625:           "%-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",
1626:                             name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1627:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1628:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1629:                             PetscAbsReal(flopr/1.0e6));
1630:       }
1631:     }
1632:   }

1634:   /* Memory usage and object creation */
1635:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");
1636:   PetscFPrintf(comm, fd, "\n");
1637:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

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

1662:   PetscFree(localStageUsed);
1663:   PetscFree(stageUsed);
1664:   PetscFree(localStageVisible);
1665:   PetscFree(stageVisible);

1667:   /* Information unrelated to this particular run */
1668:   PetscFPrintf(comm, fd, "========================================================================================================================\n");
1669:   PetscTime(&y);
1670:   PetscTime(&x);
1671:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1672:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1673:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1674:   /* MPI information */
1675:   if (size > 1) {
1676:     MPI_Status  status;
1677:     PetscMPIInt tag;
1678:     MPI_Comm    newcomm;

1680:     MPI_Barrier(comm);
1681:     PetscTime(&x);
1682:     MPI_Barrier(comm);
1683:     MPI_Barrier(comm);
1684:     MPI_Barrier(comm);
1685:     MPI_Barrier(comm);
1686:     MPI_Barrier(comm);
1687:     PetscTime(&y);
1688:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1689:     PetscCommDuplicate(comm,&newcomm, &tag);
1690:     MPI_Barrier(comm);
1691:     if (rank) {
1692:       MPI_Recv(0, 0, MPI_INT, rank-1,            tag, newcomm, &status);
1693:       MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1694:     } else {
1695:       PetscTime(&x);
1696:       MPI_Send(0, 0, MPI_INT, 1,          tag, newcomm);
1697:       MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1698:       PetscTime(&y);
1699:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1700:     }
1701:     PetscCommDestroy(&newcomm);
1702:   }
1703:   PetscOptionsView(NULL,viewer);

1705:   /* Machine and compile information */
1706: #if defined(PETSC_USE_FORTRAN_KERNELS)
1707:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1708: #else
1709:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1710: #endif
1711: #if defined(PETSC_USE_REAL_SINGLE)
1712:   PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1713: #elif defined(PETSC_USE_LONGDOUBLE)
1714:   PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1715: #endif

1717: #if defined(PETSC_USE_REAL_MAT_SINGLE)
1718:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1719: #else
1720:   PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1721: #endif
1722:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1723:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));

1725:   PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1726:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1727:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1728:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1729:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1731:   /* Cleanup */
1732:   PetscFPrintf(comm, fd, "\n");
1733:   PetscLogViewWarnDebugging(comm,fd);
1734:   return(0);
1735: }

1737: PetscErrorCode  PetscLogView_Nested(PetscViewer);

1741: /*@C
1742:   PetscLogView - Prints a summary of the logging.

1744:   Collective over MPI_Comm

1746:   Input Parameter:
1747: .  viewer - an ASCII viewer

1749:   Options Database Keys:
1750: +  -log_view [:filename] - Prints summary of log information
1751: .  -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1752: .  -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
1753:              Apple MacOS systems use open -a Safari filename.xml
1754: .  -log_all - Saves a file Log.rank for each MPI process with details of each step of the computation
1755: -  -log_trace [filename] - Displays a trace of what each process is doing

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

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

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

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

1767:   Level: beginner

1769: .keywords: log, dump, print
1770: .seealso: PetscLogDefaultBegin(), PetscLogDump()
1771: @*/
1772: PetscErrorCode  PetscLogView(PetscViewer viewer)
1773: {
1774:   PetscErrorCode    ierr;
1775:   PetscBool         isascii;
1776:   PetscViewerFormat format;
1777:   int               stage, lastStage;
1778:   PetscStageLog     stageLog;

1781:   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_summary or PetscLogDefaultBegin() before calling this routine");
1782:   /* Pop off any stages the user forgot to remove */
1783:   lastStage = 0;
1784:   PetscLogGetStageLog(&stageLog);
1785:   PetscStageLogGetCurrent(stageLog, &stage);
1786:   while (stage >= 0) {
1787:     lastStage = stage;
1788:     PetscStageLogPop(stageLog);
1789:     PetscStageLogGetCurrent(stageLog, &stage);
1790:   }
1791:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
1792:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
1793:   PetscViewerGetFormat(viewer,&format);
1794:   if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
1795:     PetscLogView_Default(viewer);
1796:   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1797:     PetscLogView_Detailed(viewer);
1798:   } else if (format == PETSC_VIEWER_ASCII_XML) {
1799:     PetscLogView_Nested(viewer);
1800:   }
1801:   PetscStageLogPush(stageLog, lastStage);
1802:   return(0);
1803: }

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

1810:   Collective on PETSC_COMM_WORLD

1812:   Not normally called by user

1814:   Level: intermediate

1816: @*/
1817: PetscErrorCode PetscLogViewFromOptions(void)
1818: {
1819:   PetscErrorCode    ierr;
1820:   PetscViewer       viewer;
1821:   PetscBool         flg;
1822:   PetscViewerFormat format;

1825:   PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,"-log_view",&viewer,&format,&flg);
1826:   if (flg) {
1827:     PetscViewerPushFormat(viewer,format);
1828:     PetscLogView(viewer);
1829:     PetscViewerPopFormat(viewer);
1830:     PetscViewerDestroy(&viewer);
1831:   }
1832:   return(0);
1833: }



1837: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1840: /*@C
1841:    PetscGetFlops - Returns the number of flops used on this processor
1842:    since the program began.

1844:    Not Collective

1846:    Output Parameter:
1847:    flops - number of floating point operations

1849:    Notes:
1850:    A global counter logs all PETSc flop counts.  The user can use
1851:    PetscLogFlops() to increment this counter to include flops for the
1852:    application code.

1854:    Level: intermediate

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

1858: .seealso: PetscTime(), PetscLogFlops()
1859: @*/
1860: PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
1861: {
1863:   *flops = petsc_TotalFlops;
1864:   return(0);
1865: }

1869: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
1870: {
1872:   size_t         fullLength;
1873:   va_list        Argp;

1876:   if (!petsc_logObjects) return(0);
1877:   va_start(Argp, format);
1878:   PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);
1879:   va_end(Argp);
1880:   return(0);
1881: }


1884: /*MC
1885:    PetscLogFlops - Adds floating point operations to the global counter.

1887:    Synopsis:
1888:    #include <petsclog.h>
1889:    PetscErrorCode PetscLogFlops(PetscLogDouble f)

1891:    Not Collective

1893:    Input Parameter:
1894: .  f - flop counter


1897:    Usage:
1898: .vb
1899:      PetscLogEvent USER_EVENT;
1900:      PetscLogEventRegister("User event",0,&USER_EVENT);
1901:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1902:         [code segment to monitor]
1903:         PetscLogFlops(user_flops)
1904:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1905: .ve

1907:    Notes:
1908:    A global counter logs all PETSc flop counts.  The user can use
1909:    PetscLogFlops() to increment this counter to include flops for the
1910:    application code.

1912:    Level: intermediate

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

1916: .keywords: log, flops, floating point operations
1917: M*/

1919: /*MC
1920:    PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1921:     to get accurate timings

1923:    Synopsis:
1924:    #include <petsclog.h>
1925:    void PetscPreLoadBegin(PetscBool  flag,char *name);

1927:    Not Collective

1929:    Input Parameter:
1930: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1931:            with command line option -preload true or -preload false
1932: -   name - name of first stage (lines of code timed separately with -log_summary) to
1933:            be preloaded

1935:    Usage:
1936: .vb
1937:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
1938:        lines of code
1939:        PetscPreLoadStage("second stage");
1940:        lines of code
1941:      PetscPreLoadEnd();
1942: .ve

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

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

1954:    Level: intermediate

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

1958:    Concepts: preloading
1959:    Concepts: timing^accurate
1960:    Concepts: paging^eliminating effects of


1963: M*/

1965: /*MC
1966:    PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
1967:     to get accurate timings

1969:    Synopsis:
1970:    #include <petsclog.h>
1971:    void PetscPreLoadEnd(void);

1973:    Not Collective

1975:    Usage:
1976: .vb
1977:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
1978:        lines of code
1979:        PetscPreLoadStage("second stage");
1980:        lines of code
1981:      PetscPreLoadEnd();
1982: .ve

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

1986:    Level: intermediate

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

1990: M*/

1992: /*MC
1993:    PetscPreLoadStage - Start a new segment of code to be timed separately.
1994:     to get accurate timings

1996:    Synopsis:
1997:    #include <petsclog.h>
1998:    void PetscPreLoadStage(char *name);

2000:    Not Collective

2002:    Usage:
2003: .vb
2004:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2005:        lines of code
2006:        PetscPreLoadStage("second stage");
2007:        lines of code
2008:      PetscPreLoadEnd();
2009: .ve

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

2013:    Level: intermediate

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

2017: M*/


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

2024: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2025: {
2027:   return(0);
2028: }

2030: #endif /* PETSC_USE_LOG*/


2033: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2034: PetscClassId PETSC_OBJECT_CLASSID  = 0;

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

2041:   Not Collective

2043:   Input Parameter:
2044: . name   - The class name

2046:   Output Parameter:
2047: . oclass - The class id or classid

2049:   Level: developer

2051: .keywords: log, class, register

2053: @*/
2054: PetscErrorCode  PetscClassIdRegister(const char name[],PetscClassId *oclass)
2055: {
2056: #if defined(PETSC_USE_LOG)
2057:   PetscStageLog  stageLog;
2058:   PetscInt       stage;
2060: #endif

2063:   *oclass = ++PETSC_LARGEST_CLASSID;
2064: #if defined(PETSC_USE_LOG)
2065:   PetscLogGetStageLog(&stageLog);
2066:   PetscClassRegLogRegister(stageLog->classLog, name, *oclass);
2067:   for (stage = 0; stage < stageLog->numStages; stage++) {
2068:     PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2069:   }
2070: #endif
2071:   return(0);
2072: }

2074: #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2075: #include <mpe.h>

2077: PetscBool PetscBeganMPE = PETSC_FALSE;

2079: PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2080: PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);

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

2088:    Collective over PETSC_COMM_WORLD

2090:    Options Database Keys:
2091: . -log_mpe - Prints extensive log information

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

2098:    Level: advanced

2100:    Concepts: logging^MPE
2101:    Concepts: logging^message passing

2103: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2104:           PetscLogEventDeactivate()
2105: @*/
2106: PetscErrorCode  PetscLogMPEBegin(void)
2107: {

2111:   /* Do MPE initialization */
2112:   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2113:     PetscInfo(0,"Initializing MPE.\n");
2114:     MPE_Init_log();

2116:     PetscBeganMPE = PETSC_TRUE;
2117:   } else {
2118:     PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");
2119:   }
2120:   PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);
2121:   return(0);
2122: }

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

2129:    Collective over PETSC_COMM_WORLD

2131:    Level: advanced

2133: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2134: @*/
2135: PetscErrorCode  PetscLogMPEDump(const char sname[])
2136: {
2137:   char           name[PETSC_MAX_PATH_LEN];

2141:   if (PetscBeganMPE) {
2142:     PetscInfo(0,"Finalizing MPE.\n");
2143:     if (sname) {
2144:       PetscStrcpy(name,sname);
2145:     } else {
2146:       PetscGetProgramName(name,PETSC_MAX_PATH_LEN);
2147:     }
2148:     MPE_Finish_log(name);
2149:   } else {
2150:     PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");
2151:   }
2152:   return(0);
2153: }

2155: #define PETSC_RGB_COLORS_MAX 39
2156: static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2157:   "OliveDrab:      ",
2158:   "BlueViolet:     ",
2159:   "CadetBlue:      ",
2160:   "CornflowerBlue: ",
2161:   "DarkGoldenrod:  ",
2162:   "DarkGreen:      ",
2163:   "DarkKhaki:      ",
2164:   "DarkOliveGreen: ",
2165:   "DarkOrange:     ",
2166:   "DarkOrchid:     ",
2167:   "DarkSeaGreen:   ",
2168:   "DarkSlateGray:  ",
2169:   "DarkTurquoise:  ",
2170:   "DeepPink:       ",
2171:   "DarkKhaki:      ",
2172:   "DimGray:        ",
2173:   "DodgerBlue:     ",
2174:   "GreenYellow:    ",
2175:   "HotPink:        ",
2176:   "IndianRed:      ",
2177:   "LavenderBlush:  ",
2178:   "LawnGreen:      ",
2179:   "LemonChiffon:   ",
2180:   "LightCoral:     ",
2181:   "LightCyan:      ",
2182:   "LightPink:      ",
2183:   "LightSalmon:    ",
2184:   "LightSlateGray: ",
2185:   "LightYellow:    ",
2186:   "LimeGreen:      ",
2187:   "MediumPurple:   ",
2188:   "MediumSeaGreen: ",
2189:   "MediumSlateBlue:",
2190:   "MidnightBlue:   ",
2191:   "MintCream:      ",
2192:   "MistyRose:      ",
2193:   "NavajoWhite:    ",
2194:   "NavyBlue:       ",
2195:   "OliveDrab:      "
2196: };

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

2203:   Not collective. Maybe it should be?

2205:   Output Parameter
2206: . str - character string representing the color

2208:   Level: developer

2210: .keywords: log, mpe , color
2211: .seealso: PetscLogEventRegister
2212: @*/
2213: PetscErrorCode  PetscLogMPEGetRGBColor(const char *str[])
2214: {
2215:   static int idx = 0;

2218:   *str = PetscLogMPERGBColors[idx];
2219:   idx  = (idx + 1)% PETSC_RGB_COLORS_MAX;
2220:   return(0);
2221: }

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