Actual source code: plog.c
1: #define PETSC_DLL
2: /*
3: PETSc code to log object creation and destruction and PETSc events.
4: */
5: #include petsc.h
6: #include petsctime.h
7: #if defined(PETSC_HAVE_MPE)
8: #include "mpe.h"
9: #endif
10: #include <stdarg.h>
11: #include <sys/types.h>
12: #include petscsys.h
13: #if defined(PETSC_HAVE_STDLIB_H)
14: #include <stdlib.h>
15: #endif
16: #if defined(PETSC_HAVE_MALLOC_H)
17: #include <malloc.h>
18: #endif
19: #include "petscfix.h"
20: #include plog.h
22: PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT;
24: #if defined(PETSC_USE_LOG)
25: #include "petscmachineinfo.h"
26: #include "petscconfiginfo.h"
28: /* used in the MPI_XXX() count macros in petsclog.h */
30: /* Action and object logging variables */
31: Action *actions = PETSC_NULL;
32: Object *objects = PETSC_NULL;
33: PetscTruth logActions = PETSC_FALSE;
34: PetscTruth logObjects = PETSC_FALSE;
35: int numActions = 0, maxActions = 100;
36: int numObjects = 0, maxObjects = 100;
37: int numObjectsDestroyed = 0;
39: /* Global counters */
40: PetscLogDouble BaseTime = 0.0;
41: PetscLogDouble _TotalFlops = 0.0; /* The number of flops */
42: PetscLogDouble petsc_tmp_flops = 0.0; /* The incremental number of flops */
43: PetscLogDouble send_ct = 0.0; /* The number of sends */
44: PetscLogDouble recv_ct = 0.0; /* The number of receives */
45: PetscLogDouble send_len = 0.0; /* The total length of all sent messages */
46: PetscLogDouble recv_len = 0.0; /* The total length of all received messages */
47: PetscLogDouble isend_ct = 0.0; /* The number of immediate sends */
48: PetscLogDouble irecv_ct = 0.0; /* The number of immediate receives */
49: PetscLogDouble isend_len = 0.0; /* The total length of all immediate send messages */
50: PetscLogDouble irecv_len = 0.0; /* The total length of all immediate receive messages */
51: PetscLogDouble wait_ct = 0.0; /* The number of waits */
52: PetscLogDouble wait_any_ct = 0.0; /* The number of anywaits */
53: PetscLogDouble wait_all_ct = 0.0; /* The number of waitalls */
54: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
55: PetscLogDouble allreduce_ct = 0.0; /* The number of reductions */
56: PetscLogDouble gather_ct = 0.0; /* The number of gathers and gathervs */
57: PetscLogDouble scatter_ct = 0.0; /* The number of scatters and scattervs */
59: /* Logging functions */
60: PetscErrorCode (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
61: PetscErrorCode (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
62: PetscErrorCode (*_PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
63: PetscErrorCode (*_PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
65: /* Tracing event logging variables */
66: FILE *tracefile = PETSC_NULL;
67: int tracelevel = 0;
68: const char *traceblanks = " ";
69: char tracespace[128] = " ";
70: PetscLogDouble tracetime = 0.0;
71: PetscTruth PetscLogBegin_PrivateCalled = PETSC_FALSE;
73: /*---------------------------------------------- General Functions --------------------------------------------------*/
76: /*@C
77: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
79: Not Collective
81: Notes:
82: This routine should not usually be used by programmers. Instead employ
83: PetscLogStagePush() and PetscLogStagePop().
85: Level: developer
87: .keywords: log, destroy
88: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
89: @*/
90: PetscErrorCode PetscLogDestroy(void)
91: {
92: StageLog stageLog;
96: PetscFree(actions);
97: actions = PETSC_NULL;
98: PetscFree(objects);
99: objects = PETSC_NULL;
100: PetscLogSet(PETSC_NULL, PETSC_NULL);
102: /* Resetting phase */
103: PetscLogGetStageLog(&stageLog);
104: StageLogDestroy(stageLog);
105: _TotalFlops = 0.0;
106: numActions = 0;
107: numObjects = 0;
108: numObjectsDestroyed = 0;
109: return(0);
110: }
114: /*@C
115: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
117: Not Collective
119: Input Parameters:
120: + b - The function called at beginning of event
121: - e - The function called at end of event
123: Level: developer
125: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
126: @*/
127: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
128: PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
129: {
131: _PetscLogPLB = b;
132: _PetscLogPLE = e;
133: return(0);
134: }
136: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
139: PetscErrorCode PetscLogBegin_Private(void)
140: {
141: int stage;
142: PetscTruth opt;
143: PetscErrorCode ierr;
146: if (PetscLogBegin_PrivateCalled) return(0);
147: PetscLogBegin_PrivateCalled = PETSC_TRUE;
149: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
150: if (opt) {
151: logActions = PETSC_FALSE;
152: }
153: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
154: if (opt) {
155: logObjects = PETSC_FALSE;
156: }
157: if (logActions) {
158: PetscMalloc(maxActions * sizeof(Action), &actions);
159: }
160: if (logObjects) {
161: PetscMalloc(maxObjects * sizeof(Object), &objects);
162: }
163: _PetscLogPHC = PetscLogObjCreateDefault;
164: _PetscLogPHD = PetscLogObjDestroyDefault;
165: /* Setup default logging structures */
166: StageLogCreate(&_stageLog);
167: StageLogRegister(_stageLog, "Main Stage", &stage);
168: /* All processors sync here for more consistent logging */
169: MPI_Barrier(PETSC_COMM_WORLD);
170: PetscTime(BaseTime);
171: PetscLogStagePush(stage);
172: return(0);
173: }
177: /*@C
178: PetscLogBegin - Turns on logging of objects and events. This logs flop
179: rates and object creation and should not slow programs down too much.
180: This routine may be called more than once.
182: Collective over PETSC_COMM_WORLD
184: Options Database Keys:
185: + -log_summary - Prints summary of flop and timing information to the
186: screen (for code compiled with PETSC_USE_LOG)
187: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
189: Usage:
190: .vb
191: PetscInitialize(...);
192: PetscLogBegin();
193: ... code ...
194: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
195: PetscFinalize();
196: .ve
198: Notes:
199: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
200: the logging information.
202: Level: advanced
204: .keywords: log, begin
205: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
206: @*/
207: PetscErrorCode PetscLogBegin(void)
208: {
212: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
213: PetscLogBegin_Private();
214: return(0);
215: }
219: /*@C
220: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
221: all events. This creates large log files and slows the program down.
223: Collective on PETSC_COMM_WORLD
225: Options Database Keys:
226: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
228: Usage:
229: .vb
230: PetscInitialize(...);
231: PetscLogAllBegin();
232: ... code ...
233: PetscLogDump(filename);
234: PetscFinalize();
235: .ve
237: Notes:
238: A related routine is PetscLogBegin (with the options key -log), which is
239: intended for production runs since it logs only flop rates and object
240: creation (and shouldn't significantly slow the programs).
242: Level: advanced
244: .keywords: log, all, begin
245: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
246: @*/
247: PetscErrorCode PetscLogAllBegin(void)
248: {
252: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
253: PetscLogBegin_Private();
254: return(0);
255: }
259: /*@
260: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
261: begins or ends, the event name is printed.
263: Collective on PETSC_COMM_WORLD
265: Input Parameter:
266: . file - The file to print trace in (e.g. stdout)
268: Options Database Key:
269: . -log_trace [filename] - Activates PetscLogTraceBegin()
271: Notes:
272: PetscLogTraceBegin() prints the processor number, the execution time (sec),
273: then "Event begin:" or "Event end:" followed by the event name.
275: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
276: to determine where a program is hanging without running in the
277: debugger. Can be used in conjunction with the -info option.
279: Level: intermediate
281: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
282: @*/
283: PetscErrorCode PetscLogTraceBegin(FILE *file)
284: {
288: tracefile = file;
289: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
290: PetscLogBegin_Private();
291: return(0);
292: }
296: /*@
297: PetscLogActions - Determines whether actions are logged for the graphical viewer.
299: Not Collective
301: Input Parameter:
302: . flag - PETSC_TRUE if actions are to be logged
304: Level: intermediate
306: Note: Logging of actions continues to consume more memory as the program
307: runs. Long running programs should consider turning this feature off.
309: Options Database Keys:
310: . -log_exclude_actions - Turns off actions logging
312: .keywords: log, stage, register
313: .seealso: PetscLogStagePush(), PetscLogStagePop()
314: @*/
315: PetscErrorCode PetscLogActions(PetscTruth flag)
316: {
318: logActions = flag;
319: return(0);
320: }
324: /*@
325: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
327: Not Collective
329: Input Parameter:
330: . flag - PETSC_TRUE if objects are to be logged
332: Level: intermediate
334: Note: Logging of objects continues to consume more memory as the program
335: runs. Long running programs should consider turning this feature off.
337: Options Database Keys:
338: . -log_exclude_objects - Turns off objects logging
340: .keywords: log, stage, register
341: .seealso: PetscLogStagePush(), PetscLogStagePop()
342: @*/
343: PetscErrorCode PetscLogObjects(PetscTruth flag)
344: {
346: logObjects = flag;
347: return(0);
348: }
350: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
353: /*@C
354: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
356: Not Collective
358: Input Parameter:
359: . sname - The name to associate with that stage
361: Output Parameter:
362: . stage - The stage number
364: Level: intermediate
366: .keywords: log, stage, register
367: .seealso: PetscLogStagePush(), PetscLogStagePop()
368: @*/
369: PetscErrorCode PetscLogStageRegister(const char sname[],PetscLogStage *stage)
370: {
371: StageLog stageLog;
372: PetscLogEvent event;
376: PetscLogGetStageLog(&stageLog);
377: StageLogRegister(stageLog, sname, stage);
378: /* Copy events already changed in the main stage, this sucks */
379: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
380: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
381: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
382: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
383: }
384: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
385: return(0);
386: }
390: /*@C
391: PetscLogStagePush - This function pushes a stage on the stack.
393: Not Collective
395: Input Parameter:
396: . stage - The stage on which to log
398: Usage:
399: If the option -log_sumary is used to run the program containing the
400: following code, then 2 sets of summary data will be printed during
401: PetscFinalize().
402: .vb
403: PetscInitialize(int *argc,char ***args,0,0);
404: [stage 0 of code]
405: PetscLogStagePush(1);
406: [stage 1 of code]
407: PetscLogStagePop();
408: PetscBarrier(...);
409: [more stage 0 of code]
410: PetscFinalize();
411: .ve
412:
413: Notes:
414: Use PetscLogStageRegister() to register a stage.
416: Level: intermediate
418: .keywords: log, push, stage
419: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
420: @*/
421: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
422: {
423: StageLog stageLog;
427: PetscLogGetStageLog(&stageLog);
428: StageLogPush(stageLog, stage);
429: return(0);
430: }
434: /*@C
435: PetscLogStagePop - This function pops a stage from the stack.
437: Not Collective
439: Usage:
440: If the option -log_sumary is used to run the program containing the
441: following code, then 2 sets of summary data will be printed during
442: PetscFinalize().
443: .vb
444: PetscInitialize(int *argc,char ***args,0,0);
445: [stage 0 of code]
446: PetscLogStagePush(1);
447: [stage 1 of code]
448: PetscLogStagePop();
449: PetscBarrier(...);
450: [more stage 0 of code]
451: PetscFinalize();
452: .ve
454: Notes:
455: Use PetscLogStageRegister() to register a stage.
457: Level: intermediate
459: .keywords: log, pop, stage
460: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
461: @*/
462: PetscErrorCode PetscLogStagePop(void)
463: {
464: StageLog stageLog;
468: PetscLogGetStageLog(&stageLog);
469: StageLogPop(stageLog);
470: return(0);
471: }
475: /*@
476: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
478: Not Collective
480: Input Parameters:
481: + stage - The stage
482: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
484: Level: intermediate
486: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
487: @*/
488: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscTruth isActive)
489: {
490: StageLog stageLog;
494: PetscLogGetStageLog(&stageLog);
495: StageLogSetActive(stageLog, stage, isActive);
496: return(0);
497: }
501: /*@
502: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
504: Not Collective
506: Input Parameter:
507: . stage - The stage
509: Output Parameter:
510: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
512: Level: intermediate
514: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
515: @*/
516: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscTruth *isActive)
517: {
518: StageLog stageLog;
522: PetscLogGetStageLog(&stageLog);
523: StageLogGetActive(stageLog, stage, isActive);
524: return(0);
525: }
529: /*@
530: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
532: Not Collective
534: Input Parameters:
535: + stage - The stage
536: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
538: Level: intermediate
540: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
541: @*/
542: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscTruth isVisible)
543: {
544: StageLog stageLog;
548: PetscLogGetStageLog(&stageLog);
549: StageLogSetVisible(stageLog, stage, isVisible);
550: return(0);
551: }
555: /*@
556: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
558: Not Collective
560: Input Parameter:
561: . stage - The stage
563: Output Parameter:
564: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
566: Level: intermediate
568: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
569: @*/
570: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscTruth *isVisible)
571: {
572: StageLog stageLog;
576: PetscLogGetStageLog(&stageLog);
577: StageLogGetVisible(stageLog, stage, isVisible);
578: return(0);
579: }
583: /*@C
584: PetscLogStageGetId - Returns the stage id when given the stage name.
586: Not Collective
588: Input Parameter:
589: . name - The stage name
591: Output Parameter:
592: . stage - The stage
594: Level: intermediate
596: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
597: @*/
598: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
599: {
600: StageLog stageLog;
604: PetscLogGetStageLog(&stageLog);
605: StageLogGetStage(stageLog, name, stage);
606: return(0);
607: }
609: /*------------------------------------------------ Event Functions --------------------------------------------------*/
612: /*@C
613: PetscLogEventRegister - Registers an event name for logging operations in an application code.
615: Not Collective
617: Input Parameter:
618: + name - The name associated with the event
619: - cookie - The cookie associated to the class for this event, obtain either with
620: PetscCookieRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
621:
622: Output Parameter:
623: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
625: Example of Usage:
626: .vb
627: PetscLogEvent USER_EVENT;
628: PetscCookie cookie;
629: int user_event_flops;
630: PetscCookieRegister("class name",&cookie);
631: PetscLogEventRegister("User event name",cookie,&USER_EVENT);
632: PetscLogEventBegin(USER_EVENT,0,0,0,0);
633: [code segment to monitor]
634: PetscLogFlops(user_event_flops);
635: PetscLogEventEnd(USER_EVENT,0,0,0,0);
636: .ve
638: Notes:
639: PETSc automatically logs library events if the code has been
640: compiled with -DPETSC_USE_LOG (which is the default) and -log,
641: -log_summary, or -log_all are specified. PetscLogEventRegister() is
642: intended for logging user events to supplement this PETSc
643: information.
645: PETSc can gather data for use with the utilities Upshot/Nupshot
646: (part of the MPICH distribution). If PETSc has been compiled
647: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
648: MPICH), the user can employ another command line option, -log_mpe,
649: to create a logfile, "mpe.log", which can be visualized
650: Upshot/Nupshot.
652: The cookie is associated with each event so that classes of events
653: can be disabled simultaneously, such as all matrix events. The user
654: can either use an existing cookie, such as MAT_COOKIE, or create
655: their own as shown in the example.
657: Level: intermediate
659: .keywords: log, event, register
660: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
661: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
662: PetscLogEventActivate(), PetscLogEventDeactivate(), PetscCookieRegister()
663: @*/
664: PetscErrorCode PetscLogEventRegister(const char name[],PetscCookie cookie,PetscLogEvent *event)
665: {
666: StageLog stageLog;
667: int stage;
671: *event = PETSC_DECIDE;
672: PetscLogGetStageLog(&stageLog);
673: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
674: for(stage = 0; stage < stageLog->numStages; stage++) {
675: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
676: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
677: }
678: return(0);
679: }
683: /*@
684: PetscLogEventActivate - Indicates that a particular event should be logged.
686: Not Collective
688: Input Parameter:
689: . event - The event id
691: Usage:
692: .vb
693: PetscLogEventDeactivate(VEC_SetValues);
694: [code where you do not want to log VecSetValues()]
695: PetscLogEventActivate(VEC_SetValues);
696: [code where you do want to log VecSetValues()]
697: .ve
699: Note:
700: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
701: or an event number obtained with PetscLogEventRegister().
703: Level: advanced
705: .keywords: log, event, activate
706: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
707: @*/
708: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
709: {
710: StageLog stageLog;
711: int stage;
715: PetscLogGetStageLog(&stageLog);
716: StageLogGetCurrent(stageLog, &stage);
717: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
718: return(0);
719: }
723: /*@
724: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
726: Not Collective
728: Input Parameter:
729: . event - The event id
731: Usage:
732: .vb
733: PetscLogEventDeactivate(VEC_SetValues);
734: [code where you do not want to log VecSetValues()]
735: PetscLogEventActivate(VEC_SetValues);
736: [code where you do want to log VecSetValues()]
737: .ve
739: Note:
740: The event may be either a pre-defined PETSc event (found in
741: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
743: Level: advanced
745: .keywords: log, event, deactivate
746: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
747: @*/
748: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
749: {
750: StageLog stageLog;
751: int stage;
755: PetscLogGetStageLog(&stageLog);
756: StageLogGetCurrent(stageLog, &stage);
757: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
758: return(0);
759: }
763: /*@
764: PetscLogEventSetActiveAll - Sets the event activity in every stage.
766: Not Collective
768: Input Parameters:
769: + event - The event id
770: - isActive - The activity flag determining whether the event is logged
772: Level: advanced
774: .keywords: log, event, activate
775: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
776: @*/
777: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscTruth isActive)
778: {
779: StageLog stageLog;
780: int stage;
784: PetscLogGetStageLog(&stageLog);
785: for(stage = 0; stage < stageLog->numStages; stage++) {
786: if (isActive) {
787: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
788: } else {
789: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
790: }
791: }
792: return(0);
793: }
797: /*@
798: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
800: Not Collective
802: Input Parameter:
803: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
805: Level: developer
807: .keywords: log, event, activate, class
808: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
809: @*/
810: PetscErrorCode PetscLogEventActivateClass(PetscCookie cookie)
811: {
812: StageLog stageLog;
813: int stage;
817: PetscLogGetStageLog(&stageLog);
818: StageLogGetCurrent(stageLog, &stage);
819: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
820: return(0);
821: }
825: /*@
826: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
828: Not Collective
830: Input Parameter:
831: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
833: Level: developer
835: .keywords: log, event, deactivate, class
836: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
837: @*/
838: PetscErrorCode PetscLogEventDeactivateClass(PetscCookie cookie)
839: {
840: StageLog stageLog;
841: int stage;
845: PetscLogGetStageLog(&stageLog);
846: StageLogGetCurrent(stageLog, &stage);
847: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
848: return(0);
849: }
851: /*MC
852: PetscLogEventBegin - Logs the beginning of a user event.
854: Input Parameters:
855: + e - integer associated with the event obtained from PetscLogEventRegister()
856: - o1,o2,o3,o4 - objects associated with the event, or 0
858: Synopsis:
859: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
860: PetscObject o4)
862: Fortran Synopsis:
863: void PetscLogEventEnd(int e,PetscErrorCode ierr)
865: Usage:
866: .vb
867: int USER_EVENT;
868: int user_event_flops;
869: PetscLogEventRegister("User event",0,&USER_EVENT);
870: PetscLogEventBegin(USER_EVENT,0,0,0,0);
871: [code segment to monitor]
872: PetscLogFlops(user_event_flops);
873: PetscLogEventEnd(USER_EVENT,0,0,0,0);
874: .ve
876: Notes:
877: You need to register each integer event with the command
878: PetscLogEventRegister(). The source code must be compiled with
879: -DPETSC_USE_LOG, which is the default.
881: PETSc automatically logs library events if the code has been
882: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
883: specified. PetscLogEventBegin() is intended for logging user events
884: to supplement this PETSc information.
886: Level: intermediate
888: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
890: .keywords: log, event, begin
891: M*/
893: /*MC
894: PetscLogEventEnd - Log the end of a user event.
896: Input Parameters:
897: + e - integer associated with the event obtained with PetscLogEventRegister()
898: - o1,o2,o3,o4 - objects associated with the event, or 0
900: Synopsis:
901: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
902: PetscObject o4)
904: Fortran Synopsis:
905: void PetscLogEventEnd(int e,PetscErrorCode ierr)
907: Usage:
908: .vb
909: int USER_EVENT;
910: int user_event_flops;
911: PetscLogEventRegister("User event",0,&USER_EVENT,);
912: PetscLogEventBegin(USER_EVENT,0,0,0,0);
913: [code segment to monitor]
914: PetscLogFlops(user_event_flops);
915: PetscLogEventEnd(USER_EVENT,0,0,0,0);
916: .ve
918: Notes:
919: You should also register each additional integer event with the command
920: PetscLogEventRegister(). Source code must be compiled with
921: -DPETSC_USE_LOG, which is the default.
923: PETSc automatically logs library events if the code has been
924: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
925: specified. PetscLogEventEnd() is intended for logging user events
926: to supplement this PETSc information.
928: Level: intermediate
930: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
932: .keywords: log, event, end
933: M*/
935: /*MC
936: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
938: Input Parameters:
939: . e - integer associated with the event obtained from PetscLogEventRegister()
940: . o1,o2,o3,o4 - objects associated with the event, or 0
941: . comm - communicator the barrier takes place over
943: Synopsis:
944: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
945: PetscObject o4,MPI_Comm comm)
947: Usage:
948: .vb
949: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
950: MPI_Allreduce()
951: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
952: .ve
954: Notes:
955: This is for logging the amount of time spent in a barrier for an event
956: that requires synchronization.
958: Additional Notes:
959: Synchronization events always come in pairs; for example, VEC_NormBarrier and
960: VEC_NormComm = VEC_NormBarrier + 1
962: Level: advanced
964: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
965: PetscLogEventBarrierEnd()
967: .keywords: log, event, begin, barrier
968: M*/
970: /*MC
971: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
973: Input Parameters:
974: . e - integer associated with the event obtained from PetscLogEventRegister()
975: . o1,o2,o3,o4 - objects associated with the event, or 0
976: . comm - communicator the barrier takes place over
978: Synopsis:
979: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
980: PetscObject o4,MPI_Comm comm)
982: Usage:
983: .vb
984: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
985: MPI_Allreduce()
986: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
987: .ve
989: Notes:
990: This is for logging the amount of time spent in a barrier for an event
991: that requires synchronization.
993: Additional Notes:
994: Synchronization events always come in pairs; for example, VEC_NormBarrier and
995: VEC_NormComm = VEC_NormBarrier + 1
997: Level: advanced
999: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1000: PetscLogEventBarrierBegin()
1002: .keywords: log, event, begin, barrier
1003: M*/
1007: /*@C
1008: PetscLogEventGetId - Returns the event id when given the event name.
1010: Not Collective
1012: Input Parameter:
1013: . name - The event name
1015: Output Parameter:
1016: . event - The event
1018: Level: intermediate
1020: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1021: @*/
1022: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1023: {
1024: StageLog stageLog;
1028: PetscLogGetStageLog(&stageLog);
1029: EventRegLogGetEvent(stageLog->eventLog, name, event);
1030: return(0);
1031: }
1034: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1037: /*@C
1038: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1039: be read by petsc/bin/petscview.
1041: Collective on PETSC_COMM_WORLD
1043: Input Parameter:
1044: . name - an optional file name
1046: Options Database Keys:
1047: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1048: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1049:
1050: Usage:
1051: .vb
1052: PetscInitialize(...);
1053: PetscLogBegin(); or PetscLogAllBegin();
1054: ... code ...
1055: PetscLogDump(filename);
1056: PetscFinalize();
1057: .ve
1059: Notes:
1060: The default file name is
1061: $ Log.<rank>
1062: where <rank> is the processor number. If no name is specified,
1063: this file will be used.
1065: Level: advanced
1067: .keywords: log, dump
1068: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1069: @*/
1070: PetscErrorCode PetscLogDump(const char sname[])
1071: {
1072: StageLog stageLog;
1073: EventPerfInfo *eventInfo;
1074: FILE *fd;
1075: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1076: PetscLogDouble flops, _TotalTime;
1077: PetscMPIInt rank;
1078: int action, object, curStage;
1079: PetscLogEvent event;
1081:
1083: /* Calculate the total elapsed time */
1084: PetscTime(_TotalTime);
1085: _TotalTime -= BaseTime;
1086: /* Open log file */
1087: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1088: if (sname) {
1089: sprintf(file, "%s.%d", sname, rank);
1090: } else {
1091: sprintf(file, "Log.%d", rank);
1092: }
1093: PetscFixFilename(file, fname);
1094: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1095: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1096: /* Output totals */
1097: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1098: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1099: /* Output actions */
1100: if (logActions) {
1101: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1102: for(action = 0; action < numActions; action++) {
1103: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1104: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1105: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1106: }
1107: }
1108: /* Output objects */
1109: if (logObjects) {
1110: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1111: for(object = 0; object < numObjects; object++) {
1112: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1113: if (!objects[object].name[0]) {
1114: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1115: } else {
1116: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1117: }
1118: if (objects[object].info[0] != 0) {
1119: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1120: } else {
1121: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1122: }
1123: }
1124: }
1125: /* Output events */
1126: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1127: PetscLogGetStageLog(&stageLog);
1128: StackTop(stageLog->stack, &curStage);
1129: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1130: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1131: if (eventInfo[event].time != 0.0) {
1132: flops = eventInfo[event].flops/eventInfo[event].time;
1133: } else {
1134: flops = 0.0;
1135: }
1136: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1137: eventInfo[event].flops, eventInfo[event].time, flops);
1138: }
1139: PetscFClose(PETSC_COMM_WORLD, fd);
1140: return(0);
1141: }
1145: /*@C
1146: PetscLogPrintSummary - Prints a summary of the logging.
1148: Collective over MPI_Comm
1150: Input Parameter:
1151: + comm - The MPI communicator (only one processor prints output)
1152: - file - [Optional] The output file name
1154: Options Database Keys:
1155: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1157: Usage:
1158: .vb
1159: PetscInitialize(...);
1160: PetscLogBegin();
1161: ... code ...
1162: PetscLogPrintSummary(MPI_Comm,filename);
1163: PetscFinalize(...);
1164: .ve
1166: Notes:
1167: By default the summary is printed to stdout.
1169: Level: beginner
1170:
1171: .keywords: log, dump, print
1172: .seealso: PetscLogBegin(), PetscLogDump()
1173: @*/
1174: PetscErrorCode PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1175: {
1176: FILE *fd = PETSC_STDOUT;
1177: PetscLogDouble zero = 0.0;
1178: StageLog stageLog;
1179: StageInfo *stageInfo = PETSC_NULL;
1180: EventPerfInfo *eventInfo = PETSC_NULL;
1181: ClassPerfInfo *classInfo;
1182: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1183: const char *name;
1184: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1185: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1186: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1187: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1188: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1189: PetscLogDouble min, max, tot, ratio, avg, x, y;
1190: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1191: PetscMPIInt minCt, maxCt;
1192: PetscMPIInt size, rank;
1193: PetscTruth *localStageUsed, *stageUsed;
1194: PetscTruth *localStageVisible, *stageVisible;
1195: int numStages, localNumEvents, numEvents;
1196: int stage, lastStage, oclass;
1197: PetscLogEvent event;
1199: char version[256];
1202: MPI_Comm_size(comm, &size);
1203: MPI_Comm_rank(comm, &rank);
1204: /* Pop off any stages the user forgot to remove */
1205: lastStage = 0;
1206: PetscLogGetStageLog(&stageLog);
1207: StageLogGetCurrent(stageLog, &stage);
1208: while (stage >= 0) {
1209: lastStage = stage;
1210: StageLogPop(stageLog);
1211: StageLogGetCurrent(stageLog, &stage);
1212: }
1213: /* Get the total elapsed time */
1214: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1215: /* Open the summary file */
1216: if (filename) {
1217: PetscFOpen(comm, filename, "w", &fd);
1218: }
1220: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1221: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1222: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1223: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1224: PetscGetArchType(arch, 10);
1225: PetscGetHostName(hostname, 64);
1226: PetscGetUserName(username, 16);
1227: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1228: PetscGetDate(date, 64);
1229: PetscGetVersion(version,256);
1230: if (size == 1) {
1231: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1232: } else {
1233: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1234: }
1235: PetscFPrintf(comm, fd, "Using %s\n", version);
1237: /* Must preserve reduction count before we go on */
1238: red = allreduce_ct + gather_ct + scatter_ct;
1240: /* Calculate summary information */
1241: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1242: /* Time */
1243: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1244: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1245: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1246: avg = (tot)/((PetscLogDouble) size);
1247: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1248: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1249: TotalTime = tot;
1250: /* Objects */
1251: avg = (PetscLogDouble) numObjects;
1252: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1253: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1254: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1255: avg = (tot)/((PetscLogDouble) size);
1256: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1257: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1258: /* Flops */
1259: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1260: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1261: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1262: avg = (tot)/((PetscLogDouble) size);
1263: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1264: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1265: TotalFlops = tot;
1266: /* Flops/sec -- Must talk to Barry here */
1267: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1268: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1269: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1270: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1271: avg = (tot)/((PetscLogDouble) size);
1272: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1273: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1274: /* Memory */
1275: PetscMallocGetMaximumUsage(&mem);
1276: if (mem > 0.0) {
1277: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1278: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1279: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1280: avg = (tot)/((PetscLogDouble) size);
1281: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1282: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1283: }
1284: /* Messages */
1285: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1286: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1287: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1288: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1289: avg = (tot)/((PetscLogDouble) size);
1290: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1291: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1292: numMessages = tot;
1293: /* Message Lengths */
1294: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1295: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1296: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1297: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1298: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1299: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1300: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1301: messageLength = tot;
1302: /* Reductions */
1303: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1304: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1305: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1306: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1307: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1308: numReductions = red; /* wrong because uses count from process zero */
1309: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1310: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1311: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1313: /* Get total number of stages --
1314: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1315: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1316: This seems best accomplished by assoicating a communicator with each stage.
1317: */
1318: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1319: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1320: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1321: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1322: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1323: if (numStages > 0) {
1324: stageInfo = stageLog->stageInfo;
1325: for(stage = 0; stage < numStages; stage++) {
1326: if (stage < stageLog->numStages) {
1327: localStageUsed[stage] = stageInfo[stage].used;
1328: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1329: } else {
1330: localStageUsed[stage] = PETSC_FALSE;
1331: localStageVisible[stage] = PETSC_TRUE;
1332: }
1333: }
1334: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1335: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1336: for(stage = 0; stage < numStages; stage++) {
1337: if (stageUsed[stage]) {
1338: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1339: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1340: break;
1341: }
1342: }
1343: for(stage = 0; stage < numStages; stage++) {
1344: if (!stageUsed[stage]) continue;
1345: if (localStageUsed[stage]) {
1346: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1348: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1349: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1350: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1351: name = stageInfo[stage].name;
1352: } else {
1353: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1354: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1355: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1356: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1357: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1358: name = "";
1359: }
1360: mess *= 0.5; messLen *= 0.5; red /= size;
1361: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1362: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1363: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1364: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1365: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1366: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1367: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1368: PetscFPrintf(comm, fd, "%2d: %15s: %6.4e %5.1f%% %6.4e %5.1f%% %5.3e %5.1f%% %5.3e %5.1f%% %5.3e %5.1f%% \n",
1369: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1370: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1371: }
1372: }
1374: PetscFPrintf(comm, fd,
1375: "\n------------------------------------------------------------------------------------------------------------------------\n");
1376:
1377: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1378: PetscFPrintf(comm, fd, "Phase summary info:\n");
1379: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1380: PetscFPrintf(comm, fd, " Time and Flops: Max - maximum over all processors\n");
1381: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1382: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1383: PetscFPrintf(comm, fd, " Avg. len: average message length\n");
1384: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1385: PetscFPrintf(comm, fd, " Global: entire computation\n");
1386: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1387: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1388: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1389: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1390: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1391: PetscFPrintf(comm, fd,
1392: "------------------------------------------------------------------------------------------------------------------------\n");
1393:
1395: #if defined(PETSC_USE_DEBUG)
1396: PetscFPrintf(comm, fd, "\n\n");
1397: PetscFPrintf(comm, fd, " ##########################################################\n");
1398: PetscFPrintf(comm, fd, " # #\n");
1399: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1400: PetscFPrintf(comm, fd, " # #\n");
1401: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1402: PetscFPrintf(comm, fd, " # To get timing results run config/configure.py #\n");
1403: PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n");
1404: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1405: PetscFPrintf(comm, fd, " # #\n");
1406: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1407: #endif
1408: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1409: PetscFPrintf(comm, fd, "\n\n");
1410: PetscFPrintf(comm, fd, " ##########################################################\n");
1411: PetscFPrintf(comm, fd, " # #\n");
1412: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1413: PetscFPrintf(comm, fd, " # #\n");
1414: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1415: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1416: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1417: PetscFPrintf(comm, fd, " # faster, specify --with-fortran-kernels=generic #\n");
1418: PetscFPrintf(comm, fd, " # when running config/configure.py. #\n");
1419: PetscFPrintf(comm, fd, " # #\n");
1420: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1421: #endif
1423: /* Report events */
1424: PetscFPrintf(comm, fd,
1425: "Event Count Time (sec) Flops --- Global --- --- Stage --- Total\n");
1426:
1427: PetscFPrintf(comm, fd,
1428: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1429:
1430: PetscFPrintf(comm,fd,
1431: "------------------------------------------------------------------------------------------------------------------------\n");
1433:
1434: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1435: for(stage = 0; stage < numStages; stage++) {
1436: if (!stageVisible[stage]) continue;
1437: if (localStageUsed[stage]) {
1438: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1439: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1440: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1441: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1442: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1443: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1444: } else {
1445: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1446: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1447: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1448: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1449: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1450: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1451: }
1452: mess *= 0.5; messLen *= 0.5; red /= size;
1454: /* Get total number of events in this stage --
1455: Currently, a single processor can register more events than another, but events must all be registered in order,
1456: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1457: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1459: Problem: If the event did not happen on proc 1, its name will not be available.
1460: Problem: Event visibility is not implemented
1461: */
1462: if (localStageUsed[stage]) {
1463: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1464: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1465: } else {
1466: localNumEvents = 0;
1467: }
1468: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1469: for(event = 0; event < numEvents; event++) {
1470: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1471: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1472: flopr = eventInfo[event].flops;
1473: } else {
1474: flopr = 0.0;
1475: }
1476: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1477: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1478: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1479: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1480: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1481: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1482: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1483: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1484: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1485: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1486: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1487: name = stageLog->eventLog->eventInfo[event].name;
1488: } else {
1489: flopr = 0.0;
1490: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1491: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1492: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1493: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1494: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1495: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1496: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1497: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1498: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1499: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1500: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1501: name = "";
1502: }
1503: if (mint < 0.0) {
1504: PetscFPrintf(comm, fd, "WARNING!!! Minimum time %g over all processors for %s is negative! This happens\n on some machines whose times cannot handle too rapid calls.!\n artificially changing minimum to zero.\n",mint,name);
1505: mint = 0;
1506: }
1507: if (minf < 0.0) SETERRQ2(PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1508: totm *= 0.5; totml *= 0.5; totr /= size;
1509:
1510: if (maxCt != 0) {
1511: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1512: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1513: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1514: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1515: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1516: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1517: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1518: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1519: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1520: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1521: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1522: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1523: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1524: if (totm != 0.0) totml /= totm; else totml = 0.0;
1525: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1526: PetscFPrintf(comm, fd,
1527: "%-16s %7d%4.1f %5.4e%4.1f %3.2e%4.1f %2.1e %2.1e %2.1e%3.0f%3.0f%3.0f%3.0f%3.0f %3.0f%3.0f%3.0f%3.0f%3.0f %5.0f\n",
1528: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1529: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1530: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1531: flopr/1.0e6);
1532: }
1533: }
1534: }
1536: /* Memory usage and object creation */
1537: PetscFPrintf(comm, fd,
1538: "------------------------------------------------------------------------------------------------------------------------\n");
1539: PetscFPrintf(comm, fd, "\n");
1540: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1542: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1543: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1544: stats for stages local to processor sets.
1545: */
1546: /* We should figure out the longest object name here (now 20 characters) */
1547: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1548: for(stage = 0; stage < numStages; stage++) {
1549: if (localStageUsed[stage]) {
1550: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1551: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1552: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1553: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1554: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %g\n", stageLog->classLog->classInfo[oclass].name,
1555: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1556: classInfo[oclass].descMem);
1557: }
1558: }
1559: } else {
1560: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1561: }
1562: }
1564: PetscFree(localStageUsed);
1565: PetscFree(stageUsed);
1566: PetscFree(localStageVisible);
1567: PetscFree(stageVisible);
1569: /* Information unrelated to this particular run */
1570: PetscFPrintf(comm, fd,
1571: "========================================================================================================================\n");
1572: PetscTime(y);
1573: PetscTime(x);
1574: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1575: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1576: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1577: /* MPI information */
1578: if (size > 1) {
1579: MPI_Status status;
1580: PetscMPIInt tag;
1581: MPI_Comm newcomm;
1583: MPI_Barrier(comm);
1584: PetscTime(x);
1585: MPI_Barrier(comm);
1586: MPI_Barrier(comm);
1587: MPI_Barrier(comm);
1588: MPI_Barrier(comm);
1589: MPI_Barrier(comm);
1590: PetscTime(y);
1591: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1592: PetscCommDuplicate(comm,&newcomm, &tag);
1593: MPI_Barrier(comm);
1594: if (rank) {
1595: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1596: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1597: } else {
1598: PetscTime(x);
1599: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1600: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1601: PetscTime(y);
1602: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1603: }
1604: PetscCommDestroy(&newcomm);
1605: }
1606: if (!rank) {
1607: PetscOptionsPrint(fd);
1608: }
1609: /* Machine and compile information */
1610: #if defined(PETSC_USE_FORTRAN_KERNELS)
1611: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1612: #else
1613: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1614: #endif
1615: #if defined(PETSC_USE_SINGLE)
1616: PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1617: #elif defined(PETSC_USE_LONGDOUBLE)
1618: PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1619: #elif defined(PETSC_USE_INT)
1620: PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1621: #endif
1623: #if defined(PETSC_USE_MAT_SINGLE)
1624: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1625: #else
1626: PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1627: #endif
1628: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1629: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));
1631: PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1632: PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1633: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1634: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1635: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1636: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1638: /* Cleanup */
1639: PetscFPrintf(comm, fd, "\n");
1640: PetscFClose(comm, fd);
1641: StageLogPush(stageLog, lastStage);
1642: return(0);
1643: }
1647: /*@C
1648: PetscLogPrintDetailed - Each process prints the times for its own events
1650: Collective over MPI_Comm
1652: Input Parameter:
1653: + comm - The MPI communicator (only one processor prints output)
1654: - file - [Optional] The output file name
1656: Options Database Keys:
1657: . -log_summary_detailed - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1659: Usage:
1660: .vb
1661: PetscInitialize(...);
1662: PetscLogBegin();
1663: ... code ...
1664: PetscLogPrintDetailed(MPI_Comm,filename);
1665: PetscFinalize(...);
1666: .ve
1668: Notes:
1669: By default the summary is printed to stdout.
1671: Level: beginner
1672:
1673: .keywords: log, dump, print
1674: .seealso: PetscLogBegin(), PetscLogDump(), PetscLogPrintSummary()
1675: @*/
1676: PetscErrorCode PetscLogPrintDetailed(MPI_Comm comm, const char filename[])
1677: {
1678: FILE *fd = PETSC_STDOUT;
1679: StageLog stageLog;
1680: StageInfo *stageInfo = PETSC_NULL;
1681: EventPerfInfo *eventInfo = PETSC_NULL;
1682: const char *name = PETSC_NULL;
1683: PetscLogDouble TotalTime;
1684: PetscLogDouble stageTime, flops, flopr, mess, messLen, red;
1685: PetscLogDouble maxf, totf, maxt, tott, totm, totml, totr = 0.0;
1686: PetscMPIInt maxCt;
1687: PetscMPIInt size, rank;
1688: PetscTruth *stageUsed;
1689: PetscTruth *stageVisible;
1690: int numStages, numEvents;
1691: int stage;
1692: PetscLogEvent event;
1696: MPI_Comm_size(comm, &size);
1697: MPI_Comm_rank(comm, &rank);
1698: /* Pop off any stages the user forgot to remove */
1699: PetscLogGetStageLog(&stageLog);
1700: StageLogGetCurrent(stageLog, &stage);
1701: while (stage >= 0) {
1702: StageLogPop(stageLog);
1703: StageLogGetCurrent(stageLog, &stage);
1704: }
1705: /* Get the total elapsed time */
1706: PetscTime(TotalTime); TotalTime -= BaseTime;
1707: /* Open the summary file */
1708: if (filename) {
1709: PetscFOpen(comm, filename, "w", &fd);
1710: }
1712: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1713: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1714: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1717: numStages = stageLog->numStages;
1718: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1719: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1720: if (numStages > 0) {
1721: stageInfo = stageLog->stageInfo;
1722: for(stage = 0; stage < numStages; stage++) {
1723: if (stage < stageLog->numStages) {
1724: stageUsed[stage] = stageInfo[stage].used;
1725: stageVisible[stage] = stageInfo[stage].perfInfo.visible;
1726: } else {
1727: stageUsed[stage] = PETSC_FALSE;
1728: stageVisible[stage] = PETSC_TRUE;
1729: }
1730: }
1731: }
1733: /* Report events */
1734: PetscFPrintf(comm, fd,"Event Count Time (sec) Flops/sec \n");
1735: PetscFPrintf(comm, fd," Mess Avg len Reduct \n");
1736: PetscFPrintf(comm,fd,"-----------------------------------------------------------------------------------\n");
1737: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1738: for(stage = 0; stage < numStages; stage++) {
1739: if (!stageVisible[stage]) continue;
1740: if (stageUsed[stage]) {
1741: PetscSynchronizedFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1742: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1743: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1744: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1745: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1746: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1747: }
1748: mess *= 0.5; messLen *= 0.5;
1750: /* Get total number of events in this stage --
1751: */
1752: if (stageUsed[stage]) {
1753: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1754: numEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1755: } else {
1756: numEvents = 0;
1757: }
1758: for(event = 0; event < numEvents; event++) {
1759: if (stageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1760: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1761: flopr = eventInfo[event].flops/eventInfo[event].time;
1762: } else {
1763: flopr = 0.0;
1764: }
1765: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1766: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1767: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1768: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1769: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1770: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1771: totr = eventInfo[event].numReductions;
1772: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, PETSC_COMM_SELF);
1773: name = stageLog->eventLog->eventInfo[event].name;
1774: totm *= 0.5; totml *= 0.5;
1775: }
1776:
1777: if (maxCt != 0) {
1778: if (totm != 0.0) totml /= totm; else totml = 0.0;
1779: PetscSynchronizedFPrintf(comm, fd,"%-16s %7d %5.4e %3.2e %2.1e %2.1e %2.1e\n",name, maxCt, maxt, maxf, totm, totml, totr);
1780: }
1781: }
1782: }
1783: PetscSynchronizedFlush(comm);
1785: PetscFree(stageUsed);
1786: PetscFree(stageVisible);
1788: PetscFClose(comm, fd);
1789: return(0);
1790: }
1792: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1795: /*@C
1796: PetscGetFlops - Returns the number of flops used on this processor
1797: since the program began.
1799: Not Collective
1801: Output Parameter:
1802: flops - number of floating point operations
1804: Notes:
1805: A global counter logs all PETSc flop counts. The user can use
1806: PetscLogFlops() to increment this counter to include flops for the
1807: application code.
1809: PETSc automatically logs library events if the code has been
1810: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1811: -log_summary, or -log_all are specified. PetscLogFlops() is
1812: intended for logging user flops to supplement this PETSc
1813: information.
1815: Level: intermediate
1817: .keywords: log, flops, floating point operations
1819: .seealso: PetscGetTime(), PetscLogFlops()
1820: @*/
1821: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1822: {
1824: *flops = _TotalFlops;
1825: return(0);
1826: }
1830: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1831: {
1833: int fullLength;
1834: va_list Argp;
1837: if (!logObjects) return(0);
1838: va_start(Argp, format);
1839: PetscVSNPrintf(objects[obj->id].info, 64,format,&fullLength, Argp);
1840: va_end(Argp);
1841: return(0);
1842: }
1846: /*@
1847: PetscLogGetStageLog - This function returns the default stage logging object.
1849: Not collective
1851: Output Parameter:
1852: . stageLog - The default StageLog
1854: Level: beginner
1856: .keywords: log, stage
1857: .seealso: StageLogCreate()
1858: @*/
1859: PetscErrorCode PetscLogGetStageLog(StageLog *stageLog)
1860: {
1863: *stageLog = _stageLog;
1864: return(0);
1865: }
1867: /*MC
1868: PetscLogFlops - Adds floating point operations to the global counter.
1870: Input Parameter:
1871: . f - flop counter
1873: Synopsis:
1874: void PetscLogFlops(int f)
1876: Usage:
1877: .vb
1878: int USER_EVENT;
1879: PetscLogEventRegister("User event",0,&USER_EVENT);
1880: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1881: [code segment to monitor]
1882: PetscLogFlops(user_flops)
1883: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1884: .ve
1886: Notes:
1887: A global counter logs all PETSc flop counts. The user can use
1888: PetscLogFlops() to increment this counter to include flops for the
1889: application code.
1891: PETSc automatically logs library events if the code has been
1892: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1893: -log_summary, or -log_all are specified. PetscLogFlops() is
1894: intended for logging user flops to supplement this PETSc
1895: information.
1897: Level: intermediate
1899: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1901: .keywords: log, flops, floating point operations
1902: M*/
1904: /*MC
1905: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1906: to get accurate timings
1908: Input Parameter:
1909: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1910: with command line option -preload true or -preload false
1911: - name - name of first stage (lines of code timed separately with -log_summary) to
1912: be preloaded
1914: Synopsis:
1915: void PreLoadBegin(PetscTruth flag,char *name);
1917: Usage:
1918: .vb
1919: PreLoadBegin(PETSC_TRUE,"first stage);
1920: lines of code
1921: PreLoadStage("second stage");
1922: lines of code
1923: PreLoadEnd();
1924: .ve
1926: Notes: Only works in C/C++, not Fortran
1928: Flags available within the macro.
1929: + PetscPreLoadingUsed - true if we are or have done preloading
1930: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1931: . PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1932: - PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1933: The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1934: and PreLoadEnd()
1936: Level: intermediate
1938: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1940: Concepts: preloading
1941: Concepts: timing^accurate
1942: Concepts: paging^eliminating effects of
1945: M*/
1947: /*MC
1948: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1949: to get accurate timings
1951: Synopsis:
1952: void PreLoadEnd(void);
1954: Usage:
1955: .vb
1956: PreLoadBegin(PETSC_TRUE,"first stage);
1957: lines of code
1958: PreLoadStage("second stage");
1959: lines of code
1960: PreLoadEnd();
1961: .ve
1963: Notes: only works in C/C++ not fortran
1965: Level: intermediate
1967: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1969: M*/
1971: /*MC
1972: PreLoadStage - Start a new segment of code to be timed separately.
1973: to get accurate timings
1975: Synopsis:
1976: void PreLoadStage(char *name);
1978: Usage:
1979: .vb
1980: PreLoadBegin(PETSC_TRUE,"first stage);
1981: lines of code
1982: PreLoadStage("second stage");
1983: lines of code
1984: PreLoadEnd();
1985: .ve
1987: Notes: only works in C/C++ not fortran
1989: Level: intermediate
1991: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1993: M*/
1995: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1998: /*@C
1999: StackDestroy - This function destroys a stack.
2001: Not Collective
2003: Input Parameter:
2004: . stack - The stack
2006: Level: beginner
2008: .keywords: log, stack, destroy
2009: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
2010: @*/
2011: PetscErrorCode StackDestroy(IntStack stack)
2012: {
2016: PetscFree(stack->stack);
2017: PetscFree(stack);
2018: return(0);
2019: }
2023: /*@C
2024: StackEmpty - This function determines whether any items have been pushed.
2026: Not Collective
2028: Input Parameter:
2029: . stack - The stack
2031: Output Parameter:
2032: . empty - PETSC_TRUE if the stack is empty
2034: Level: intermediate
2036: .keywords: log, stack, empty
2037: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
2038: @*/
2039: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
2040: {
2043: if (stack->top == -1) {
2044: *empty = PETSC_TRUE;
2045: } else {
2046: *empty = PETSC_FALSE;
2047: }
2048: return(0);
2049: }
2053: /*@C
2054: StackTop - This function returns the top of the stack.
2056: Not Collective
2058: Input Parameter:
2059: . stack - The stack
2061: Output Parameter:
2062: . top - The integer on top of the stack
2064: Level: intermediate
2066: .keywords: log, stack, top
2067: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
2068: @*/
2069: PetscErrorCode StackTop(IntStack stack, int *top)
2070: {
2073: *top = stack->stack[stack->top];
2074: return(0);
2075: }
2079: /*@C
2080: StackPush - This function pushes an integer on the stack.
2082: Not Collective
2084: Input Parameters:
2085: + stack - The stack
2086: - item - The integer to push
2088: Level: intermediate
2090: .keywords: log, stack, push
2091: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
2092: @*/
2093: PetscErrorCode StackPush(IntStack stack, int item)
2094: {
2095: int *array;
2099: stack->top++;
2100: if (stack->top >= stack->max) {
2101: PetscMalloc(stack->max*2 * sizeof(int), &array);
2102: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2103: PetscFree(stack->stack);
2104: stack->stack = array;
2105: stack->max *= 2;
2106: }
2107: stack->stack[stack->top] = item;
2108: return(0);
2109: }
2113: /*@C
2114: StackPop - This function pops an integer from the stack.
2116: Not Collective
2118: Input Parameter:
2119: . stack - The stack
2121: Output Parameter:
2122: . item - The integer popped
2124: Level: intermediate
2126: .keywords: log, stack, pop
2127: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2128: @*/
2129: PetscErrorCode StackPop(IntStack stack, int *item)
2130: {
2133: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2134: *item = stack->stack[stack->top--];
2135: return(0);
2136: }
2140: /*@C
2141: StackCreate - This function creates a stack.
2143: Not Collective
2145: Output Parameter:
2146: . stack - The stack
2148: Level: beginner
2150: .keywords: log, stack, pop
2151: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2152: @*/
2153: PetscErrorCode StackCreate(IntStack *stack)
2154: {
2155: IntStack s;
2160: PetscNew(struct _n_IntStack, &s);
2161: s->top = -1;
2162: s->max = 128;
2163: PetscMalloc(s->max * sizeof(int), &s->stack);
2164: PetscMemzero(s->stack, s->max * sizeof(int));
2165: *stack = s;
2166: return(0);
2167: }
2169: #else /* end of -DPETSC_USE_LOG section */
2173: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2174: {
2176: return(0);
2177: }
2179: #endif /* PETSC_USE_LOG*/
2182: PetscCookie PETSC_LARGEST_COOKIE = PETSC_SMALLEST_COOKIE;
2183: PetscCookie PETSC_OBJECT_COOKIE = 0;
2187: /*@C
2188: PetscCookieRegister - Registers a new class name for objects and logging operations in an application code.
2190: Not Collective
2192: Input Parameter:
2193: . name - The class name
2194:
2195: Output Parameter:
2196: . oclass - The class id or cookie
2198: Level: developer
2200: .keywords: log, class, register
2202: @*/
2203: PetscErrorCode PetscCookieRegister(const char name[],PetscCookie *oclass )
2204: {
2205: #if defined(PETSC_USE_LOG)
2206: StageLog stageLog;
2207: PetscInt stage;
2209: #endif
2212: *oclass = ++PETSC_LARGEST_COOKIE;
2213: #if defined(PETSC_USE_LOG)
2214: PetscLogGetStageLog(&stageLog);
2215: ClassRegLogRegister(stageLog->classLog, name, *oclass);
2216: for(stage = 0; stage < stageLog->numStages; stage++) {
2217: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2218: }
2219: #endif
2220: return(0);
2221: }