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 "petscmachineinfo.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 src/sys/src/plog/ptime.h
21: #include plog.h
23: PetscCookie PETSC_LARGEST_COOKIE = PETSC_COOKIE;
24: PetscEvent PETSC_LARGEST_EVENT = PETSC_EVENT;
26: #if defined(PETSC_USE_LOG)
28: /* used in the MPI_XXX() count macros in petsclog.h */
29: int PETSC_DLLEXPORT PETSC_DUMMY_SIZE = 0;
30: int PETSC_DLLEXPORT 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 PETSC_DLLEXPORT BaseTime = 0.0;
43: PetscLogDouble PETSC_DLLEXPORT _TotalFlops = 0.0; /* The number of flops */
44: PetscLogDouble PETSC_DLLEXPORT send_ct = 0.0; /* The number of sends */
45: PetscLogDouble PETSC_DLLEXPORT recv_ct = 0.0; /* The number of receives */
46: PetscLogDouble PETSC_DLLEXPORT send_len = 0.0; /* The total length of all sent messages */
47: PetscLogDouble PETSC_DLLEXPORT recv_len = 0.0; /* The total length of all received messages */
48: PetscLogDouble PETSC_DLLEXPORT isend_ct = 0.0; /* The number of immediate sends */
49: PetscLogDouble PETSC_DLLEXPORT irecv_ct = 0.0; /* The number of immediate receives */
50: PetscLogDouble PETSC_DLLEXPORT isend_len = 0.0; /* The total length of all immediate send messages */
51: PetscLogDouble PETSC_DLLEXPORT irecv_len = 0.0; /* The total length of all immediate receive messages */
52: PetscLogDouble PETSC_DLLEXPORT wait_ct = 0.0; /* The number of waits */
53: PetscLogDouble PETSC_DLLEXPORT wait_any_ct = 0.0; /* The number of anywaits */
54: PetscLogDouble PETSC_DLLEXPORT wait_all_ct = 0.0; /* The number of waitalls */
55: PetscLogDouble PETSC_DLLEXPORT sum_of_waits_ct = 0.0; /* The total number of waits */
56: PetscLogDouble PETSC_DLLEXPORT allreduce_ct = 0.0; /* The number of reductions */
58: /* Logging functions */
59: PetscErrorCode PETSC_DLLEXPORT (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
60: PetscErrorCode PETSC_DLLEXPORT (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
61: PetscErrorCode PETSC_DLLEXPORT (*_PetscLogPLB)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
62: PetscErrorCode PETSC_DLLEXPORT (*_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 PETSC_DLLEXPORT PetscLogDestroy(void)
89: {
90: StageLog stageLog;
94: if (actions) {
95: PetscFree(actions);
96: actions = PETSC_NULL;
97: }
98: if (objects) {
99: PetscFree(objects);
100: objects = PETSC_NULL;
101: }
102: PetscLogSet(PETSC_NULL, PETSC_NULL);
104: /* Resetting phase */
105: PetscLogGetStageLog(&stageLog);
106: StageLogDestroy(stageLog);
107: _TotalFlops = 0.0;
108: numActions = 0;
109: numObjects = 0;
110: numObjectsDestroyed = 0;
111: return(0);
112: }
116: /*@C
117: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
119: Not Collective
121: Input Parameters:
122: + b - The function called at beginning of event
123: - e - The function called at end of event
125: Level: developer
127: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
128: @*/
129: PetscErrorCode PETSC_DLLEXPORT PetscLogSet(PetscErrorCode (*b)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
130: PetscErrorCode (*e)(PetscEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
131: {
133: _PetscLogPLB = b;
134: _PetscLogPLE = e;
135: return(0);
136: }
138: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
141: PetscErrorCode PETSC_DLLEXPORT PetscLogBegin_Private(void)
142: {
143: static PetscTruth initialized = PETSC_FALSE;
144: int stage;
145: PetscTruth opt;
146: PetscErrorCode ierr;
149: if (initialized) return(0);
150: initialized = PETSC_TRUE;
151: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
152: if (opt) {
153: logActions = PETSC_FALSE;
154: }
155: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
156: if (opt) {
157: logObjects = PETSC_FALSE;
158: }
159: if (logActions) {
160: PetscMalloc(maxActions * sizeof(Action), &actions);
161: }
162: if (logObjects) {
163: PetscMalloc(maxObjects * sizeof(Object), &objects);
164: }
165: _PetscLogPHC = PetscLogObjCreateDefault;
166: _PetscLogPHD = PetscLogObjDestroyDefault;
167: /* Setup default logging structures */
168: StageLogCreate(&_stageLog);
169: StageLogRegister(_stageLog, "Main Stage", &stage);
170: /* All processors sync here for more consistent logging */
171: MPI_Barrier(PETSC_COMM_WORLD);
172: PetscTime(BaseTime);
173: PetscLogStagePush(stage);
174: return(0);
175: }
179: /*@C
180: PetscLogBegin - Turns on logging of objects and events. This logs flop
181: rates and object creation and should not slow programs down too much.
182: This routine may be called more than once.
184: Collective over PETSC_COMM_WORLD
186: Options Database Keys:
187: + -log_summary - Prints summary of flop and timing information to the
188: screen (for code compiled with PETSC_USE_LOG)
189: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
191: Usage:
192: .vb
193: PetscInitialize(...);
194: PetscLogBegin();
195: ... code ...
196: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
197: PetscFinalize();
198: .ve
200: Notes:
201: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
202: the logging information.
204: Level: advanced
206: .keywords: log, begin
207: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
208: @*/
209: PetscErrorCode PETSC_DLLEXPORT PetscLogBegin(void)
210: {
214: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
215: PetscLogBegin_Private();
216: return(0);
217: }
221: /*@C
222: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
223: all events. This creates large log files and slows the program down.
225: Collective on PETSC_COMM_WORLD
227: Options Database Keys:
228: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
230: Usage:
231: .vb
232: PetscInitialize(...);
233: PetscLogAllBegin();
234: ... code ...
235: PetscLogDump(filename);
236: PetscFinalize();
237: .ve
239: Notes:
240: A related routine is PetscLogBegin (with the options key -log), which is
241: intended for production runs since it logs only flop rates and object
242: creation (and shouldn't significantly slow the programs).
244: Level: advanced
246: .keywords: log, all, begin
247: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
248: @*/
249: PetscErrorCode PETSC_DLLEXPORT PetscLogAllBegin(void)
250: {
254: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
255: PetscLogBegin_Private();
256: return(0);
257: }
261: /*@
262: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
263: begins or ends, the event name is printed.
265: Collective on PETSC_COMM_WORLD
267: Input Parameter:
268: . file - The file to print trace in (e.g. stdout)
270: Options Database Key:
271: . -log_trace [filename] - Activates PetscLogTraceBegin()
273: Notes:
274: PetscLogTraceBegin() prints the processor number, the execution time (sec),
275: then "Event begin:" or "Event end:" followed by the event name.
277: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
278: to determine where a program is hanging without running in the
279: debugger. Can be used in conjunction with the -log_info option.
281: Level: intermediate
283: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
284: @*/
285: PetscErrorCode PETSC_DLLEXPORT PetscLogTraceBegin(FILE *file)
286: {
290: tracefile = file;
291: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
292: PetscLogBegin_Private();
293: return(0);
294: }
298: /*@
299: PetscLogActions - Determines whether actions are logged for the graphical viewer.
301: Not Collective
303: Input Parameter:
304: . flag - PETSC_TRUE if actions are to be logged
306: Level: intermediate
308: Note: Logging of actions continues to consume more memory as the program
309: runs. Long running programs should consider turning this feature off.
311: Options Database Keys:
312: . -log_exclude_actions - Turns off actions logging
314: .keywords: log, stage, register
315: .seealso: PetscLogStagePush(), PetscLogStagePop()
316: @*/
317: PetscErrorCode PETSC_DLLEXPORT PetscLogActions(PetscTruth flag)
318: {
320: logActions = flag;
321: return(0);
322: }
326: /*@
327: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
329: Not Collective
331: Input Parameter:
332: . flag - PETSC_TRUE if objects are to be logged
334: Level: intermediate
336: Note: Logging of objects continues to consume more memory as the program
337: runs. Long running programs should consider turning this feature off.
339: Options Database Keys:
340: . -log_exclude_objects - Turns off objects logging
342: .keywords: log, stage, register
343: .seealso: PetscLogStagePush(), PetscLogStagePop()
344: @*/
345: PetscErrorCode PETSC_DLLEXPORT PetscLogObjects(PetscTruth flag)
346: {
348: logObjects = flag;
349: return(0);
350: }
352: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
355: /*@C
356: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
358: Not Collective
360: Input Parameter:
361: . sname - The name to associate with that stage
363: Output Parameter:
364: . stage - The stage number
366: Level: intermediate
368: .keywords: log, stage, register
369: .seealso: PetscLogStagePush(), PetscLogStagePop()
370: @*/
371: PetscErrorCode PETSC_DLLEXPORT PetscLogStageRegister(int *stage, const char sname[])
372: {
373: StageLog stageLog;
374: PetscEvent event;
378: PetscLogGetStageLog(&stageLog);
379: StageLogRegister(stageLog, sname, stage);
380: /* Copy events already changed in the main stage, this sucks */
381: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
382: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
383: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
384: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
385: }
386: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
387: return(0);
388: }
392: /*@C
393: PetscLogStagePush - This function pushes a stage on the stack.
395: Not Collective
397: Input Parameter:
398: . stage - The stage on which to log
400: Usage:
401: If the option -log_sumary is used to run the program containing the
402: following code, then 2 sets of summary data will be printed during
403: PetscFinalize().
404: .vb
405: PetscInitialize(int *argc,char ***args,0,0);
406: [stage 0 of code]
407: PetscLogStagePush(1);
408: [stage 1 of code]
409: PetscLogStagePop();
410: PetscBarrier(...);
411: [more stage 0 of code]
412: PetscFinalize();
413: .ve
414:
415: Notes:
416: Use PetscLogStageRegister() to register a stage.
418: Level: intermediate
420: .keywords: log, push, stage
421: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
422: @*/
423: PetscErrorCode PETSC_DLLEXPORT PetscLogStagePush(int stage)
424: {
425: StageLog stageLog;
429: PetscLogGetStageLog(&stageLog);
430: StageLogPush(stageLog, stage);
431: return(0);
432: }
436: /*@C
437: PetscLogStagePop - This function pops a stage from the stack.
439: Not Collective
441: Usage:
442: If the option -log_sumary is used to run the program containing the
443: following code, then 2 sets of summary data will be printed during
444: PetscFinalize().
445: .vb
446: PetscInitialize(int *argc,char ***args,0,0);
447: [stage 0 of code]
448: PetscLogStagePush(1);
449: [stage 1 of code]
450: PetscLogStagePop();
451: PetscBarrier(...);
452: [more stage 0 of code]
453: PetscFinalize();
454: .ve
456: Notes:
457: Use PetscLogStageRegister() to register a stage.
459: Level: intermediate
461: .keywords: log, pop, stage
462: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
463: @*/
464: PetscErrorCode PETSC_DLLEXPORT PetscLogStagePop(void)
465: {
466: StageLog stageLog;
470: PetscLogGetStageLog(&stageLog);
471: StageLogPop(stageLog);
472: return(0);
473: }
477: /*@
478: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
480: Not Collective
482: Input Parameters:
483: + stage - The stage
484: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
486: Level: intermediate
488: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
489: @*/
490: PetscErrorCode PETSC_DLLEXPORT PetscLogStageSetActive(int stage, PetscTruth isActive)
491: {
492: StageLog stageLog;
496: PetscLogGetStageLog(&stageLog);
497: StageLogSetActive(stageLog, stage, isActive);
498: return(0);
499: }
503: /*@
504: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
506: Not Collective
508: Input Parameter:
509: . stage - The stage
511: Output Parameter:
512: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
514: Level: intermediate
516: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
517: @*/
518: PetscErrorCode PETSC_DLLEXPORT PetscLogStageGetActive(int stage, PetscTruth *isActive) \
519: {
520: StageLog stageLog;
524: PetscLogGetStageLog(&stageLog);
525: StageLogGetActive(stageLog, stage, isActive);
526: return(0);
527: }
531: /*@
532: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
534: Not Collective
536: Input Parameters:
537: + stage - The stage
538: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
540: Level: intermediate
542: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
543: @*/
544: PetscErrorCode PETSC_DLLEXPORT PetscLogStageSetVisible(int stage, PetscTruth isVisible)
545: {
546: StageLog stageLog;
550: PetscLogGetStageLog(&stageLog);
551: StageLogSetVisible(stageLog, stage, isVisible);
552: return(0);
553: }
557: /*@
558: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
560: Not Collective
562: Input Parameter:
563: . stage - The stage
565: Output Parameter:
566: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
568: Level: intermediate
570: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
571: @*/
572: PetscErrorCode PETSC_DLLEXPORT PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
573: {
574: StageLog stageLog;
578: PetscLogGetStageLog(&stageLog);
579: StageLogGetVisible(stageLog, stage, isVisible);
580: return(0);
581: }
585: /*@
586: PetscLogStageGetId - Returns the stage id when given the stage name.
588: Not Collective
590: Input Parameter:
591: . name - The stage name
593: Output Parameter:
594: . stage - The stage
596: Level: intermediate
598: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
599: @*/
600: PetscErrorCode PETSC_DLLEXPORT PetscLogStageGetId(const char name[], int *stage)
601: {
602: StageLog stageLog;
606: PetscLogGetStageLog(&stageLog);
607: StageLogGetStage(stageLog, name, stage);
608: return(0);
609: }
611: /*------------------------------------------------ Event Functions --------------------------------------------------*/
614: /*@C
615: PetscLogEventRegister - Registers an event name for logging operations in an application code.
617: Not Collective
619: Input Parameter:
620: + name - The name associated with the event
621: - cookie - The cookie associated to the class for this event
622:
623: Output Parameter:
624: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
626: Example of Usage:
627: .vb
628: int USER_EVENT;
629: int user_event_flops;
630: PetscLogEventRegister(&USER_EVENT,"User event name");
631: PetscLogEventBegin(USER_EVENT,0,0,0,0);
632: [code segment to monitor]
633: PetscLogFlops(user_event_flops);
634: PetscLogEventEnd(USER_EVENT,0,0,0,0);
635: .ve
637: Notes:
638: PETSc automatically logs library events if the code has been
639: compiled with -DPETSC_USE_LOG (which is the default) and -log,
640: -log_summary, or -log_all are specified. PetscLogEventRegister() is
641: intended for logging user events to supplement this PETSc
642: information.
644: PETSc can gather data for use with the utilities Upshot/Nupshot
645: (part of the MPICH distribution). If PETSc has been compiled
646: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
647: MPICH), the user can employ another command line option, -log_mpe,
648: to create a logfile, "mpe.log", which can be visualized
649: Upshot/Nupshot.
651: Level: intermediate
653: .keywords: log, event, register
654: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
655: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
656: PetscLogEventActivate(), PetscLogEventDeactivate()
657: @*/
658: PetscErrorCode PETSC_DLLEXPORT PetscLogEventRegister(PetscEvent *event, const char name[],PetscCookie cookie)
659: {
660: StageLog stageLog;
661: int stage;
665: *event = PETSC_DECIDE;
666: PetscLogGetStageLog(&stageLog);
667: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
668: for(stage = 0; stage < stageLog->numStages; stage++) {
669: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
670: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
671: }
672: return(0);
673: }
677: /*@
678: PetscLogEventActivate - Indicates that a particular event should be logged.
680: Not Collective
682: Input Parameter:
683: . event - The event id
685: Usage:
686: .vb
687: PetscLogEventDeactivate(VEC_SetValues);
688: [code where you do not want to log VecSetValues()]
689: PetscLogEventActivate(VEC_SetValues);
690: [code where you do want to log VecSetValues()]
691: .ve
693: Note:
694: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
695: or an event number obtained with PetscLogEventRegister().
697: Level: advanced
699: .keywords: log, event, activate
700: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
701: @*/
702: PetscErrorCode PETSC_DLLEXPORT PetscLogEventActivate(PetscEvent event)
703: {
704: StageLog stageLog;
705: int stage;
709: PetscLogGetStageLog(&stageLog);
710: StageLogGetCurrent(stageLog, &stage);
711: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
712: return(0);
713: }
717: /*@
718: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
720: Not Collective
722: Input Parameter:
723: . event - The event id
725: Usage:
726: .vb
727: PetscLogEventDeactivate(VEC_SetValues);
728: [code where you do not want to log VecSetValues()]
729: PetscLogEventActivate(VEC_SetValues);
730: [code where you do want to log VecSetValues()]
731: .ve
733: Note:
734: The event may be either a pre-defined PETSc event (found in
735: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
737: Level: advanced
739: .keywords: log, event, deactivate
740: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
741: @*/
742: PetscErrorCode PETSC_DLLEXPORT PetscLogEventDeactivate(PetscEvent event)
743: {
744: StageLog stageLog;
745: int stage;
749: PetscLogGetStageLog(&stageLog);
750: StageLogGetCurrent(stageLog, &stage);
751: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
752: return(0);
753: }
757: /*@
758: PetscLogEventSetActiveAll - Sets the event activity in every stage.
760: Not Collective
762: Input Parameters:
763: + event - The event id
764: - isActive - The activity flag determining whether the event is logged
766: Level: advanced
768: .keywords: log, event, activate
769: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
770: @*/
771: PetscErrorCode PETSC_DLLEXPORT PetscLogEventSetActiveAll(PetscEvent event, PetscTruth isActive)
772: {
773: StageLog stageLog;
774: int stage;
778: PetscLogGetStageLog(&stageLog);
779: for(stage = 0; stage < stageLog->numStages; stage++) {
780: if (isActive) {
781: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
782: } else {
783: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
784: }
785: }
786: return(0);
787: }
791: /*@
792: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
794: Not Collective
796: Input Parameter:
797: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
799: Level: developer
801: .keywords: log, event, activate, class
802: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
803: @*/
804: PetscErrorCode PETSC_DLLEXPORT PetscLogEventActivateClass(PetscCookie cookie)
805: {
806: StageLog stageLog;
807: int stage;
811: PetscLogGetStageLog(&stageLog);
812: StageLogGetCurrent(stageLog, &stage);
813: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
814: return(0);
815: }
819: /*@
820: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
822: Not Collective
824: Input Parameter:
825: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
827: Level: developer
829: .keywords: log, event, deactivate, class
830: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
831: @*/
832: PetscErrorCode PETSC_DLLEXPORT PetscLogEventDeactivateClass(PetscCookie cookie)
833: {
834: StageLog stageLog;
835: int stage;
839: PetscLogGetStageLog(&stageLog);
840: StageLogGetCurrent(stageLog, &stage);
841: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
842: return(0);
843: }
845: /*MC
846: PetscLogEventBegin - Logs the beginning of a user event.
848: Input Parameters:
849: + e - integer associated with the event obtained from PetscLogEventRegister()
850: - o1,o2,o3,o4 - objects associated with the event, or 0
852: Synopsis:
853: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
854: PetscObject o4)
856: Fortran Synopsis:
857: void PetscLogEventEnd(int e,PetscErrorCode ierr)
859: Usage:
860: .vb
861: int USER_EVENT;
862: int user_event_flops;
863: PetscLogEventRegister(&USER_EVENT,"User event");
864: PetscLogEventBegin(USER_EVENT,0,0,0,0);
865: [code segment to monitor]
866: PetscLogFlops(user_event_flops);
867: PetscLogEventEnd(USER_EVENT,0,0,0,0);
868: .ve
870: Notes:
871: You need to register each integer event with the command
872: PetscLogEventRegister(). The source code must be compiled with
873: -DPETSC_USE_LOG, which is the default.
875: PETSc automatically logs library events if the code has been
876: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
877: specified. PetscLogEventBegin() is intended for logging user events
878: to supplement this PETSc information.
880: Level: intermediate
882: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
884: .keywords: log, event, begin
885: M*/
887: /*MC
888: PetscLogEventEnd - Log the end of a user event.
890: Input Parameters:
891: + e - integer associated with the event obtained with PetscLogEventRegister()
892: - o1,o2,o3,o4 - objects associated with the event, or 0
894: Synopsis:
895: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
896: PetscObject o4)
898: Fortran Synopsis:
899: void PetscLogEventEnd(int e,PetscErrorCode ierr)
901: Usage:
902: .vb
903: int USER_EVENT;
904: int user_event_flops;
905: PetscLogEventRegister(&USER_EVENT,"User event");
906: PetscLogEventBegin(USER_EVENT,0,0,0,0);
907: [code segment to monitor]
908: PetscLogFlops(user_event_flops);
909: PetscLogEventEnd(USER_EVENT,0,0,0,0);
910: .ve
912: Notes:
913: You should also register each additional integer event with the command
914: PetscLogEventRegister(). Source code must be compiled with
915: -DPETSC_USE_LOG, which is the default.
917: PETSc automatically logs library events if the code has been
918: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
919: specified. PetscLogEventEnd() is intended for logging user events
920: to supplement this PETSc information.
922: Level: intermediate
924: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
926: .keywords: log, event, end
927: M*/
929: /*MC
930: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
932: Input Parameters:
933: . e - integer associated with the event obtained from PetscLogEventRegister()
934: . o1,o2,o3,o4 - objects associated with the event, or 0
935: . comm - communicator the barrier takes place over
937: Synopsis:
938: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
939: PetscObject o4,MPI_Comm comm)
941: Usage:
942: .vb
943: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
944: MPI_Allreduce()
945: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
946: .ve
948: Notes:
949: This is for logging the amount of time spent in a barrier for an event
950: that requires synchronization.
952: Additional Notes:
953: Synchronization events always come in pairs; for example, VEC_NormBarrier and
954: VEC_NormComm = VEC_NormBarrier + 1
956: Level: advanced
958: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
959: PetscLogEventBarrierEnd()
961: .keywords: log, event, begin, barrier
962: M*/
964: /*MC
965: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
967: Input Parameters:
968: . e - integer associated with the event obtained from PetscLogEventRegister()
969: . o1,o2,o3,o4 - objects associated with the event, or 0
970: . comm - communicator the barrier takes place over
972: Synopsis:
973: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
974: PetscObject o4,MPI_Comm comm)
976: Usage:
977: .vb
978: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
979: MPI_Allreduce()
980: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
981: .ve
983: Notes:
984: This is for logging the amount of time spent in a barrier for an event
985: that requires synchronization.
987: Additional Notes:
988: Synchronization events always come in pairs; for example, VEC_NormBarrier and
989: VEC_NormComm = VEC_NormBarrier + 1
991: Level: advanced
993: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
994: PetscLogEventBarrierBegin()
996: .keywords: log, event, begin, barrier
997: M*/
999: /*------------------------------------------------ Class Functions --------------------------------------------------*/
1002: /*@C
1003: PetscLogClassRegister - Registers a class name for logging operations in an application code.
1005: Not Collective
1007: Input Parameter:
1008: . name - The class name
1009:
1010: Output Parameter:
1011: . oclass - The class id or cookie
1013: Level: developer
1015: .keywords: log, class, register
1016: .seealso: ClassLogRegister()
1017: @*/
1018: PetscErrorCode PETSC_DLLEXPORT PetscLogClassRegister(PetscCookie *oclass, const char name[])
1019: {
1020: StageLog stageLog;
1021: int stage;
1025: *oclass = PETSC_DECIDE;
1026: PetscLogGetStageLog(&stageLog);
1027: ClassRegLogRegister(stageLog->classLog, name, oclass);
1028: for(stage = 0; stage < stageLog->numStages; stage++) {
1029: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
1030: }
1031: return(0);
1032: }
1034: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1037: /*@C
1038: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1039: be read by petsc/bin/petscview.
1041: Collective on PETSC_COMM_WORLD
1043: Input Parameter:
1044: . name - an optional file name
1046: Options Database Keys:
1047: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1048: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1049:
1050: Usage:
1051: .vb
1052: PetscInitialize(...);
1053: PetscLogBegin(); or PetscLogAllBegin();
1054: ... code ...
1055: PetscLogDump(filename);
1056: PetscFinalize();
1057: .ve
1059: Notes:
1060: The default file name is
1061: $ Log.<rank>
1062: where <rank> is the processor number. If no name is specified,
1063: this file will be used.
1065: Level: advanced
1067: .keywords: log, dump
1068: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1069: @*/
1070: PetscErrorCode PETSC_DLLEXPORT PetscLogDump(const char sname[])
1071: {
1072: StageLog stageLog;
1073: EventPerfInfo *eventInfo;
1074: FILE *fd;
1075: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1076: PetscLogDouble flops, _TotalTime;
1077: PetscMPIInt rank;
1078: int action, object, curStage;
1079: PetscEvent event;
1081:
1083: /* Calculate the total elapsed time */
1084: PetscTime(_TotalTime);
1085: _TotalTime -= BaseTime;
1086: /* Open log file */
1087: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1088: if (sname) {
1089: sprintf(file, "%s.%d", sname, rank);
1090: } else {
1091: sprintf(file, "Log.%d", rank);
1092: }
1093: PetscFixFilename(file, fname);
1094: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1095: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1096: /* Output totals */
1097: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1098: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1099: /* Output actions */
1100: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1101: for(action = 0; action < numActions; action++) {
1102: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1103: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1104: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1105: }
1106: /* Output objects */
1107: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1108: for(object = 0; object < numObjects; object++) {
1109: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1110: if (!objects[object].name[0]) {
1111: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1112: } else {
1113: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1114: }
1115: if (objects[object].info[0] != 0) {
1116: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1117: } else {
1118: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
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.
1164: More extensive examination of the log information can be done with
1165: PetscLogDump(), which is activated by the option -log or -log_all, in
1166: combination with petsc/bin/petscview.
1168: Level: beginner
1169:
1170: .keywords: log, dump, print
1171: .seealso: PetscLogBegin(), PetscLogDump()
1172: @*/
1173: PetscErrorCode PETSC_DLLEXPORT PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1174: {
1175: FILE *fd = stdout;
1176: PetscScalar zero = 0.0;
1177: StageLog stageLog;
1178: StageInfo *stageInfo = PETSC_NULL;
1179: EventPerfInfo *eventInfo = PETSC_NULL;
1180: ClassPerfInfo *classInfo;
1181: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1182: const char *name;
1183: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1184: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1185: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1186: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1187: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1188: PetscLogDouble min, max, tot, ratio, avg, x, y;
1189: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1190: int minCt, maxCt;
1191: PetscMPIInt size, rank;
1192: PetscTruth *localStageUsed, *stageUsed;
1193: PetscTruth *localStageVisible, *stageVisible;
1194: int numStages, localNumEvents, numEvents;
1195: int stage, oclass;
1196: PetscEvent event;
1198: char version[256];
1201: MPI_Comm_size(comm, &size);
1202: MPI_Comm_rank(comm, &rank);
1203: /* Pop off any stages the user forgot to remove */
1204: PetscLogGetStageLog(&stageLog);
1205: StageLogGetCurrent(stageLog, &stage);
1206: while (stage >= 0) {
1207: StageLogPop(stageLog);
1208: StageLogGetCurrent(stageLog, &stage);
1209: }
1210: /* Get the total elapsed time */
1211: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1212: /* Open the summary file */
1213: if (filename) {
1214: PetscFOpen(comm, filename, "w", &fd);
1215: }
1217: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1218: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1219: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1220: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1221: PetscGetArchType(arch, 10);
1222: PetscGetHostName(hostname, 64);
1223: PetscGetUserName(username, 16);
1224: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1225: PetscGetDate(date, 64);
1226: PetscGetVersion(&version);
1227: if (size == 1) {
1228: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1229:
1230: } else {
1231: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1232:
1233: }
1234: PetscFPrintf(comm, fd, "Using %s\n", version);
1236: /* Must preserve reduction count before we go on */
1237: red = allreduce_ct/((PetscLogDouble) size);
1239: /* Calculate summary information */
1240: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1241: /* Time */
1242: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1243: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1244: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1245: avg = (tot)/((PetscLogDouble) size);
1246: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1247: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1248: TotalTime = tot;
1249: /* Objects */
1250: avg = (PetscLogDouble) numObjects;
1251: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1252: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1253: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1254: avg = (tot)/((PetscLogDouble) size);
1255: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1256: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1257: /* Flops */
1258: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1259: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1260: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1261: avg = (tot)/((PetscLogDouble) size);
1262: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1263: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1264: TotalFlops = tot;
1265: /* Flops/sec -- Must talk to Barry here */
1266: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1267: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1268: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1269: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1270: avg = (tot)/((PetscLogDouble) size);
1271: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1272: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1273: /* Memory */
1274: PetscMallocGetMaximumUsage(&mem);
1275: if (mem > 0.0) {
1276: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1277: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1278: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1279: avg = (tot)/((PetscLogDouble) size);
1280: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1281: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1282: }
1283: /* Messages */
1284: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1285: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1286: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1287: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1288: avg = (tot)/((PetscLogDouble) size);
1289: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1290: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1291: numMessages = tot;
1292: /* Message Lengths */
1293: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1294: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1295: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1296: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1297: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1298: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1299: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1300: messageLength = tot;
1301: /* Reductions */
1302: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1303: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1304: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1305: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1306: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1307: numReductions = tot;
1308: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1309: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1310: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1312: /* Get total number of stages --
1313: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1314: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1315: This seems best accomplished by assoicating a communicator with each stage.
1316: */
1317: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1318: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1319: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1320: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1321: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1322: if (numStages > 0) {
1323: stageInfo = stageLog->stageInfo;
1324: for(stage = 0; stage < numStages; stage++) {
1325: if (stage < stageLog->numStages) {
1326: localStageUsed[stage] = stageInfo[stage].used;
1327: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1328: } else {
1329: localStageUsed[stage] = PETSC_FALSE;
1330: localStageVisible[stage] = PETSC_TRUE;
1331: }
1332: }
1333: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1334: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1335: for(stage = 0; stage < numStages; stage++) {
1336: if (stageUsed[stage]) {
1337: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1338: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1339: break;
1340: }
1341: }
1342: for(stage = 0; stage < numStages; stage++) {
1343: if (!stageUsed[stage]) continue;
1344: if (localStageUsed[stage]) {
1345: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1346: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1348: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1349: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1350: name = stageInfo[stage].name;
1351: } else {
1352: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1353: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1354: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1355: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1356: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1357: name = "";
1358: }
1359: mess *= 0.5; messLen *= 0.5; red /= size;
1360: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1361: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1362: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1363: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1364: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1365: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1366: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1367: 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",
1368: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1369: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1370:
1371: }
1372: }
1374: PetscFPrintf(comm, fd,
1375: "\n------------------------------------------------------------------------------------------------------------------------\n");
1376:
1377: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1378: PetscFPrintf(comm, fd, "Phase summary info:\n");
1379: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1380: PetscFPrintf(comm, fd, " Time and Flops/sec: Max - maximum over all processors\n");
1381: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1382: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1383: PetscFPrintf(comm, fd, " Avg. len: average message length\n");
1384: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1385: PetscFPrintf(comm, fd, " Global: entire computation\n");
1386: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1387: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1388: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1389: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1390: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1391: PetscFPrintf(comm, fd,
1392: "------------------------------------------------------------------------------------------------------------------------\n");
1393:
1395: #if defined(PETSC_USE_DEBUG)
1396: PetscFPrintf(comm, fd, "\n\n");
1397: PetscFPrintf(comm, fd, " ##########################################################\n");
1398: PetscFPrintf(comm, fd, " # #\n");
1399: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1400: PetscFPrintf(comm, fd, " # #\n");
1401: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1402: PetscFPrintf(comm, fd, " # To get timing results run config/configure.py #\n");
1403: PetscFPrintf(comm, fd, " # without --with-debugging=no, the performance will #\n");
1404: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1405: PetscFPrintf(comm, fd, " # #\n");
1406: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1407: #endif
1408: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1409: PetscFPrintf(comm, fd, "\n\n");
1410: PetscFPrintf(comm, fd, " ##########################################################\n");
1411: PetscFPrintf(comm, fd, " # #\n");
1412: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1413: PetscFPrintf(comm, fd, " # #\n");
1414: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1415: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1416: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1417: PetscFPrintf(comm, fd, " # faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #\n");
1418: PetscFPrintf(comm, fd, " # in base_variables and recompile the PETSc libraries. #\n");
1419: PetscFPrintf(comm, fd, " # #\n");
1420: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1421: #endif
1423: if (!PetscPreLoadingUsed) {
1424: PetscFPrintf(comm,fd,"\n\n");
1425: PetscFPrintf(comm,fd," ##########################################################\n");
1426: PetscFPrintf(comm,fd," # #\n");
1427: PetscFPrintf(comm,fd," # WARNING!!! #\n");
1428: PetscFPrintf(comm,fd," # #\n");
1429: PetscFPrintf(comm,fd," # This code was run without the PreLoadBegin() #\n");
1430: PetscFPrintf(comm,fd," # macros. To get timing results we always recommend #\n");
1431: PetscFPrintf(comm,fd," # preloading. otherwise timing numbers may be #\n");
1432: PetscFPrintf(comm,fd," # meaningless. #\n");
1433: PetscFPrintf(comm,fd," ##########################################################\n\n\n");
1434: }
1436: /* Report events */
1437: PetscFPrintf(comm, fd,
1438: "Event Count Time (sec) Flops/sec --- Global --- --- Stage --- Total\n");
1439:
1440: PetscFPrintf(comm, fd,
1441: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1442:
1443: PetscFPrintf(comm,fd,
1444: "------------------------------------------------------------------------------------------------------------------------\n");
1446:
1447: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1448: for(stage = 0; stage < numStages; stage++) {
1449: if (!stageVisible[stage]) continue;
1450: if (localStageUsed[stage]) {
1451: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1452: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1453: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1454: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1455: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1456: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1457: } else {
1458: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1459: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1460: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1461: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1462: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1463: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1464: }
1465: mess *= 0.5; messLen *= 0.5; red /= size;
1467: /* Get total number of events in this stage --
1468: Currently, a single processor can register more events than another, but events must all be registered in order,
1469: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1470: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1472: Problem: If the event did not happen on proc 1, its name will not be available.
1473: Problem: Event visibility is not implemented
1474: */
1475: if (localStageUsed[stage]) {
1476: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1477: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1478: } else {
1479: localNumEvents = 0;
1480: }
1481: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1482: for(event = 0; event < numEvents; event++) {
1483: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1484: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1485: flopr = eventInfo[event].flops/eventInfo[event].time;
1486: } else {
1487: flopr = 0.0;
1488: }
1489: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1490: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1491: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1492: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1493: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1494: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1495: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1496: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1497: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1498: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1499: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1500: name = stageLog->eventLog->eventInfo[event].name;
1501: } else {
1502: flopr = 0.0;
1503: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1504: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1505: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1506: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1507: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1508: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1509: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1510: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1511: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1512: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1513: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1514: name = "";
1515: }
1516: totm *= 0.5; totml *= 0.5; totr /= size;
1517:
1518: if (maxCt != 0) {
1519: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1520: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1521: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1522: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1523: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1524: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1525: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1526: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1527: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1528: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1529: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1530: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1531: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1532: if (totm != 0.0) totml /= totm; else totml = 0.0;
1533: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1534: PetscFPrintf(comm, fd,
1535: "%-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",
1536: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1537: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1538: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1539: flopr/1.0e6);
1540:
1541: }
1542: }
1543: }
1545: /* Memory usage and object creation */
1546: PetscFPrintf(comm, fd,
1547: "------------------------------------------------------------------------------------------------------------------------\n");
1548:
1549: PetscFPrintf(comm, fd, "\n");
1550: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1552: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1553: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1554: stats for stages local to processor sets.
1555: */
1556: /* We should figure out the longest object name here (now 20 characters) */
1557: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1558: for(stage = 0; stage < numStages; stage++) {
1559: if (localStageUsed[stage]) {
1560: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1561: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1562: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1563: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1564: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %g\n", stageLog->classLog->classInfo[oclass].name,
1565: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1566: classInfo[oclass].descMem);
1567:
1568: }
1569: }
1570: } else {
1571: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1572: }
1573: }
1575: PetscFree(localStageUsed);
1576: PetscFree(stageUsed);
1577: PetscFree(localStageVisible);
1578: PetscFree(stageVisible);
1580: /* Information unrelated to this particular run */
1581: PetscFPrintf(comm, fd,
1582: "========================================================================================================================\n");
1583:
1584: PetscTime(y);
1585: PetscTime(x);
1586: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1587: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1588: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1589: /* MPI information */
1590: if (size > 1) {
1591: MPI_Status status;
1592: PetscMPIInt tag;
1593: MPI_Comm newcomm;
1595: MPI_Barrier(comm);
1596: PetscTime(x);
1597: MPI_Barrier(comm);
1598: MPI_Barrier(comm);
1599: MPI_Barrier(comm);
1600: MPI_Barrier(comm);
1601: MPI_Barrier(comm);
1602: PetscTime(y);
1603: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1604: PetscCommDuplicate(comm,&newcomm, &tag);
1605: MPI_Barrier(comm);
1606: if (rank) {
1607: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1608: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1609: } else {
1610: PetscTime(x);
1611: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1612: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1613: PetscTime(y);
1614: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1615: }
1616: PetscCommDestroy(&newcomm);
1617: }
1618: /* Machine and compile information */
1619: #if defined(PETSC_USE_FORTRAN_KERNELS)
1620: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1621: #else
1622: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1623: #endif
1624: #if defined(PETSC_USE_MAT_SINGLE)
1625: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1626: #else
1627: PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)\n");
1628: #endif
1629: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d\n",
1630: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1632: PetscFPrintf(comm, fd, "Configure run at: %s\n",PETSC_CONFIGURE_RUN_TIME);
1633: PetscFPrintf(comm, fd, "Configure options: %s",PETSC_CONFIGURE_OPTIONS);
1634: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1635: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1636: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1637: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1639: /* Cleanup */
1640: PetscFPrintf(comm, fd, "\n");
1641: PetscFClose(comm, fd);
1642: return(0);
1643: }
1645: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1648: /*@C
1649: PetscGetFlops - Returns the number of flops used on this processor
1650: since the program began.
1652: Not Collective
1654: Output Parameter:
1655: flops - number of floating point operations
1657: Notes:
1658: A global counter logs all PETSc flop counts. The user can use
1659: PetscLogFlops() to increment this counter to include flops for the
1660: application code.
1662: PETSc automatically logs library events if the code has been
1663: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1664: -log_summary, or -log_all are specified. PetscLogFlops() is
1665: intended for logging user flops to supplement this PETSc
1666: information.
1668: Level: intermediate
1670: .keywords: log, flops, floating point operations
1672: .seealso: PetscGetTime(), PetscLogFlops()
1673: @*/
1674: PetscErrorCode PETSC_DLLEXPORT PetscGetFlops(PetscLogDouble *flops)
1675: {
1677: *flops = _TotalFlops;
1678: return(0);
1679: }
1683: PetscErrorCode PETSC_DLLEXPORT PetscLogObjectState(PetscObject obj, const char format[], ...)
1684: {
1686: va_list Argp;
1689: if (!logObjects) return(0);
1690: va_start(Argp, format);
1691: PetscVSNPrintf(objects[obj->id].info, 64,format, Argp);
1692: va_end(Argp);
1693: return(0);
1694: }
1696: #else /* end of -DPETSC_USE_LOG section */
1700: PetscErrorCode PETSC_DLLEXPORT PetscLogObjectState(PetscObject obj, const char format[], ...)
1701: {
1703: return(0);
1704: }
1706: #endif /* PETSC_USE_LOG*/
1710: /*@
1711: PetscGetTime - Returns the current time of day in seconds. This
1712: returns wall-clock time.
1714: Not Collective
1716: Output Parameter:
1717: . v - time counter
1719: Usage:
1720: .vb
1721: PetscLogDouble v1,v2,elapsed_time;
1722: PetscGetTime(&v1);CHKERR(ierr);
1723: .... perform some calculation ...
1724: PetscGetTime(&v2);CHKERR(ierr);
1725: elapsed_time = v2 - v1;
1726: .ve
1728: Notes:
1729: Since the PETSc libraries incorporate timing of phases and operations,
1730: PetscGetTime() is intended only for timing of application codes.
1731: The options database commands -log, -log_summary, and -log_all activate
1732: PETSc library timing. See the users manual for further details.
1734: Level: intermediate
1736: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStagePush(),
1737: PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()
1739: .keywords: get, time
1740: @*/
1741: PetscErrorCode PETSC_DLLEXPORT PetscGetTime(PetscLogDouble *t)
1742: {
1744: PetscTime(*t);
1745: return(0);
1746: }
1750: /*@
1751: PetscLogGetStageLog - This function returns the default stage logging object.
1753: Not collective
1755: Output Parameter:
1756: . stageLog - The default StageLog
1758: Level: beginner
1760: .keywords: log, stage
1761: .seealso: StageLogCreate()
1762: @*/
1763: PetscErrorCode PETSC_DLLEXPORT PetscLogGetStageLog(StageLog *stageLog)
1764: {
1767: *stageLog = _stageLog;
1768: return(0);
1769: }
1771: /*MC
1772: PetscLogFlops - Adds floating point operations to the global counter.
1774: Input Parameter:
1775: . f - flop counter
1777: Synopsis:
1778: void PetscLogFlops(int f)
1780: Usage:
1781: .vb
1782: int USER_EVENT;
1783: PetscLogEventRegister(&USER_EVENT,"User event");
1784: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1785: [code segment to monitor]
1786: PetscLogFlops(user_flops)
1787: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1788: .ve
1790: Notes:
1791: A global counter logs all PETSc flop counts. The user can use
1792: PetscLogFlops() to increment this counter to include flops for the
1793: application code.
1795: PETSc automatically logs library events if the code has been
1796: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1797: -log_summary, or -log_all are specified. PetscLogFlops() is
1798: intended for logging user flops to supplement this PETSc
1799: information.
1801: Level: intermediate
1803: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1805: .keywords: log, flops, floating point operations
1806: M*/
1808: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1809: PetscTruth PetscPreLoadingOn = PETSC_FALSE;
1811: /*MC
1812: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1813: to get accurate timings
1815: Input Parameter:
1816: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1817: with command line option -preload true or -preload false
1818: - name - name of first stage (lines of code timed seperately with -log_summary) to
1819: be preloaded
1821: Synopsis:
1822: void PreLoadBegin(PetscTruth flag,char *name);
1824: Usage:
1825: .vb
1826: PreLoadBegin(PETSC_TRUE,"first stage);
1827: lines of code
1828: PreLoadStage("second stage");
1829: lines of code
1830: PreLoadEnd();
1831: .ve
1833: Notes: Only works in C/C++, not Fortran
1835: Flags available within the macro.
1836: + PetscPreLoadingUsed - true if we are or have done preloading
1837: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1838: . PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1839: - PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1840: The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1841: and PreLoadEnd()
1843: Level: intermediate
1845: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1847: Concepts: preloading
1848: Concepts: timing^accurate
1849: Concepts: paging^eliminating effects of
1852: M*/
1854: /*MC
1855: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1856: to get accurate timings
1858: Synopsis:
1859: void PreLoadEnd(void);
1861: Usage:
1862: .vb
1863: PreLoadBegin(PETSC_TRUE,"first stage);
1864: lines of code
1865: PreLoadStage("second stage");
1866: lines of code
1867: PreLoadEnd();
1868: .ve
1870: Notes: only works in C/C++ not fortran
1872: Level: intermediate
1874: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1876: M*/
1878: /*MC
1879: PreLoadStage - Start a new segment of code to be timed seperately.
1880: to get accurate timings
1882: Synopsis:
1883: void PreLoadStage(char *name);
1885: Usage:
1886: .vb
1887: PreLoadBegin(PETSC_TRUE,"first stage);
1888: lines of code
1889: PreLoadStage("second stage");
1890: lines of code
1891: PreLoadEnd();
1892: .ve
1894: Notes: only works in C/C++ not fortran
1896: Level: intermediate
1898: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1900: M*/
1902: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1905: /*@C
1906: StackDestroy - This function destroys a stack.
1908: Not Collective
1910: Input Parameter:
1911: . stack - The stack
1913: Level: beginner
1915: .keywords: log, stack, destroy
1916: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1917: @*/
1918: PetscErrorCode StackDestroy(IntStack stack)
1919: {
1923: PetscFree(stack->stack);
1924: PetscFree(stack);
1925: return(0);
1926: }
1930: /*@C
1931: StackEmpty - This function determines whether any items have been pushed.
1933: Not Collective
1935: Input Parameter:
1936: . stack - The stack
1938: Output Parameter:
1939: . empty - PETSC_TRUE if the stack is empty
1941: Level: intermediate
1943: .keywords: log, stack, empty
1944: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1945: @*/
1946: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
1947: {
1950: if (stack->top == -1) {
1951: *empty = PETSC_TRUE;
1952: } else {
1953: *empty = PETSC_FALSE;
1954: }
1955: return(0);
1956: }
1960: /*@C
1961: StackTop - This function returns the top of the stack.
1963: Not Collective
1965: Input Parameter:
1966: . stack - The stack
1968: Output Parameter:
1969: . top - The integer on top of the stack
1971: Level: intermediate
1973: .keywords: log, stack, top
1974: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1975: @*/
1976: PetscErrorCode StackTop(IntStack stack, int *top)
1977: {
1980: *top = stack->stack[stack->top];
1981: return(0);
1982: }
1986: /*@C
1987: StackPush - This function pushes an integer on the stack.
1989: Not Collective
1991: Input Parameters:
1992: + stack - The stack
1993: - item - The integer to push
1995: Level: intermediate
1997: .keywords: log, stack, push
1998: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1999: @*/
2000: PetscErrorCode StackPush(IntStack stack, int item)
2001: {
2002: int *array;
2006: stack->top++;
2007: if (stack->top >= stack->max) {
2008: PetscMalloc(stack->max*2 * sizeof(int), &array);
2009: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
2010: PetscFree(stack->stack);
2011: stack->stack = array;
2012: stack->max *= 2;
2013: }
2014: stack->stack[stack->top] = item;
2015: return(0);
2016: }
2020: /*@C
2021: StackPop - This function pops an integer from the stack.
2023: Not Collective
2025: Input Parameter:
2026: . stack - The stack
2028: Output Parameter:
2029: . item - The integer popped
2031: Level: intermediate
2033: .keywords: log, stack, pop
2034: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
2035: @*/
2036: PetscErrorCode StackPop(IntStack stack, int *item)
2037: {
2040: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
2041: *item = stack->stack[stack->top--];
2042: return(0);
2043: }
2047: /*@C
2048: StackCreate - This function creates a stack.
2050: Not Collective
2052: Output Parameter:
2053: . stack - The stack
2055: Level: beginner
2057: .keywords: log, stack, pop
2058: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2059: @*/
2060: PetscErrorCode StackCreate(IntStack *stack)
2061: {
2062: IntStack s;
2067: PetscNew(struct _IntStack, &s);
2068: s->top = -1;
2069: s->max = 128;
2070: PetscMalloc(s->max * sizeof(int), &s->stack);
2071: PetscMemzero(s->stack, s->max * sizeof(int));
2072: *stack = s;
2073: return(0);
2074: }