Actual source code: plog.c

petsc-3.13.6 2020-09-29
Report Typos and Errors

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

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

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

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

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

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

 26:    Not collective.

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

 32:    Level: developer

 34:    Developer Notes:
 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: PetscLogDouble petsc_gflops          = 0.0;  /* The flops done on a GPU */
 89: PetscLogDouble petsc_gtime           = 0.0;  /* The time spent on a GPU */
 90: #endif

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

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

106: PETSC_INTERN PetscErrorCode PetscLogInitialize(void)
107: {
108:   int            stage;
109:   PetscBool      opt;

113:   if (PetscLogInitializeCalled) return(0);
114:   PetscLogInitializeCalled = PETSC_TRUE;

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

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

139: PETSC_INTERN PetscErrorCode PetscLogFinalize(void)
140: {
141:   PetscStageLog  stageLog;

145:   PetscFree(petsc_actions);
146:   PetscFree(petsc_objects);
147:   PetscLogNestedEnd();
148:   PetscLogSet(NULL, NULL);

150:   /* Resetting phase */
151:   PetscLogGetStageLog(&stageLog);
152:   PetscStageLogDestroy(stageLog);

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

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

208:   Not Collective

210:   Input Parameters:
211: + b - The function called at beginning of event
212: - e - The function called at end of event

214:   Level: developer

216: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
217: @*/
218: PetscErrorCode  PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
219:                             PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
220: {
222:   PetscLogPLB = b;
223:   PetscLogPLE = e;
224:   return(0);
225: }

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

232:   Logically Collective over PETSC_COMM_WORLD

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

238:   Usage:
239: .vb
240:       PetscInitialize(...);
241:       PetscLogDefaultBegin();
242:        ... code ...
243:       PetscLogView(viewer); or PetscLogDump();
244:       PetscFinalize();
245: .ve

247:   Notes:
248:   PetscLogView(viewer) or PetscLogDump() actually cause the printing of
249:   the logging information.

251:   Level: advanced

253: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogTraceBegin()
254: @*/
255: PetscErrorCode  PetscLogDefaultBegin(void)
256: {

260:   PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
261:   return(0);
262: }

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

268:   Logically Collective on PETSC_COMM_WORLD

270:   Options Database Keys:
271: . -log_all - Prints extensive log information

273:   Usage:
274: .vb
275:      PetscInitialize(...);
276:      PetscLogAllBegin();
277:      ... code ...
278:      PetscLogDump(filename);
279:      PetscFinalize();
280: .ve

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

287:   Level: advanced

289: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogTraceBegin()
290: @*/
291: PetscErrorCode  PetscLogAllBegin(void)
292: {

296:   PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
297:   return(0);
298: }

300: /*@
301:   PetscLogTraceBegin - Activates trace logging.  Every time a PETSc event
302:   begins or ends, the event name is printed.

304:   Logically Collective on PETSC_COMM_WORLD

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

309:   Options Database Key:
310: . -log_trace [filename] - Activates PetscLogTraceBegin()

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

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

320:   Level: intermediate

322: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogDefaultBegin()
323: @*/
324: PetscErrorCode  PetscLogTraceBegin(FILE *file)
325: {

329:   petsc_tracefile = file;

331:   PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
332:   return(0);
333: }

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

338:   Not Collective

340:   Input Parameter:
341: . flag - PETSC_TRUE if actions are to be logged

343:   Level: intermediate

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

348:   Options Database Keys:
349: . -log_exclude_actions - Turns off actions logging

351: .seealso: PetscLogStagePush(), PetscLogStagePop()
352: @*/
353: PetscErrorCode  PetscLogActions(PetscBool flag)
354: {
356:   petsc_logActions = flag;
357:   return(0);
358: }

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

363:   Not Collective

365:   Input Parameter:
366: . flag - PETSC_TRUE if objects are to be logged

368:   Level: intermediate

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

373:   Options Database Keys:
374: . -log_exclude_objects - Turns off objects logging

376: .seealso: PetscLogStagePush(), PetscLogStagePop()
377: @*/
378: PetscErrorCode  PetscLogObjects(PetscBool flag)
379: {
381:   petsc_logObjects = flag;
382:   return(0);
383: }

385: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
386: /*@C
387:   PetscLogStageRegister - Attaches a character string name to a logging stage.

389:   Not Collective

391:   Input Parameter:
392: . sname - The name to associate with that stage

394:   Output Parameter:
395: . stage - The stage number

397:   Level: intermediate

399: .seealso: PetscLogStagePush(), PetscLogStagePop()
400: @*/
401: PetscErrorCode  PetscLogStageRegister(const char sname[],PetscLogStage *stage)
402: {
403:   PetscStageLog  stageLog;
404:   PetscLogEvent  event;

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

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

422:   Not Collective

424:   Input Parameter:
425: . stage - The stage on which to log

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

442:   Notes:
443:   Use PetscLogStageRegister() to register a stage.

445:   Level: intermediate

447: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
448: @*/
449: PetscErrorCode  PetscLogStagePush(PetscLogStage stage)
450: {
451:   PetscStageLog  stageLog;

455:   PetscLogGetStageLog(&stageLog);
456:   PetscStageLogPush(stageLog, stage);
457:   return(0);
458: }

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

463:   Not Collective

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

480:   Notes:
481:   Use PetscLogStageRegister() to register a stage.

483:   Level: intermediate

485: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
486: @*/
487: PetscErrorCode  PetscLogStagePop(void)
488: {
489:   PetscStageLog  stageLog;

493:   PetscLogGetStageLog(&stageLog);
494:   PetscStageLogPop(stageLog);
495:   return(0);
496: }

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

501:   Not Collective

503:   Input Parameters:
504: + stage    - The stage
505: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)

507:   Level: intermediate

509: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
510: @*/
511: PetscErrorCode  PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
512: {
513:   PetscStageLog  stageLog;

517:   PetscLogGetStageLog(&stageLog);
518:   PetscStageLogSetActive(stageLog, stage, isActive);
519:   return(0);
520: }

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

525:   Not Collective

527:   Input Parameter:
528: . stage    - The stage

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

533:   Level: intermediate

535: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
536: @*/
537: PetscErrorCode  PetscLogStageGetActive(PetscLogStage stage, PetscBool  *isActive)
538: {
539:   PetscStageLog  stageLog;

543:   PetscLogGetStageLog(&stageLog);
544:   PetscStageLogGetActive(stageLog, stage, isActive);
545:   return(0);
546: }

548: /*@
549:   PetscLogStageSetVisible - Determines stage visibility in PetscLogView()

551:   Not Collective

553:   Input Parameters:
554: + stage     - The stage
555: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)

557:   Level: intermediate

559: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
560: @*/
561: PetscErrorCode  PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
562: {
563:   PetscStageLog  stageLog;

567:   PetscLogGetStageLog(&stageLog);
568:   PetscStageLogSetVisible(stageLog, stage, isVisible);
569:   return(0);
570: }

572: /*@
573:   PetscLogStageGetVisible - Returns stage visibility in PetscLogView()

575:   Not Collective

577:   Input Parameter:
578: . stage     - The stage

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

583:   Level: intermediate

585: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
586: @*/
587: PetscErrorCode  PetscLogStageGetVisible(PetscLogStage stage, PetscBool  *isVisible)
588: {
589:   PetscStageLog  stageLog;

593:   PetscLogGetStageLog(&stageLog);
594:   PetscStageLogGetVisible(stageLog, stage, isVisible);
595:   return(0);
596: }

598: /*@C
599:   PetscLogStageGetId - Returns the stage id when given the stage name.

601:   Not Collective

603:   Input Parameter:
604: . name  - The stage name

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

609:   Level: intermediate

611: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
612: @*/
613: PetscErrorCode  PetscLogStageGetId(const char name[], PetscLogStage *stage)
614: {
615:   PetscStageLog  stageLog;

619:   PetscLogGetStageLog(&stageLog);
620:   PetscStageLogGetStage(stageLog, name, stage);
621:   return(0);
622: }

624: /*------------------------------------------------ Event Functions --------------------------------------------------*/
625: /*@C
626:   PetscLogEventRegister - Registers an event name for logging operations in an Section 1.5 Writing Application Codes with PETSc code.

628:   Not Collective

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

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

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

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

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

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

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

674:   Level: intermediate

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

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

698: /*@
699:   PetscLogEventSetCollective - Indicates that a particular event is collective.

701:   Not Collective

703:   Input Parameter:
704: + event - The event id
705: - collective - Bolean flag indicating whether a particular event is collective

707:   Note:
708:   New events returned from PetscLogEventRegister() are collective by default.

710:   Level: developer

712: .seealso: PetscLogEventRegister()
713: @*/
714: PetscErrorCode PetscLogEventSetCollective(PetscLogEvent event,PetscBool collective)
715: {
716:   PetscStageLog    stageLog;
717:   PetscEventRegLog eventRegLog;
718:   PetscErrorCode   ierr;

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

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

731:   Not Collective

733:   Input Parameter:
734: . classid - The object class, for example MAT_CLASSID, SNES_CLASSID, etc.

736:   Level: developer

738: .seealso: PetscLogEventActivateClass(),PetscLogEventDeactivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
739: @*/
740: PetscErrorCode  PetscLogEventIncludeClass(PetscClassId classid)
741: {
742:   PetscStageLog  stageLog;
743:   int            stage;

747:   PetscLogGetStageLog(&stageLog);
748:   for (stage = 0; stage < stageLog->numStages; stage++) {
749:     PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
750:   }
751:   return(0);
752: }

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

757:   Not Collective

759:   Input Parameter:
760: . classid - The object class, for example MAT_CLASSID, SNES_CLASSID, etc.

762:   Level: developer

764: .seealso: PetscLogEventDeactivateClass(),PetscLogEventActivateClass(),PetscLogEventDeactivate(),PetscLogEventActivate()
765: @*/
766: PetscErrorCode  PetscLogEventExcludeClass(PetscClassId classid)
767: {
768:   PetscStageLog  stageLog;
769:   int            stage;

773:   PetscLogGetStageLog(&stageLog);
774:   for (stage = 0; stage < stageLog->numStages; stage++) {
775:     PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
776:   }
777:   return(0);
778: }

780: /*@
781:   PetscLogEventActivate - Indicates that a particular event should be logged.

783:   Not Collective

785:   Input Parameter:
786: . event - The event id

788:   Usage:
789: .vb
790:       PetscLogEventDeactivate(VEC_SetValues);
791:         [code where you do not want to log VecSetValues()]
792:       PetscLogEventActivate(VEC_SetValues);
793:         [code where you do want to log VecSetValues()]
794: .ve

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

800:   Level: advanced

802: .seealso: PlogEventDeactivate()
803: @*/
804: PetscErrorCode  PetscLogEventActivate(PetscLogEvent event)
805: {
806:   PetscStageLog  stageLog;
807:   int            stage;

811:   PetscLogGetStageLog(&stageLog);
812:   PetscStageLogGetCurrent(stageLog, &stage);
813:   PetscEventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
814:   return(0);
815: }

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

820:   Not Collective

822:   Input Parameter:
823: . event - The event id

825:   Usage:
826: .vb
827:       PetscLogEventDeactivate(VEC_SetValues);
828:         [code where you do not want to log VecSetValues()]
829:       PetscLogEventActivate(VEC_SetValues);
830:         [code where you do want to log VecSetValues()]
831: .ve

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

837:   Level: advanced

839: .seealso: PlogEventActivate()
840: @*/
841: PetscErrorCode  PetscLogEventDeactivate(PetscLogEvent event)
842: {
843:   PetscStageLog  stageLog;
844:   int            stage;

848:   PetscLogGetStageLog(&stageLog);
849:   PetscStageLogGetCurrent(stageLog, &stage);
850:   PetscEventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
851:   return(0);
852: }

854: /*@
855:   PetscLogEventSetActiveAll - Sets the event activity in every stage.

857:   Not Collective

859:   Input Parameters:
860: + event    - The event id
861: - isActive - The activity flag determining whether the event is logged

863:   Level: advanced

865: .seealso: PlogEventActivate(),PlogEventDeactivate()
866: @*/
867: PetscErrorCode  PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
868: {
869:   PetscStageLog  stageLog;
870:   int            stage;

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

885: /*@
886:   PetscLogEventActivateClass - Activates event logging for a PETSc object class.

888:   Not Collective

890:   Input Parameter:
891: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

893:   Level: developer

895: .seealso: PetscLogEventDeactivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
896: @*/
897: PetscErrorCode  PetscLogEventActivateClass(PetscClassId classid)
898: {
899:   PetscStageLog  stageLog;
900:   int            stage;

904:   PetscLogGetStageLog(&stageLog);
905:   PetscStageLogGetCurrent(stageLog, &stage);
906:   PetscEventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
907:   return(0);
908: }

910: /*@
911:   PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.

913:   Not Collective

915:   Input Parameter:
916: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.

918:   Level: developer

920: .seealso: PetscLogEventActivateClass(),PetscLogEventActivate(),PetscLogEventDeactivate()
921: @*/
922: PetscErrorCode  PetscLogEventDeactivateClass(PetscClassId classid)
923: {
924:   PetscStageLog  stageLog;
925:   int            stage;

929:   PetscLogGetStageLog(&stageLog);
930:   PetscStageLogGetCurrent(stageLog, &stage);
931:   PetscEventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
932:   return(0);
933: }

935: /*MC
936:    PetscLogEventSync - Synchronizes the beginning of a user event.

938:    Synopsis:
939:  #include <petsclog.h>
940:    PetscErrorCode PetscLogEventSync(int e,MPI_Comm comm)

942:    Collective

944:    Input Parameters:
945: +  e - integer associated with the event obtained from PetscLogEventRegister()
946: -  comm - an MPI communicator

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

958:    Notes:
959:    This routine should be called only if there is not a
960:    PetscObject available to pass to PetscLogEventBegin().

962:    Level: developer

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

966: M*/

968: /*MC
969:    PetscLogEventBegin - Logs the beginning of a user event.

971:    Synopsis:
972:  #include <petsclog.h>
973:    PetscErrorCode PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)

975:    Not Collective

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


982:    Fortran Synopsis:
983:    void PetscLogEventBegin(int e,PetscErrorCode ierr)

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

996:    Notes:
997:    You need to register each integer event with the command
998:    PetscLogEventRegister().

1000:    Level: intermediate

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

1004: M*/

1006: /*MC
1007:    PetscLogEventEnd - Log the end of a user event.

1009:    Synopsis:
1010:  #include <petsclog.h>
1011:    PetscErrorCode PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)

1013:    Not Collective

1015:    Input Parameters:
1016: +  e - integer associated with the event obtained with PetscLogEventRegister()
1017: -  o1,o2,o3,o4 - objects associated with the event, or 0


1020:    Fortran Synopsis:
1021:    void PetscLogEventEnd(int e,PetscErrorCode ierr)

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

1034:    Notes:
1035:    You should also register each additional integer event with the command
1036:    PetscLogEventRegister().

1038:    Level: intermediate

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

1042: M*/

1044: /*@C
1045:   PetscLogEventGetId - Returns the event id when given the event name.

1047:   Not Collective

1049:   Input Parameter:
1050: . name  - The event name

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

1055:   Level: intermediate

1057: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1058: @*/
1059: PetscErrorCode  PetscLogEventGetId(const char name[], PetscLogEvent *event)
1060: {
1061:   PetscStageLog  stageLog;

1065:   PetscLogGetStageLog(&stageLog);
1066:   PetscEventRegLogGetEvent(stageLog->eventLog, name, event);
1067:   return(0);
1068: }


1071: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1072: /*@C
1073:   PetscLogDump - Dumps logs of objects to a file. This file is intended to
1074:   be read by bin/petscview. This program no longer exists.

1076:   Collective on PETSC_COMM_WORLD

1078:   Input Parameter:
1079: . name - an optional file name

1081:   Usage:
1082: .vb
1083:      PetscInitialize(...);
1084:      PetscLogDefaultBegin(); or PetscLogAllBegin();
1085:      ... code ...
1086:      PetscLogDump(filename);
1087:      PetscFinalize();
1088: .ve

1090:   Notes:
1091:   The default file name is
1092: $    Log.<rank>
1093:   where <rank> is the processor number. If no name is specified,
1094:   this file will be used.

1096:   Level: advanced

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

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

1167: /*
1168:   PetscLogView_Detailed - Each process prints the times for its own events

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

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

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

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

1266:   MPI_Comm_size(comm, &size);
1267:   MPI_Comm_rank(comm, &rank);
1268:   /* Must preserve reduction count before we go on */
1269:   /* Get the total elapsed time */
1270:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;
1271:   PetscLogGetStageLog(&stageLog);
1272:   MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1273:   PetscMallocGetMaximumUsage(&maxMem);
1274:   PetscViewerASCIIPushSynchronized(viewer);
1275:   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);
1276:   PetscViewerFlush(viewer);
1277:   for (stage=0; stage<numStages; stage++) {
1278:     PetscEventPerfInfo *stageInfo = &stageLog->stageInfo[stage].perfInfo;

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

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

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

1326: static PetscErrorCode PetscLogViewWarnDebugging(MPI_Comm comm,FILE *fd)
1327: {
1328: #if defined(PETSC_USE_DEBUG)

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

1349: static PetscErrorCode PetscLogViewWarnNoGpuAwareMpi(MPI_Comm comm,FILE *fd)
1350: {
1351: #if defined(PETSC_HAVE_CUDA)

1355:   if (use_gpu_aware_mpi) return(0);
1356:   PetscFPrintf(comm, fd, "\n\n");
1357:   PetscFPrintf(comm, fd, "      ##########################################################\n");
1358:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1359:   PetscFPrintf(comm, fd, "      #                       WARNING!!!                       #\n");
1360:   PetscFPrintf(comm, fd, "      #                                                        #\n");
1361:   PetscFPrintf(comm, fd, "      #   This code was compiled with GPU support but you used #\n");
1362:   PetscFPrintf(comm, fd, "      #   an MPI that's not GPU-aware, such Petsc had to copy  #\n");
1363:   PetscFPrintf(comm, fd, "      #   data from GPU to CPU for MPI communication. To get   #\n");
1364:   PetscFPrintf(comm, fd, "      #   meaningfull timing results, please use a GPU-aware   #\n");
1365:   PetscFPrintf(comm, fd, "      #   MPI instead.                                         #\n");
1366:   PetscFPrintf(comm, fd, "      ##########################################################\n\n\n");
1367:   return(0);
1368: #else
1369:   return 0;
1370: #endif
1371: }

1373: #if defined(PETSC_HAVE_OPENMP)
1374: extern PetscInt PetscNumOMPThreads;
1375: #endif

1377: PetscErrorCode  PetscLogView_Default(PetscViewer viewer)
1378: {
1379:   FILE               *fd;
1380:   PetscLogDouble     zero       = 0.0;
1381:   PetscStageLog      stageLog;
1382:   PetscStageInfo     *stageInfo = NULL;
1383:   PetscEventPerfInfo *eventInfo = NULL;
1384:   PetscClassPerfInfo *classInfo;
1385:   char               arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
1386:   const char         *name;
1387:   PetscLogDouble     locTotalTime, TotalTime, TotalFlops;
1388:   PetscLogDouble     numMessages, messageLength, avgMessLen, numReductions;
1389:   PetscLogDouble     stageTime, flops, flopr, mem, mess, messLen, red;
1390:   PetscLogDouble     fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1391:   PetscLogDouble     fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1392:   PetscLogDouble     min, max, tot, ratio, avg, x, y;
1393:   PetscLogDouble     minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratC, totm, totml, totr, mal, malmax, emalmax;
1394:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1395:   PetscLogDouble     cct, gct, csz, gsz, gmaxt, gflops, gflopr, fracgflops;
1396:   #endif
1397:   PetscMPIInt        minC, maxC;
1398:   PetscMPIInt        size, rank;
1399:   PetscBool          *localStageUsed,    *stageUsed;
1400:   PetscBool          *localStageVisible, *stageVisible;
1401:   int                numStages, localNumEvents, numEvents;
1402:   int                stage, oclass;
1403:   PetscLogEvent      event;
1404:   PetscErrorCode     ierr;
1405:   char               version[256];
1406:   MPI_Comm           comm;

1409:   PetscObjectGetComm((PetscObject)viewer,&comm);
1410:   PetscViewerASCIIGetPointer(viewer,&fd);
1411:   MPI_Comm_size(comm, &size);
1412:   MPI_Comm_rank(comm, &rank);
1413:   /* Get the total elapsed time */
1414:   PetscTime(&locTotalTime);  locTotalTime -= petsc_BaseTime;

1416:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1417:   PetscFPrintf(comm, fd, "***             WIDEN YOUR WINDOW TO 120 CHARACTERS.  Use 'enscript -r -fCourier9' to print this document            ***\n");
1418:   PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1419:   PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1420:   PetscLogViewWarnSync(comm,fd);
1421:   PetscLogViewWarnDebugging(comm,fd);
1422:   PetscLogViewWarnNoGpuAwareMpi(comm,fd);
1423:   PetscGetArchType(arch,sizeof(arch));
1424:   PetscGetHostName(hostname,sizeof(hostname));
1425:   PetscGetUserName(username,sizeof(username));
1426:   PetscGetProgramName(pname,sizeof(pname));
1427:   PetscGetDate(date,sizeof(date));
1428:   PetscGetVersion(version,sizeof(version));
1429:   if (size == 1) {
1430:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1431:   } else {
1432:     PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1433:   }
1434: #if defined(PETSC_HAVE_OPENMP)
1435:   PetscFPrintf(comm,fd,"Using %D OpenMP threads\n", PetscNumOMPThreads);
1436: #endif
1437:   PetscFPrintf(comm, fd, "Using %s\n", version);

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

1442:   /* Calculate summary information */
1443:   PetscFPrintf(comm, fd, "\n                         Max       Max/Min     Avg       Total\n");
1444:   /*   Time */
1445:   MPIU_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1446:   MPIU_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1447:   MPIU_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1448:   avg  = tot/((PetscLogDouble) size);
1449:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1450:   PetscFPrintf(comm, fd, "Time (sec):           %5.3e   %7.3f   %5.3e\n", max, ratio, avg);
1451:   TotalTime = tot;
1452:   /*   Objects */
1453:   avg  = (PetscLogDouble) petsc_numObjects;
1454:   MPIU_Allreduce(&avg,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1455:   MPIU_Allreduce(&avg,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1456:   MPIU_Allreduce(&avg,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1457:   avg  = tot/((PetscLogDouble) size);
1458:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1459:   PetscFPrintf(comm, fd, "Objects:              %5.3e   %7.3f   %5.3e\n", max, ratio, avg);
1460:   /*   Flops */
1461:   MPIU_Allreduce(&petsc_TotalFlops,  &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1462:   MPIU_Allreduce(&petsc_TotalFlops,  &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1463:   MPIU_Allreduce(&petsc_TotalFlops,  &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1464:   avg  = tot/((PetscLogDouble) size);
1465:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1466:   PetscFPrintf(comm, fd, "Flop:                 %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1467:   TotalFlops = tot;
1468:   /*   Flops/sec -- Must talk to Barry here */
1469:   if (locTotalTime != 0.0) flops = petsc_TotalFlops/locTotalTime; else flops = 0.0;
1470:   MPIU_Allreduce(&flops,        &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1471:   MPIU_Allreduce(&flops,        &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1472:   MPIU_Allreduce(&flops,        &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1473:   avg  = tot/((PetscLogDouble) size);
1474:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1475:   PetscFPrintf(comm, fd, "Flop/sec:             %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1476:   /*   Memory */
1477:   PetscMallocGetMaximumUsage(&mem);
1478:   if (mem > 0.0) {
1479:     MPIU_Allreduce(&mem,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1480:     MPIU_Allreduce(&mem,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1481:     MPIU_Allreduce(&mem,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1482:     avg  = tot/((PetscLogDouble) size);
1483:     if (min != 0.0) ratio = max/min; else ratio = 0.0;
1484:     PetscFPrintf(comm, fd, "Memory:               %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1485:   }
1486:   /*   Messages */
1487:   mess = 0.5*(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct);
1488:   MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1489:   MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1490:   MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1491:   avg  = tot/((PetscLogDouble) size);
1492:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1493:   PetscFPrintf(comm, fd, "MPI Messages:         %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1494:   numMessages = tot;
1495:   /*   Message Lengths */
1496:   mess = 0.5*(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len);
1497:   MPIU_Allreduce(&mess,         &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1498:   MPIU_Allreduce(&mess,         &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1499:   MPIU_Allreduce(&mess,         &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1500:   if (numMessages != 0) avg = tot/numMessages; else avg = 0.0;
1501:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1502:   PetscFPrintf(comm, fd, "MPI Message Lengths:  %5.3e   %7.3f   %5.3e  %5.3e\n", max, ratio, avg, tot);
1503:   messageLength = tot;
1504:   /*   Reductions */
1505:   MPIU_Allreduce(&red,          &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1506:   MPIU_Allreduce(&red,          &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1507:   MPIU_Allreduce(&red,          &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1508:   if (min != 0.0) ratio = max/min; else ratio = 0.0;
1509:   PetscFPrintf(comm, fd, "MPI Reductions:       %5.3e   %7.3f\n", max, ratio);
1510:   numReductions = red; /* wrong because uses count from process zero */
1511:   PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1512:   PetscFPrintf(comm, fd, "                            e.g., VecAXPY() for real vectors of length N --> 2N flop\n");
1513:   PetscFPrintf(comm, fd, "                            and VecAXPY() for complex vectors of length N --> 8N flop\n");

1515:   /* Get total number of stages --
1516:        Currently, a single processor can register more stages than another, but stages must all be registered in order.
1517:        We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1518:        This seems best accomplished by assoicating a communicator with each stage.
1519:   */
1520:   PetscLogGetStageLog(&stageLog);
1521:   MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1522:   PetscMalloc1(numStages, &localStageUsed);
1523:   PetscMalloc1(numStages, &stageUsed);
1524:   PetscMalloc1(numStages, &localStageVisible);
1525:   PetscMalloc1(numStages, &stageVisible);
1526:   if (numStages > 0) {
1527:     stageInfo = stageLog->stageInfo;
1528:     for (stage = 0; stage < numStages; stage++) {
1529:       if (stage < stageLog->numStages) {
1530:         localStageUsed[stage]    = stageInfo[stage].used;
1531:         localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1532:       } else {
1533:         localStageUsed[stage]    = PETSC_FALSE;
1534:         localStageVisible[stage] = PETSC_TRUE;
1535:       }
1536:     }
1537:     MPIU_Allreduce(localStageUsed,    stageUsed,    numStages, MPIU_BOOL, MPI_LOR,  comm);
1538:     MPIU_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);
1539:     for (stage = 0; stage < numStages; stage++) {
1540:       if (stageUsed[stage]) {
1541:         PetscFPrintf(comm, fd, "\nSummary of Stages:   ----- Time ------  ----- Flop ------  --- Messages ---  -- Message Lengths --  -- Reductions --\n");
1542:         PetscFPrintf(comm, fd, "                        Avg     %%Total     Avg     %%Total    Count   %%Total     Avg         %%Total    Count   %%Total\n");
1543:         break;
1544:       }
1545:     }
1546:     for (stage = 0; stage < numStages; stage++) {
1547:       if (!stageUsed[stage]) continue;
1548:       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1549:       if (localStageUsed[stage]) {
1550:         MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1551:         MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1552:         MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1553:         MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1554:         MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1555:         name = stageInfo[stage].name;
1556:       } else {
1557:         MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1558:         MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1559:         MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1560:         MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1561:         MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1562:         name = "";
1563:       }
1564:       mess *= 0.5; messLen *= 0.5; red /= size;
1565:       if (TotalTime     != 0.0) fracTime       = stageTime/TotalTime;    else fracTime       = 0.0;
1566:       if (TotalFlops    != 0.0) fracFlops      = flops/TotalFlops;       else fracFlops      = 0.0;
1567:       /* Talk to Barry if (stageTime     != 0.0) flops          = (size*flops)/stageTime; else flops          = 0.0; */
1568:       if (numMessages   != 0.0) fracMessages   = mess/numMessages;       else fracMessages   = 0.0;
1569:       if (mess          != 0.0) avgMessLen     = messLen/mess;           else avgMessLen     = 0.0;
1570:       if (messageLength != 0.0) fracLength     = messLen/messageLength;  else fracLength     = 0.0;
1571:       if (numReductions != 0.0) fracReductions = red/numReductions;      else fracReductions = 0.0;
1572:       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",
1573:                           stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1574:                           mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1575:     }
1576:   }

1578:   PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");
1579:   PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1580:   PetscFPrintf(comm, fd, "Phase summary info:\n");
1581:   PetscFPrintf(comm, fd, "   Count: number of times phase was executed\n");
1582:   PetscFPrintf(comm, fd, "   Time and Flop: Max - maximum over all processors\n");
1583:   PetscFPrintf(comm, fd, "                  Ratio - ratio of maximum to minimum over all processors\n");
1584:   PetscFPrintf(comm, fd, "   Mess: number of messages sent\n");
1585:   PetscFPrintf(comm, fd, "   AvgLen: average message length (bytes)\n");
1586:   PetscFPrintf(comm, fd, "   Reduct: number of global reductions\n");
1587:   PetscFPrintf(comm, fd, "   Global: entire computation\n");
1588:   PetscFPrintf(comm, fd, "   Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1589:   PetscFPrintf(comm, fd, "      %%T - percent time in this phase         %%F - percent flop in this phase\n");
1590:   PetscFPrintf(comm, fd, "      %%M - percent messages in this phase     %%L - percent message lengths in this phase\n");
1591:   PetscFPrintf(comm, fd, "      %%R - percent reductions in this phase\n");
1592:   PetscFPrintf(comm, fd, "   Total Mflop/s: 10e-6 * (sum of flop over all processors)/(max time over all processors)\n");
1593:   if (PetscLogMemory) {
1594:     PetscFPrintf(comm, fd, "   Malloc Mbytes: Memory allocated and kept during event (sum over all calls to event)\n");
1595:     PetscFPrintf(comm, fd, "   EMalloc Mbytes: extra memory allocated during event and then freed (maximum over all calls to events)\n");
1596:     PetscFPrintf(comm, fd, "   MMalloc Mbytes: Increase in high water mark of allocated memory (sum over all calls to event)\n");
1597:     PetscFPrintf(comm, fd, "   RMI Mbytes: Increase in resident memory (sum over all calls to event)\n");
1598:   }
1599:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1600:   PetscFPrintf(comm, fd, "   GPU Mflop/s: 10e-6 * (sum of flop on GPU over all processors)/(max GPU time over all processors)\n");
1601:   PetscFPrintf(comm, fd, "   CpuToGpu Count: total number of CPU to GPU copies per processor\n");
1602:   PetscFPrintf(comm, fd, "   CpuToGpu Size (Mbytes): 10e-6 * (total size of CPU to GPU copies per processor)\n");
1603:   PetscFPrintf(comm, fd, "   GpuToCpu Count: total number of GPU to CPU copies per processor\n");
1604:   PetscFPrintf(comm, fd, "   GpuToCpu Size (Mbytes): 10e-6 * (total size of GPU to CPU copies per processor)\n");
1605:   PetscFPrintf(comm, fd, "   GPU %%F: percent flops on GPU in this event\n");
1606:   #endif
1607:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");

1609:   PetscLogViewWarnDebugging(comm,fd);

1611:   /* Report events */
1612:   PetscFPrintf(comm, fd,"Event                Count      Time (sec)     Flop                              --- Global ---  --- Stage ----  Total");
1613:   if (PetscLogMemory) {
1614:     PetscFPrintf(comm, fd,"  Malloc EMalloc MMalloc RMI");
1615:   } 
1616:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1617:   PetscFPrintf(comm, fd,"   GPU    - CpuToGpu -   - GpuToCpu - GPU");
1618:   #endif
1619:   PetscFPrintf(comm, fd,"\n");
1620:   PetscFPrintf(comm, fd,"                   Max Ratio  Max     Ratio   Max  Ratio  Mess   AvgLen  Reduct  %%T %%F %%M %%L %%R  %%T %%F %%M %%L %%R Mflop/s");
1621:   if (PetscLogMemory) {
1622:     PetscFPrintf(comm, fd," Mbytes Mbytes Mbytes Mbytes");
1623:   }
1624:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1625:   PetscFPrintf(comm, fd," Mflop/s Count   Size   Count   Size  %%F"); 
1626:   #endif
1627:   PetscFPrintf(comm, fd,"\n");
1628:   PetscFPrintf(comm, fd,"------------------------------------------------------------------------------------------------------------------------");
1629:   if (PetscLogMemory) {
1630:     PetscFPrintf(comm, fd,"-----------------------------");
1631:   }
1632:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1633:   PetscFPrintf(comm, fd,"---------------------------------------"); 
1634:   #endif
1635:   PetscFPrintf(comm, fd,"\n");

1637:   /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1638:   for (stage = 0; stage < numStages; stage++) {
1639:     if (!stageVisible[stage]) continue;
1640:     /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1641:     if (localStageUsed[stage]) {
1642:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1643:       MPI_Allreduce(&stageInfo[stage].perfInfo.time,          &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1644:       MPI_Allreduce(&stageInfo[stage].perfInfo.flops,         &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1645:       MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages,   &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1646:       MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1647:       MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1648:     } else {
1649:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1650:       MPI_Allreduce(&zero,                           &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1651:       MPI_Allreduce(&zero,                           &flops,     1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1652:       MPI_Allreduce(&zero,                           &mess,      1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1653:       MPI_Allreduce(&zero,                           &messLen,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1654:       MPI_Allreduce(&zero,                           &red,       1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1655:     }
1656:     mess *= 0.5; messLen *= 0.5; red /= size;

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

1663:        Problem: If the event did not happen on proc 1, its name will not be available.
1664:        Problem: Event visibility is not implemented
1665:     */
1666:     if (localStageUsed[stage]) {
1667:       eventInfo      = stageLog->stageInfo[stage].eventLog->eventInfo;
1668:       localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1669:     } else localNumEvents = 0;
1670:     MPIU_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1671:     for (event = 0; event < numEvents; event++) {
1672:       /* CANNOT use MPIU_Allreduce() since it might fail the line number check */
1673:       if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1674:         if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops; else flopr = 0.0;
1675:         MPI_Allreduce(&flopr,                          &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1676:         MPI_Allreduce(&flopr,                          &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1677:         MPI_Allreduce(&eventInfo[event].flops,         &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1678:         MPI_Allreduce(&eventInfo[event].time,          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1679:         MPI_Allreduce(&eventInfo[event].time,          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1680:         MPI_Allreduce(&eventInfo[event].time,          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1681:         MPI_Allreduce(&eventInfo[event].numMessages,   &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1682:         MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1683:         MPI_Allreduce(&eventInfo[event].numReductions, &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1684:         MPI_Allreduce(&eventInfo[event].count,         &minC,  1, MPI_INT,             MPI_MIN, comm);
1685:         MPI_Allreduce(&eventInfo[event].count,         &maxC,  1, MPI_INT,             MPI_MAX, comm);
1686:         if (PetscLogMemory) {
1687:           MPI_Allreduce(&eventInfo[event].memIncrease,    &mem,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1688:           MPI_Allreduce(&eventInfo[event].mallocSpace,    &mal,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1689:           MPI_Allreduce(&eventInfo[event].mallocIncrease, &malmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1690:           MPI_Allreduce(&eventInfo[event].mallocIncreaseEvent, &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1691:         }
1692:         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1693:         MPI_Allreduce(&eventInfo[event].CpuToGpuCount,    &cct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1694:         MPI_Allreduce(&eventInfo[event].GpuToCpuCount,    &gct,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1695:         MPI_Allreduce(&eventInfo[event].CpuToGpuSize,     &csz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1696:         MPI_Allreduce(&eventInfo[event].GpuToCpuSize,     &gsz,   1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1697:         MPI_Allreduce(&eventInfo[event].GpuFlops,         &gflops,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1698:         MPI_Allreduce(&eventInfo[event].GpuTime,          &gmaxt ,1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1699:         #endif
1700:         name = stageLog->eventLog->eventInfo[event].name;
1701:       } else {
1702:         flopr = 0.0;
1703:         MPI_Allreduce(&flopr,                         &minf,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1704:         MPI_Allreduce(&flopr,                         &maxf,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1705:         MPI_Allreduce(&zero,                          &totf,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1706:         MPI_Allreduce(&zero,                          &mint,  1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1707:         MPI_Allreduce(&zero,                          &maxt,  1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1708:         MPI_Allreduce(&zero,                          &tott,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1709:         MPI_Allreduce(&zero,                          &totm,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1710:         MPI_Allreduce(&zero,                          &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1711:         MPI_Allreduce(&zero,                          &totr,  1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1712:         MPI_Allreduce(&ierr,                          &minC,  1, MPI_INT,             MPI_MIN, comm);
1713:         MPI_Allreduce(&ierr,                          &maxC,  1, MPI_INT,             MPI_MAX, comm);
1714:         if (PetscLogMemory) {
1715:           MPI_Allreduce(&zero,                        &mem,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1716:           MPI_Allreduce(&zero,                        &mal,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1717:           MPI_Allreduce(&zero,                        &malmax, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1718:           MPI_Allreduce(&zero,                        &emalmax,1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1719:         }
1720:         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1721:         MPI_Allreduce(&zero,                          &cct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1722:         MPI_Allreduce(&zero,                          &gct,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1723:         MPI_Allreduce(&zero,                          &csz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1724:         MPI_Allreduce(&zero,                          &gsz,    1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1725:         MPI_Allreduce(&zero,                          &gflops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1726:         MPI_Allreduce(&zero,                          &gmaxt , 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1727:         #endif
1728:         name  = "";
1729:       }
1730:       if (mint < 0.0) {
1731:         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);
1732:         mint = 0;
1733:       }
1734:       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);
1735:       totm *= 0.5; totml *= 0.5; totr /= size;

1737:       if (maxC != 0) {
1738:         if (minC          != 0)   ratC             = ((PetscLogDouble)maxC)/minC;else ratC             = 0.0;
1739:         if (mint          != 0.0) ratt             = maxt/mint;                  else ratt             = 0.0;
1740:         if (minf          != 0.0) ratf             = maxf/minf;                  else ratf             = 0.0;
1741:         if (TotalTime     != 0.0) fracTime         = tott/TotalTime;             else fracTime         = 0.0;
1742:         if (TotalFlops    != 0.0) fracFlops        = totf/TotalFlops;            else fracFlops        = 0.0;
1743:         if (stageTime     != 0.0) fracStageTime    = tott/stageTime;             else fracStageTime    = 0.0;
1744:         if (flops         != 0.0) fracStageFlops   = totf/flops;                 else fracStageFlops   = 0.0;
1745:         if (numMessages   != 0.0) fracMess         = totm/numMessages;           else fracMess         = 0.0;
1746:         if (messageLength != 0.0) fracMessLen      = totml/messageLength;        else fracMessLen      = 0.0;
1747:         if (numReductions != 0.0) fracRed          = totr/numReductions;         else fracRed          = 0.0;
1748:         if (mess          != 0.0) fracStageMess    = totm/mess;                  else fracStageMess    = 0.0;
1749:         if (messLen       != 0.0) fracStageMessLen = totml/messLen;              else fracStageMessLen = 0.0;
1750:         if (red           != 0.0) fracStageRed     = totr/red;                   else fracStageRed     = 0.0;
1751:         if (totm          != 0.0) totml           /= totm;                       else totml            = 0.0;
1752:         if (maxt          != 0.0) flopr            = totf/maxt;                  else flopr            = 0.0;
1753:         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");
1754:         PetscFPrintf(comm, fd,
1755:                             "%-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",
1756:                             name, maxC, ratC, maxt, ratt, maxf, ratf, totm, totml, totr,
1757:                             100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1758:                             100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1759:                             PetscAbs(flopr)/1.0e6);
1760:         if (PetscLogMemory) {
1761:           PetscFPrintf(comm, fd," %5.0f   %5.0f   %5.0f   %5.0f",mal/1.0e6,emalmax/1.0e6,malmax/1.0e6,mem/1.0e6);
1762:         } 
1763:         #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1764:         if (totf  != 0.0) fracgflops = gflops/totf;  else fracgflops = 0.0;
1765:         if (gmaxt != 0.0) gflopr     = gflops/gmaxt; else gflopr     = 0.0;
1766:         PetscFPrintf(comm, fd,"   %5.0f   %4.0f %3.2e %4.0f %3.2e% 3.0f",PetscAbs(gflopr)/1.0e6,cct/size,csz/(1.0e6*size),gct/size,gsz/(1.0e6*size),100.0*fracgflops);
1767:         #endif
1768:         PetscFPrintf(comm, fd,"\n");
1769:       }
1770:     }
1771:   }

1773:   /* Memory usage and object creation */
1774:   PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------");
1775:   if (PetscLogMemory) {
1776:     PetscFPrintf(comm, fd, "-----------------------------");
1777:   }
1778:   #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 
1779:   PetscFPrintf(comm, fd, "---------------------------------------"); 
1780:   #endif
1781:   PetscFPrintf(comm, fd, "\n");
1782:   PetscFPrintf(comm, fd, "\n");
1783:   PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");

1785:   /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1786:      the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1787:      stats for stages local to processor sets.
1788:   */
1789:   /* We should figure out the longest object name here (now 20 characters) */
1790:   PetscFPrintf(comm, fd, "Object Type          Creations   Destructions     Memory  Descendants' Mem.\n");
1791:   PetscFPrintf(comm, fd, "Reports information only for process 0.\n");
1792:   for (stage = 0; stage < numStages; stage++) {
1793:     if (localStageUsed[stage]) {
1794:       classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1795:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1796:       for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1797:         if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1798:           PetscFPrintf(comm, fd, "%20s %5d          %5d  %11.0f     %g\n", stageLog->classLog->classInfo[oclass].name,
1799:                               classInfo[oclass].creations, classInfo[oclass].destructions, classInfo[oclass].mem,
1800:                               classInfo[oclass].descMem);
1801:         }
1802:       }
1803:     } else {
1804:       if (!localStageVisible[stage]) continue;
1805:       PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1806:     }
1807:   }

1809:   PetscFree(localStageUsed);
1810:   PetscFree(stageUsed);
1811:   PetscFree(localStageVisible);
1812:   PetscFree(stageVisible);

1814:   /* Information unrelated to this particular run */
1815:   PetscFPrintf(comm, fd, "========================================================================================================================\n");
1816:   PetscTime(&y);
1817:   PetscTime(&x);
1818:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1819:   PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1820:   PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1821:   /* MPI information */
1822:   if (size > 1) {
1823:     MPI_Status  status;
1824:     PetscMPIInt tag;
1825:     MPI_Comm    newcomm;

1827:     MPI_Barrier(comm);
1828:     PetscTime(&x);
1829:     MPI_Barrier(comm);
1830:     MPI_Barrier(comm);
1831:     MPI_Barrier(comm);
1832:     MPI_Barrier(comm);
1833:     MPI_Barrier(comm);
1834:     PetscTime(&y);
1835:     PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1836:     PetscCommDuplicate(comm,&newcomm, &tag);
1837:     MPI_Barrier(comm);
1838:     if (rank) {
1839:       MPI_Recv(NULL, 0, MPI_INT, rank-1,            tag, newcomm, &status);
1840:       MPI_Send(NULL, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1841:     } else {
1842:       PetscTime(&x);
1843:       MPI_Send(NULL, 0, MPI_INT, 1,          tag, newcomm);
1844:       MPI_Recv(NULL, 0, MPI_INT, size-1, tag, newcomm, &status);
1845:       PetscTime(&y);
1846:       PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1847:     }
1848:     PetscCommDestroy(&newcomm);
1849:   }
1850:   PetscOptionsView(NULL,viewer);

1852:   /* Machine and compile information */
1853: #if defined(PETSC_USE_FORTRAN_KERNELS)
1854:   PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1855: #else
1856:   PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1857: #endif
1858: #if defined(PETSC_USE_64BIT_INDICES)
1859:   PetscFPrintf(comm, fd, "Compiled with 64 bit PetscInt\n");
1860: #elif defined(PETSC_USE___FLOAT128)
1861:   PetscFPrintf(comm, fd, "Compiled with 32 bit PetscInt\n");
1862: #endif
1863: #if defined(PETSC_USE_REAL_SINGLE)
1864:   PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1865: #elif defined(PETSC_USE___FLOAT128)
1866:   PetscFPrintf(comm, fd, "Compiled with 128 bit precision PetscScalar and PetscReal\n");
1867: #endif
1868: #if defined(PETSC_USE_REAL_MAT_SINGLE)
1869:   PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1870: #else
1871:   PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1872: #endif
1873:   PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1874:                       (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));

1876:   PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1877:   PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1878:   PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1879:   PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1880:   PetscFPrintf(comm, fd, "%s", petsclinkerinfo);

1882:   /* Cleanup */
1883:   PetscFPrintf(comm, fd, "\n");
1884:   PetscLogViewWarnNoGpuAwareMpi(comm,fd);
1885:   PetscLogViewWarnDebugging(comm,fd);
1886:   return(0);
1887: }

1889: /*@C
1890:   PetscLogView - Prints a summary of the logging.

1892:   Collective over MPI_Comm

1894:   Input Parameter:
1895: .  viewer - an ASCII viewer

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

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

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

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

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

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

1924:   Level: beginner

1926: .seealso: PetscLogDefaultBegin(), PetscLogDump()
1927: @*/
1928: PetscErrorCode  PetscLogView(PetscViewer viewer)
1929: {
1930:   PetscErrorCode    ierr;
1931:   PetscBool         isascii;
1932:   PetscViewerFormat format;
1933:   int               stage, lastStage;
1934:   PetscStageLog     stageLog;

1937:   if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_view or PetscLogDefaultBegin() before calling this routine");
1938:   /* Pop off any stages the user forgot to remove */
1939:   lastStage = 0;
1940:   PetscLogGetStageLog(&stageLog);
1941:   PetscStageLogGetCurrent(stageLog, &stage);
1942:   while (stage >= 0) {
1943:     lastStage = stage;
1944:     PetscStageLogPop(stageLog);
1945:     PetscStageLogGetCurrent(stageLog, &stage);
1946:   }
1947:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
1948:   if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
1949:   PetscViewerGetFormat(viewer,&format);
1950:   if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
1951:     PetscLogView_Default(viewer);
1952:   } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1953:     PetscLogView_Detailed(viewer);
1954:   } else if (format == PETSC_VIEWER_ASCII_CSV) {
1955:     PetscLogView_CSV(viewer);
1956:   } else if (format == PETSC_VIEWER_ASCII_XML) {
1957:     PetscLogView_Nested(viewer);
1958:   }
1959:   PetscStageLogPush(stageLog, lastStage);
1960:   return(0);
1961: }

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

1966:   Collective on PETSC_COMM_WORLD

1968:   Not normally called by user

1970:   Level: intermediate

1972: @*/
1973: PetscErrorCode PetscLogViewFromOptions(void)
1974: {
1975:   PetscErrorCode    ierr;
1976:   PetscViewer       viewer;
1977:   PetscBool         flg;
1978:   PetscViewerFormat format;

1981:   PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,NULL,"-log_view",&viewer,&format,&flg);
1982:   if (flg) {
1983:     PetscViewerPushFormat(viewer,format);
1984:     PetscLogView(viewer);
1985:     PetscViewerPopFormat(viewer);
1986:     PetscViewerDestroy(&viewer);
1987:   }
1988:   return(0);
1989: }



1993: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1994: /*@C
1995:    PetscGetFlops - Returns the number of flops used on this processor
1996:    since the program began.

1998:    Not Collective

2000:    Output Parameter:
2001:    flops - number of floating point operations

2003:    Notes:
2004:    A global counter logs all PETSc flop counts.  The user can use
2005:    PetscLogFlops() to increment this counter to include flops for the
2006:    Section 1.5 Writing Application Codes with PETSc code.

2008:    Level: intermediate

2010: .seealso: PetscTime(), PetscLogFlops()
2011: @*/
2012: PetscErrorCode  PetscGetFlops(PetscLogDouble *flops)
2013: {
2015:   *flops = petsc_TotalFlops;
2016:   return(0);
2017: }

2019: PetscErrorCode  PetscLogObjectState(PetscObject obj, const char format[], ...)
2020: {
2022:   size_t         fullLength;
2023:   va_list        Argp;

2026:   if (!petsc_logObjects) return(0);
2027:   va_start(Argp, format);
2028:   PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);
2029:   va_end(Argp);
2030:   return(0);
2031: }


2034: /*MC
2035:    PetscLogFlops - Adds floating point operations to the global counter.

2037:    Synopsis:
2038:  #include <petsclog.h>
2039:    PetscErrorCode PetscLogFlops(PetscLogDouble f)

2041:    Not Collective

2043:    Input Parameter:
2044: .  f - flop counter


2047:    Usage:
2048: .vb
2049:      PetscLogEvent USER_EVENT;
2050:      PetscLogEventRegister("User event",0,&USER_EVENT);
2051:      PetscLogEventBegin(USER_EVENT,0,0,0,0);
2052:         [code segment to monitor]
2053:         PetscLogFlops(user_flops)
2054:      PetscLogEventEnd(USER_EVENT,0,0,0,0);
2055: .ve

2057:    Notes:
2058:    A global counter logs all PETSc flop counts.  The user can use
2059:    PetscLogFlops() to increment this counter to include flops for the
2060:    Section 1.5 Writing Application Codes with PETSc code.

2062:    Level: intermediate

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

2066: M*/

2068: /*MC
2069:    PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
2070:     to get accurate timings

2072:    Synopsis:
2073:  #include <petsclog.h>
2074:    void PetscPreLoadBegin(PetscBool  flag,char *name);

2076:    Not Collective

2078:    Input Parameter:
2079: +   flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
2080:            with command line option -preload true or -preload false
2081: -   name - name of first stage (lines of code timed separately with -log_view) to
2082:            be preloaded

2084:    Usage:
2085: .vb
2086:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2087:        lines of code
2088:        PetscPreLoadStage("second stage");
2089:        lines of code
2090:      PetscPreLoadEnd();
2091: .ve

2093:    Notes:
2094:     Only works in C/C++, not Fortran

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

2104:    Level: intermediate

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


2109: M*/

2111: /*MC
2112:    PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
2113:     to get accurate timings

2115:    Synopsis:
2116:  #include <petsclog.h>
2117:    void PetscPreLoadEnd(void);

2119:    Not Collective

2121:    Usage:
2122: .vb
2123:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2124:        lines of code
2125:        PetscPreLoadStage("second stage");
2126:        lines of code
2127:      PetscPreLoadEnd();
2128: .ve

2130:    Notes:
2131:     only works in C/C++ not fortran

2133:    Level: intermediate

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

2137: M*/

2139: /*MC
2140:    PetscPreLoadStage - Start a new segment of code to be timed separately.
2141:     to get accurate timings

2143:    Synopsis:
2144:  #include <petsclog.h>
2145:    void PetscPreLoadStage(char *name);

2147:    Not Collective

2149:    Usage:
2150: .vb
2151:      PetscPreLoadBegin(PETSC_TRUE,"first stage);
2152:        lines of code
2153:        PetscPreLoadStage("second stage");
2154:        lines of code
2155:      PetscPreLoadEnd();
2156: .ve

2158:    Notes:
2159:     only works in C/C++ not fortran

2161:    Level: intermediate

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

2165: M*/


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

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

2176: #endif /* PETSC_USE_LOG*/


2179: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2180: PetscClassId PETSC_OBJECT_CLASSID  = 0;

2182: /*@C
2183:   PetscClassIdRegister - Registers a new class name for objects and logging operations in an Section 1.5 Writing Application Codes with PETSc code.

2185:   Not Collective

2187:   Input Parameter:
2188: . name   - The class name

2190:   Output Parameter:
2191: . oclass - The class id or classid

2193:   Level: developer

2195: @*/
2196: PetscErrorCode  PetscClassIdRegister(const char name[],PetscClassId *oclass)
2197: {
2198: #if defined(PETSC_USE_LOG)
2199:   PetscStageLog  stageLog;
2200:   PetscInt       stage;
2202: #endif

2205:   *oclass = ++PETSC_LARGEST_CLASSID;
2206: #if defined(PETSC_USE_LOG)
2207:   PetscLogGetStageLog(&stageLog);
2208:   PetscClassRegLogRegister(stageLog->classLog, name, *oclass);
2209:   for (stage = 0; stage < stageLog->numStages; stage++) {
2210:     PetscClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2211:   }
2212: #endif
2213:   return(0);
2214: }

2216: #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2217: #include <mpe.h>

2219: PetscBool PetscBeganMPE = PETSC_FALSE;

2221: PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2222: PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);

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

2228:    Collective over PETSC_COMM_WORLD

2230:    Options Database Keys:
2231: . -log_mpe - Prints extensive log information

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

2238:    Level: advanced


2241: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2242:           PetscLogEventDeactivate()
2243: @*/
2244: PetscErrorCode  PetscLogMPEBegin(void)
2245: {

2249:   /* Do MPE initialization */
2250:   if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2251:     PetscInfo(0,"Initializing MPE.\n");
2252:     MPE_Init_log();

2254:     PetscBeganMPE = PETSC_TRUE;
2255:   } else {
2256:     PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");
2257:   }
2258:   PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);
2259:   return(0);
2260: }

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

2265:    Collective over PETSC_COMM_WORLD

2267:    Level: advanced

2269: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2270: @*/
2271: PetscErrorCode  PetscLogMPEDump(const char sname[])
2272: {
2273:   char           name[PETSC_MAX_PATH_LEN];

2277:   if (PetscBeganMPE) {
2278:     PetscInfo(0,"Finalizing MPE.\n");
2279:     if (sname) {
2280:       PetscStrcpy(name,sname);
2281:     } else {
2282:       PetscGetProgramName(name,PETSC_MAX_PATH_LEN);
2283:     }
2284:     MPE_Finish_log(name);
2285:   } else {
2286:     PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");
2287:   }
2288:   return(0);
2289: }

2291: #define PETSC_RGB_COLORS_MAX 39
2292: static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2293:   "OliveDrab:      ",
2294:   "BlueViolet:     ",
2295:   "CadetBlue:      ",
2296:   "CornflowerBlue: ",
2297:   "DarkGoldenrod:  ",
2298:   "DarkGreen:      ",
2299:   "DarkKhaki:      ",
2300:   "DarkOliveGreen: ",
2301:   "DarkOrange:     ",
2302:   "DarkOrchid:     ",
2303:   "DarkSeaGreen:   ",
2304:   "DarkSlateGray:  ",
2305:   "DarkTurquoise:  ",
2306:   "DeepPink:       ",
2307:   "DarkKhaki:      ",
2308:   "DimGray:        ",
2309:   "DodgerBlue:     ",
2310:   "GreenYellow:    ",
2311:   "HotPink:        ",
2312:   "IndianRed:      ",
2313:   "LavenderBlush:  ",
2314:   "LawnGreen:      ",
2315:   "LemonChiffon:   ",
2316:   "LightCoral:     ",
2317:   "LightCyan:      ",
2318:   "LightPink:      ",
2319:   "LightSalmon:    ",
2320:   "LightSlateGray: ",
2321:   "LightYellow:    ",
2322:   "LimeGreen:      ",
2323:   "MediumPurple:   ",
2324:   "MediumSeaGreen: ",
2325:   "MediumSlateBlue:",
2326:   "MidnightBlue:   ",
2327:   "MintCream:      ",
2328:   "MistyRose:      ",
2329:   "NavajoWhite:    ",
2330:   "NavyBlue:       ",
2331:   "OliveDrab:      "
2332: };

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

2337:   Not collective. Maybe it should be?

2339:   Output Parameter:
2340: . str - character string representing the color

2342:   Level: developer

2344: .seealso: PetscLogEventRegister
2345: @*/
2346: PetscErrorCode  PetscLogMPEGetRGBColor(const char *str[])
2347: {
2348:   static int idx = 0;

2351:   *str = PetscLogMPERGBColors[idx];
2352:   idx  = (idx + 1)% PETSC_RGB_COLORS_MAX;
2353:   return(0);
2354: }

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