Actual source code: plog.c

petsc-master 2019-06-26
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:
 35:     Currently we do not always do a good job of associating all memory allocations with an object.

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

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

 47: PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT;

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

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

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

 64: /* Global counters */
 65: PetscLogDouble petsc_BaseTime        = 0.0;
 66: PetscLogDouble petsc_TotalFlops      = 0.0;  /* The number of flops */
 67: PetscLogDouble petsc_tmp_flops       = 0.0;  /* The incremental number of flops */
 68: PetscLogDouble petsc_send_ct         = 0.0;  /* The number of sends */
 69: PetscLogDouble petsc_recv_ct         = 0.0;  /* The number of receives */
 70: PetscLogDouble petsc_send_len        = 0.0;  /* The total length of all sent messages */
 71: PetscLogDouble petsc_recv_len        = 0.0;  /* The total length of all received messages */
 72: PetscLogDouble petsc_isend_ct        = 0.0;  /* The number of immediate sends */
 73: PetscLogDouble petsc_irecv_ct        = 0.0;  /* The number of immediate receives */
 74: PetscLogDouble petsc_isend_len       = 0.0;  /* The total length of all immediate send messages */
 75: PetscLogDouble petsc_irecv_len       = 0.0;  /* The total length of all immediate receive messages */
 76: PetscLogDouble petsc_wait_ct         = 0.0;  /* The number of waits */
 77: PetscLogDouble petsc_wait_any_ct     = 0.0;  /* The number of anywaits */
 78: PetscLogDouble petsc_wait_all_ct     = 0.0;  /* The number of waitalls */
 79: PetscLogDouble petsc_sum_of_waits_ct = 0.0;  /* The total number of waits */
 80: PetscLogDouble petsc_allreduce_ct    = 0.0;  /* The number of reductions */
 81: PetscLogDouble petsc_gather_ct       = 0.0;  /* The number of gathers and gathervs */
 82: PetscLogDouble petsc_scatter_ct      = 0.0;  /* The number of scatters and scattervs */
 83: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
 84: PetscLogDouble petsc_ctog_ct         = 0.0;  /* The total number of CPU to GPU copies */
 85: PetscLogDouble petsc_gtoc_ct         = 0.0;  /* The total number of GPU to CPU copies */
 86: PetscLogDouble petsc_ctog_sz         = 0.0;  /* The total size of CPU to GPU copies */
 87: PetscLogDouble petsc_gtoc_sz         = 0.0;  /* The total size of GPU to CPU copies */
 88: #endif

 90: /* Logging functions */
 91: PetscErrorCode (*PetscLogPHC)(PetscObject) = NULL;
 92: PetscErrorCode (*PetscLogPHD)(PetscObject) = NULL;
 93: PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
 94: PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;

 96: /* Tracing event logging variables */
 97: FILE             *petsc_tracefile            = NULL;
 98: int              petsc_tracelevel            = 0;
 99: const char       *petsc_traceblanks          = "                                                                                                    ";
100: char             petsc_tracespace[128]       = " ";
101: PetscLogDouble   petsc_tracetime             = 0.0;
102: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;

104: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
105: {
106:   int            stage;
107:   PetscBool      opt;

111:   if (PetscLogInitializeCalled) return(0);
112:   PetscLogInitializeCalled = PETSC_TRUE;

114:   PetscOptionsHasName(NULL,NULL, "-log_exclude_actions", &opt);
115:   if (opt) petsc_logActions = PETSC_FALSE;
116:   PetscOptionsHasName(NULL,NULL, "-log_exclude_objects", &opt);
117:   if (opt) petsc_logObjects = PETSC_FALSE;
118:   if (petsc_logActions) {
119:     PetscMalloc1(petsc_maxActions, &petsc_actions);
120:   }
121:   if (petsc_logObjects) {
122:     PetscMalloc1(petsc_maxObjects, &petsc_objects);
123:   }
124:   PetscLogPHC = PetscLogObjCreateDefault;
125:   PetscLogPHD = PetscLogObjDestroyDefault;
126:   /* Setup default logging structures */
127:   PetscStageLogCreate(&petsc_stageLog);
128:   PetscStageLogRegister(petsc_stageLog, "Main Stage", &stage);

130:   /* All processors sync here for more consistent logging */
131:   MPI_Barrier(PETSC_COMM_WORLD);
132:   PetscTime(&petsc_BaseTime);
133:   PetscLogStagePush(stage);
134:   return(0);
135: }

137: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
138: {
139:   PetscStageLog  stageLog;

143:   PetscFree(petsc_actions);
144:   PetscFree(petsc_objects);
145:   PetscLogNestedEnd();
146:   PetscLogSet(NULL, NULL);

148:   /* Resetting phase */
149:   PetscLogGetStageLog(&stageLog);
150:   PetscStageLogDestroy(stageLog);

152:   petsc_TotalFlops            = 0.0;
153:   petsc_numActions            = 0;
154:   petsc_numObjects            = 0;
155:   petsc_numObjectsDestroyed   = 0;
156:   petsc_maxActions            = 100;
157:   petsc_maxObjects            = 100;
158:   petsc_actions               = NULL;
159:   petsc_objects               = NULL;
160:   petsc_logActions            = PETSC_FALSE;
161:   petsc_logObjects            = PETSC_FALSE;
162:   petsc_BaseTime              = 0.0;
163:   petsc_TotalFlops            = 0.0;
164:   petsc_tmp_flops             = 0.0;
165:   petsc_send_ct               = 0.0;
166:   petsc_recv_ct               = 0.0;
167:   petsc_send_len              = 0.0;
168:   petsc_recv_len              = 0.0;
169:   petsc_isend_ct              = 0.0;
170:   petsc_irecv_ct              = 0.0;
171:   petsc_isend_len             = 0.0;
172:   petsc_irecv_len             = 0.0;
173:   petsc_wait_ct               = 0.0;
174:   petsc_wait_any_ct           = 0.0;
175:   petsc_wait_all_ct           = 0.0;
176:   petsc_sum_of_waits_ct       = 0.0;
177:   petsc_allreduce_ct          = 0.0;
178:   petsc_gather_ct             = 0.0;
179:   petsc_scatter_ct            = 0.0;
180:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
181:   petsc_ctog_ct               = 0.0;
182:   petsc_gtoc_ct               = 0.0;
183:   petsc_ctog_sz               = 0.0;
184:   petsc_gtoc_sz               = 0.0;
185:   #endif
186:   PETSC_LARGEST_EVENT         = PETSC_EVENT;
187:   PetscLogPHC                 = NULL;
188:   PetscLogPHD                 = NULL;
189:   petsc_tracefile             = NULL;
190:   petsc_tracelevel            = 0;
191:   petsc_traceblanks           = "                                                                                                    ";
192:   petsc_tracespace[0]         = ' '; petsc_tracespace[1] = 0;
193:   petsc_tracetime             = 0.0;
194:   PETSC_LARGEST_CLASSID       = PETSC_SMALLEST_CLASSID;
195:   PETSC_OBJECT_CLASSID        = 0;
196:   petsc_stageLog              = 0;
197:   PetscLogInitializeCalled    = PETSC_FALSE;
198:   return(0);
199: }

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

204:   Not Collective

206:   Input Parameters:
207: + b - The function called at beginning of event
208: - e - The function called at end of event

210:   Level: developer

212: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
213: @*/
214: PetscErrorCode  PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
215:                             PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
216: {
218:   PetscLogPLB = b;
219:   PetscLogPLE = e;
220:   return(0);
221: }

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

228:   Logically Collective over PETSC_COMM_WORLD

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

234:   Usage:
235: .vb
236:       PetscInitialize(...);
237:       PetscLogDefaultBegin();
238:        ... code ...
239:       PetscLogView(viewer); or PetscLogDump();
240:       PetscFinalize();
241: .ve

243:   Notes:
244:   PetscLogView(viewer) or PetscLogDump() actually cause the printing of
245:   the logging information.

247:   Level: advanced

249: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogTraceBegin()
250: @*/
251: PetscErrorCode  PetscLogDefaultBegin(void)
252: {

256:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
257:   return(0);
258: }

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

264:   Logically Collective on PETSC_COMM_WORLD

266:   Options Database Keys:
267: . -log_all - Prints extensive log information

269:   Usage:
270: .vb
271:      PetscInitialize(...);
272:      PetscLogAllBegin();
273:      ... code ...
274:      PetscLogDump(filename);
275:      PetscFinalize();
276: .ve

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

283:   Level: advanced

285: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogTraceBegin()
286: @*/
287: PetscErrorCode  PetscLogAllBegin(void)
288: {

292:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
293:   return(0);
294: }

296: /*@
297:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
298:   begins or ends, the event name is printed.

300:   Logically Collective on PETSC_COMM_WORLD

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

305:   Options Database Key:
306: . -log_trace [filename] - Activates PetscLogTraceBegin()

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

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

316:   Level: intermediate

318: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogDefaultBegin()
319: @*/
320: PetscErrorCode  PetscLogTraceBegin(FILE *file)
321: {

325:   petsc_tracefile = file;

327:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
328:   return(0);
329: }

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

334:   Not Collective

336:   Input Parameter:
337: . flag - PETSC_TRUE if actions are to be logged

339:   Level: intermediate

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

344:   Options Database Keys:
345: . -log_exclude_actions - Turns off actions logging

347: .seealso: PetscLogStagePush(), PetscLogStagePop()
348: @*/
349: PetscErrorCode  PetscLogActions(PetscBool flag)
350: {
352:   petsc_logActions = flag;
353:   return(0);
354: }

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

359:   Not Collective

361:   Input Parameter:
362: . flag - PETSC_TRUE if objects are to be logged

364:   Level: intermediate

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

369:   Options Database Keys:
370: . -log_exclude_objects - Turns off objects logging

372: .seealso: PetscLogStagePush(), PetscLogStagePop()
373: @*/
374: PetscErrorCode  PetscLogObjects(PetscBool flag)
375: {
377:   petsc_logObjects = flag;
378:   return(0);
379: }

381: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
382: /*@C
383:   PetscLogStageRegister - Attaches a character string name to a logging stage.

385:   Not Collective

387:   Input Parameter:
388: . sname - The name to associate with that stage

390:   Output Parameter:
391: . stage - The stage number

393:   Level: intermediate

395: .seealso: PetscLogStagePush(), PetscLogStagePop()
396: @*/
397: PetscErrorCode  PetscLogStageRegister(const char sname[],PetscLogStage *stage)
398: {
399:   PetscStageLog  stageLog;
400:   PetscLogEvent  event;

404:   PetscLogGetStageLog(&stageLog);
405:   PetscStageLogRegister(stageLog, sname, stage);
406:   /* Copy events already changed in the main stage, this sucks */
407:   PetscEventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
408:   for (event = 0; event < stageLog->eventLog->numEvents; event++) {
409:     PetscEventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],&stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
410:   }
411:   PetscClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
412:   return(0);
413: }

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

418:   Not Collective

420:   Input Parameter:
421: . stage - The stage on which to log

423:   Usage:
424:   If the option -log_sumary is used to run the program containing the
425:   following code, then 2 sets of summary data will be printed during
426:   PetscFinalize().
427: .vb
428:       PetscInitialize(int *argc,char ***args,0,0);
429:       [stage 0 of code]
430:       PetscLogStagePush(1);
431:       [stage 1 of code]
432:       PetscLogStagePop();
433:       PetscBarrier(...);
434:       [more stage 0 of code]
435:       PetscFinalize();
436: .ve

438:   Notes:
439:   Use PetscLogStageRegister() to register a stage.

441:   Level: intermediate

443: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
444: @*/
445: PetscErrorCode  PetscLogStagePush(PetscLogStage stage)
446: {
447:   PetscStageLog  stageLog;

451:   PetscLogGetStageLog(&stageLog);
452:   PetscStageLogPush(stageLog, stage);
453:   return(0);
454: }

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

459:   Not Collective

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

476:   Notes:
477:   Use PetscLogStageRegister() to register a stage.

479:   Level: intermediate

481: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
482: @*/
483: PetscErrorCode  PetscLogStagePop(void)
484: {
485:   PetscStageLog  stageLog;

489:   PetscLogGetStageLog(&stageLog);
490:   PetscStageLogPop(stageLog);
491:   return(0);
492: }

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

497:   Not Collective

499:   Input Parameters:
500: + stage    - The stage
501: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

503:   Level: intermediate

505: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
506: @*/
507: PetscErrorCode  PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
508: {
509:   PetscStageLog  stageLog;

513:   PetscLogGetStageLog(&stageLog);
514:   PetscStageLogSetActive(stageLog, stage, isActive);
515:   return(0);
516: }

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

521:   Not Collective

523:   Input Parameter:
524: . stage    - The stage

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

529:   Level: intermediate

531: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
532: @*/
533: PetscErrorCode  PetscLogStageGetActive(PetscLogStage stage, PetscBool  *isActive)
534: {
535:   PetscStageLog  stageLog;

539:   PetscLogGetStageLog(&stageLog);
540:   PetscStageLogGetActive(stageLog, stage, isActive);
541:   return(0);
542: }

544: /*@
545:   PetscLogStageSetVisible - Determines stage visibility in PetscLogView()

547:   Not Collective

549:   Input Parameters:
550: + stage     - The stage
551: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

553:   Level: intermediate

555: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
556: @*/
557: PetscErrorCode  PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
558: {
559:   PetscStageLog  stageLog;

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

568: /*@
569:   PetscLogStageGetVisible - Returns stage visibility in PetscLogView()

571:   Not Collective

573:   Input Parameter:
574: . stage     - The stage

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

579:   Level: intermediate

581: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
582: @*/
583: PetscErrorCode  PetscLogStageGetVisible(PetscLogStage stage, PetscBool  *isVisible)
584: {
585:   PetscStageLog  stageLog;

589:   PetscLogGetStageLog(&stageLog);
590:   PetscStageLogGetVisible(stageLog, stage, isVisible);
591:   return(0);
592: }

594: /*@C
595:   PetscLogStageGetId - Returns the stage id when given the stage name.

597:   Not Collective

599:   Input Parameter:
600: . name  - The stage name

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

605:   Level: intermediate

607: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
608: @*/
609: PetscErrorCode  PetscLogStageGetId(const char name[], PetscLogStage *stage)
610: {
611:   PetscStageLog  stageLog;

615:   PetscLogGetStageLog(&stageLog);
616:   PetscStageLogGetStage(stageLog, name, stage);
617:   return(0);
618: }

620: /*------------------------------------------------ Event Functions --------------------------------------------------*/
621: /*@C
622:   PetscLogEventRegister - Registers an event name for logging operations in an application code.

624:   Not Collective

626:   Input Parameter:
627: + name   - The name associated with the event
628: - classid - The classid associated to the class for this event, obtain either with
629:            PetscClassIdRegister() or use a predefined one such as KSP_CLASSID, SNES_CLASSID, the predefined ones
630:            are only available in C code

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

635:   Example of Usage:
636: .vb
637:       PetscLogEvent USER_EVENT;
638:       PetscClassId classid;
639:       PetscLogDouble user_event_flops;
640:       PetscClassIdRegister("class name",&classid);
641:       PetscLogEventRegister("User event name",classid,&USER_EVENT);
642:       PetscLogEventBegin(USER_EVENT,0,0,0,0);
643:          [code segment to monitor]
644:          PetscLogFlops(user_event_flops);
645:       PetscLogEventEnd(USER_EVENT,0,0,0,0);
646: .ve

648:   Notes:
649:   PETSc automatically logs library events if the code has been
650:   configured with --with-log (which is the default) and
651:   -log_view or -log_all is specified.  PetscLogEventRegister() is
652:   intended for logging user events to supplement this PETSc
653:   information.

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

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

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

670:   Level: intermediate

672: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
673:           PetscLogEventActivate(), PetscLogEventDeactivate(), PetscClassIdRegister()
674: @*/
675: PetscErrorCode  PetscLogEventRegister(const char name[],PetscClassId classid,PetscLogEvent *event)
676: {
677:   PetscStageLog  stageLog;
678:   int            stage;

682:   *event = PETSC_DECIDE;
683:   PetscLogGetStageLog(&stageLog);
684:   PetscEventRegLogGetEvent(stageLog->eventLog, name, event);
685:   if (*event > 0) return(0);
686:   PetscEventRegLogRegister(stageLog->eventLog, name, classid, event);
687:   for (stage = 0; stage < stageLog->numStages; stage++) {
688:     PetscEventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
689:     PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
690:   }
691:   return(0);
692: }

694: /*@
695:   PetscLogEventSetCollective - Indicates that a particular event is collective.

697:   Not Collective

699:   Input Parameter:
700: + event - The event id
701: - collective - Bolean flag indicating whether a particular event is collective

703:   Note:
704:   New events returned from PetscLogEventRegister() are collective by default.

706:   Level: developer

708: .seealso: PetscLogEventRegister()
709: @*/
710: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event,PetscBool collective)
711: {
712:   PetscStageLog    stageLog;
713:   PetscEventRegLog eventRegLog;
714:   PetscErrorCode   ierr;

717:   PetscLogGetStageLog(&stageLog);
718:   PetscStageLogGetEventRegLog(stageLog,&eventRegLog);
719:   if (event < 0 || event > eventRegLog->numEvents) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid event id");
720:   eventRegLog->eventInfo[event].collective = collective;
721:   return(0);
722: }

724: /*@
725:   PetscLogEventIncludeClass - Activates event logging for a PETSc object class in every stage.

727:   Not Collective

729:   Input Parameter:
730: . classid - The object class, for example MAT_CLASSID, SNES_CLASSID, etc.

732:   Level: developer

734: .seealso: PetscLogEventActivateClass(),PetscLogEventDeactivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
735: @*/
736: PetscErrorCode  PetscLogEventIncludeClass(PetscClassId classid)
737: {
738:   PetscStageLog  stageLog;
739:   int            stage;

743:   PetscLogGetStageLog(&stageLog);
744:   for (stage = 0; stage < stageLog->numStages; stage++) {
745:     PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
746:   }
747:   return(0);
748: }

750: /*@
751:   PetscLogEventExcludeClass - Deactivates event logging for a PETSc object class in every stage.

753:   Not Collective

755:   Input Parameter:
756: . classid - The object class, for example MAT_CLASSID, SNES_CLASSID, etc.

758:   Level: developer

760: .seealso: PetscLogEventDeactivateClass(),PetscLogEventActivateClass(),PetscLogEventDeactivate(),PetscLogEventActivate()
761: @*/
762: PetscErrorCode  PetscLogEventExcludeClass(PetscClassId classid)
763: {
764:   PetscStageLog  stageLog;
765:   int            stage;

769:   PetscLogGetStageLog(&stageLog);
770:   for (stage = 0; stage < stageLog->numStages; stage++) {
771:     PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
772:   }
773:   return(0);
774: }

776: /*@
777:   PetscLogEventActivate - Indicates that a particular event should be logged.

779:   Not Collective

781:   Input Parameter:
782: . event - The event id

784:   Usage:
785: .vb
786:       PetscLogEventDeactivate(VEC_SetValues);
787:         [code where you do not want to log VecSetValues()]
788:       PetscLogEventActivate(VEC_SetValues);
789:         [code where you do want to log VecSetValues()]
790: .ve

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

796:   Level: advanced

798: .seealso: PlogEventDeactivate()
799: @*/
800: PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
801: {
802:   PetscStageLog  stageLog;
803:   int            stage;

807:   PetscLogGetStageLog(&stageLog);
808:   PetscStageLogGetCurrent(stageLog, &stage);
809:   PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
810:   return(0);
811: }

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

816:   Not Collective

818:   Input Parameter:
819: . event - The event id

821:   Usage:
822: .vb
823:       PetscLogEventDeactivate(VEC_SetValues);
824:         [code where you do not want to log VecSetValues()]
825:       PetscLogEventActivate(VEC_SetValues);
826:         [code where you do want to log VecSetValues()]
827: .ve

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

833:   Level: advanced

835: .seealso: PlogEventActivate()
836: @*/
837: PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
838: {
839:   PetscStageLog  stageLog;
840:   int            stage;

844:   PetscLogGetStageLog(&stageLog);
845:   PetscStageLogGetCurrent(stageLog, &stage);
846:   PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
847:   return(0);
848: }

850: /*@
851:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

853:   Not Collective

855:   Input Parameters:
856: + event    - The event id
857: - isActive - The activity flag determining whether the event is logged

859:   Level: advanced

861: .seealso: PlogEventActivate(),PlogEventDeactivate()
862: @*/
863: PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
864: {
865:   PetscStageLog  stageLog;
866:   int            stage;

870:   PetscLogGetStageLog(&stageLog);
871:   for (stage = 0; stage < stageLog->numStages; stage++) {
872:     if (isActive) {
873:       PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
874:     } else {
875:       PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
876:     }
877:   }
878:   return(0);
879: }

881: /*@
882:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

884:   Not Collective

886:   Input Parameter:
887: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

889:   Level: developer

891: .seealso: PetscLogEventDeactivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
892: @*/
893: PetscErrorCode  PetscLogEventActivateClass(PetscClassId classid)
894: {
895:   PetscStageLog  stageLog;
896:   int            stage;

900:   PetscLogGetStageLog(&stageLog);
901:   PetscStageLogGetCurrent(stageLog, &stage);
902:   PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
903:   return(0);
904: }

906: /*@
907:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

909:   Not Collective

911:   Input Parameter:
912: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

914:   Level: developer

916: .seealso: PetscLogEventActivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
917: @*/
918: PetscErrorCode  PetscLogEventDeactivateClass(PetscClassId classid)
919: {
920:   PetscStageLog  stageLog;
921:   int            stage;

925:   PetscLogGetStageLog(&stageLog);
926:   PetscStageLogGetCurrent(stageLog, &stage);
927:   PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
928:   return(0);
929: }

931: /*MC
932:    PetscLogEventSync - Synchronizes the beginning of a user event.

934:    Synopsis:
935:    #include <petsclog.h>
936:    PetscErrorCode PetscLogEventSync(int e,MPI_Comm comm)

938:    Collective

940:    Input Parameters:
941: +  e - integer associated with the event obtained from PetscLogEventRegister()
942: -  comm - an MPI communicator

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

954:    Notes:
955:    This routine should be called only if there is not a
956:    PetscObject available to pass to PetscLogEventBegin().

958:    Level: developer

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

962: M*/

964: /*MC
965:    PetscLogEventBegin - Logs the beginning of a user event.

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

971:    Not Collective

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


978:    Fortran Synopsis:
979:    void PetscLogEventBegin(int e,PetscErrorCode ierr)

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

992:    Notes:
993:    You need to register each integer event with the command
994:    PetscLogEventRegister().

996:    Level: intermediate

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

1000: M*/

1002: /*MC
1003:    PetscLogEventEnd - Log the end of a user event.

1005:    Synopsis:
1006:    #include <petsclog.h>
1007:    PetscErrorCode PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)

1009:    Not Collective

1011:    Input Parameters:
1012: +  e - integer associated with the event obtained with PetscLogEventRegister()
1013: -  o1,o2,o3,o4 - objects associated with the event, or 0


1016:    Fortran Synopsis:
1017:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

1019:    Usage:
1020: .vb
1021:      PetscLogEvent USER_EVENT;
1022:      PetscLogDouble user_event_flops;
1023:      PetscLogEventRegister("User event",0,&USER_EVENT,);
1024:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
1025:         [code segment to monitor]
1026:         PetscLogFlops(user_event_flops);
1027:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
1028: .ve

1030:    Notes:
1031:    You should also register each additional integer event with the command
1032:    PetscLogEventRegister().

1034:    Level: intermediate

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

1038: M*/

1040: /*@C
1041:   PetscLogEventGetId - Returns the event id when given the event name.

1043:   Not Collective

1045:   Input Parameter:
1046: . name  - The event name

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

1051:   Level: intermediate

1053: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1054: @*/
1055: PetscErrorCode  PetscLogEventGetId(const char name[], PetscLogEvent *event)
1056: {
1057:   PetscStageLog  stageLog;

1061:   PetscLogGetStageLog(&stageLog);
1062:   PetscEventRegLogGetEvent(stageLog->eventLog, name, event);
1063:   return(0);
1064: }


1067: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1068: /*@C
1069:   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1070:   be read by bin/petscview. This program no longer exists.

1072:   Collective on PETSC_COMM_WORLD

1074:   Input Parameter:
1075: . name - an optional file name

1077:   Usage:
1078: .vb
1079:      PetscInitialize(...);
1080:      PetscLogDefaultBegin(); or PetscLogAllBegin();
1081:      ... code ...
1082:      PetscLogDump(filename);
1083:      PetscFinalize();
1084: .ve

1086:   Notes:
1087:   The default file name is
1088: $    Log.<rank>
1089:   where <rank> is the processor number. If no name is specified,
1090:   this file will be used.

1092:   Level: advanced

1094: .seealso: PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogView()
1095: @*/
1096: PetscErrorCode  PetscLogDump(const char sname[])
1097: {
1098:   PetscStageLog      stageLog;
1099:   PetscEventPerfInfo *eventInfo;
1100:   FILE               *fd;
1101:   char               file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1102:   PetscLogDouble     flops, _TotalTime;
1103:   PetscMPIInt        rank;
1104:   int                action, object, curStage;
1105:   PetscLogEvent      event;
1106:   PetscErrorCode     ierr;

1109:   /* Calculate the total elapsed time */
1110:   PetscTime(&_TotalTime);
1111:   _TotalTime -= petsc_BaseTime;
1112:   /* Open log file */
1113:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1114:   if (sname && sname[0]) sprintf(file, "%s.%d", sname, rank);
1115:   else sprintf(file, "Log.%d", rank);
1116:   PetscFixFilename(file, fname);
1117:   PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1118:   if ((!rank) && (!fd)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1119:   /* Output totals */
1120:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flop %14e %16.8e\n", petsc_TotalFlops, _TotalTime);
1121:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1122:   /* Output actions */
1123:   if (petsc_logActions) {
1124:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", petsc_numActions);
1125:     for (action = 0; action < petsc_numActions; action++) {
1126:       PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1127:                           petsc_actions[action].time, petsc_actions[action].action, (int)petsc_actions[action].event, (int)petsc_actions[action].classid, petsc_actions[action].id1,
1128:                           petsc_actions[action].id2, petsc_actions[action].id3, petsc_actions[action].flops, petsc_actions[action].mem, petsc_actions[action].maxmem);
1129:     }
1130:   }
1131:   /* Output objects */
1132:   if (petsc_logObjects) {
1133:     PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", petsc_numObjects, petsc_numObjectsDestroyed);
1134:     for (object = 0; object < petsc_numObjects; object++) {
1135:       PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", petsc_objects[object].parent, (int) petsc_objects[object].mem);
1136:       if (!petsc_objects[object].name[0]) {
1137:         PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1138:       } else {
1139:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", petsc_objects[object].name);
1140:       }
1141:       if (petsc_objects[object].info[0] != 0) {
1142:         PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1143:       } else {
1144:         PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", petsc_objects[object].info);
1145:       }
1146:     }
1147:   }
1148:   /* Output events */
1149:   PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1150:   PetscLogGetStageLog(&stageLog);
1151:   PetscIntStackTop(stageLog->stack, &curStage);
1152:   eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1153:   for (event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1154:     if (eventInfo[event].time != 0.0) flops = eventInfo[event].flops/eventInfo[event].time;
1155:     else flops = 0.0;
1156:     PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1157:                         eventInfo[event].flops, eventInfo[event].time, flops);
1158:   }
1159:   PetscFClose(PETSC_COMM_WORLD, fd);
1160:   return(0);
1161: }

1163: /*
1164:   PetscLogView_Detailed - Each process prints the times for its own events

1166: */
1167: PetscErrorCode  PetscLogView_Detailed(PetscViewer viewer)
1168: {
1169:   PetscStageLog      stageLog;
1170:   PetscEventPerfInfo *eventInfo = NULL, *stageInfo = NULL;
1171:   PetscLogDouble     locTotalTime, numRed, maxMem;
1172:   int                numStages,numEvents,stage,event;
1173:   MPI_Comm           comm = PetscObjectComm((PetscObject) viewer);
1174:   PetscMPIInt        rank,size;
1175:   PetscErrorCode     ierr;

1178:   MPI_Comm_size(comm, &size);
1179:   MPI_Comm_rank(comm, &rank);
1180:   /* Must preserve reduction count before we go on */
1181:   numRed = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1182:   /* Get the total elapsed time */
1183:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1184:   PetscViewerASCIIPrintf(viewer,"size = %d\n",size);
1185:   PetscViewerASCIIPrintf(viewer,"LocalTimes = {}\n");
1186:   PetscViewerASCIIPrintf(viewer,"LocalMessages = {}\n");
1187:   PetscViewerASCIIPrintf(viewer,"LocalMessageLens = {}\n");
1188:   PetscViewerASCIIPrintf(viewer,"LocalReductions = {}\n");
1189:   PetscViewerASCIIPrintf(viewer,"LocalFlop = {}\n");
1190:   PetscViewerASCIIPrintf(viewer,"LocalObjects = {}\n");
1191:   PetscViewerASCIIPrintf(viewer,"LocalMemory = {}\n");
1192:   PetscLogGetStageLog(&stageLog);
1193:   MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1194:   PetscViewerASCIIPrintf(viewer,"Stages = {}\n");
1195:   for (stage=0; stage<numStages; stage++) {
1196:     PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"] = {}\n",stageLog->stageInfo[stage].name);
1197:     PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"summary\"] = {}\n",stageLog->stageInfo[stage].name);
1198:     MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1199:     for (event = 0; event < numEvents; event++) {
1200:       PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"%s\"] = {}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name);
1201:     }
1202:   }
1203:   PetscMallocGetMaximumUsage(&maxMem);
1204:   PetscViewerASCIIPushSynchronized(viewer);
1205:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalTimes[%d] = %g\n",rank,locTotalTime);
1206:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessages[%d] = %g\n",rank,(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct));
1207:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessageLens[%d] = %g\n",rank,(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len));
1208:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalReductions[%d] = %g\n",rank,numRed);
1209:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalFlop[%d] = %g\n",rank,petsc_TotalFlops);
1210:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalObjects[%d] = %d\n",rank,petsc_numObjects);
1211:   PetscViewerASCIISynchronizedPrintf(viewer,"LocalMemory[%d] = %g\n",rank,maxMem);
1212:   PetscViewerFlush(viewer);
1213:   for (stage=0; stage<numStages; stage++) {
1214:     stageInfo = &stageLog->stageInfo[stage].perfInfo;
1215:     PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"summary\"][%d] = {\"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flop\" : %g}\n",
1216:                                               stageLog->stageInfo[stage].name,rank,
1217:                                               stageInfo->time,stageInfo->numMessages,stageInfo->messageLength,stageInfo->numReductions,stageInfo->flops);
1218:     MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1219:     for (event = 0; event < numEvents; event++) {
1220:       eventInfo = &stageLog->stageInfo[stage].eventLog->eventInfo[event];
1221:       PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"%s\"][%d] = {\"count\" : %D, \"time\" : %g, \"syncTime\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flop\" : %g",
1222:                                                 stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name,rank,
1223:                                                 eventInfo->count,eventInfo->time,eventInfo->syncTime,eventInfo->numMessages,eventInfo->messageLength,eventInfo->numReductions,eventInfo->flops);
1224:       if (eventInfo->dof[0] >= 0.) {
1225:         PetscInt d, e;

1227:         PetscViewerASCIISynchronizedPrintf(viewer, ", \"dof\" : [");
1228:         for (d = 0; d < 8; ++d) {
1229:           if (d > 0) {PetscViewerASCIISynchronizedPrintf(viewer, ", ");}
1230:           PetscViewerASCIISynchronizedPrintf(viewer, "%g", eventInfo->dof[d]);
1231:         }
1232:         PetscViewerASCIISynchronizedPrintf(viewer, "]");
1233:         PetscViewerASCIISynchronizedPrintf(viewer, ", \"error\" : [");
1234:         for (e = 0; e < 8; ++e) {
1235:           if (e > 0) {PetscViewerASCIISynchronizedPrintf(viewer, ", ");}
1236:           PetscViewerASCIISynchronizedPrintf(viewer, "%g", eventInfo->errors[e]);
1237:         }
1238:         PetscViewerASCIISynchronizedPrintf(viewer, "]");
1239:       }
1240:       PetscViewerASCIISynchronizedPrintf(viewer,"}\n");
1241:     }
1242:   }
1243:   PetscViewerFlush(viewer);
1244:   PetscViewerASCIIPopSynchronized(viewer);
1245:   return(0);
1246: }

1248: /*
1249:   PetscLogView_CSV - Each process prints the times for its own events in Comma-Separated Value Format
1250: */
1251: PetscErrorCode  PetscLogView_CSV(PetscViewer viewer)
1252: {
1253:   PetscStageLog      stageLog;
1254:   PetscEventPerfInfo *eventInfo = NULL;
1255:   PetscLogDouble     locTotalTime, maxMem;
1256:   int                numStages,numEvents,stage,event;
1257:   MPI_Comm           comm = PetscObjectComm((PetscObject) viewer);
1258:   PetscMPIInt        rank,size;
1259:   PetscErrorCode     ierr;

1262:   MPI_Comm_size(comm, &size);
1263:   MPI_Comm_rank(comm, &rank);
1264:   /* Must preserve reduction count before we go on */
1265:   /* Get the total elapsed time */
1266:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1267:   PetscLogGetStageLog(&stageLog);
1268:   MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1269:   PetscMallocGetMaximumUsage(&maxMem);
1270:   PetscViewerASCIIPushSynchronized(viewer);
1271:   PetscViewerASCIIPrintf(viewer,"Stage Name,Event Name,Rank,Time,Num Messages,Message Length,Num Reductions,FLOP,dof0,dof1,dof2,dof3,dof4,dof5,dof6,dof7,e0,e1,e2,e3,e4,e5,e6,e7,%d\n", size);
1272:   PetscViewerFlush(viewer);
1273:   for (stage=0; stage<numStages; stage++) {
1274:     PetscEventPerfInfo *stageInfo = &stageLog->stageInfo[stage].perfInfo;

1276:     PetscViewerASCIISynchronizedPrintf(viewer,"%s,summary,%d,%g,%g,%g,%g,%g\n",
1277:                                               stageLog->stageInfo[stage].name,rank,stageInfo->time,stageInfo->numMessages,stageInfo->messageLength,stageInfo->numReductions,stageInfo->flops);
1278:     MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1279:     for (event = 0; event < numEvents; event++) {
1280:       eventInfo = &stageLog->stageInfo[stage].eventLog->eventInfo[event];
1281:       PetscViewerASCIISynchronizedPrintf(viewer,"%s,%s,%d,%g,%g,%g,%g,%g",stageLog->stageInfo[stage].name,
1282:                                                 stageLog->eventLog->eventInfo[event].name,rank,eventInfo->time,eventInfo->numMessages,
1283:                                                 eventInfo->messageLength,eventInfo->numReductions,eventInfo->flops);
1284:       if (eventInfo->dof[0] >= 0.) {
1285:         PetscInt d, e;

1287:         for (d = 0; d < 8; ++d) {
1288:           PetscViewerASCIISynchronizedPrintf(viewer, ",%g", eventInfo->dof[d]);
1289:         }
1290:         for (e = 0; e < 8; ++e) {
1291:           PetscViewerASCIISynchronizedPrintf(viewer, ",%g", eventInfo->errors[e]);
1292:         }
1293:       }
1294:       PetscViewerASCIISynchronizedPrintf(viewer,"\n");
1295:     }
1296:   }
1297:   PetscViewerFlush(viewer);
1298:   PetscViewerASCIIPopSynchronized(viewer);
1299:   return(0);
1300: }

1302: static PetscErrorCode PetscLogViewWarnSync(MPI_Comm comm,FILE *fd)
1303: {
1306:   if (!PetscLogSyncOn) return(0);
1307:   PetscFPrintf(comm, fd, "\n\n");
1308:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1309:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1310:   PetscFPrintf(comm, fd, "      #                       WARNING!!!                       #\n");
1311:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1312:   PetscFPrintf(comm, fd, "      #   This program was run with logging synchronization.   #\n");
1313:   PetscFPrintf(comm, fd, "      #   This option provides more meaningful imbalance       #\n");
1314:   PetscFPrintf(comm, fd, "      #   figures at the expense of slowing things down and    #\n");
1315:   PetscFPrintf(comm, fd, "      #   providing a distorted view of the overall runtime.   #\n");
1316:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1317:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1318:   return(0);
1319:   return(0);
1320: }

1322: static PetscErrorCode PetscLogViewWarnDebugging(MPI_Comm comm,FILE *fd)
1323: {
1324: #if defined(PETSC_USE_DEBUG)

1328:   PetscFPrintf(comm, fd, "\n\n");
1329:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1330:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1331:   PetscFPrintf(comm, fd, "      #                       WARNING!!!                       #\n");
1332:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1333:   PetscFPrintf(comm, fd, "      #   This code was compiled with a debugging option.      #\n");
1334:   PetscFPrintf(comm, fd, "      #   To get timing results run ./configure                #\n");
1335:   PetscFPrintf(comm, fd, "      #   using --with-debugging=no, the performance will      #\n");
1336:   PetscFPrintf(comm, fd, "      #   be generally two or three times faster.              #\n");
1337:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1338:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1339:   return(0);
1340: #else
1341:   return 0;
1342: #endif
1343: }

1345: #if defined(PETSC_HAVE_OPENMP)
1346: extern PetscInt PetscNumOMPThreads;
1347: #endif

1349: PetscErrorCode  PetscLogView_Default(PetscViewer viewer)
1350: {
1351:   FILE               *fd;
1352:   PetscLogDouble     zero       = 0.0;
1353:   PetscStageLog      stageLog;
1354:   PetscStageInfo     *stageInfo = NULL;
1355:   PetscEventPerfInfo *eventInfo = NULL;
1356:   PetscClassPerfInfo *classInfo;
1357:   char               arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
1358:   const char         *name;
1359:   PetscLogDouble     locTotalTime, TotalTime, TotalFlops;
1360:   PetscLogDouble     numMessages, messageLength, avgMessLen, numReductions;
1361:   PetscLogDouble     stageTime, flops, flopr, mem, mess, messLen, red;
1362:   PetscLogDouble     fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1363:   PetscLogDouble     fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1364:   PetscLogDouble     min, max, tot, ratio, avg, x, y;
1365:   PetscLogDouble     minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratC, totm, totml, totr, mal, malmax, emalmax;
1366:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1367:   PetscLogDouble     cct, gct, csz, gsz;
1368:   #endif
1369:   PetscMPIInt        minC, maxC;
1370:   PetscMPIInt        size, rank;
1371:   PetscBool          *localStageUsed,    *stageUsed;
1372:   PetscBool          *localStageVisible, *stageVisible;
1373:   int                numStages, localNumEvents, numEvents;
1374:   int                stage, oclass;
1375:   PetscLogEvent      event;
1376:   PetscErrorCode     ierr;
1377:   char               version[256];
1378:   MPI_Comm           comm;

1381:   PetscObjectGetComm((PetscObject)viewer,&comm);
1382:   PetscViewerASCIIGetPointer(viewer,&fd);
1383:   MPI_Comm_size(comm, &size);
1384:   MPI_Comm_rank(comm, &rank);
1385:   /* Get the total elapsed time */
1386:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;

1388:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1389:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1390:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1391:   PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1392:   PetscLogViewWarnSync(comm,fd);
1393:   PetscLogViewWarnDebugging(comm,fd);
1394:   PetscGetArchType(arch,sizeof(arch));
1395:   PetscGetHostName(hostname,sizeof(hostname));
1396:   PetscGetUserName(username,sizeof(username));
1397:   PetscGetProgramName(pname,sizeof(pname));
1398:   PetscGetDate(date,sizeof(date));
1399:   PetscGetVersion(version,sizeof(version));
1400:   if (size == 1) {
1401:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1402:   } else {
1403:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1404:   }
1405: #if defined(PETSC_HAVE_OPENMP)
1406:   PetscFPrintf(comm,fd,"Using %D OpenMP threads\n", PetscNumOMPThreads);
1407: #endif
1408:   PetscFPrintf(comm, fd, "Using %s\n", version);

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

1413:   /* Calculate summary information */
1414:   PetscFPrintf(comm, fd, "\n                         Max       Max/Min     Avg       Total \n");
1415:   /*   Time */
1416:   MPIU_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1417:   MPIU_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1418:   MPIU_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1419:   avg  = tot/((PetscLogDouble) size);
1420:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1421:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %7.3f   %5.3e\n", max, ratio, avg);
1422:   TotalTime = tot;
1423:   /*   Objects */
1424:   avg  = (PetscLogDouble) petsc_numObjects;
1425:   MPIU_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1426:   MPIU_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1427:   MPIU_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1428:   avg  = tot/((PetscLogDouble) size);
1429:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1430:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %7.3f   %5.3e\n", max, ratio, avg);
1431:   /*   Flops */
1432:   MPIU_Allreduce(&petsc_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1433:   MPIU_Allreduce(&petsc_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1434:   MPIU_Allreduce(&petsc_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1435:   avg  = tot/((PetscLogDouble) size);
1436:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1437:   PetscFPrintf(comm, fd, "Flop:                 %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1438:   TotalFlops = tot;
1439:   /*   Flops/sec -- Must talk to Barry here */
1440:   if (locTotalTime != 0.0) flops = petsc_TotalFlops/locTotalTime; else flops = 0.0;
1441:   MPIU_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1442:   MPIU_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1443:   MPIU_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1444:   avg  = tot/((PetscLogDouble) size);
1445:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1446:   PetscFPrintf(comm, fd, "Flop/sec:             %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1447:   /*   Memory */
1448:   PetscMallocGetMaximumUsage(&mem);
1449:   if (mem > 0.0) {
1450:     MPIU_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1451:     MPIU_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1452:     MPIU_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1453:     avg  = tot/((PetscLogDouble) size);
1454:     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1455:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1456:   }
1457:   /*   Messages */
1458:   mess = 0.5*(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct);
1459:   MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1460:   MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1461:   MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1462:   avg  = tot/((PetscLogDouble) size);
1463:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1464:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1465:   numMessages = tot;
1466:   /*   Message Lengths */
1467:   mess = 0.5*(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len);
1468:   MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1469:   MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1470:   MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1471:   if (numMessages != 0) avg = tot/numMessages; else avg = 0.0;
1472:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1473:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1474:   messageLength = tot;
1475:   /*   Reductions */
1476:   MPIU_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1477:   MPIU_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1478:   MPIU_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1479:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1480:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %7.3f\n", max, ratio);
1481:   numReductions = red; /* wrong because uses count from process zero */
1482:   PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1483:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flop\n");
1484:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flop\n");

1486:   /* Get total number of stages --
1487:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1488:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1489:        This seems best accomplished by assoicating a communicator with each stage.
1490:   */
1491:   PetscLogGetStageLog(&stageLog);
1492:   MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1493:   PetscMalloc1(numStages, &localStageUsed);
1494:   PetscMalloc1(numStages, &stageUsed);
1495:   PetscMalloc1(numStages, &localStageVisible);
1496:   PetscMalloc1(numStages, &stageVisible);
1497:   if (numStages > 0) {
1498:     stageInfo = stageLog->stageInfo;
1499:     for (stage = 0; stage < numStages; stage++) {
1500:       if (stage < stageLog->numStages) {
1501:         localStageUsed[stage]    = stageInfo[stage].used;
1502:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1503:       } else {
1504:         localStageUsed[stage]    = PETSC_FALSE;
1505:         localStageVisible[stage] = PETSC_TRUE;
1506:       }
1507:     }
1508:     MPIU_Allreduce(localStageUsed,    stageUsed,    numStages, MPIU_BOOL, MPI_LOR,  comm);
1509:     MPIU_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);
1510:     for (stage = 0; stage < numStages; stage++) {
1511:       if (stageUsed[stage]) {
1512:         PetscFPrintf(comm, fd, "\nSummary of Stages:   ----- Time ------  ----- Flop ------  --- Messages ---  -- Message Lengths --  -- Reductions --\n");
1513:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total    Count   %%Total     Avg         %%Total    Count   %%Total \n");
1514:         break;
1515:       }
1516:     }
1517:     for (stage = 0; stage < numStages; stage++) {
1518:       if (!stageUsed[stage]) continue;
1519:       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1520:       if (localStageUsed[stage]) {
1521:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1522:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1523:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1524:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1525:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1526:         name = stageInfo[stage].name;
1527:       } else {
1528:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1529:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1530:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1531:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1532:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1533:         name = "";
1534:       }
1535:       mess *= 0.5; messLen *= 0.5; red /= size;
1536:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1537:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1538:       /* Talk to Barry if (stageTime     != 0.0) flops          = (size*flops)/stageTime; else flops          = 0.0; */
1539:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1540:       if (mess          != 0.0) avgMessLen     = messLen/mess;           else avgMessLen     = 0.0;
1541:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1542:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1543:       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",
1544:                           stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1545:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1546:     }
1547:   }

1549:   PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");
1550:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1551:   PetscFPrintf(comm, fd, "Phase summary info:\n");
1552:   PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");
1553:   PetscFPrintf(comm, fd, "   Time and Flop: Max - maximum over all processors\n");
1554:   PetscFPrintf(comm, fd, "                  Ratio - ratio of maximum to minimum over all processors\n");
1555:   PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");
1556:   PetscFPrintf(comm, fd, "   AvgLen: average message length (bytes)\n");
1557:   PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");
1558:   PetscFPrintf(comm, fd, "   Global: entire computation\n");
1559:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1560:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flop in this phase\n");
1561:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");
1562:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");
1563:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flop over all processors)/(max time over all processors)\n");
1564:   if (PetscLogMemory) {
1565:     PetscFPrintf(comm, fd, "   Malloc Mbytes: Memory allocated and kept during event (sum over all calls to event)\n");
1566:     PetscFPrintf(comm, fd, "   EMalloc Mbytes: extra memory allocated during event and then freed (maximum over all calls to events)\n");
1567:     PetscFPrintf(comm, fd, "   MMalloc Mbytes: Increase in high water mark of allocated memory (sum over all calls to event)\n");
1568:     PetscFPrintf(comm, fd, "   RMI Mbytes: Increase in resident memory (sum over all calls to event)\n");
1569:   }
1570:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1571:   PetscFPrintf(comm, fd, "   CpuToGpu Count: total number of CPU to GPU copies over all processors\n");
1572:   PetscFPrintf(comm, fd, "   CpuToGpu Size (Mbytes): 10e-6 * (total size of CPU to GPU copies)\n");
1573:   PetscFPrintf(comm, fd, "   GpuToCpu Count: total number of GPU to CPU copies over all processors\n");
1574:   PetscFPrintf(comm, fd, "   GpuToCpu Size (Mbytes): 10e-6 * (total size of GPU to CPU copies)\n");
1575:   #endif
1576:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");

1578:   PetscLogViewWarnDebugging(comm,fd);

1580:   /* Report events */
1581:   PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flop                              --- Global ---  --- Stage ----  Total");
1582:   if (PetscLogMemory) {
1583:     PetscFPrintf(comm, fd,"  Malloc EMalloc MMalloc RMI");
1584:   }
1585:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1586:   PetscFPrintf(comm, fd,"   - CpuToGpu -   - GpuToCpu -");
1587:   #endif
1588:   PetscFPrintf(comm, fd,"\n");
1589:   PetscFPrintf(comm, fd,"                   Max Ratio  Max     Ratio   Max  Ratio  Mess   AvgLen  Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s");
1590:   if (PetscLogMemory) {
1591:     PetscFPrintf(comm, fd," Mbytes Mbytes Mbytes Mbytes");
1592:   }
1593:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1594:   PetscFPrintf(comm, fd,"  Count   Size   Count   Size");
1595:   #endif
1596:   PetscFPrintf(comm, fd,"\n");
1597:   PetscFPrintf(comm, fd,"------------------------------------------------------------------------------------------------------------------------\n");

1599:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1600:   for (stage = 0; stage < numStages; stage++) {
1601:     if (!stageVisible[stage]) continue;
1602:     /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1603:     if (localStageUsed[stage]) {
1604:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1605:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1606:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1607:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1608:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1609:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1610:     } else {
1611:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1612:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1613:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1614:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1615:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1616:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1617:     }
1618:     mess *= 0.5; messLen *= 0.5; red /= size;

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

1625:        Problem: If the event did not happen on proc 1, its name will not be available.
1626:        Problem: Event visibility is not implemented
1627:     */
1628:     if (localStageUsed[stage]) {
1629:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1630:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1631:     } else localNumEvents = 0;
1632:     MPIU_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1633:     for (event = 0; event < numEvents; event++) {
1634:       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1635:       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1636:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops; else flopr = 0.0;
1637:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1638:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1639:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1640:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1641:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1642:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1643:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1644:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1645:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1646:         MPI_Allreduce(&eventInfo[event].count,         &minC,  1, MPI_INT,             MPI_MIN, comm);
1647:         MPI_Allreduce(&eventInfo[event].count,         &maxC,  1, MPI_INT,             MPI_MAX, comm);
1648:         if (PetscLogMemory) {
1649:           MPI_Allreduce(&eventInfo[event].memIncrease,    &mem,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1650:           MPI_Allreduce(&eventInfo[event].mallocSpace,    &mal,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1651:           MPI_Allreduce(&eventInfo[event].mallocIncrease, &malmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1652:           MPI_Allreduce(&eventInfo[event].mallocIncreaseEvent, &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1653:         }
1654:         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1655:         MPI_Allreduce(&eventInfo[event].CpuToGpuCount,    &cct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1656:         MPI_Allreduce(&eventInfo[event].GpuToCpuCount,    &gct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1657:         MPI_Allreduce(&eventInfo[event].CpuToGpuSize,     &csz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1658:         MPI_Allreduce(&eventInfo[event].GpuToCpuSize,     &gsz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1659:         #endif
1660:         name = stageLog->eventLog->eventInfo[event].name;
1661:       } else {
1662:         flopr = 0.0;
1663:         MPI_Allreduce(&flopr,                         &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1664:         MPI_Allreduce(&flopr,                         &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1665:         MPI_Allreduce(&zero,                          &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1666:         MPI_Allreduce(&zero,                          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1667:         MPI_Allreduce(&zero,                          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1668:         MPI_Allreduce(&zero,                          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1669:         MPI_Allreduce(&zero,                          &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1670:         MPI_Allreduce(&zero,                          &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1671:         MPI_Allreduce(&zero,                          &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1672:         MPI_Allreduce(&ierr,                          &minC,  1, MPI_INT,             MPI_MIN, comm);
1673:         MPI_Allreduce(&ierr,                          &maxC,  1, MPI_INT,             MPI_MAX, comm);
1674:         if (PetscLogMemory) {
1675:           MPI_Allreduce(&zero,                        &mem,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1676:           MPI_Allreduce(&zero,                        &mal,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1677:           MPI_Allreduce(&zero,                        &malmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1678:           MPI_Allreduce(&zero,                        &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1679:         }
1680:         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1681:         MPI_Allreduce(&zero,                          &cct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1682:         MPI_Allreduce(&zero,                          &gct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1683:         MPI_Allreduce(&zero,                          &csz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1684:         MPI_Allreduce(&zero,                          &gsz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1685:         #endif
1686:         name  = "";
1687:       }
1688:       if (mint < 0.0) {
1689:         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);
1690:         mint = 0;
1691:       }
1692:       if (minf < 0.0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Minimum flop %g over all processors for %s is negative! Not possible!",minf,name);
1693:       totm *= 0.5; totml *= 0.5; totr /= size;

1695:       if (maxC != 0) {
1696:         if (minC          != 0)   ratC             = ((PetscLogDouble)maxC)/minC;else ratC             = 0.0;
1697:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1698:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1699:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1700:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1701:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1702:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1703:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1704:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1705:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1706:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1707:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1708:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1709:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1710:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1711:         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");
1712:         PetscFPrintf(comm, fd,
1713:                             "%-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",
1714:                             name, maxC, ratC, maxt, ratt, maxf, ratf, totm, totml, totr,
1715:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1716:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1717:                             PetscAbs(flopr)/1.0e6);
1718:         if (PetscLogMemory) {
1719:           PetscFPrintf(comm, fd," %5.0f   %5.0f   %5.0f   %5.0f",mal/1.0e6,emalmax/1.0e6,malmax/1.0e6,mem/1.0e6);
1720:         }
1721:         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1722:         PetscFPrintf(comm, fd,"    %4.0f %3.2e %4.0f %3.2e", cct, csz/1.0e6, gct, gsz/1.0e6);
1723:         #endif
1724:         PetscFPrintf(comm, fd,"\n");
1725:       }
1726:     }
1727:   }

1729:   /* Memory usage and object creation */
1730:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");
1731:   PetscFPrintf(comm, fd, "\n");
1732:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

1734:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1735:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1736:      stats for stages local to processor sets.
1737:   */
1738:   /* We should figure out the longest object name here (now 20 characters) */
1739:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions     Memory  Descendants' Mem.\n");
1740:   PetscFPrintf(comm, fd, "Reports information only for process 0.\n");
1741:   for (stage = 0; stage < numStages; stage++) {
1742:     if (localStageUsed[stage]) {
1743:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1744:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1745:       for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1746:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1747:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %11.0f     %g\n", stageLog->classLog->classInfo[oclass].name,
1748:                               classInfo[oclass].creations, classInfo[oclass].destructions, classInfo[oclass].mem,
1749:                               classInfo[oclass].descMem);
1750:         }
1751:       }
1752:     } else {
1753:       if (!localStageVisible[stage]) continue;
1754:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1755:     }
1756:   }

1758:   PetscFree(localStageUsed);
1759:   PetscFree(stageUsed);
1760:   PetscFree(localStageVisible);
1761:   PetscFree(stageVisible);

1763:   /* Information unrelated to this particular run */
1764:   PetscFPrintf(comm, fd, "========================================================================================================================\n");
1765:   PetscTime(&y);
1766:   PetscTime(&x);
1767:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1768:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1769:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1770:   /* MPI information */
1771:   if (size > 1) {
1772:     MPI_Status  status;
1773:     PetscMPIInt tag;
1774:     MPI_Comm    newcomm;

1776:     MPI_Barrier(comm);
1777:     PetscTime(&x);
1778:     MPI_Barrier(comm);
1779:     MPI_Barrier(comm);
1780:     MPI_Barrier(comm);
1781:     MPI_Barrier(comm);
1782:     MPI_Barrier(comm);
1783:     PetscTime(&y);
1784:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1785:     PetscCommDuplicate(comm,&newcomm, &tag);
1786:     MPI_Barrier(comm);
1787:     if (rank) {
1788:       MPI_Recv(NULL, 0, MPI_INT, rank-1,            tag, newcomm, &status);
1789:       MPI_Send(NULL, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1790:     } else {
1791:       PetscTime(&x);
1792:       MPI_Send(NULL, 0, MPI_INT, 1,          tag, newcomm);
1793:       MPI_Recv(NULL, 0, MPI_INT, size-1, tag, newcomm, &status);
1794:       PetscTime(&y);
1795:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1796:     }
1797:     PetscCommDestroy(&newcomm);
1798:   }
1799:   PetscOptionsView(NULL,viewer);

1801:   /* Machine and compile information */
1802: #if defined(PETSC_USE_FORTRAN_KERNELS)
1803:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1804: #else
1805:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1806: #endif
1807: #if defined(PETSC_USE_64BIT_INDICES)
1808:   PetscFPrintf(comm, fd, "Compiled with 64 bit PetscInt\n");
1809: #elif defined(PETSC_USE___FLOAT128)
1810:   PetscFPrintf(comm, fd, "Compiled with 32 bit PetscInt\n");
1811: #endif
1812: #if defined(PETSC_USE_REAL_SINGLE)
1813:   PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1814: #elif defined(PETSC_USE___FLOAT128)
1815:   PetscFPrintf(comm, fd, "Compiled with 128 bit precision PetscScalar and PetscReal\n");
1816: #endif
1817: #if defined(PETSC_USE_REAL_MAT_SINGLE)
1818:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1819: #else
1820:   PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1821: #endif
1822:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1823:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));

1825:   PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1826:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1827:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1828:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1829:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1831:   /* Cleanup */
1832:   PetscFPrintf(comm, fd, "\n");
1833:   PetscLogViewWarnDebugging(comm,fd);
1834:   return(0);
1835: }

1837: /*@C
1838:   PetscLogView - Prints a summary of the logging.

1840:   Collective over MPI_Comm

1842:   Input Parameter:
1843: .  viewer - an ASCII viewer

1845:   Options Database Keys:
1846: +  -log_view [:filename] - Prints summary of log information
1847: .  -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1848: .  -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format (see below for how to view it)
1849: .  -log_all - Saves a file Log.rank for each MPI process with details of each step of the computation
1850: -  -log_trace [filename] - Displays a trace of what each process is doing

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

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

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

1860:   To view the nested XML format filename.xml first copy  ${PETSC_DIR}/share/petsc/xml/performance_xml2html.xsl to the current
1861:   directory then open filename.xml with your browser. Specific notes for certain browsers
1862: $    Firefox and Internet explorer - simply open the file
1863: $    Google Chrome - you must start up Chrome with the option --allow-file-access-from-files
1864: $    Safari - see https://ccm.net/faq/36342-safari-how-to-enable-local-file-access
1865:   or one can use the package http://xmlsoft.org/XSLT/xsltproc2.html to translate the xml file to html and then open it with
1866:   your browser.
1867:   Alternatively, use the script ${PETSC_DIR}/lib/petsc/bin/petsc-performance-view to automatically open a new browser
1868:   window and render the XML log file contents.

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

1872:   Level: beginner

1874: .seealso: PetscLogDefaultBegin(), PetscLogDump()
1875: @*/
1876: PetscErrorCode  PetscLogView(PetscViewer viewer)
1877: {
1878:   PetscErrorCode    ierr;
1879:   PetscBool         isascii;
1880:   PetscViewerFormat format;
1881:   int               stage, lastStage;
1882:   PetscStageLog     stageLog;

1885:   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_view or PetscLogDefaultBegin() before calling this routine");
1886:   /* Pop off any stages the user forgot to remove */
1887:   lastStage = 0;
1888:   PetscLogGetStageLog(&stageLog);
1889:   PetscStageLogGetCurrent(stageLog, &stage);
1890:   while (stage >= 0) {
1891:     lastStage = stage;
1892:     PetscStageLogPop(stageLog);
1893:     PetscStageLogGetCurrent(stageLog, &stage);
1894:   }
1895:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
1896:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
1897:   PetscViewerGetFormat(viewer,&format);
1898:   if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
1899:     PetscLogView_Default(viewer);
1900:   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1901:     PetscLogView_Detailed(viewer);
1902:   } else if (format == PETSC_VIEWER_ASCII_CSV) {
1903:     PetscLogView_CSV(viewer);
1904:   } else if (format == PETSC_VIEWER_ASCII_XML) {
1905:     PetscLogView_Nested(viewer);
1906:   }
1907:   PetscStageLogPush(stageLog, lastStage);
1908:   return(0);
1909: }

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

1914:   Collective on PETSC_COMM_WORLD

1916:   Not normally called by user

1918:   Level: intermediate

1920: @*/
1921: PetscErrorCode PetscLogViewFromOptions(void)
1922: {
1923:   PetscErrorCode    ierr;
1924:   PetscViewer       viewer;
1925:   PetscBool         flg;
1926:   PetscViewerFormat format;

1929:   PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,NULL,"-log_view",&viewer,&format,&flg);
1930:   if (flg) {
1931:     PetscViewerPushFormat(viewer,format);
1932:     PetscLogView(viewer);
1933:     PetscViewerPopFormat(viewer);
1934:     PetscViewerDestroy(&viewer);
1935:   }
1936:   return(0);
1937: }



1941: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1942: /*@C
1943:    PetscGetFlops - Returns the number of flops used on this processor
1944:    since the program began.

1946:    Not Collective

1948:    Output Parameter:
1949:    flops - number of floating point operations

1951:    Notes:
1952:    A global counter logs all PETSc flop counts.  The user can use
1953:    PetscLogFlops() to increment this counter to include flops for the
1954:    application code.

1956:    Level: intermediate

1958: .seealso: PetscTime(), PetscLogFlops()
1959: @*/
1960: PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
1961: {
1963:   *flops = petsc_TotalFlops;
1964:   return(0);
1965: }

1967: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
1968: {
1970:   size_t         fullLength;
1971:   va_list        Argp;

1974:   if (!petsc_logObjects) return(0);
1975:   va_start(Argp, format);
1976:   PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);
1977:   va_end(Argp);
1978:   return(0);
1979: }


1982: /*MC
1983:    PetscLogFlops - Adds floating point operations to the global counter.

1985:    Synopsis:
1986:    #include <petsclog.h>
1987:    PetscErrorCode PetscLogFlops(PetscLogDouble f)

1989:    Not Collective

1991:    Input Parameter:
1992: .  f - flop counter


1995:    Usage:
1996: .vb
1997:      PetscLogEvent USER_EVENT;
1998:      PetscLogEventRegister("User event",0,&USER_EVENT);
1999:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
2000:         [code segment to monitor]
2001:         PetscLogFlops(user_flops)
2002:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
2003: .ve

2005:    Notes:
2006:    A global counter logs all PETSc flop counts.  The user can use
2007:    PetscLogFlops() to increment this counter to include flops for the
2008:    application code.

2010:    Level: intermediate

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

2014: M*/

2016: /*MC
2017:    PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
2018:     to get accurate timings

2020:    Synopsis:
2021:    #include <petsclog.h>
2022:    void PetscPreLoadBegin(PetscBool  flag,char *name);

2024:    Not Collective

2026:    Input Parameter:
2027: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
2028:            with command line option -preload true or -preload false
2029: -   name - name of first stage (lines of code timed separately with -log_view) to
2030:            be preloaded

2032:    Usage:
2033: .vb
2034:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2035:        lines of code
2036:        PetscPreLoadStage("second stage");
2037:        lines of code
2038:      PetscPreLoadEnd();
2039: .ve

2041:    Notes:
2042:     Only works in C/C++, not Fortran

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

2052:    Level: intermediate

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


2057: M*/

2059: /*MC
2060:    PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
2061:     to get accurate timings

2063:    Synopsis:
2064:    #include <petsclog.h>
2065:    void PetscPreLoadEnd(void);

2067:    Not Collective

2069:    Usage:
2070: .vb
2071:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2072:        lines of code
2073:        PetscPreLoadStage("second stage");
2074:        lines of code
2075:      PetscPreLoadEnd();
2076: .ve

2078:    Notes:
2079:     only works in C/C++ not fortran

2081:    Level: intermediate

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

2085: M*/

2087: /*MC
2088:    PetscPreLoadStage - Start a new segment of code to be timed separately.
2089:     to get accurate timings

2091:    Synopsis:
2092:    #include <petsclog.h>
2093:    void PetscPreLoadStage(char *name);

2095:    Not Collective

2097:    Usage:
2098: .vb
2099:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2100:        lines of code
2101:        PetscPreLoadStage("second stage");
2102:        lines of code
2103:      PetscPreLoadEnd();
2104: .ve

2106:    Notes:
2107:     only works in C/C++ not fortran

2109:    Level: intermediate

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

2113: M*/


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

2118: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2119: {
2121:   return(0);
2122: }

2124: #endif /* PETSC_USE_LOG*/


2127: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2128: PetscClassId PETSC_OBJECT_CLASSID  = 0;

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

2133:   Not Collective

2135:   Input Parameter:
2136: . name   - The class name

2138:   Output Parameter:
2139: . oclass - The class id or classid

2141:   Level: developer

2143: @*/
2144: PetscErrorCode  PetscClassIdRegister(const char name[],PetscClassId *oclass)
2145: {
2146: #if defined(PETSC_USE_LOG)
2147:   PetscStageLog  stageLog;
2148:   PetscInt       stage;
2150: #endif

2153:   *oclass = ++PETSC_LARGEST_CLASSID;
2154: #if defined(PETSC_USE_LOG)
2155:   PetscLogGetStageLog(&stageLog);
2156:   PetscClassRegLogRegister(stageLog->classLog, name, *oclass);
2157:   for (stage = 0; stage < stageLog->numStages; stage++) {
2158:     PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2159:   }
2160: #endif
2161:   return(0);
2162: }

2164: #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2165: #include <mpe.h>

2167: PetscBool PetscBeganMPE = PETSC_FALSE;

2169: PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2170: PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);

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

2176:    Collective over PETSC_COMM_WORLD

2178:    Options Database Keys:
2179: . -log_mpe - Prints extensive log information

2181:    Notes:
2182:    A related routine is PetscLogDefaultBegin() (with the options key -log_view), which is
2183:    intended for production runs since it logs only flop rates and object
2184:    creation (and should not significantly slow the programs).

2186:    Level: advanced


2189: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2190:           PetscLogEventDeactivate()
2191: @*/
2192: PetscErrorCode  PetscLogMPEBegin(void)
2193: {

2197:   /* Do MPE initialization */
2198:   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2199:     PetscInfo(0,"Initializing MPE.\n");
2200:     MPE_Init_log();

2202:     PetscBeganMPE = PETSC_TRUE;
2203:   } else {
2204:     PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");
2205:   }
2206:   PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);
2207:   return(0);
2208: }

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

2213:    Collective over PETSC_COMM_WORLD

2215:    Level: advanced

2217: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2218: @*/
2219: PetscErrorCode  PetscLogMPEDump(const char sname[])
2220: {
2221:   char           name[PETSC_MAX_PATH_LEN];

2225:   if (PetscBeganMPE) {
2226:     PetscInfo(0,"Finalizing MPE.\n");
2227:     if (sname) {
2228:       PetscStrcpy(name,sname);
2229:     } else {
2230:       PetscGetProgramName(name,PETSC_MAX_PATH_LEN);
2231:     }
2232:     MPE_Finish_log(name);
2233:   } else {
2234:     PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");
2235:   }
2236:   return(0);
2237: }

2239: #define PETSC_RGB_COLORS_MAX 39
2240: static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2241:   "OliveDrab:      ",
2242:   "BlueViolet:     ",
2243:   "CadetBlue:      ",
2244:   "CornflowerBlue: ",
2245:   "DarkGoldenrod:  ",
2246:   "DarkGreen:      ",
2247:   "DarkKhaki:      ",
2248:   "DarkOliveGreen: ",
2249:   "DarkOrange:     ",
2250:   "DarkOrchid:     ",
2251:   "DarkSeaGreen:   ",
2252:   "DarkSlateGray:  ",
2253:   "DarkTurquoise:  ",
2254:   "DeepPink:       ",
2255:   "DarkKhaki:      ",
2256:   "DimGray:        ",
2257:   "DodgerBlue:     ",
2258:   "GreenYellow:    ",
2259:   "HotPink:        ",
2260:   "IndianRed:      ",
2261:   "LavenderBlush:  ",
2262:   "LawnGreen:      ",
2263:   "LemonChiffon:   ",
2264:   "LightCoral:     ",
2265:   "LightCyan:      ",
2266:   "LightPink:      ",
2267:   "LightSalmon:    ",
2268:   "LightSlateGray: ",
2269:   "LightYellow:    ",
2270:   "LimeGreen:      ",
2271:   "MediumPurple:   ",
2272:   "MediumSeaGreen: ",
2273:   "MediumSlateBlue:",
2274:   "MidnightBlue:   ",
2275:   "MintCream:      ",
2276:   "MistyRose:      ",
2277:   "NavajoWhite:    ",
2278:   "NavyBlue:       ",
2279:   "OliveDrab:      "
2280: };

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

2285:   Not collective. Maybe it should be?

2287:   Output Parameter
2288: . str - character string representing the color

2290:   Level: developer

2292: .seealso: PetscLogEventRegister
2293: @*/
2294: PetscErrorCode  PetscLogMPEGetRGBColor(const char *str[])
2295: {
2296:   static int idx = 0;

2299:   *str = PetscLogMPERGBColors[idx];
2300:   idx  = (idx + 1)% PETSC_RGB_COLORS_MAX;
2301:   return(0);
2302: }

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