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;
72: /*---------------------------------------------- General Functions --------------------------------------------------*/
75: /*@C
76: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
78: Not Collective
80: Notes:
81: This routine should not usually be used by programmers. Instead employ
82: PetscLogStagePush() and PetscLogStagePop().
84: Level: developer
86: .keywords: log, destroy
87: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
88: @*/
89: PetscErrorCode PetscLogDestroy(void)
90: {
91: StageLog stageLog;
95: PetscFree(actions);
96: actions = PETSC_NULL;
97: PetscFree(objects);
98: objects = PETSC_NULL;
99: PetscLogSet(PETSC_NULL, PETSC_NULL);
101: /* Resetting phase */
102: PetscLogGetStageLog(&stageLog);
103: StageLogDestroy(stageLog);
104: _TotalFlops = 0.0;
105: numActions = 0;
106: numObjects = 0;
107: numObjectsDestroyed = 0;
108: return(0);
109: }
113: /*@C
114: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
116: Not Collective
118: Input Parameters:
119: + b - The function called at beginning of event
120: - e - The function called at end of event
122: Level: developer
124: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
125: @*/
126: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
127: PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
128: {
130: _PetscLogPLB = b;
131: _PetscLogPLE = e;
132: return(0);
133: }
135: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
138: PetscErrorCode PetscLogBegin_Private(void)
139: {
140: int stage;
141: PetscTruth opt;
142: PetscErrorCode ierr;
145: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
146: if (opt) {
147: logActions = PETSC_FALSE;
148: }
149: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
150: if (opt) {
151: logObjects = PETSC_FALSE;
152: }
153: if (logActions) {
154: PetscMalloc(maxActions * sizeof(Action), &actions);
155: }
156: if (logObjects) {
157: PetscMalloc(maxObjects * sizeof(Object), &objects);
158: }
159: _PetscLogPHC = PetscLogObjCreateDefault;
160: _PetscLogPHD = PetscLogObjDestroyDefault;
161: /* Setup default logging structures */
162: StageLogCreate(&_stageLog);
163: StageLogRegister(_stageLog, "Main Stage", &stage);
164: /* All processors sync here for more consistent logging */
165: MPI_Barrier(PETSC_COMM_WORLD);
166: PetscTime(BaseTime);
167: PetscLogStagePush(stage);
168: return(0);
169: }
173: /*@C
174: PetscLogBegin - Turns on logging of objects and events. This logs flop
175: rates and object creation and should not slow programs down too much.
176: This routine may be called more than once.
178: Collective over PETSC_COMM_WORLD
180: Options Database Keys:
181: + -log_summary - Prints summary of flop and timing information to the
182: screen (for code compiled with PETSC_USE_LOG)
183: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
185: Usage:
186: .vb
187: PetscInitialize(...);
188: PetscLogBegin();
189: ... code ...
190: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
191: PetscFinalize();
192: .ve
194: Notes:
195: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
196: the logging information.
198: Level: advanced
200: .keywords: log, begin
201: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
202: @*/
203: PetscErrorCode PetscLogBegin(void)
204: {
208: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
209: PetscLogBegin_Private();
210: return(0);
211: }
215: /*@C
216: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
217: all events. This creates large log files and slows the program down.
219: Collective on PETSC_COMM_WORLD
221: Options Database Keys:
222: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
224: Usage:
225: .vb
226: PetscInitialize(...);
227: PetscLogAllBegin();
228: ... code ...
229: PetscLogDump(filename);
230: PetscFinalize();
231: .ve
233: Notes:
234: A related routine is PetscLogBegin (with the options key -log), which is
235: intended for production runs since it logs only flop rates and object
236: creation (and shouldn't significantly slow the programs).
238: Level: advanced
240: .keywords: log, all, begin
241: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
242: @*/
243: PetscErrorCode PetscLogAllBegin(void)
244: {
248: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
249: PetscLogBegin_Private();
250: return(0);
251: }
255: /*@
256: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
257: begins or ends, the event name is printed.
259: Collective on PETSC_COMM_WORLD
261: Input Parameter:
262: . file - The file to print trace in (e.g. stdout)
264: Options Database Key:
265: . -log_trace [filename] - Activates PetscLogTraceBegin()
267: Notes:
268: PetscLogTraceBegin() prints the processor number, the execution time (sec),
269: then "Event begin:" or "Event end:" followed by the event name.
271: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
272: to determine where a program is hanging without running in the
273: debugger. Can be used in conjunction with the -info option.
275: Level: intermediate
277: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
278: @*/
279: PetscErrorCode PetscLogTraceBegin(FILE *file)
280: {
284: tracefile = file;
285: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
286: PetscLogBegin_Private();
287: return(0);
288: }
292: /*@
293: PetscLogActions - Determines whether actions are logged for the graphical viewer.
295: Not Collective
297: Input Parameter:
298: . flag - PETSC_TRUE if actions are to be logged
300: Level: intermediate
302: Note: Logging of actions continues to consume more memory as the program
303: runs. Long running programs should consider turning this feature off.
305: Options Database Keys:
306: . -log_exclude_actions - Turns off actions logging
308: .keywords: log, stage, register
309: .seealso: PetscLogStagePush(), PetscLogStagePop()
310: @*/
311: PetscErrorCode PetscLogActions(PetscTruth flag)
312: {
314: logActions = flag;
315: return(0);
316: }
320: /*@
321: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
323: Not Collective
325: Input Parameter:
326: . flag - PETSC_TRUE if objects are to be logged
328: Level: intermediate
330: Note: Logging of objects continues to consume more memory as the program
331: runs. Long running programs should consider turning this feature off.
333: Options Database Keys:
334: . -log_exclude_objects - Turns off objects logging
336: .keywords: log, stage, register
337: .seealso: PetscLogStagePush(), PetscLogStagePop()
338: @*/
339: PetscErrorCode PetscLogObjects(PetscTruth flag)
340: {
342: logObjects = flag;
343: return(0);
344: }
346: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
349: /*@C
350: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
352: Not Collective
354: Input Parameter:
355: . sname - The name to associate with that stage
357: Output Parameter:
358: . stage - The stage number
360: Level: intermediate
362: .keywords: log, stage, register
363: .seealso: PetscLogStagePush(), PetscLogStagePop()
364: @*/
365: PetscErrorCode PetscLogStageRegister(const char sname[],PetscLogStage *stage)
366: {
367: StageLog stageLog;
368: PetscLogEvent event;
372: PetscLogGetStageLog(&stageLog);
373: StageLogRegister(stageLog, sname, stage);
374: /* Copy events already changed in the main stage, this sucks */
375: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
376: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
377: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
378: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
379: }
380: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
381: return(0);
382: }
386: /*@C
387: PetscLogStagePush - This function pushes a stage on the stack.
389: Not Collective
391: Input Parameter:
392: . stage - The stage on which to log
394: Usage:
395: If the option -log_sumary is used to run the program containing the
396: following code, then 2 sets of summary data will be printed during
397: PetscFinalize().
398: .vb
399: PetscInitialize(int *argc,char ***args,0,0);
400: [stage 0 of code]
401: PetscLogStagePush(1);
402: [stage 1 of code]
403: PetscLogStagePop();
404: PetscBarrier(...);
405: [more stage 0 of code]
406: PetscFinalize();
407: .ve
408:
409: Notes:
410: Use PetscLogStageRegister() to register a stage.
412: Level: intermediate
414: .keywords: log, push, stage
415: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
416: @*/
417: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
418: {
419: StageLog stageLog;
423: PetscLogGetStageLog(&stageLog);
424: StageLogPush(stageLog, stage);
425: return(0);
426: }
430: /*@C
431: PetscLogStagePop - This function pops a stage from the stack.
433: Not Collective
435: Usage:
436: If the option -log_sumary is used to run the program containing the
437: following code, then 2 sets of summary data will be printed during
438: PetscFinalize().
439: .vb
440: PetscInitialize(int *argc,char ***args,0,0);
441: [stage 0 of code]
442: PetscLogStagePush(1);
443: [stage 1 of code]
444: PetscLogStagePop();
445: PetscBarrier(...);
446: [more stage 0 of code]
447: PetscFinalize();
448: .ve
450: Notes:
451: Use PetscLogStageRegister() to register a stage.
453: Level: intermediate
455: .keywords: log, pop, stage
456: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
457: @*/
458: PetscErrorCode PetscLogStagePop(void)
459: {
460: StageLog stageLog;
464: PetscLogGetStageLog(&stageLog);
465: StageLogPop(stageLog);
466: return(0);
467: }
471: /*@
472: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
474: Not Collective
476: Input Parameters:
477: + stage - The stage
478: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
480: Level: intermediate
482: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
483: @*/
484: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscTruth isActive)
485: {
486: StageLog stageLog;
490: PetscLogGetStageLog(&stageLog);
491: StageLogSetActive(stageLog, stage, isActive);
492: return(0);
493: }
497: /*@
498: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
500: Not Collective
502: Input Parameter:
503: . stage - The stage
505: Output Parameter:
506: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
508: Level: intermediate
510: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
511: @*/
512: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscTruth *isActive)
513: {
514: StageLog stageLog;
518: PetscLogGetStageLog(&stageLog);
519: StageLogGetActive(stageLog, stage, isActive);
520: return(0);
521: }
525: /*@
526: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
528: Not Collective
530: Input Parameters:
531: + stage - The stage
532: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
534: Level: intermediate
536: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
537: @*/
538: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscTruth isVisible)
539: {
540: StageLog stageLog;
544: PetscLogGetStageLog(&stageLog);
545: StageLogSetVisible(stageLog, stage, isVisible);
546: return(0);
547: }
551: /*@
552: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
554: Not Collective
556: Input Parameter:
557: . stage - The stage
559: Output Parameter:
560: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
562: Level: intermediate
564: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
565: @*/
566: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscTruth *isVisible)
567: {
568: StageLog stageLog;
572: PetscLogGetStageLog(&stageLog);
573: StageLogGetVisible(stageLog, stage, isVisible);
574: return(0);
575: }
579: /*@C
580: PetscLogStageGetId - Returns the stage id when given the stage name.
582: Not Collective
584: Input Parameter:
585: . name - The stage name
587: Output Parameter:
588: . stage - The stage
590: Level: intermediate
592: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
593: @*/
594: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
595: {
596: StageLog stageLog;
600: PetscLogGetStageLog(&stageLog);
601: StageLogGetStage(stageLog, name, stage);
602: return(0);
603: }
605: /*------------------------------------------------ Event Functions --------------------------------------------------*/
608: /*@C
609: PetscLogEventRegister - Registers an event name for logging operations in an application code.
611: Not Collective
613: Input Parameter:
614: + name - The name associated with the event
615: - cookie - The cookie associated to the class for this event, obtain either with
616: PetscCookieRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
617:
618: Output Parameter:
619: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
621: Example of Usage:
622: .vb
623: PetscLogEvent USER_EVENT;
624: PetscCookie cookie;
625: int user_event_flops;
626: PetscCookieRegister("class name",&cookie);
627: PetscLogEventRegister("User event name",cookie,&USER_EVENT);
628: PetscLogEventBegin(USER_EVENT,0,0,0,0);
629: [code segment to monitor]
630: PetscLogFlops(user_event_flops);
631: PetscLogEventEnd(USER_EVENT,0,0,0,0);
632: .ve
634: Notes:
635: PETSc automatically logs library events if the code has been
636: compiled with -DPETSC_USE_LOG (which is the default) and -log,
637: -log_summary, or -log_all are specified. PetscLogEventRegister() is
638: intended for logging user events to supplement this PETSc
639: information.
641: PETSc can gather data for use with the utilities Upshot/Nupshot
642: (part of the MPICH distribution). If PETSc has been compiled
643: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
644: MPICH), the user can employ another command line option, -log_mpe,
645: to create a logfile, "mpe.log", which can be visualized
646: Upshot/Nupshot.
648: The cookie is associated with each event so that classes of events
649: can be disabled simultaneously, such as all matrix events. The user
650: can either use an existing cookie, such as MAT_COOKIE, or create
651: their own as shown in the example.
653: Level: intermediate
655: .keywords: log, event, register
656: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
657: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
658: PetscLogEventActivate(), PetscLogEventDeactivate(), PetscCookieRegister()
659: @*/
660: PetscErrorCode PetscLogEventRegister(const char name[],PetscCookie cookie,PetscLogEvent *event)
661: {
662: StageLog stageLog;
663: int stage;
667: *event = PETSC_DECIDE;
668: PetscLogGetStageLog(&stageLog);
669: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
670: for(stage = 0; stage < stageLog->numStages; stage++) {
671: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
672: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
673: }
674: return(0);
675: }
679: /*@
680: PetscLogEventActivate - Indicates that a particular event should be logged.
682: Not Collective
684: Input Parameter:
685: . event - The event id
687: Usage:
688: .vb
689: PetscLogEventDeactivate(VEC_SetValues);
690: [code where you do not want to log VecSetValues()]
691: PetscLogEventActivate(VEC_SetValues);
692: [code where you do want to log VecSetValues()]
693: .ve
695: Note:
696: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
697: or an event number obtained with PetscLogEventRegister().
699: Level: advanced
701: .keywords: log, event, activate
702: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
703: @*/
704: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
705: {
706: StageLog stageLog;
707: int stage;
711: PetscLogGetStageLog(&stageLog);
712: StageLogGetCurrent(stageLog, &stage);
713: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
714: return(0);
715: }
719: /*@
720: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
722: Not Collective
724: Input Parameter:
725: . event - The event id
727: Usage:
728: .vb
729: PetscLogEventDeactivate(VEC_SetValues);
730: [code where you do not want to log VecSetValues()]
731: PetscLogEventActivate(VEC_SetValues);
732: [code where you do want to log VecSetValues()]
733: .ve
735: Note:
736: The event may be either a pre-defined PETSc event (found in
737: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
739: Level: advanced
741: .keywords: log, event, deactivate
742: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
743: @*/
744: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
745: {
746: StageLog stageLog;
747: int stage;
751: PetscLogGetStageLog(&stageLog);
752: StageLogGetCurrent(stageLog, &stage);
753: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
754: return(0);
755: }
759: /*@
760: PetscLogEventSetActiveAll - Sets the event activity in every stage.
762: Not Collective
764: Input Parameters:
765: + event - The event id
766: - isActive - The activity flag determining whether the event is logged
768: Level: advanced
770: .keywords: log, event, activate
771: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
772: @*/
773: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscTruth isActive)
774: {
775: StageLog stageLog;
776: int stage;
780: PetscLogGetStageLog(&stageLog);
781: for(stage = 0; stage < stageLog->numStages; stage++) {
782: if (isActive) {
783: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
784: } else {
785: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
786: }
787: }
788: return(0);
789: }
793: /*@
794: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
796: Not Collective
798: Input Parameter:
799: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
801: Level: developer
803: .keywords: log, event, activate, class
804: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
805: @*/
806: PetscErrorCode PetscLogEventActivateClass(PetscCookie cookie)
807: {
808: StageLog stageLog;
809: int stage;
813: PetscLogGetStageLog(&stageLog);
814: StageLogGetCurrent(stageLog, &stage);
815: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
816: return(0);
817: }
821: /*@
822: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
824: Not Collective
826: Input Parameter:
827: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
829: Level: developer
831: .keywords: log, event, deactivate, class
832: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
833: @*/
834: PetscErrorCode PetscLogEventDeactivateClass(PetscCookie cookie)
835: {
836: StageLog stageLog;
837: int stage;
841: PetscLogGetStageLog(&stageLog);
842: StageLogGetCurrent(stageLog, &stage);
843: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
844: return(0);
845: }
847: /*MC
848: PetscLogEventBegin - Logs the beginning of a user event.
850: Input Parameters:
851: + e - integer associated with the event obtained from PetscLogEventRegister()
852: - o1,o2,o3,o4 - objects associated with the event, or 0
854: Synopsis:
855: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
856: PetscObject o4)
858: Fortran Synopsis:
859: void PetscLogEventEnd(int e,PetscErrorCode ierr)
861: Usage:
862: .vb
863: int USER_EVENT;
864: int user_event_flops;
865: PetscLogEventRegister("User event",0,&USER_EVENT);
866: PetscLogEventBegin(USER_EVENT,0,0,0,0);
867: [code segment to monitor]
868: PetscLogFlops(user_event_flops);
869: PetscLogEventEnd(USER_EVENT,0,0,0,0);
870: .ve
872: Notes:
873: You need to register each integer event with the command
874: PetscLogEventRegister(). The source code must be compiled with
875: -DPETSC_USE_LOG, which is the default.
877: PETSc automatically logs library events if the code has been
878: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
879: specified. PetscLogEventBegin() is intended for logging user events
880: to supplement this PETSc information.
882: Level: intermediate
884: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
886: .keywords: log, event, begin
887: M*/
889: /*MC
890: PetscLogEventEnd - Log the end of a user event.
892: Input Parameters:
893: + e - integer associated with the event obtained with PetscLogEventRegister()
894: - o1,o2,o3,o4 - objects associated with the event, or 0
896: Synopsis:
897: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
898: PetscObject o4)
900: Fortran Synopsis:
901: void PetscLogEventEnd(int e,PetscErrorCode ierr)
903: Usage:
904: .vb
905: int USER_EVENT;
906: int user_event_flops;
907: PetscLogEventRegister("User event",0,&USER_EVENT,);
908: PetscLogEventBegin(USER_EVENT,0,0,0,0);
909: [code segment to monitor]
910: PetscLogFlops(user_event_flops);
911: PetscLogEventEnd(USER_EVENT,0,0,0,0);
912: .ve
914: Notes:
915: You should also register each additional integer event with the command
916: PetscLogEventRegister(). Source code must be compiled with
917: -DPETSC_USE_LOG, which is the default.
919: PETSc automatically logs library events if the code has been
920: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
921: specified. PetscLogEventEnd() is intended for logging user events
922: to supplement this PETSc information.
924: Level: intermediate
926: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
928: .keywords: log, event, end
929: M*/
931: /*MC
932: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
934: Input Parameters:
935: . e - integer associated with the event obtained from PetscLogEventRegister()
936: . o1,o2,o3,o4 - objects associated with the event, or 0
937: . comm - communicator the barrier takes place over
939: Synopsis:
940: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
941: PetscObject o4,MPI_Comm comm)
943: Usage:
944: .vb
945: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
946: MPI_Allreduce()
947: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
948: .ve
950: Notes:
951: This is for logging the amount of time spent in a barrier for an event
952: that requires synchronization.
954: Additional Notes:
955: Synchronization events always come in pairs; for example, VEC_NormBarrier and
956: VEC_NormComm = VEC_NormBarrier + 1
958: Level: advanced
960: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
961: PetscLogEventBarrierEnd()
963: .keywords: log, event, begin, barrier
964: M*/
966: /*MC
967: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
969: Input Parameters:
970: . e - integer associated with the event obtained from PetscLogEventRegister()
971: . o1,o2,o3,o4 - objects associated with the event, or 0
972: . comm - communicator the barrier takes place over
974: Synopsis:
975: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
976: PetscObject o4,MPI_Comm comm)
978: Usage:
979: .vb
980: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
981: MPI_Allreduce()
982: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
983: .ve
985: Notes:
986: This is for logging the amount of time spent in a barrier for an event
987: that requires synchronization.
989: Additional Notes:
990: Synchronization events always come in pairs; for example, VEC_NormBarrier and
991: VEC_NormComm = VEC_NormBarrier + 1
993: Level: advanced
995: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
996: PetscLogEventBarrierBegin()
998: .keywords: log, event, begin, barrier
999: M*/
1003: /*@C
1004: PetscLogEventGetId - Returns the event id when given the event name.
1006: Not Collective
1008: Input Parameter:
1009: . name - The event name
1011: Output Parameter:
1012: . event - The event
1014: Level: intermediate
1016: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1017: @*/
1018: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1019: {
1020: StageLog stageLog;
1024: PetscLogGetStageLog(&stageLog);
1025: EventRegLogGetEvent(stageLog->eventLog, name, event);
1026: return(0);
1027: }
1030: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1033: /*@C
1034: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1035: be read by petsc/bin/petscview.
1037: Collective on PETSC_COMM_WORLD
1039: Input Parameter:
1040: . name - an optional file name
1042: Options Database Keys:
1043: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1044: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1045:
1046: Usage:
1047: .vb
1048: PetscInitialize(...);
1049: PetscLogBegin(); or PetscLogAllBegin();
1050: ... code ...
1051: PetscLogDump(filename);
1052: PetscFinalize();
1053: .ve
1055: Notes:
1056: The default file name is
1057: $ Log.<rank>
1058: where <rank> is the processor number. If no name is specified,
1059: this file will be used.
1061: Level: advanced
1063: .keywords: log, dump
1064: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1065: @*/
1066: PetscErrorCode PetscLogDump(const char sname[])
1067: {
1068: StageLog stageLog;
1069: EventPerfInfo *eventInfo;
1070: FILE *fd;
1071: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1072: PetscLogDouble flops, _TotalTime;
1073: PetscMPIInt rank;
1074: int action, object, curStage;
1075: PetscLogEvent event;
1077:
1079: /* Calculate the total elapsed time */
1080: PetscTime(_TotalTime);
1081: _TotalTime -= BaseTime;
1082: /* Open log file */
1083: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1084: if (sname) {
1085: sprintf(file, "%s.%d", sname, rank);
1086: } else {
1087: sprintf(file, "Log.%d", rank);
1088: }
1089: PetscFixFilename(file, fname);
1090: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1091: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1092: /* Output totals */
1093: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1094: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1095: /* Output actions */
1096: if (logActions) {
1097: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1098: for(action = 0; action < numActions; action++) {
1099: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1100: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1101: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1102: }
1103: }
1104: /* Output objects */
1105: if (logObjects) {
1106: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1107: for(object = 0; object < numObjects; object++) {
1108: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1109: if (!objects[object].name[0]) {
1110: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1111: } else {
1112: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1113: }
1114: if (objects[object].info[0] != 0) {
1115: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1116: } else {
1117: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1118: }
1119: }
1120: }
1121: /* Output events */
1122: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1123: PetscLogGetStageLog(&stageLog);
1124: StackTop(stageLog->stack, &curStage);
1125: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1126: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1127: if (eventInfo[event].time != 0.0) {
1128: flops = eventInfo[event].flops/eventInfo[event].time;
1129: } else {
1130: flops = 0.0;
1131: }
1132: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1133: eventInfo[event].flops, eventInfo[event].time, flops);
1134: }
1135: PetscFClose(PETSC_COMM_WORLD, fd);
1136: return(0);
1137: }
1141: /*@C
1142: PetscLogPrintSummary - Prints a summary of the logging.
1144: Collective over MPI_Comm
1146: Input Parameter:
1147: + comm - The MPI communicator (only one processor prints output)
1148: - file - [Optional] The output file name
1150: Options Database Keys:
1151: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1153: Usage:
1154: .vb
1155: PetscInitialize(...);
1156: PetscLogBegin();
1157: ... code ...
1158: PetscLogPrintSummary(MPI_Comm,filename);
1159: PetscFinalize(...);
1160: .ve
1162: Notes:
1163: By default the summary is printed to stdout.
1165: Level: beginner
1166:
1167: .keywords: log, dump, print
1168: .seealso: PetscLogBegin(), PetscLogDump()
1169: @*/
1170: PetscErrorCode PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1171: {
1172: FILE *fd = PETSC_STDOUT;
1173: PetscLogDouble zero = 0.0;
1174: StageLog stageLog;
1175: StageInfo *stageInfo = PETSC_NULL;
1176: EventPerfInfo *eventInfo = PETSC_NULL;
1177: ClassPerfInfo *classInfo;
1178: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1179: const char *name;
1180: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1181: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1182: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1183: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1184: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1185: PetscLogDouble min, max, tot, ratio, avg, x, y;
1186: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1187: PetscMPIInt minCt, maxCt;
1188: PetscMPIInt size, rank;
1189: PetscTruth *localStageUsed, *stageUsed;
1190: PetscTruth *localStageVisible, *stageVisible;
1191: int numStages, localNumEvents, numEvents;
1192: int stage, lastStage, oclass;
1193: PetscLogEvent event;
1195: char version[256];
1198: MPI_Comm_size(comm, &size);
1199: MPI_Comm_rank(comm, &rank);
1200: /* Pop off any stages the user forgot to remove */
1201: lastStage = 0;
1202: PetscLogGetStageLog(&stageLog);
1203: StageLogGetCurrent(stageLog, &stage);
1204: while (stage >= 0) {
1205: lastStage = stage;
1206: StageLogPop(stageLog);
1207: StageLogGetCurrent(stageLog, &stage);
1208: }
1209: /* Get the total elapsed time */
1210: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1211: /* Open the summary file */
1212: if (filename) {
1213: PetscFOpen(comm, filename, "w", &fd);
1214: }
1216: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1217: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1218: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1219: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1220: PetscGetArchType(arch, 10);
1221: PetscGetHostName(hostname, 64);
1222: PetscGetUserName(username, 16);
1223: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1224: PetscGetDate(date, 64);
1225: PetscGetVersion(version,256);
1226: if (size == 1) {
1227: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1228: } else {
1229: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1230: }
1231: PetscFPrintf(comm, fd, "Using %s\n", version);
1233: /* Must preserve reduction count before we go on */
1234: red = allreduce_ct + gather_ct + scatter_ct;
1236: /* Calculate summary information */
1237: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1238: /* Time */
1239: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1240: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1241: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1242: avg = (tot)/((PetscLogDouble) size);
1243: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1244: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1245: TotalTime = tot;
1246: /* Objects */
1247: avg = (PetscLogDouble) numObjects;
1248: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1249: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1250: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1251: avg = (tot)/((PetscLogDouble) size);
1252: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1253: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1254: /* Flops */
1255: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1256: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1257: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1258: avg = (tot)/((PetscLogDouble) size);
1259: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1260: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1261: TotalFlops = tot;
1262: /* Flops/sec -- Must talk to Barry here */
1263: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1264: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1265: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1266: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1267: avg = (tot)/((PetscLogDouble) size);
1268: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1269: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1270: /* Memory */
1271: PetscMallocGetMaximumUsage(&mem);
1272: if (mem > 0.0) {
1273: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1274: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1275: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1276: avg = (tot)/((PetscLogDouble) size);
1277: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1278: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1279: }
1280: /* Messages */
1281: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1282: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1283: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1284: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1285: avg = (tot)/((PetscLogDouble) size);
1286: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1287: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1288: numMessages = tot;
1289: /* Message Lengths */
1290: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1291: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1292: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1293: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1294: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1295: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1296: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1297: messageLength = tot;
1298: /* Reductions */
1299: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1300: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1301: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1302: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1303: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1304: numReductions = red; /* wrong because uses count from process zero */
1305: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1306: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1307: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1309: /* Get total number of stages --
1310: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1311: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1312: This seems best accomplished by assoicating a communicator with each stage.
1313: */
1314: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1315: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1316: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1317: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1318: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1319: if (numStages > 0) {
1320: stageInfo = stageLog->stageInfo;
1321: for(stage = 0; stage < numStages; stage++) {
1322: if (stage < stageLog->numStages) {
1323: localStageUsed[stage] = stageInfo[stage].used;
1324: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1325: } else {
1326: localStageUsed[stage] = PETSC_FALSE;
1327: localStageVisible[stage] = PETSC_TRUE;
1328: }
1329: }
1330: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1331: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1332: for(stage = 0; stage < numStages; stage++) {
1333: if (stageUsed[stage]) {
1334: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1335: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1336: break;
1337: }
1338: }
1339: for(stage = 0; stage < numStages; stage++) {
1340: if (!stageUsed[stage]) continue;
1341: if (localStageUsed[stage]) {
1342: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1343: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1344: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1345: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1346: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347: name = stageInfo[stage].name;
1348: } else {
1349: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1350: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1351: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1352: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1353: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1354: name = "";
1355: }
1356: mess *= 0.5; messLen *= 0.5; red /= size;
1357: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1358: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1359: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1360: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1361: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1362: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1363: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1364: 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",
1365: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1366: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1367: }
1368: }
1370: PetscFPrintf(comm, fd,
1371: "\n------------------------------------------------------------------------------------------------------------------------\n");
1372:
1373: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1374: PetscFPrintf(comm, fd, "Phase summary info:\n");
1375: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1376: PetscFPrintf(comm, fd, " Time and Flops: Max - maximum over all processors\n");
1377: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1378: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1379: PetscFPrintf(comm, fd, " Avg. len: average message length\n");
1380: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1381: PetscFPrintf(comm, fd, " Global: entire computation\n");
1382: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1383: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1384: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1385: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1386: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1387: PetscFPrintf(comm, fd,
1388: "------------------------------------------------------------------------------------------------------------------------\n");
1389:
1391: #if defined(PETSC_USE_DEBUG)
1392: PetscFPrintf(comm, fd, "\n\n");
1393: PetscFPrintf(comm, fd, " ##########################################################\n");
1394: PetscFPrintf(comm, fd, " # #\n");
1395: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1396: PetscFPrintf(comm, fd, " # #\n");
1397: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1398: PetscFPrintf(comm, fd, " # To get timing results run config/configure.py #\n");
1399: PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n");
1400: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1401: PetscFPrintf(comm, fd, " # #\n");
1402: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1403: #endif
1404: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1405: PetscFPrintf(comm, fd, "\n\n");
1406: PetscFPrintf(comm, fd, " ##########################################################\n");
1407: PetscFPrintf(comm, fd, " # #\n");
1408: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1409: PetscFPrintf(comm, fd, " # #\n");
1410: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1411: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1412: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1413: PetscFPrintf(comm, fd, " # faster, specify --with-fortran-kernels=generic #\n");
1414: PetscFPrintf(comm, fd, " # when running config/configure.py. #\n");
1415: PetscFPrintf(comm, fd, " # #\n");
1416: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1417: #endif
1419: /* Report events */
1420: PetscFPrintf(comm, fd,
1421: "Event Count Time (sec) Flops --- Global --- --- Stage --- Total\n");
1422:
1423: PetscFPrintf(comm, fd,
1424: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1425:
1426: PetscFPrintf(comm,fd,
1427: "------------------------------------------------------------------------------------------------------------------------\n");
1429:
1430: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1431: for(stage = 0; stage < numStages; stage++) {
1432: if (!stageVisible[stage]) continue;
1433: if (localStageUsed[stage]) {
1434: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1435: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1436: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1437: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1438: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1439: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1440: } else {
1441: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1442: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1443: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1444: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1445: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1446: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1447: }
1448: mess *= 0.5; messLen *= 0.5; red /= size;
1450: /* Get total number of events in this stage --
1451: Currently, a single processor can register more events than another, but events must all be registered in order,
1452: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1453: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1455: Problem: If the event did not happen on proc 1, its name will not be available.
1456: Problem: Event visibility is not implemented
1457: */
1458: if (localStageUsed[stage]) {
1459: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1460: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1461: } else {
1462: localNumEvents = 0;
1463: }
1464: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1465: for(event = 0; event < numEvents; event++) {
1466: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1467: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1468: flopr = eventInfo[event].flops;
1469: } else {
1470: flopr = 0.0;
1471: }
1472: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1473: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1474: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1475: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1476: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1477: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1478: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1479: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1480: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1481: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1482: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1483: name = stageLog->eventLog->eventInfo[event].name;
1484: } else {
1485: flopr = 0.0;
1486: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1487: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1488: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1489: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1490: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1491: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1492: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1493: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1494: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1495: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1496: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1497: name = "";
1498: }
1499: if (mint < 0.0) {
1500: 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);
1501: mint = 0;
1502: }
1503: if (minf < 0.0) SETERRQ2(PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1504: totm *= 0.5; totml *= 0.5; totr /= size;
1505:
1506: if (maxCt != 0) {
1507: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1508: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1509: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1510: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1511: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1512: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1513: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1514: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1515: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1516: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1517: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1518: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1519: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1520: if (totm != 0.0) totml /= totm; else totml = 0.0;
1521: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1522: PetscFPrintf(comm, fd,
1523: "%-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",
1524: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1525: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1526: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1527: flopr/1.0e6);
1528: }
1529: }
1530: }
1532: /* Memory usage and object creation */
1533: PetscFPrintf(comm, fd,
1534: "------------------------------------------------------------------------------------------------------------------------\n");
1535: PetscFPrintf(comm, fd, "\n");
1536: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1538: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1539: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1540: stats for stages local to processor sets.
1541: */
1542: /* We should figure out the longest object name here (now 20 characters) */
1543: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1544: for(stage = 0; stage < numStages; stage++) {
1545: if (localStageUsed[stage]) {
1546: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1547: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1548: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1549: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1550: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %g\n", stageLog->classLog->classInfo[oclass].name,
1551: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1552: classInfo[oclass].descMem);
1553: }
1554: }
1555: } else {
1556: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1557: }
1558: }
1560: PetscFree(localStageUsed);
1561: PetscFree(stageUsed);
1562: PetscFree(localStageVisible);
1563: PetscFree(stageVisible);
1565: /* Information unrelated to this particular run */
1566: PetscFPrintf(comm, fd,
1567: "========================================================================================================================\n");
1568: PetscTime(y);
1569: PetscTime(x);
1570: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1571: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1572: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1573: /* MPI information */
1574: if (size > 1) {
1575: MPI_Status status;
1576: PetscMPIInt tag;
1577: MPI_Comm newcomm;
1579: MPI_Barrier(comm);
1580: PetscTime(x);
1581: MPI_Barrier(comm);
1582: MPI_Barrier(comm);
1583: MPI_Barrier(comm);
1584: MPI_Barrier(comm);
1585: MPI_Barrier(comm);
1586: PetscTime(y);
1587: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1588: PetscCommDuplicate(comm,&newcomm, &tag);
1589: MPI_Barrier(comm);
1590: if (rank) {
1591: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1592: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1593: } else {
1594: PetscTime(x);
1595: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1596: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1597: PetscTime(y);
1598: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1599: }
1600: PetscCommDestroy(&newcomm);
1601: }
1602: if (!rank) {
1603: PetscOptionsPrint(fd);
1604: }
1605: /* Machine and compile information */
1606: #if defined(PETSC_USE_FORTRAN_KERNELS)
1607: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1608: #else
1609: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1610: #endif
1611: #if defined(PETSC_USE_SINGLE)
1612: PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1613: #elif defined(PETSC_USE_LONGDOUBLE)
1614: PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1615: #elif defined(PETSC_USE_INT)
1616: PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1617: #endif
1619: #if defined(PETSC_USE_MAT_SINGLE)
1620: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1621: #else
1622: PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1623: #endif
1624: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1625: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));
1627: PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1628: PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1629: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1630: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1631: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1632: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1634: /* Cleanup */
1635: PetscFPrintf(comm, fd, "\n");
1636: PetscFClose(comm, fd);
1637: StageLogPush(stageLog, lastStage);
1638: return(0);
1639: }
1643: /*@C
1644: PetscLogPrintDetailed - Each process prints the times for its own events
1646: Collective over MPI_Comm
1648: Input Parameter:
1649: + comm - The MPI communicator (only one processor prints output)
1650: - file - [Optional] The output file name
1652: Options Database Keys:
1653: . -log_summary_detailed - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1655: Usage:
1656: .vb
1657: PetscInitialize(...);
1658: PetscLogBegin();
1659: ... code ...
1660: PetscLogPrintDetailed(MPI_Comm,filename);
1661: PetscFinalize(...);
1662: .ve
1664: Notes:
1665: By default the summary is printed to stdout.
1667: Level: beginner
1668:
1669: .keywords: log, dump, print
1670: .seealso: PetscLogBegin(), PetscLogDump(), PetscLogPrintSummary()
1671: @*/
1672: PetscErrorCode PetscLogPrintDetailed(MPI_Comm comm, const char filename[])
1673: {
1674: FILE *fd = PETSC_STDOUT;
1675: StageLog stageLog;
1676: StageInfo *stageInfo = PETSC_NULL;
1677: EventPerfInfo *eventInfo = PETSC_NULL;
1678: const char *name = PETSC_NULL;
1679: PetscLogDouble TotalTime;
1680: PetscLogDouble stageTime, flops, flopr, mess, messLen, red;
1681: PetscLogDouble maxf, totf, maxt, tott, totm, totml, totr = 0.0;
1682: PetscMPIInt maxCt;
1683: PetscMPIInt size, rank;
1684: PetscTruth *stageUsed;
1685: PetscTruth *stageVisible;
1686: int numStages, numEvents;
1687: int stage;
1688: PetscLogEvent event;
1692: MPI_Comm_size(comm, &size);
1693: MPI_Comm_rank(comm, &rank);
1694: /* Pop off any stages the user forgot to remove */
1695: PetscLogGetStageLog(&stageLog);
1696: StageLogGetCurrent(stageLog, &stage);
1697: while (stage >= 0) {
1698: StageLogPop(stageLog);
1699: StageLogGetCurrent(stageLog, &stage);
1700: }
1701: /* Get the total elapsed time */
1702: PetscTime(TotalTime); TotalTime -= BaseTime;
1703: /* Open the summary file */
1704: if (filename) {
1705: PetscFOpen(comm, filename, "w", &fd);
1706: }
1708: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1709: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1710: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1713: numStages = stageLog->numStages;
1714: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1715: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1716: if (numStages > 0) {
1717: stageInfo = stageLog->stageInfo;
1718: for(stage = 0; stage < numStages; stage++) {
1719: if (stage < stageLog->numStages) {
1720: stageUsed[stage] = stageInfo[stage].used;
1721: stageVisible[stage] = stageInfo[stage].perfInfo.visible;
1722: } else {
1723: stageUsed[stage] = PETSC_FALSE;
1724: stageVisible[stage] = PETSC_TRUE;
1725: }
1726: }
1727: }
1729: /* Report events */
1730: PetscFPrintf(comm, fd,"Event Count Time (sec) Flops/sec \n");
1731: PetscFPrintf(comm, fd," Mess Avg len Reduct \n");
1732: PetscFPrintf(comm,fd,"-----------------------------------------------------------------------------------\n");
1733: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1734: for(stage = 0; stage < numStages; stage++) {
1735: if (!stageVisible[stage]) continue;
1736: if (stageUsed[stage]) {
1737: PetscSynchronizedFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1738: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1739: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1740: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1741: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1742: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1743: }
1744: mess *= 0.5; messLen *= 0.5;
1746: /* Get total number of events in this stage --
1747: */
1748: if (stageUsed[stage]) {
1749: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1750: numEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1751: } else {
1752: numEvents = 0;
1753: }
1754: for(event = 0; event < numEvents; event++) {
1755: if (stageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1756: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1757: flopr = eventInfo[event].flops/eventInfo[event].time;
1758: } else {
1759: flopr = 0.0;
1760: }
1761: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1762: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1763: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, PETSC_COMM_SELF);
1764: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1765: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1766: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, PETSC_COMM_SELF);
1767: totr = eventInfo[event].numReductions;
1768: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, PETSC_COMM_SELF);
1769: name = stageLog->eventLog->eventInfo[event].name;
1770: totm *= 0.5; totml *= 0.5;
1771: }
1772:
1773: if (maxCt != 0) {
1774: if (totm != 0.0) totml /= totm; else totml = 0.0;
1775: PetscSynchronizedFPrintf(comm, fd,"%-16s %7d %5.4e %3.2e %2.1e %2.1e %2.1e\n",name, maxCt, maxt, maxf, totm, totml, totr);
1776: }
1777: }
1778: }
1779: PetscSynchronizedFlush(comm);
1781: PetscFree(stageUsed);
1782: PetscFree(stageVisible);
1784: PetscFClose(comm, fd);
1785: return(0);
1786: }
1788: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1791: /*@C
1792: PetscGetFlops - Returns the number of flops used on this processor
1793: since the program began.
1795: Not Collective
1797: Output Parameter:
1798: flops - number of floating point operations
1800: Notes:
1801: A global counter logs all PETSc flop counts. The user can use
1802: PetscLogFlops() to increment this counter to include flops for the
1803: application code.
1805: PETSc automatically logs library events if the code has been
1806: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1807: -log_summary, or -log_all are specified. PetscLogFlops() is
1808: intended for logging user flops to supplement this PETSc
1809: information.
1811: Level: intermediate
1813: .keywords: log, flops, floating point operations
1815: .seealso: PetscGetTime(), PetscLogFlops()
1816: @*/
1817: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1818: {
1820: *flops = _TotalFlops;
1821: return(0);
1822: }
1826: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1827: {
1829: int fullLength;
1830: va_list Argp;
1833: if (!logObjects) return(0);
1834: va_start(Argp, format);
1835: PetscVSNPrintf(objects[obj->id].info, 64,format,&fullLength, Argp);
1836: va_end(Argp);
1837: return(0);
1838: }
1842: /*@
1843: PetscLogGetStageLog - This function returns the default stage logging object.
1845: Not collective
1847: Output Parameter:
1848: . stageLog - The default StageLog
1850: Level: beginner
1852: .keywords: log, stage
1853: .seealso: StageLogCreate()
1854: @*/
1855: PetscErrorCode PetscLogGetStageLog(StageLog *stageLog)
1856: {
1859: *stageLog = _stageLog;
1860: return(0);
1861: }
1863: /*MC
1864: PetscLogFlops - Adds floating point operations to the global counter.
1866: Input Parameter:
1867: . f - flop counter
1869: Synopsis:
1870: void PetscLogFlops(int f)
1872: Usage:
1873: .vb
1874: int USER_EVENT;
1875: PetscLogEventRegister("User event",0,&USER_EVENT);
1876: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1877: [code segment to monitor]
1878: PetscLogFlops(user_flops)
1879: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1880: .ve
1882: Notes:
1883: A global counter logs all PETSc flop counts. The user can use
1884: PetscLogFlops() to increment this counter to include flops for the
1885: application code.
1887: PETSc automatically logs library events if the code has been
1888: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1889: -log_summary, or -log_all are specified. PetscLogFlops() is
1890: intended for logging user flops to supplement this PETSc
1891: information.
1893: Level: intermediate
1895: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1897: .keywords: log, flops, floating point operations
1898: M*/
1900: /*MC
1901: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1902: to get accurate timings
1904: Input Parameter:
1905: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1906: with command line option -preload true or -preload false
1907: - name - name of first stage (lines of code timed separately with -log_summary) to
1908: be preloaded
1910: Synopsis:
1911: void PreLoadBegin(PetscTruth flag,char *name);
1913: Usage:
1914: .vb
1915: PreLoadBegin(PETSC_TRUE,"first stage);
1916: lines of code
1917: PreLoadStage("second stage");
1918: lines of code
1919: PreLoadEnd();
1920: .ve
1922: Notes: Only works in C/C++, not Fortran
1924: Flags available within the macro.
1925: + PetscPreLoadingUsed - true if we are or have done preloading
1926: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1927: . PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1928: - PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1929: The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1930: and PreLoadEnd()
1932: Level: intermediate
1934: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1936: Concepts: preloading
1937: Concepts: timing^accurate
1938: Concepts: paging^eliminating effects of
1941: M*/
1943: /*MC
1944: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1945: to get accurate timings
1947: Synopsis:
1948: void PreLoadEnd(void);
1950: Usage:
1951: .vb
1952: PreLoadBegin(PETSC_TRUE,"first stage);
1953: lines of code
1954: PreLoadStage("second stage");
1955: lines of code
1956: PreLoadEnd();
1957: .ve
1959: Notes: only works in C/C++ not fortran
1961: Level: intermediate
1963: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1965: M*/
1967: /*MC
1968: PreLoadStage - Start a new segment of code to be timed separately.
1969: to get accurate timings
1971: Synopsis:
1972: void PreLoadStage(char *name);
1974: Usage:
1975: .vb
1976: PreLoadBegin(PETSC_TRUE,"first stage);
1977: lines of code
1978: PreLoadStage("second stage");
1979: lines of code
1980: PreLoadEnd();
1981: .ve
1983: Notes: only works in C/C++ not fortran
1985: Level: intermediate
1987: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1989: M*/
1991: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1994: /*@C
1995: StackDestroy - This function destroys a stack.
1997: Not Collective
1999: Input Parameter:
2000: . stack - The stack
2002: Level: beginner
2004: .keywords: log, stack, destroy
2005: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
2006: @*/
2007: PetscErrorCode StackDestroy(IntStack stack)
2008: {
2012: PetscFree(stack->stack);
2013: PetscFree(stack);
2014: return(0);
2015: }
2019: /*@C
2020: StackEmpty - This function determines whether any items have been pushed.
2022: Not Collective
2024: Input Parameter:
2025: . stack - The stack
2027: Output Parameter:
2028: . empty - PETSC_TRUE if the stack is empty
2030: Level: intermediate
2032: .keywords: log, stack, empty
2033: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
2034: @*/
2035: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
2036: {
2039: if (stack->top == -1) {
2040: *empty = PETSC_TRUE;
2041: } else {
2042: *empty = PETSC_FALSE;
2043: }
2044: return(0);
2045: }
2049: /*@C
2050: StackTop - This function returns the top of the stack.
2052: Not Collective
2054: Input Parameter:
2055: . stack - The stack
2057: Output Parameter:
2058: . top - The integer on top of the stack
2060: Level: intermediate
2062: .keywords: log, stack, top
2063: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
2064: @*/
2065: PetscErrorCode StackTop(IntStack stack, int *top)
2066: {
2069: *top = stack->stack[stack->top];
2070: return(0);
2071: }
2075: /*@C
2076: StackPush - This function pushes an integer on the stack.
2078: Not Collective
2080: Input Parameters:
2081: + stack - The stack
2082: - item - The integer to push
2084: Level: intermediate
2086: .keywords: log, stack, push
2087: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
2088: @*/
2089: PetscErrorCode StackPush(IntStack stack, int item)
2090: {
2091: int *array;
2095: stack->top++;
2096: if (stack->top >= stack->max) {
2097: PetscMalloc(stack->max*2 * sizeof(int), &array);
2098: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2099: PetscFree(stack->stack);
2100: stack->stack = array;
2101: stack->max *= 2;
2102: }
2103: stack->stack[stack->top] = item;
2104: return(0);
2105: }
2109: /*@C
2110: StackPop - This function pops an integer from the stack.
2112: Not Collective
2114: Input Parameter:
2115: . stack - The stack
2117: Output Parameter:
2118: . item - The integer popped
2120: Level: intermediate
2122: .keywords: log, stack, pop
2123: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2124: @*/
2125: PetscErrorCode StackPop(IntStack stack, int *item)
2126: {
2129: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2130: *item = stack->stack[stack->top--];
2131: return(0);
2132: }
2136: /*@C
2137: StackCreate - This function creates a stack.
2139: Not Collective
2141: Output Parameter:
2142: . stack - The stack
2144: Level: beginner
2146: .keywords: log, stack, pop
2147: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2148: @*/
2149: PetscErrorCode StackCreate(IntStack *stack)
2150: {
2151: IntStack s;
2156: PetscNew(struct _n_IntStack, &s);
2157: s->top = -1;
2158: s->max = 128;
2159: PetscMalloc(s->max * sizeof(int), &s->stack);
2160: PetscMemzero(s->stack, s->max * sizeof(int));
2161: *stack = s;
2162: return(0);
2163: }
2165: #else /* end of -DPETSC_USE_LOG section */
2169: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2170: {
2172: return(0);
2173: }
2175: #endif /* PETSC_USE_LOG*/
2178: PetscCookie PETSC_LARGEST_COOKIE = PETSC_SMALLEST_COOKIE;
2179: PetscCookie PETSC_OBJECT_COOKIE = 0;
2183: /*@C
2184: PetscCookieRegister - Registers a new class name for objects and logging operations in an application code.
2186: Not Collective
2188: Input Parameter:
2189: . name - The class name
2190:
2191: Output Parameter:
2192: . oclass - The class id or cookie
2194: Level: developer
2196: .keywords: log, class, register
2198: @*/
2199: PetscErrorCode PetscCookieRegister(const char name[],PetscCookie *oclass )
2200: {
2201: #if defined(PETSC_USE_LOG)
2202: StageLog stageLog;
2203: PetscInt stage;
2205: #endif
2208: *oclass = ++PETSC_LARGEST_COOKIE;
2209: #if defined(PETSC_USE_LOG)
2210: PetscLogGetStageLog(&stageLog);
2211: ClassRegLogRegister(stageLog->classLog, name, *oclass);
2212: for(stage = 0; stage < stageLog->numStages; stage++) {
2213: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2214: }
2215: #endif
2216: return(0);
2217: }