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: PetscEvent 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 */
29: int PETSC_DUMMY_SIZE = 0;
30: int PETSC_DUMMY_COUNT = 0;
32: /* Action and object logging variables */
33: Action *actions = PETSC_NULL;
34: Object *objects = PETSC_NULL;
35: PetscTruth logActions = PETSC_FALSE;
36: PetscTruth logObjects = PETSC_FALSE;
37: int numActions = 0, maxActions = 100;
38: int numObjects = 0, maxObjects = 100;
39: int numObjectsDestroyed = 0;
41: /* Global counters */
42: PetscLogDouble BaseTime = 0.0;
43: PetscLogDouble _TotalFlops = 0.0; /* The number of flops */
44: PetscLogDouble send_ct = 0.0; /* The number of sends */
45: PetscLogDouble recv_ct = 0.0; /* The number of receives */
46: PetscLogDouble send_len = 0.0; /* The total length of all sent messages */
47: PetscLogDouble recv_len = 0.0; /* The total length of all received messages */
48: PetscLogDouble isend_ct = 0.0; /* The number of immediate sends */
49: PetscLogDouble irecv_ct = 0.0; /* The number of immediate receives */
50: PetscLogDouble isend_len = 0.0; /* The total length of all immediate send messages */
51: PetscLogDouble irecv_len = 0.0; /* The total length of all immediate receive messages */
52: PetscLogDouble wait_ct = 0.0; /* The number of waits */
53: PetscLogDouble wait_any_ct = 0.0; /* The number of anywaits */
54: PetscLogDouble wait_all_ct = 0.0; /* The number of waitalls */
55: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
56: PetscLogDouble allreduce_ct = 0.0; /* The number of reductions */
58: /* Logging functions */
59: PetscErrorCode (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
60: PetscErrorCode (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
61: PetscErrorCode (*_PetscLogPLB)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
62: PetscErrorCode (*_PetscLogPLE)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
64: /* Tracing event logging variables */
65: FILE *tracefile = PETSC_NULL;
66: int tracelevel = 0;
67: const char *traceblanks = " ";
68: char tracespace[128] = " ";
69: PetscLogDouble tracetime = 0.0;
71: /*---------------------------------------------- General Functions --------------------------------------------------*/
74: /*@C
75: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
77: Not Collective
79: Notes:
80: This routine should not usually be used by programmers. Instead employ
81: PetscLogStagePush() and PetscLogStagePop().
83: Level: developer
85: .keywords: log, destroy
86: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
87: @*/
88: PetscErrorCode PetscLogDestroy(void)
89: {
90: StageLog stageLog;
94: PetscFree(actions);
95: actions = PETSC_NULL;
96: PetscFree(objects);
97: objects = PETSC_NULL;
98: PetscLogSet(PETSC_NULL, PETSC_NULL);
100: /* Resetting phase */
101: PetscLogGetStageLog(&stageLog);
102: StageLogDestroy(stageLog);
103: _TotalFlops = 0.0;
104: numActions = 0;
105: numObjects = 0;
106: numObjectsDestroyed = 0;
107: return(0);
108: }
112: /*@C
113: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
115: Not Collective
117: Input Parameters:
118: + b - The function called at beginning of event
119: - e - The function called at end of event
121: Level: developer
123: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
124: @*/
125: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
126: PetscErrorCode (*e)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
127: {
129: _PetscLogPLB = b;
130: _PetscLogPLE = e;
131: return(0);
132: }
134: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
137: PetscErrorCode PetscLogBegin_Private(void)
138: {
139: static PetscTruth initialized = PETSC_FALSE;
140: int stage;
141: PetscTruth opt;
142: PetscErrorCode ierr;
145: if (initialized) return(0);
146: initialized = PETSC_TRUE;
147: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
148: if (opt) {
149: logActions = PETSC_FALSE;
150: }
151: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
152: if (opt) {
153: logObjects = PETSC_FALSE;
154: }
155: if (logActions) {
156: PetscMalloc(maxActions * sizeof(Action), &actions);
157: }
158: if (logObjects) {
159: PetscMalloc(maxObjects * sizeof(Object), &objects);
160: }
161: _PetscLogPHC = PetscLogObjCreateDefault;
162: _PetscLogPHD = PetscLogObjDestroyDefault;
163: /* Setup default logging structures */
164: StageLogCreate(&_stageLog);
165: StageLogRegister(_stageLog, "Main Stage", &stage);
166: /* All processors sync here for more consistent logging */
167: MPI_Barrier(PETSC_COMM_WORLD);
168: PetscTime(BaseTime);
169: PetscLogStagePush(stage);
170: return(0);
171: }
175: /*@C
176: PetscLogBegin - Turns on logging of objects and events. This logs flop
177: rates and object creation and should not slow programs down too much.
178: This routine may be called more than once.
180: Collective over PETSC_COMM_WORLD
182: Options Database Keys:
183: + -log_summary - Prints summary of flop and timing information to the
184: screen (for code compiled with PETSC_USE_LOG)
185: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
187: Usage:
188: .vb
189: PetscInitialize(...);
190: PetscLogBegin();
191: ... code ...
192: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
193: PetscFinalize();
194: .ve
196: Notes:
197: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
198: the logging information.
200: Level: advanced
202: .keywords: log, begin
203: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
204: @*/
205: PetscErrorCode PetscLogBegin(void)
206: {
211: PetscLogBegin_Private();
212: return(0);
213: }
217: /*@C
218: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
219: all events. This creates large log files and slows the program down.
221: Collective on PETSC_COMM_WORLD
223: Options Database Keys:
224: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
226: Usage:
227: .vb
228: PetscInitialize(...);
229: PetscLogAllBegin();
230: ... code ...
231: PetscLogDump(filename);
232: PetscFinalize();
233: .ve
235: Notes:
236: A related routine is PetscLogBegin (with the options key -log), which is
237: intended for production runs since it logs only flop rates and object
238: creation (and shouldn't significantly slow the programs).
240: Level: advanced
242: .keywords: log, all, begin
243: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
244: @*/
245: PetscErrorCode PetscLogAllBegin(void)
246: {
251: PetscLogBegin_Private();
252: return(0);
253: }
257: /*@
258: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
259: begins or ends, the event name is printed.
261: Collective on PETSC_COMM_WORLD
263: Input Parameter:
264: . file - The file to print trace in (e.g. stdout)
266: Options Database Key:
267: . -log_trace [filename] - Activates PetscLogTraceBegin()
269: Notes:
270: PetscLogTraceBegin() prints the processor number, the execution time (sec),
271: then "Event begin:" or "Event end:" followed by the event name.
273: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
274: to determine where a program is hanging without running in the
275: debugger. Can be used in conjunction with the -info option.
277: Level: intermediate
279: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
280: @*/
281: PetscErrorCode PetscLogTraceBegin(FILE *file)
282: {
286: tracefile = file;
288: PetscLogBegin_Private();
289: return(0);
290: }
294: /*@
295: PetscLogActions - Determines whether actions are logged for the graphical viewer.
297: Not Collective
299: Input Parameter:
300: . flag - PETSC_TRUE if actions are to be logged
302: Level: intermediate
304: Note: Logging of actions continues to consume more memory as the program
305: runs. Long running programs should consider turning this feature off.
307: Options Database Keys:
308: . -log_exclude_actions - Turns off actions logging
310: .keywords: log, stage, register
311: .seealso: PetscLogStagePush(), PetscLogStagePop()
312: @*/
313: PetscErrorCode PetscLogActions(PetscTruth flag)
314: {
316: logActions = flag;
317: return(0);
318: }
322: /*@
323: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
325: Not Collective
327: Input Parameter:
328: . flag - PETSC_TRUE if objects are to be logged
330: Level: intermediate
332: Note: Logging of objects continues to consume more memory as the program
333: runs. Long running programs should consider turning this feature off.
335: Options Database Keys:
336: . -log_exclude_objects - Turns off objects logging
338: .keywords: log, stage, register
339: .seealso: PetscLogStagePush(), PetscLogStagePop()
340: @*/
341: PetscErrorCode PetscLogObjects(PetscTruth flag)
342: {
344: logObjects = flag;
345: return(0);
346: }
348: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
351: /*@C
352: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
354: Not Collective
356: Input Parameter:
357: . sname - The name to associate with that stage
359: Output Parameter:
360: . stage - The stage number
362: Level: intermediate
364: .keywords: log, stage, register
365: .seealso: PetscLogStagePush(), PetscLogStagePop()
366: @*/
367: PetscErrorCode PetscLogStageRegister(int *stage, const char sname[])
368: {
369: StageLog stageLog;
370: PetscEvent event;
374: PetscLogGetStageLog(&stageLog);
375: StageLogRegister(stageLog, sname, stage);
376: /* Copy events already changed in the main stage, this sucks */
377: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
378: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
379: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
380: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
381: }
382: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
383: return(0);
384: }
388: /*@C
389: PetscLogStagePush - This function pushes a stage on the stack.
391: Not Collective
393: Input Parameter:
394: . stage - The stage on which to log
396: Usage:
397: If the option -log_sumary is used to run the program containing the
398: following code, then 2 sets of summary data will be printed during
399: PetscFinalize().
400: .vb
401: PetscInitialize(int *argc,char ***args,0,0);
402: [stage 0 of code]
403: PetscLogStagePush(1);
404: [stage 1 of code]
405: PetscLogStagePop();
406: PetscBarrier(...);
407: [more stage 0 of code]
408: PetscFinalize();
409: .ve
410:
411: Notes:
412: Use PetscLogStageRegister() to register a stage.
414: Level: intermediate
416: .keywords: log, push, stage
417: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
418: @*/
419: PetscErrorCode PetscLogStagePush(int stage)
420: {
421: StageLog stageLog;
425: PetscLogGetStageLog(&stageLog);
426: StageLogPush(stageLog, stage);
427: return(0);
428: }
432: /*@C
433: PetscLogStagePop - This function pops a stage from the stack.
435: Not Collective
437: Usage:
438: If the option -log_sumary is used to run the program containing the
439: following code, then 2 sets of summary data will be printed during
440: PetscFinalize().
441: .vb
442: PetscInitialize(int *argc,char ***args,0,0);
443: [stage 0 of code]
444: PetscLogStagePush(1);
445: [stage 1 of code]
446: PetscLogStagePop();
447: PetscBarrier(...);
448: [more stage 0 of code]
449: PetscFinalize();
450: .ve
452: Notes:
453: Use PetscLogStageRegister() to register a stage.
455: Level: intermediate
457: .keywords: log, pop, stage
458: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
459: @*/
460: PetscErrorCode PetscLogStagePop(void)
461: {
462: StageLog stageLog;
466: PetscLogGetStageLog(&stageLog);
467: StageLogPop(stageLog);
468: return(0);
469: }
473: /*@
476: Not Collective
478: Input Parameters:
479: + stage - The stage
480: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
482: Level: intermediate
485: @*/
486: PetscErrorCode PetscLogStageSetActive(int stage, PetscTruth isActive)
487: {
488: StageLog stageLog;
492: PetscLogGetStageLog(&stageLog);
493: StageLogSetActive(stageLog, stage, isActive);
494: return(0);
495: }
499: /*@
502: Not Collective
504: Input Parameter:
505: . stage - The stage
507: Output Parameter:
508: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
510: Level: intermediate
513: @*/
514: PetscErrorCode PetscLogStageGetActive(int stage, PetscTruth *isActive)
515: {
516: StageLog stageLog;
520: PetscLogGetStageLog(&stageLog);
521: StageLogGetActive(stageLog, stage, isActive);
522: return(0);
523: }
527: /*@
528: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
530: Not Collective
532: Input Parameters:
533: + stage - The stage
534: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
536: Level: intermediate
538: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
539: @*/
540: PetscErrorCode PetscLogStageSetVisible(int stage, PetscTruth isVisible)
541: {
542: StageLog stageLog;
546: PetscLogGetStageLog(&stageLog);
547: StageLogSetVisible(stageLog, stage, isVisible);
548: return(0);
549: }
553: /*@
554: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
556: Not Collective
558: Input Parameter:
559: . stage - The stage
561: Output Parameter:
562: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
564: Level: intermediate
566: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
567: @*/
568: PetscErrorCode PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
569: {
570: StageLog stageLog;
574: PetscLogGetStageLog(&stageLog);
575: StageLogGetVisible(stageLog, stage, isVisible);
576: return(0);
577: }
581: /*@
582: PetscLogStageGetId - Returns the stage id when given the stage name.
584: Not Collective
586: Input Parameter:
587: . name - The stage name
589: Output Parameter:
590: . stage - The stage
592: Level: intermediate
594: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
595: @*/
596: PetscErrorCode PetscLogStageGetId(const char name[], int *stage)
597: {
598: StageLog stageLog;
602: PetscLogGetStageLog(&stageLog);
603: StageLogGetStage(stageLog, name, stage);
604: return(0);
605: }
607: /*------------------------------------------------ Event Functions --------------------------------------------------*/
610: /*@C
613: Not Collective
615: Input Parameter:
616: + name - The name associated with the event
617: - cookie - The cookie associated to the class for this event, obtain either with
618: PetscLogClassRegister() or use a predefined one such as KSP_COOKIE, SNES_COOKIE
619:
620: Output Parameter:
623: Example of Usage:
624: .vb
625: PetscEvent USER_EVENT;
626: PetscCookie cookie;
627: int user_event_flops;
628: PetscLogClassRegister(&cookie,"class name");
631: [code segment to monitor]
632: PetscLogFlops(user_event_flops);
634: .ve
636: Notes:
637: PETSc automatically logs library events if the code has been
638: compiled with -DPETSC_USE_LOG (which is the default) and -log,
640: intended for logging user events to supplement this PETSc
641: information.
643: PETSc can gather data for use with the utilities Upshot/Nupshot
644: (part of the MPICH distribution). If PETSc has been compiled
645: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
646: MPICH), the user can employ another command line option, -log_mpe,
647: to create a logfile, "mpe.log", which can be visualized
648: Upshot/Nupshot.
650: The cookie is associated with each event so that classes of events
651: can be disabled simultaneously, such as all matrix events. The user
652: can either use an existing cookie, such as MAT_COOKIE, or create
653: their own as shown in the example.
655: Level: intermediate
657: .keywords: log, event, register
661: @*/
663: {
664: StageLog stageLog;
665: int stage;
669: *event = PETSC_DECIDE;
670: PetscLogGetStageLog(&stageLog);
671: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
672: for(stage = 0; stage < stageLog->numStages; stage++) {
673: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
674: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
675: }
676: return(0);
677: }
681: /*@
684: Not Collective
686: Input Parameter:
687: . event - The event id
689: Usage:
690: .vb
692: [code where you do not want to log VecSetValues()]
694: [code where you do want to log VecSetValues()]
695: .ve
697: Note:
698: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
701: Level: advanced
703: .keywords: log, event, activate
705: @*/
707: {
708: StageLog stageLog;
709: int stage;
713: PetscLogGetStageLog(&stageLog);
714: StageLogGetCurrent(stageLog, &stage);
715: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
716: return(0);
717: }
721: /*@
724: Not Collective
726: Input Parameter:
727: . event - The event id
729: Usage:
730: .vb
732: [code where you do not want to log VecSetValues()]
734: [code where you do want to log VecSetValues()]
735: .ve
737: Note:
738: The event may be either a pre-defined PETSc event (found in
741: Level: advanced
743: .keywords: log, event, deactivate
745: @*/
747: {
748: StageLog stageLog;
749: int stage;
753: PetscLogGetStageLog(&stageLog);
754: StageLogGetCurrent(stageLog, &stage);
755: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
756: return(0);
757: }
761: /*@
764: Not Collective
766: Input Parameters:
767: + event - The event id
768: - isActive - The activity flag determining whether the event is logged
770: Level: advanced
772: .keywords: log, event, activate
774: @*/
776: {
777: StageLog stageLog;
778: int stage;
782: PetscLogGetStageLog(&stageLog);
783: for(stage = 0; stage < stageLog->numStages; stage++) {
784: if (isActive) {
785: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
786: } else {
787: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
788: }
789: }
790: return(0);
791: }
795: /*@
798: Not Collective
800: Input Parameter:
801: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
803: Level: developer
805: .keywords: log, event, activate, class
807: @*/
809: {
810: StageLog stageLog;
811: int stage;
815: PetscLogGetStageLog(&stageLog);
816: StageLogGetCurrent(stageLog, &stage);
817: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
818: return(0);
819: }
823: /*@
826: Not Collective
828: Input Parameter:
829: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
831: Level: developer
833: .keywords: log, event, deactivate, class
835: @*/
837: {
838: StageLog stageLog;
839: int stage;
843: PetscLogGetStageLog(&stageLog);
844: StageLogGetCurrent(stageLog, &stage);
845: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
846: return(0);
847: }
849: /*MC
852: Input Parameters:
854: - o1,o2,o3,o4 - objects associated with the event, or 0
856: Synopsis:
858: PetscObject o4)
860: Fortran Synopsis:
863: Usage:
864: .vb
865: int USER_EVENT;
866: int user_event_flops;
869: [code segment to monitor]
870: PetscLogFlops(user_event_flops);
872: .ve
874: Notes:
875: You need to register each integer event with the command
877: -DPETSC_USE_LOG, which is the default.
879: PETSc automatically logs library events if the code has been
880: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
882: to supplement this PETSc information.
884: Level: intermediate
888: .keywords: log, event, begin
889: M*/
891: /*MC
894: Input Parameters:
896: - o1,o2,o3,o4 - objects associated with the event, or 0
898: Synopsis:
900: PetscObject o4)
902: Fortran Synopsis:
905: Usage:
906: .vb
907: int USER_EVENT;
908: int user_event_flops;
911: [code segment to monitor]
912: PetscLogFlops(user_event_flops);
914: .ve
916: Notes:
917: You should also register each additional integer event with the command
919: -DPETSC_USE_LOG, which is the default.
921: PETSc automatically logs library events if the code has been
922: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
924: to supplement this PETSc information.
926: Level: intermediate
930: .keywords: log, event, end
931: M*/
933: /*MC
936: Input Parameters:
938: . o1,o2,o3,o4 - objects associated with the event, or 0
939: . comm - communicator the barrier takes place over
941: Synopsis:
943: PetscObject o4,MPI_Comm comm)
945: Usage:
946: .vb
948: MPI_Allreduce()
950: .ve
952: Notes:
953: This is for logging the amount of time spent in a barrier for an event
954: that requires synchronization.
956: Additional Notes:
957: Synchronization events always come in pairs; for example, VEC_NormBarrier and
958: VEC_NormComm = VEC_NormBarrier + 1
960: Level: advanced
965: .keywords: log, event, begin, barrier
966: M*/
968: /*MC
971: Input Parameters:
973: . o1,o2,o3,o4 - objects associated with the event, or 0
974: . comm - communicator the barrier takes place over
976: Synopsis:
978: PetscObject o4,MPI_Comm comm)
980: Usage:
981: .vb
983: MPI_Allreduce()
985: .ve
987: Notes:
988: This is for logging the amount of time spent in a barrier for an event
989: that requires synchronization.
991: Additional Notes:
992: Synchronization events always come in pairs; for example, VEC_NormBarrier and
993: VEC_NormComm = VEC_NormBarrier + 1
995: Level: advanced
1000: .keywords: log, event, begin, barrier
1001: M*/
1003: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1006: /*@C
1007: PetscLogClassRegister - Registers a class name for logging operations in an application code.
1009: Not Collective
1011: Input Parameter:
1012: . name - The class name
1013:
1014: Output Parameter:
1015: . oclass - The class id or cookie
1017: Level: developer
1019: .keywords: log, class, register
1021: @*/
1022: PetscErrorCode PetscLogClassRegister(PetscCookie *oclass, const char name[])
1023: {
1024: StageLog stageLog;
1025: int stage;
1029: PetscLogGetStageLog(&stageLog);
1030: ClassRegLogRegister(stageLog->classLog, name, oclass);
1031: for(stage = 0; stage < stageLog->numStages; stage++) {
1032: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
1033: }
1034: return(0);
1035: }
1037: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1040: /*@C
1041: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1042: be read by petsc/bin/petscview.
1044: Collective on PETSC_COMM_WORLD
1046: Input Parameter:
1047: . name - an optional file name
1049: Options Database Keys:
1050: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1051: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1052:
1053: Usage:
1054: .vb
1055: PetscInitialize(...);
1056: PetscLogBegin(); or PetscLogAllBegin();
1057: ... code ...
1058: PetscLogDump(filename);
1059: PetscFinalize();
1060: .ve
1062: Notes:
1063: The default file name is
1064: $ Log.<rank>
1065: where <rank> is the processor number. If no name is specified,
1066: this file will be used.
1068: Level: advanced
1070: .keywords: log, dump
1071: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1072: @*/
1073: PetscErrorCode PetscLogDump(const char sname[])
1074: {
1075: StageLog stageLog;
1076: EventPerfInfo *eventInfo;
1077: FILE *fd;
1078: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1079: PetscLogDouble flops, _TotalTime;
1080: PetscMPIInt rank;
1081: int action, object, curStage;
1082: PetscEvent event;
1084:
1086: /* Calculate the total elapsed time */
1087: PetscTime(_TotalTime);
1088: _TotalTime -= BaseTime;
1089: /* Open log file */
1090: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1091: if (sname) {
1092: sprintf(file, "%s.%d", sname, rank);
1093: } else {
1094: sprintf(file, "Log.%d", rank);
1095: }
1096: PetscFixFilename(file, fname);
1097: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1098: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1099: /* Output totals */
1100: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1101: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1102: /* Output actions */
1103: if (logActions) {
1104: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1105: for(action = 0; action < numActions; action++) {
1106: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1107: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1108: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1109: }
1110: }
1111: /* Output objects */
1112: if (logObjects) {
1113: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1114: for(object = 0; object < numObjects; object++) {
1115: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1116: if (!objects[object].name[0]) {
1117: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1118: } else {
1119: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1120: }
1121: if (objects[object].info[0] != 0) {
1122: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1123: } else {
1124: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1125: }
1126: }
1127: }
1128: /* Output events */
1129: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1130: PetscLogGetStageLog(&stageLog);
1131: StackTop(stageLog->stack, &curStage);
1132: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1133: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1134: if (eventInfo[event].time != 0.0) {
1135: flops = eventInfo[event].flops/eventInfo[event].time;
1136: } else {
1137: flops = 0.0;
1138: }
1139: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1140: eventInfo[event].flops, eventInfo[event].time, flops);
1141: }
1142: PetscFClose(PETSC_COMM_WORLD, fd);
1143: return(0);
1144: }
1148: /*@C
1149: PetscLogPrintSummary - Prints a summary of the logging.
1151: Collective over MPI_Comm
1153: Input Parameter:
1154: + comm - The MPI communicator (only one processor prints output)
1155: - file - [Optional] The output file name
1157: Options Database Keys:
1158: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1160: Usage:
1161: .vb
1162: PetscInitialize(...);
1163: PetscLogBegin();
1164: ... code ...
1165: PetscLogPrintSummary(MPI_Comm,filename);
1166: PetscFinalize(...);
1167: .ve
1169: Notes:
1170: By default the summary is printed to stdout.
1172: Level: beginner
1173:
1174: .keywords: log, dump, print
1175: .seealso: PetscLogBegin(), PetscLogDump()
1176: @*/
1177: PetscErrorCode PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1178: {
1179: FILE *fd = stdout;
1180: PetscScalar zero = 0.0;
1181: StageLog stageLog;
1182: StageInfo *stageInfo = PETSC_NULL;
1183: EventPerfInfo *eventInfo = PETSC_NULL;
1184: ClassPerfInfo *classInfo;
1185: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1186: const char *name;
1187: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1188: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1189: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1190: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1191: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1192: PetscLogDouble min, max, tot, ratio, avg, x, y;
1193: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1194: PetscMPIInt minCt, maxCt;
1195: PetscMPIInt size, rank;
1196: PetscTruth *localStageUsed, *stageUsed;
1197: PetscTruth *localStageVisible, *stageVisible;
1198: int numStages, localNumEvents, numEvents;
1199: int stage, lastStage, oclass;
1200: PetscEvent event;
1202: char version[256];
1205: MPI_Comm_size(comm, &size);
1206: MPI_Comm_rank(comm, &rank);
1207: /* Pop off any stages the user forgot to remove */
1208: lastStage = 0;
1209: PetscLogGetStageLog(&stageLog);
1210: StageLogGetCurrent(stageLog, &stage);
1211: while (stage >= 0) {
1212: lastStage = stage;
1213: StageLogPop(stageLog);
1214: StageLogGetCurrent(stageLog, &stage);
1215: }
1216: /* Get the total elapsed time */
1217: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1218: /* Open the summary file */
1219: if (filename) {
1220: PetscFOpen(comm, filename, "w", &fd);
1221: }
1223: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1224: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1225: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1226: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1227: PetscGetArchType(arch, 10);
1228: PetscGetHostName(hostname, 64);
1229: PetscGetUserName(username, 16);
1230: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1231: PetscGetDate(date, 64);
1232: PetscGetVersion(&version,256);
1233: if (size == 1) {
1234: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1235: } else {
1236: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1237: }
1238: PetscFPrintf(comm, fd, "Using %s\n", version);
1240: /* Must preserve reduction count before we go on */
1241: red = allreduce_ct/((PetscLogDouble) size);
1243: /* Calculate summary information */
1244: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1245: /* Time */
1246: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1247: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1248: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1249: avg = (tot)/((PetscLogDouble) size);
1250: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1251: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1252: TotalTime = tot;
1253: /* Objects */
1254: avg = (PetscLogDouble) numObjects;
1255: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1256: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1257: MPI_Allreduce(&avg, &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, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1261: /* Flops */
1262: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1263: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1264: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1265: avg = (tot)/((PetscLogDouble) size);
1266: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1267: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1268: TotalFlops = tot;
1269: /* Flops/sec -- Must talk to Barry here */
1270: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1271: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1272: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1273: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1274: avg = (tot)/((PetscLogDouble) size);
1275: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1276: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1277: /* Memory */
1278: PetscMallocGetMaximumUsage(&mem);
1279: if (mem > 0.0) {
1280: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1281: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1282: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1283: avg = (tot)/((PetscLogDouble) size);
1284: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1285: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1286: }
1287: /* Messages */
1288: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1289: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1290: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1291: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1292: avg = (tot)/((PetscLogDouble) size);
1293: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1294: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1295: numMessages = tot;
1296: /* Message Lengths */
1297: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1298: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1299: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1300: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1301: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1302: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1303: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1304: messageLength = tot;
1305: /* Reductions */
1306: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1307: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1308: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1309: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1310: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1311: numReductions = tot;
1312: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1313: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1314: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1316: /* Get total number of stages --
1317: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1318: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1319: This seems best accomplished by assoicating a communicator with each stage.
1320: */
1321: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1322: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1323: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1324: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1325: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1326: if (numStages > 0) {
1327: stageInfo = stageLog->stageInfo;
1328: for(stage = 0; stage < numStages; stage++) {
1329: if (stage < stageLog->numStages) {
1330: localStageUsed[stage] = stageInfo[stage].used;
1331: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1332: } else {
1333: localStageUsed[stage] = PETSC_FALSE;
1334: localStageVisible[stage] = PETSC_TRUE;
1335: }
1336: }
1337: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1338: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1339: for(stage = 0; stage < numStages; stage++) {
1340: if (stageUsed[stage]) {
1341: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1342: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1343: break;
1344: }
1345: }
1346: for(stage = 0; stage < numStages; stage++) {
1347: if (!stageUsed[stage]) continue;
1348: if (localStageUsed[stage]) {
1349: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1350: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1351: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1352: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1353: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1354: name = stageInfo[stage].name;
1355: } else {
1356: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1357: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1358: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1359: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1360: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1361: name = "";
1362: }
1363: mess *= 0.5; messLen *= 0.5; red /= size;
1364: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1365: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1366: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1367: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1368: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1369: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1370: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1371: 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",
1372: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1373: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1374: }
1375: }
1377: PetscFPrintf(comm, fd,
1378: "\n------------------------------------------------------------------------------------------------------------------------\n");
1379:
1380: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1381: PetscFPrintf(comm, fd, "Phase summary info:\n");
1382: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1383: PetscFPrintf(comm, fd, " Time and Flops/sec: Max - maximum over all processors\n");
1384: PetscFPrintf(comm, fd, "