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: #include "petscmachineinfo.h"
8: #include "petscconfiginfo.h"
9: #if defined(PETSC_HAVE_MPE)
10: #include "mpe.h"
11: #endif
12: #include <stdarg.h>
13: #include <sys/types.h>
14: #include petscsys.h
15: #if defined(PETSC_HAVE_STDLIB_H)
16: #include <stdlib.h>
17: #endif
18: #if defined(PETSC_HAVE_MALLOC_H)
19: #include <malloc.h>
20: #endif
21: #include "petscfix.h"
22: #include plog.h
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: 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT PetscLogBegin(void)
206: {
210: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
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 PETSC_DLLEXPORT PetscLogAllBegin(void)
246: {
250: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
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 PETSC_DLLEXPORT PetscLogTraceBegin(FILE *file)
282: {
286: tracefile = file;
287: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT PetscLogStagePop(void)
461: {
462: StageLog stageLog;
466: PetscLogGetStageLog(&stageLog);
467: StageLogPop(stageLog);
468: return(0);
469: }
473: /*@
474: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
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
484: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
485: @*/
486: PetscErrorCode PETSC_DLLEXPORT PetscLogStageSetActive(int stage, PetscTruth isActive)
487: {
488: StageLog stageLog;
492: PetscLogGetStageLog(&stageLog);
493: StageLogSetActive(stageLog, stage, isActive);
494: return(0);
495: }
499: /*@
500: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
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
512: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
513: @*/
514: PetscErrorCode PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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
611: PetscLogEventRegister - Registers an event name for logging operations in an application code.
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
618:
619: Output Parameter:
620: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
622: Example of Usage:
623: .vb
624: int USER_EVENT;
625: int user_event_flops;
626: PetscLogEventRegister(&USER_EVENT,"User event name");
627: PetscLogEventBegin(USER_EVENT,0,0,0,0);
628: [code segment to monitor]
629: PetscLogFlops(user_event_flops);
630: PetscLogEventEnd(USER_EVENT,0,0,0,0);
631: .ve
633: Notes:
634: PETSc automatically logs library events if the code has been
635: compiled with -DPETSC_USE_LOG (which is the default) and -log,
636: -log_summary, or -log_all are specified. PetscLogEventRegister() is
637: intended for logging user events to supplement this PETSc
638: information.
640: PETSc can gather data for use with the utilities Upshot/Nupshot
641: (part of the MPICH distribution). If PETSc has been compiled
642: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
643: MPICH), the user can employ another command line option, -log_mpe,
644: to create a logfile, "mpe.log", which can be visualized
645: Upshot/Nupshot.
647: Level: intermediate
649: .keywords: log, event, register
650: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
651: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
652: PetscLogEventActivate(), PetscLogEventDeactivate()
653: @*/
654: PetscErrorCode PETSC_DLLEXPORT PetscLogEventRegister(PetscEvent *event, const char name[],PetscCookie cookie)
655: {
656: StageLog stageLog;
657: int stage;
661: *event = PETSC_DECIDE;
662: PetscLogGetStageLog(&stageLog);
663: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
664: for(stage = 0; stage < stageLog->numStages; stage++) {
665: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
666: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
667: }
668: return(0);
669: }
673: /*@
674: PetscLogEventActivate - Indicates that a particular event should be logged.
676: Not Collective
678: Input Parameter:
679: . event - The event id
681: Usage:
682: .vb
683: PetscLogEventDeactivate(VEC_SetValues);
684: [code where you do not want to log VecSetValues()]
685: PetscLogEventActivate(VEC_SetValues);
686: [code where you do want to log VecSetValues()]
687: .ve
689: Note:
690: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
691: or an event number obtained with PetscLogEventRegister().
693: Level: advanced
695: .keywords: log, event, activate
696: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
697: @*/
698: PetscErrorCode PETSC_DLLEXPORT PetscLogEventActivate(PetscEvent event)
699: {
700: StageLog stageLog;
701: int stage;
705: PetscLogGetStageLog(&stageLog);
706: StageLogGetCurrent(stageLog, &stage);
707: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
708: return(0);
709: }
713: /*@
714: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
716: Not Collective
718: Input Parameter:
719: . event - The event id
721: Usage:
722: .vb
723: PetscLogEventDeactivate(VEC_SetValues);
724: [code where you do not want to log VecSetValues()]
725: PetscLogEventActivate(VEC_SetValues);
726: [code where you do want to log VecSetValues()]
727: .ve
729: Note:
730: The event may be either a pre-defined PETSc event (found in
731: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
733: Level: advanced
735: .keywords: log, event, deactivate
736: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
737: @*/
738: PetscErrorCode PETSC_DLLEXPORT PetscLogEventDeactivate(PetscEvent event)
739: {
740: StageLog stageLog;
741: int stage;
745: PetscLogGetStageLog(&stageLog);
746: StageLogGetCurrent(stageLog, &stage);
747: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
748: return(0);
749: }
753: /*@
754: PetscLogEventSetActiveAll - Sets the event activity in every stage.
756: Not Collective
758: Input Parameters:
759: + event - The event id
760: - isActive - The activity flag determining whether the event is logged
762: Level: advanced
764: .keywords: log, event, activate
765: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
766: @*/
767: PetscErrorCode PETSC_DLLEXPORT PetscLogEventSetActiveAll(PetscEvent event, PetscTruth isActive)
768: {
769: StageLog stageLog;
770: int stage;
774: PetscLogGetStageLog(&stageLog);
775: for(stage = 0; stage < stageLog->numStages; stage++) {
776: if (isActive) {
777: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
778: } else {
779: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
780: }
781: }
782: return(0);
783: }
787: /*@
788: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
790: Not Collective
792: Input Parameter:
793: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
795: Level: developer
797: .keywords: log, event, activate, class
798: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
799: @*/
800: PetscErrorCode PETSC_DLLEXPORT PetscLogEventActivateClass(PetscCookie cookie)
801: {
802: StageLog stageLog;
803: int stage;
807: PetscLogGetStageLog(&stageLog);
808: StageLogGetCurrent(stageLog, &stage);
809: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
810: return(0);
811: }
815: /*@
816: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
818: Not Collective
820: Input Parameter:
821: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
823: Level: developer
825: .keywords: log, event, deactivate, class
826: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
827: @*/
828: PetscErrorCode PETSC_DLLEXPORT PetscLogEventDeactivateClass(PetscCookie cookie)
829: {
830: StageLog stageLog;
831: int stage;
835: PetscLogGetStageLog(&stageLog);
836: StageLogGetCurrent(stageLog, &stage);
837: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
838: return(0);
839: }
841: /*MC
842: PetscLogEventBegin - Logs the beginning of a user event.
844: Input Parameters:
845: + e - integer associated with the event obtained from PetscLogEventRegister()
846: - o1,o2,o3,o4 - objects associated with the event, or 0
848: Synopsis:
849: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
850: PetscObject o4)
852: Fortran Synopsis:
853: void PetscLogEventEnd(int e,PetscErrorCode ierr)
855: Usage:
856: .vb
857: int USER_EVENT;
858: int user_event_flops;
859: PetscLogEventRegister(&USER_EVENT,"User event");
860: PetscLogEventBegin(USER_EVENT,0,0,0,0);
861: [code segment to monitor]
862: PetscLogFlops(user_event_flops);
863: PetscLogEventEnd(USER_EVENT,0,0,0,0);
864: .ve
866: Notes:
867: You need to register each integer event with the command
868: PetscLogEventRegister(). The source code must be compiled with
869: -DPETSC_USE_LOG, which is the default.
871: PETSc automatically logs library events if the code has been
872: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
873: specified. PetscLogEventBegin() is intended for logging user events
874: to supplement this PETSc information.
876: Level: intermediate
878: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
880: .keywords: log, event, begin
881: M*/
883: /*MC
884: PetscLogEventEnd - Log the end of a user event.
886: Input Parameters:
887: + e - integer associated with the event obtained with PetscLogEventRegister()
888: - o1,o2,o3,o4 - objects associated with the event, or 0
890: Synopsis:
891: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
892: PetscObject o4)
894: Fortran Synopsis:
895: void PetscLogEventEnd(int e,PetscErrorCode ierr)
897: Usage:
898: .vb
899: int USER_EVENT;
900: int user_event_flops;
901: PetscLogEventRegister(&USER_EVENT,"User event");
902: PetscLogEventBegin(USER_EVENT,0,0,0,0);
903: [code segment to monitor]
904: PetscLogFlops(user_event_flops);
905: PetscLogEventEnd(USER_EVENT,0,0,0,0);
906: .ve
908: Notes:
909: You should also register each additional integer event with the command
910: PetscLogEventRegister(). Source code must be compiled with
911: -DPETSC_USE_LOG, which is the default.
913: PETSc automatically logs library events if the code has been
914: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
915: specified. PetscLogEventEnd() is intended for logging user events
916: to supplement this PETSc information.
918: Level: intermediate
920: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
922: .keywords: log, event, end
923: M*/
925: /*MC
926: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
928: Input Parameters:
929: . e - integer associated with the event obtained from PetscLogEventRegister()
930: . o1,o2,o3,o4 - objects associated with the event, or 0
931: . comm - communicator the barrier takes place over
933: Synopsis:
934: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
935: PetscObject o4,MPI_Comm comm)
937: Usage:
938: .vb
939: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
940: MPI_Allreduce()
941: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
942: .ve
944: Notes:
945: This is for logging the amount of time spent in a barrier for an event
946: that requires synchronization.
948: Additional Notes:
949: Synchronization events always come in pairs; for example, VEC_NormBarrier and
950: VEC_NormComm = VEC_NormBarrier + 1
952: Level: advanced
954: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
955: PetscLogEventBarrierEnd()
957: .keywords: log, event, begin, barrier
958: M*/
960: /*MC
961: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
963: Input Parameters:
964: . e - integer associated with the event obtained from PetscLogEventRegister()
965: . o1,o2,o3,o4 - objects associated with the event, or 0
966: . comm - communicator the barrier takes place over
968: Synopsis:
969: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
970: PetscObject o4,MPI_Comm comm)
972: Usage:
973: .vb
974: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
975: MPI_Allreduce()
976: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
977: .ve
979: Notes:
980: This is for logging the amount of time spent in a barrier for an event
981: that requires synchronization.
983: Additional Notes:
984: Synchronization events always come in pairs; for example, VEC_NormBarrier and
985: VEC_NormComm = VEC_NormBarrier + 1
987: Level: advanced
989: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
990: PetscLogEventBarrierBegin()
992: .keywords: log, event, begin, barrier
993: M*/
995: /*------------------------------------------------ Class Functions --------------------------------------------------*/
998: /*@C
999: PetscLogClassRegister - Registers a class name for logging operations in an application code.
1001: Not Collective
1003: Input Parameter:
1004: . name - The class name
1005:
1006: Output Parameter:
1007: . oclass - The class id or cookie
1009: Level: developer
1011: .keywords: log, class, register
1012: .seealso: ClassLogRegister()
1013: @*/
1014: PetscErrorCode PETSC_DLLEXPORT PetscLogClassRegister(PetscCookie *oclass, const char name[])
1015: {
1016: StageLog stageLog;
1017: int stage;
1021: *oclass = PETSC_DECIDE;
1022: PetscLogGetStageLog(&stageLog);
1023: ClassRegLogRegister(stageLog->classLog, name, oclass);
1024: for(stage = 0; stage < stageLog->numStages; stage++) {
1025: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
1026: }
1027: return(0);
1028: }
1030: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1033: /*@C
1034: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1035: be read by petsc/bin/petscview.
1037: Collective on PETSC_COMM_WORLD
1039: Input Parameter:
1040: . name - an optional file name
1042: Options Database Keys:
1043: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
1044: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
1045:
1046: Usage:
1047: .vb
1048: PetscInitialize(...);
1049: PetscLogBegin(); or PetscLogAllBegin();
1050: ... code ...
1051: PetscLogDump(filename);
1052: PetscFinalize();
1053: .ve
1055: Notes:
1056: The default file name is
1057: $ Log.<rank>
1058: where <rank> is the processor number. If no name is specified,
1059: this file will be used.
1061: Level: advanced
1063: .keywords: log, dump
1064: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
1065: @*/
1066: PetscErrorCode PETSC_DLLEXPORT PetscLogDump(const char sname[])
1067: {
1068: StageLog stageLog;
1069: EventPerfInfo *eventInfo;
1070: FILE *fd;
1071: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1072: PetscLogDouble flops, _TotalTime;
1073: PetscMPIInt rank;
1074: int action, object, curStage;
1075: PetscEvent event;
1077:
1079: /* Calculate the total elapsed time */
1080: PetscTime(_TotalTime);
1081: _TotalTime -= BaseTime;
1082: /* Open log file */
1083: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1084: if (sname) {
1085: sprintf(file, "%s.%d", sname, rank);
1086: } else {
1087: sprintf(file, "Log.%d", rank);
1088: }
1089: PetscFixFilename(file, fname);
1090: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1091: if ((!rank) && (!fd)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1092: /* Output totals */
1093: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", _TotalFlops, _TotalTime);
1094: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1095: /* Output actions */
1096: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", numActions);
1097: for(action = 0; action < numActions; action++) {
1098: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1099: actions[action].time, actions[action].action, (int)actions[action].event, (int)actions[action].cookie, actions[action].id1,
1100: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1101: }
1102: /* Output objects */
1103: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", numObjects, numObjectsDestroyed);
1104: for(object = 0; object < numObjects; object++) {
1105: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", objects[object].parent, (int) objects[object].mem);
1106: if (!objects[object].name[0]) {
1107: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1108: } else {
1109: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", objects[object].name);
1110: }
1111: if (objects[object].info[0] != 0) {
1112: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1113: } else {
1114: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", objects[object].info);
1115: }
1116: }
1117: /* Output events */
1118: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1119: PetscLogGetStageLog(&stageLog);
1120: StackTop(stageLog->stack, &curStage);
1121: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1122: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1123: if (eventInfo[event].time != 0.0) {
1124: flops = eventInfo[event].flops/eventInfo[event].time;
1125: } else {
1126: flops = 0.0;
1127: }
1128: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1129: eventInfo[event].flops, eventInfo[event].time, flops);
1130: }
1131: PetscFClose(PETSC_COMM_WORLD, fd);
1132: return(0);
1133: }
1137: /*@C
1138: PetscLogPrintSummary - Prints a summary of the logging.
1140: Collective over MPI_Comm
1142: Input Parameter:
1143: + comm - The MPI communicator (only one processor prints output)
1144: - file - [Optional] The output file name
1146: Options Database Keys:
1147: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1149: Usage:
1150: .vb
1151: PetscInitialize(...);
1152: PetscLogBegin();
1153: ... code ...
1154: PetscLogPrintSummary(MPI_Comm,filename);
1155: PetscFinalize(...);
1156: .ve
1158: Notes:
1159: By default the summary is printed to stdout.
1160: More extensive examination of the log information can be done with
1161: PetscLogDump(), which is activated by the option -log or -log_all, in
1162: combination with petsc/bin/petscview.
1164: Level: beginner
1165:
1166: .keywords: log, dump, print
1167: .seealso: PetscLogBegin(), PetscLogDump()
1168: @*/
1169: PetscErrorCode PETSC_DLLEXPORT PetscLogPrintSummary(MPI_Comm comm, const char filename[])
1170: {
1171: FILE *fd = stdout;
1172: PetscScalar zero = 0.0;
1173: StageLog stageLog;
1174: StageInfo *stageInfo = PETSC_NULL;
1175: EventPerfInfo *eventInfo = PETSC_NULL;
1176: ClassPerfInfo *classInfo;
1177: char arch[10], hostname[64], username[16], pname[PETSC_MAX_PATH_LEN], date[64];
1178: const char *name;
1179: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1180: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1181: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1182: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1183: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1184: PetscLogDouble min, max, tot, ratio, avg, x, y;
1185: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1186: PetscMPIInt minCt, maxCt;
1187: PetscMPIInt size, rank;
1188: PetscTruth *localStageUsed, *stageUsed;
1189: PetscTruth *localStageVisible, *stageVisible;
1190: int numStages, localNumEvents, numEvents;
1191: int stage, oclass;
1192: PetscEvent event;
1194: char version[256];
1197: MPI_Comm_size(comm, &size);
1198: MPI_Comm_rank(comm, &rank);
1199: /* Pop off any stages the user forgot to remove */
1200: PetscLogGetStageLog(&stageLog);
1201: StageLogGetCurrent(stageLog, &stage);
1202: while (stage >= 0) {
1203: StageLogPop(stageLog);
1204: StageLogGetCurrent(stageLog, &stage);
1205: }
1206: /* Get the total elapsed time */
1207: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1208: /* Open the summary file */
1209: if (filename) {
1210: PetscFOpen(comm, filename, "w", &fd);
1211: }
1213: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1214: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1215: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1216: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1217: PetscGetArchType(arch, 10);
1218: PetscGetHostName(hostname, 64);
1219: PetscGetUserName(username, 16);
1220: PetscGetProgramName(pname, PETSC_MAX_PATH_LEN);
1221: PetscGetDate(date, 64);
1222: PetscGetVersion(&version);
1223: if (size == 1) {
1224: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1225: } else {
1226: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1227: }
1228: PetscFPrintf(comm, fd, "Using %s\n", version);
1230: /* Must preserve reduction count before we go on */
1231: red = allreduce_ct/((PetscLogDouble) size);
1233: /* Calculate summary information */
1234: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1235: /* Time */
1236: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1237: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1238: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1239: avg = (tot)/((PetscLogDouble) size);
1240: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1241: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1242: TotalTime = tot;
1243: /* Objects */
1244: avg = (PetscLogDouble) numObjects;
1245: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1246: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1247: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1248: avg = (tot)/((PetscLogDouble) size);
1249: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1250: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1251: /* Flops */
1252: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1253: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1254: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1255: avg = (tot)/((PetscLogDouble) size);
1256: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1257: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1258: TotalFlops = tot;
1259: /* Flops/sec -- Must talk to Barry here */
1260: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1261: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1262: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1263: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1264: avg = (tot)/((PetscLogDouble) size);
1265: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1266: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1267: /* Memory */
1268: PetscMallocGetMaximumUsage(&mem);
1269: if (mem > 0.0) {
1270: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1271: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1272: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1273: avg = (tot)/((PetscLogDouble) size);
1274: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1275: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1276: }
1277: /* Messages */
1278: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1279: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1280: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1281: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1282: avg = (tot)/((PetscLogDouble) size);
1283: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1284: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1285: numMessages = tot;
1286: /* Message Lengths */
1287: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1288: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1289: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1290: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1291: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1292: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1293: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1294: messageLength = tot;
1295: /* Reductions */
1296: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1297: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1298: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1299: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1300: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1301: numReductions = tot;
1302: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1303: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1304: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1306: /* Get total number of stages --
1307: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1308: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1309: This seems best accomplished by assoicating a communicator with each stage.
1310: */
1311: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1312: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1313: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1314: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1315: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1316: if (numStages > 0) {
1317: stageInfo = stageLog->stageInfo;
1318: for(stage = 0; stage < numStages; stage++) {
1319: if (stage < stageLog->numStages) {
1320: localStageUsed[stage] = stageInfo[stage].used;
1321: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1322: } else {
1323: localStageUsed[stage] = PETSC_FALSE;
1324: localStageVisible[stage] = PETSC_TRUE;
1325: }
1326: }
1327: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1328: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1329: for(stage = 0; stage < numStages; stage++) {
1330: if (stageUsed[stage]) {
1331: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1332: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1333: break;
1334: }
1335: }
1336: for(stage = 0; stage < numStages; stage++) {
1337: if (!stageUsed[stage]) continue;
1338: if (localStageUsed[stage]) {
1339: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1340: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1341: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1342: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1343: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1344: name = stageInfo[stage].name;
1345: } else {
1346: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1347: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1348: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1349: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1350: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1351: name = "";
1352: }
1353: mess *= 0.5; messLen *= 0.5; red /= size;
1354: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1355: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1356: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1357: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1358: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1359: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1360: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1361: 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",
1362: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1363: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1364: }
1365: }
1367: PetscFPrintf(comm, fd,
1368: "\n------------------------------------------------------------------------------------------------------------------------\n");
1369:
1370: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1371: PetscFPrintf(comm, fd, "Phase summary info:\n");
1372: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1373: PetscFPrintf(comm, fd, " Time and Flops/sec: Max - maximum over all processors\n");
1374: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1375: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1376: PetscFPrintf(comm, fd, " Avg. len: average message length\n");
1377: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1378: PetscFPrintf(comm, fd, " Global: entire computation\n");
1379: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1380: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1381: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1382: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1383: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1384: PetscFPrintf(comm, fd,
1385: "------------------------------------------------------------------------------------------------------------------------\n");
1386:
1388: #if defined(PETSC_USE_DEBUG)
1389: PetscFPrintf(comm, fd, "\n\n");
1390: PetscFPrintf(comm, fd, " ##########################################################\n");
1391: PetscFPrintf(comm, fd, " # #\n");
1392: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1393: PetscFPrintf(comm, fd, " # #\n");
1394: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1395: PetscFPrintf(comm, fd, " # To get timing results run config/configure.py #\n");
1396: PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n");
1397: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1398: PetscFPrintf(comm, fd, " # #\n");
1399: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1400: #endif
1401: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1402: PetscFPrintf(comm, fd, "\n\n");
1403: PetscFPrintf(comm, fd, " ##########################################################\n");
1404: PetscFPrintf(comm, fd, " # #\n");
1405: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1406: PetscFPrintf(comm, fd, " # #\n");
1407: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1408: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1409: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1410: PetscFPrintf(comm, fd, " # faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #\n");
1411: PetscFPrintf(comm, fd, " # in base_variables and recompile the PETSc libraries. #\n");
1412: PetscFPrintf(comm, fd, " # #\n");
1413: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1414: #endif
1416: if (!PetscPreLoadingUsed) {
1417: PetscFPrintf(comm,fd,"\n\n");
1418: PetscFPrintf(comm,fd," ##########################################################\n");
1419: PetscFPrintf(comm,fd," # #\n");
1420: PetscFPrintf(comm,fd," # WARNING!!! #\n");
1421: PetscFPrintf(comm,fd," # #\n");
1422: PetscFPrintf(comm,fd," # This code was run without the PreLoadBegin() #\n");
1423: PetscFPrintf(comm,fd," # macros. To get timing results we always recommend #\n");
1424: PetscFPrintf(comm,fd," # preloading. otherwise timing numbers may be #\n");
1425: PetscFPrintf(comm,fd," # meaningless. #\n");
1426: PetscFPrintf(comm,fd," ##########################################################\n\n\n");
1427: }
1429: /* Report events */
1430: PetscFPrintf(comm, fd,
1431: "Event Count Time (sec) Flops/sec --- Global --- --- Stage --- Total\n");
1432:
1433: PetscFPrintf(comm, fd,
1434: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1435:
1436: PetscFPrintf(comm,fd,
1437: "------------------------------------------------------------------------------------------------------------------------\n");
1439:
1440: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1441: for(stage = 0; stage < numStages; stage++) {
1442: if (!stageVisible[stage]) continue;
1443: if (localStageUsed[stage]) {
1444: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1445: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1446: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1447: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1448: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1449: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1450: } else {
1451: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1452: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1453: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1454: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1455: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1456: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1457: }
1458: mess *= 0.5; messLen *= 0.5; red /= size;
1460: /* Get total number of events in this stage --
1461: Currently, a single processor can register more events than another, but events must all be registered in order,
1462: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1463: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1465: Problem: If the event did not happen on proc 1, its name will not be available.
1466: Problem: Event visibility is not implemented
1467: */
1468: if (localStageUsed[stage]) {
1469: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1470: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1471: } else {
1472: localNumEvents = 0;
1473: }
1474: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1475: for(event = 0; event < numEvents; event++) {
1476: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1477: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1478: flopr = eventInfo[event].flops/eventInfo[event].time;
1479: } else {
1480: flopr = 0.0;
1481: }
1482: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1483: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1484: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1485: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1486: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1487: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1488: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1489: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1490: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1491: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1492: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1493: name = stageLog->eventLog->eventInfo[event].name;
1494: } else {
1495: flopr = 0.0;
1496: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1497: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1498: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1499: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1500: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1501: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1502: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1503: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1504: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1505: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1506: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1507: name = "";
1508: }
1509: totm *= 0.5; totml *= 0.5; totr /= size;
1510:
1511: if (maxCt != 0) {
1512: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1513: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1514: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1515: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1516: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1517: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1518: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1519: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1520: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1521: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1522: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1523: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1524: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1525: if (totm != 0.0) totml /= totm; else totml = 0.0;
1526: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1527: PetscFPrintf(comm, fd,
1528: "%-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",
1529: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1530: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1531: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1532: flopr/1.0e6);
1533: }
1534: }
1535: }
1537: /* Memory usage and object creation */
1538: PetscFPrintf(comm, fd,
1539: "------------------------------------------------------------------------------------------------------------------------\n");
1540: PetscFPrintf(comm, fd, "\n");
1541: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1543: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1544: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1545: stats for stages local to processor sets.
1546: */
1547: /* We should figure out the longest object name here (now 20 characters) */
1548: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1549: for(stage = 0; stage < numStages; stage++) {
1550: if (localStageUsed[stage]) {
1551: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1552: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1553: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1554: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1555: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %g\n", stageLog->classLog->classInfo[oclass].name,
1556: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1557: classInfo[oclass].descMem);
1558: }
1559: }
1560: } else {
1561: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1562: }
1563: }
1565: PetscFree(localStageUsed);
1566: PetscFree(stageUsed);
1567: PetscFree(localStageVisible);
1568: PetscFree(stageVisible);
1570: /* Information unrelated to this particular run */
1571: PetscFPrintf(comm, fd,
1572: "========================================================================================================================\n");
1573: PetscTime(y);
1574: PetscTime(x);
1575: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1576: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1577: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1578: /* MPI information */
1579: if (size > 1) {
1580: MPI_Status status;
1581: PetscMPIInt tag;
1582: MPI_Comm newcomm;
1584: MPI_Barrier(comm);
1585: PetscTime(x);
1586: MPI_Barrier(comm);
1587: MPI_Barrier(comm);
1588: MPI_Barrier(comm);
1589: MPI_Barrier(comm);
1590: MPI_Barrier(comm);
1591: PetscTime(y);
1592: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1593: PetscCommDuplicate(comm,&newcomm, &tag);
1594: MPI_Barrier(comm);
1595: if (rank) {
1596: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1597: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1598: } else {
1599: PetscTime(x);
1600: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1601: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1602: PetscTime(y);
1603: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1604: }
1605: PetscCommDestroy(&newcomm);
1606: }
1607: /* Machine and compile information */
1608: #if defined(PETSC_USE_FORTRAN_KERNELS)
1609: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1610: #else
1611: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1612: #endif
1613: #if defined(PETSC_USE_SINGLE)
1614: PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1615: #elif defined(PETSC_USE_LONGDOUBLE)
1616: PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1617: #elif defined(PETSC_USE_INT)
1618: PetscFPrintf(comm, fd, "Compiled with int PetscScalar and PetscReal\n");
1619: #endif
1621: #if defined(PETSC_USE_MAT_SINGLE)
1622: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1623: #else
1624: PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1625: #endif
1626: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d\n",
1627: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar));
1629: PetscFPrintf(comm, fd, "Configure run at: %s\n",petscconfigureruntime);
1630: PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1631: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1632: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1633: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1634: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1636: /* Cleanup */
1637: PetscFPrintf(comm, fd, "\n");
1638: PetscFClose(comm, fd);
1639: return(0);
1640: }
1642: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1645: /*@C
1646: PetscGetFlops - Returns the number of flops used on this processor
1647: since the program began.
1649: Not Collective
1651: Output Parameter:
1652: flops - number of floating point operations
1654: Notes:
1655: A global counter logs all PETSc flop counts. The user can use
1656: PetscLogFlops() to increment this counter to include flops for the
1657: application code.
1659: PETSc automatically logs library events if the code has been
1660: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1661: -log_summary, or -log_all are specified. PetscLogFlops() is
1662: intended for logging user flops to supplement this PETSc
1663: information.
1665: Level: intermediate
1667: .keywords: log, flops, floating point operations
1669: .seealso: PetscGetTime(), PetscLogFlops()
1670: @*/
1671: PetscErrorCode PETSC_DLLEXPORT PetscGetFlops(PetscLogDouble *flops)
1672: {
1674: *flops = _TotalFlops;
1675: return(0);
1676: }
1680: PetscErrorCode PETSC_DLLEXPORT PetscLogObjectState(PetscObject obj, const char format[], ...)
1681: {
1683: va_list Argp;
1686: if (!logObjects) return(0);
1687: va_start(Argp, format);
1688: PetscVSNPrintf(objects[obj->id].info, 64,format, Argp);
1689: va_end(Argp);
1690: return(0);
1691: }
1693: #else /* end of -DPETSC_USE_LOG section */
1697: PetscErrorCode PETSC_DLLEXPORT PetscLogObjectState(PetscObject obj, const char format[], ...)
1698: {
1700: return(0);
1701: }
1703: #endif /* PETSC_USE_LOG*/
1707: /*@
1708: PetscLogGetStageLog - This function returns the default stage logging object.
1710: Not collective
1712: Output Parameter:
1713: . stageLog - The default StageLog
1715: Level: beginner
1717: .keywords: log, stage
1718: .seealso: StageLogCreate()
1719: @*/
1720: PetscErrorCode PETSC_DLLEXPORT PetscLogGetStageLog(StageLog *stageLog)
1721: {
1724: *stageLog = _stageLog;
1725: return(0);
1726: }
1728: /*MC
1729: PetscLogFlops - Adds floating point operations to the global counter.
1731: Input Parameter:
1732: . f - flop counter
1734: Synopsis:
1735: void PetscLogFlops(int f)
1737: Usage:
1738: .vb
1739: int USER_EVENT;
1740: PetscLogEventRegister(&USER_EVENT,"User event");
1741: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1742: [code segment to monitor]
1743: PetscLogFlops(user_flops)
1744: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1745: .ve
1747: Notes:
1748: A global counter logs all PETSc flop counts. The user can use
1749: PetscLogFlops() to increment this counter to include flops for the
1750: application code.
1752: PETSc automatically logs library events if the code has been
1753: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1754: -log_summary, or -log_all are specified. PetscLogFlops() is
1755: intended for logging user flops to supplement this PETSc
1756: information.
1758: Level: intermediate
1760: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1762: .keywords: log, flops, floating point operations
1763: M*/
1765: /*MC
1766: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1767: to get accurate timings
1769: Input Parameter:
1770: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1771: with command line option -preload true or -preload false
1772: - name - name of first stage (lines of code timed separately with -log_summary) to
1773: be preloaded
1775: Synopsis:
1776: void PreLoadBegin(PetscTruth flag,char *name);
1778: Usage:
1779: .vb
1780: PreLoadBegin(PETSC_TRUE,"first stage);
1781: lines of code
1782: PreLoadStage("second stage");
1783: lines of code
1784: PreLoadEnd();
1785: .ve
1787: Notes: Only works in C/C++, not Fortran
1789: Flags available within the macro.
1790: + PetscPreLoadingUsed - true if we are or have done preloading
1791: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1792: . PreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1793: - PreLoadMax - number of times it will do the computation, only one when preloading is turned on
1794: The first two variables are available throughout the program, the second two only between the PreLoadBegin()
1795: and PreLoadEnd()
1797: Level: intermediate
1799: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1801: Concepts: preloading
1802: Concepts: timing^accurate
1803: Concepts: paging^eliminating effects of
1806: M*/
1808: /*MC
1809: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1810: to get accurate timings
1812: Synopsis:
1813: void PreLoadEnd(void);
1815: Usage:
1816: .vb
1817: PreLoadBegin(PETSC_TRUE,"first stage);
1818: lines of code
1819: PreLoadStage("second stage");
1820: lines of code
1821: PreLoadEnd();
1822: .ve
1824: Notes: only works in C/C++ not fortran
1826: Level: intermediate
1828: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1830: M*/
1832: /*MC
1833: PreLoadStage - Start a new segment of code to be timed separately.
1834: to get accurate timings
1836: Synopsis:
1837: void PreLoadStage(char *name);
1839: Usage:
1840: .vb
1841: PreLoadBegin(PETSC_TRUE,"first stage);
1842: lines of code
1843: PreLoadStage("second stage");
1844: lines of code
1845: PreLoadEnd();
1846: .ve
1848: Notes: only works in C/C++ not fortran
1850: Level: intermediate
1852: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1854: M*/
1856: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1859: /*@C
1860: StackDestroy - This function destroys a stack.
1862: Not Collective
1864: Input Parameter:
1865: . stack - The stack
1867: Level: beginner
1869: .keywords: log, stack, destroy
1870: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1871: @*/
1872: PetscErrorCode StackDestroy(IntStack stack)
1873: {
1877: PetscFree(stack->stack);
1878: PetscFree(stack);
1879: return(0);
1880: }
1884: /*@C
1885: StackEmpty - This function determines whether any items have been pushed.
1887: Not Collective
1889: Input Parameter:
1890: . stack - The stack
1892: Output Parameter:
1893: . empty - PETSC_TRUE if the stack is empty
1895: Level: intermediate
1897: .keywords: log, stack, empty
1898: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1899: @*/
1900: PetscErrorCode StackEmpty(IntStack stack, PetscTruth *empty)
1901: {
1904: if (stack->top == -1) {
1905: *empty = PETSC_TRUE;
1906: } else {
1907: *empty = PETSC_FALSE;
1908: }
1909: return(0);
1910: }
1914: /*@C
1915: StackTop - This function returns the top of the stack.
1917: Not Collective
1919: Input Parameter:
1920: . stack - The stack
1922: Output Parameter:
1923: . top - The integer on top of the stack
1925: Level: intermediate
1927: .keywords: log, stack, top
1928: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1929: @*/
1930: PetscErrorCode StackTop(IntStack stack, int *top)
1931: {
1934: *top = stack->stack[stack->top];
1935: return(0);
1936: }
1940: /*@C
1941: StackPush - This function pushes an integer on the stack.
1943: Not Collective
1945: Input Parameters:
1946: + stack - The stack
1947: - item - The integer to push
1949: Level: intermediate
1951: .keywords: log, stack, push
1952: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1953: @*/
1954: PetscErrorCode StackPush(IntStack stack, int item)
1955: {
1956: int *array;
1960: stack->top++;
1961: if (stack->top >= stack->max) {
1962: PetscMalloc(stack->max*2 * sizeof(int), &array);
1963: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1964: PetscFree(stack->stack);
1965: stack->stack = array;
1966: stack->max *= 2;
1967: }
1968: stack->stack[stack->top] = item;
1969: return(0);
1970: }
1974: /*@C
1975: StackPop - This function pops an integer from the stack.
1977: Not Collective
1979: Input Parameter:
1980: . stack - The stack
1982: Output Parameter:
1983: . item - The integer popped
1985: Level: intermediate
1987: .keywords: log, stack, pop
1988: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
1989: @*/
1990: PetscErrorCode StackPop(IntStack stack, int *item)
1991: {
1994: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
1995: *item = stack->stack[stack->top--];
1996: return(0);
1997: }
2001: /*@C
2002: StackCreate - This function creates a stack.
2004: Not Collective
2006: Output Parameter:
2007: . stack - The stack
2009: Level: beginner
2011: .keywords: log, stack, pop
2012: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
2013: @*/
2014: PetscErrorCode StackCreate(IntStack *stack)
2015: {
2016: IntStack s;
2021: PetscNew(struct _n_IntStack, &s);
2022: s->top = -1;
2023: s->max = 128;
2024: PetscMalloc(s->max * sizeof(int), &s->stack);
2025: PetscMemzero(s->stack, s->max * sizeof(int));
2026: *stack = s;
2027: return(0);
2028: }