Actual source code: plog.c
1: /*$Id: plog.c,v 1.262 2001/08/22 17:59:37 balay Exp $*/
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) && !defined(__cplusplus)
17: #include <malloc.h>
18: #endif
19: #include "petscfix.h"
20: #include src/sys/src/plog/ptime.h
21: #include plog.h
23: int PETSC_LARGEST_COOKIE = PETSC_COOKIE;
24: int 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_DUMMY,PETSC_DUMMY_SIZE;
31: /* Action and object logging variables */
32: Action *actions = PETSC_NULL;
33: Object *objects = PETSC_NULL;
34: PetscTruth logActions = PETSC_TRUE;
35: PetscTruth logObjects = PETSC_TRUE;
36: int numActions = 0, maxActions = 100;
37: int numObjects = 0, maxObjects = 100;
38: int numObjectsDestroyed = 0;
40: /* Global counters */
41: PetscLogDouble BaseTime;
42: PetscLogDouble _TotalFlops = 0.0; /* The number of flops */
43: PetscLogDouble send_ct = 0.0; /* The number of sends */
44: PetscLogDouble recv_ct = 0.0; /* The number of receives */
45: PetscLogDouble send_len = 0.0; /* The total length of all sent messages */
46: PetscLogDouble recv_len = 0.0; /* The total length of all received messages */
47: PetscLogDouble isend_ct = 0.0; /* The number of immediate sends */
48: PetscLogDouble irecv_ct = 0.0; /* The number of immediate receives */
49: PetscLogDouble isend_len = 0.0; /* The total length of all immediate send messages */
50: PetscLogDouble irecv_len = 0.0; /* The total length of all immediate receive messages */
51: PetscLogDouble wait_ct = 0.0; /* The number of waits */
52: PetscLogDouble wait_any_ct = 0.0; /* The number of anywaits */
53: PetscLogDouble wait_all_ct = 0.0; /* The number of waitalls */
54: PetscLogDouble sum_of_waits_ct = 0.0; /* The total number of waits */
55: PetscLogDouble allreduce_ct = 0.0; /* The number of reductions */
57: /* Logging functions */
58: int (*_PetscLogPHC)(PetscObject) = PETSC_NULL;
59: int (*_PetscLogPHD)(PetscObject) = PETSC_NULL;
60: int (*_PetscLogPLB)(int, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
61: int (*_PetscLogPLE)(int, int, PetscObject, PetscObject, PetscObject, PetscObject) = PETSC_NULL;
63: /* Tracing event logging variables */
64: FILE *tracefile = PETSC_NULL;
65: int tracelevel = 0;
66: char *traceblanks = " ";
67: char tracespace[128];
68: PetscLogDouble tracetime = 0.0;
70: /*---------------------------------------------- General Functions --------------------------------------------------*/
71: /*@C
72: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
74: Not Collective
76: Notes:
77: This routine should not usually be used by programmers. Instead employ
78: PetscLogStagePush() and PetscLogStagePop().
80: Level: developer
82: .keywords: log, destroy
83: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogStagePush(), PlogStagePop()
84: @*/
85: int PetscLogDestroy(void) {
86: StageLog stageLog;
87: int ierr;
90: if (actions != PETSC_NULL) {
91: PetscFree(actions);
92: actions = PETSC_NULL;
93: }
94: if (objects != PETSC_NULL) {
95: PetscFree(objects);
96: objects = PETSC_NULL;
97: }
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: }
110: /*@C
111: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
113: Not Collective
115: Input Parameters:
116: + b - The function called at beginning of event
117: - e - The function called at end of event
119: Level: developer
121: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
122: @*/
123: int PetscLogSet(int (*b)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
124: int (*e)(int, int, PetscObject, PetscObject, PetscObject, PetscObject))
125: {
127: _PetscLogPLB = b;
128: _PetscLogPLE = e;
129: return(0);
130: }
132: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
133: int PetscLogBegin_Private(void) {
134: static int initialized = 0;
135: int stage;
136: PetscTruth opt;
137: int ierr;
140: if (initialized) return(0);
141: initialized = 1;
142: PetscOptionsHasName(PETSC_NULL, "-log_exclude_actions", &opt);
143: if (opt == PETSC_FALSE) {
144: PetscMalloc(maxActions * sizeof(Action), &actions);
145: } else {
146: logActions = PETSC_FALSE;
147: }
148: PetscOptionsHasName(PETSC_NULL, "-log_exclude_objects", &opt);
149: if (opt == PETSC_FALSE) {
150: PetscMalloc(maxObjects * sizeof(Object), &objects);
151: } else {
152: logObjects = PETSC_FALSE;
153: }
154: _PetscLogPHC = PetscLogObjCreateDefault;
155: _PetscLogPHD = PetscLogObjDestroyDefault;
156: /* Setup default logging structures */
157: StageLogCreate(&_stageLog);
158: StageLogRegister(_stageLog, "Main Stage", &stage);
159: /* All processors sync here for more consistent logging */
160: MPI_Barrier(PETSC_COMM_WORLD);
161: PetscTime(BaseTime);
162: PetscLogStagePush(stage);
163: return(0);
164: }
166: /*@C
167: PetscLogBegin - Turns on logging of objects and events. This logs flop
168: rates and object creation and should not slow programs down too much.
169: This routine may be called more than once.
171: Collective over PETSC_COMM_WORLD
173: Options Database Keys:
174: + -log_summary - Prints summary of flop and timing information to the
175: screen (for code compiled with PETSC_USE_LOG)
176: - -log - Prints detailed log information (for code compiled with PETSC_USE_LOG)
178: Usage:
179: .vb
180: PetscInitialize(...);
181: PetscLogBegin();
182: ... code ...
183: PetscLogPrintSummary(MPI_Comm,filename); or PetscLogDump();
184: PetscFinalize();
185: .ve
187: Notes:
188: PetscLogPrintSummary(MPI_Comm,filename) or PetscLogDump() actually cause the printing of
189: the logging information.
191: Level: advanced
193: .keywords: log, begin
194: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogTraceBegin()
195: @*/
196: int PetscLogBegin(void)
197: {
201: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
202: PetscLogBegin_Private();
203: return(0);
204: }
206: /*@C
207: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
208: all events. This creates large log files and slows the program down.
210: Collective on PETSC_COMM_WORLD
212: Options Database Keys:
213: . -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
215: Usage:
216: .vb
217: PetscInitialize(...);
218: PetscLogAllBegin();
219: ... code ...
220: PetscLogDump(filename);
221: PetscFinalize();
222: .ve
224: Notes:
225: A related routine is PetscLogBegin (with the options key -log), which is
226: intended for production runs since it logs only flop rates and object
227: creation (and shouldn't significantly slow the programs).
229: Level: advanced
231: .keywords: log, all, begin
232: .seealso: PetscLogDump(), PetscLogBegin(), PetscLogTraceBegin()
233: @*/
234: int PetscLogAllBegin(void)
235: {
239: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
240: PetscLogBegin_Private();
241: return(0);
242: }
244: /*@
245: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
246: begins or ends, the event name is printed.
248: Collective on PETSC_COMM_WORLD
250: Input Parameter:
251: . file - The file to print trace in (e.g. stdout)
253: Options Database Key:
254: . -log_trace [filename] - Activates PetscLogTraceBegin()
256: Notes:
257: PetscLogTraceBegin() prints the processor number, the execution time (sec),
258: then "Event begin:" or "Event end:" followed by the event name.
260: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
261: to determine where a program is hanging without running in the
262: debugger. Can be used in conjunction with the -log_info option.
264: Level: intermediate
266: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogPrintSummary(), PetscLogBegin()
267: @*/
268: int PetscLogTraceBegin(FILE *file)
269: {
273: tracefile = file;
274: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
275: PetscLogBegin_Private();
276: return(0);
277: }
279: /*@
280: PetscLogActions - Determines whether actions are logged for the graphical viewer.
282: Not Collective
284: Input Parameter:
285: . flag - PETSC_TRUE if actions are to be logged
287: Level: intermediate
289: Note: Logging of actions continues to consume more memory as the program
290: runs. Long running programs should consider turning this feature off.
292: Options Database Keys:
293: . -log_exclude_actions - Turns off actions logging
295: .keywords: log, stage, register
296: .seealso: PetscLogStagePush(), PetscLogStagePop()
297: @*/
298: int PetscLogActions(PetscTruth flag) {
300: logActions = flag;
301: return(0);
302: }
304: /*@
305: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
307: Not Collective
309: Input Parameter:
310: . flag - PETSC_TRUE if objects are to be logged
312: Level: intermediate
314: Note: Logging of objects continues to consume more memory as the program
315: runs. Long running programs should consider turning this feature off.
317: Options Database Keys:
318: . -log_exclude_objects - Turns off objects logging
320: .keywords: log, stage, register
321: .seealso: PetscLogStagePush(), PetscLogStagePop()
322: @*/
323: int PetscLogObjects(PetscTruth flag) {
325: logObjects = flag;
326: return(0);
327: }
329: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
330: /*@C
331: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
333: Not Collective
335: Input Parameter:
336: . sname - The name to associate with that stage
338: Output Parameter:
339: . stage - The stage number
341: Level: intermediate
343: .keywords: log, stage, register
344: .seealso: PetscLogStagePush(), PetscLogStagePop()
345: @*/
346: int PetscLogStageRegister(int *stage, const char sname[]) {
347: StageLog stageLog;
348: int event;
349: int ierr;
352: PetscLogGetStageLog(&stageLog);
353: StageLogRegister(stageLog, sname, stage);
354: /* Copy events already changed in the main stage, this sucks */
355: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
356: for(event = 0; event < stageLog->eventLog->numEvents; event++) {
357: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],
358: &stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
359:
360: }
361: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
362: return(0);
363: }
365: /*@C
366: PetscLogStagePush - This function pushes a stage on the stack.
368: Not Collective
370: Input Parameter:
371: . stage - The stage on which to log
373: Usage:
374: If the option -log_sumary is used to run the program containing the
375: following code, then 2 sets of summary data will be printed during
376: PetscFinalize().
377: .vb
378: PetscInitialize(int *argc,char ***args,0,0);
379: [stage 0 of code]
380: PetscLogStagePush(1);
381: [stage 1 of code]
382: PetscLogStagePop();
383: PetscBarrier(...);
384: [more stage 0 of code]
385: PetscFinalize();
386: .ve
387:
388: Notes:
389: Use PetscLogStageRegister() to register a stage.
391: Level: intermediate
393: .keywords: log, push, stage
394: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
395: @*/
396: int PetscLogStagePush(int stage)
397: {
398: StageLog stageLog;
399: int ierr;
402: PetscLogGetStageLog(&stageLog);
403: StageLogPush(stageLog, stage);
404: return(0);
405: }
407: /*@C
408: PetscLogStagePop - This function pops a stage from the stack.
410: Not Collective
412: Usage:
413: If the option -log_sumary is used to run the program containing the
414: following code, then 2 sets of summary data will be printed during
415: PetscFinalize().
416: .vb
417: PetscInitialize(int *argc,char ***args,0,0);
418: [stage 0 of code]
419: PetscLogStagePush(1);
420: [stage 1 of code]
421: PetscLogStagePop();
422: PetscBarrier(...);
423: [more stage 0 of code]
424: PetscFinalize();
425: .ve
427: Notes:
428: Use PetscLogStageRegister() to register a stage.
430: Level: intermediate
432: .keywords: log, pop, stage
433: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
434: @*/
435: int PetscLogStagePop(void)
436: {
437: StageLog stageLog;
438: int ierr;
441: PetscLogGetStageLog(&stageLog);
442: StageLogPop(stageLog);
443: return(0);
444: }
446: /*@
447: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
449: Not Collective
451: Input Parameters:
452: + stage - The stage
453: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
455: Level: intermediate
457: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
458: @*/
459: int PetscLogStageSetActive(int stage, PetscTruth isActive) {
460: StageLog stageLog;
461: int ierr;
464: PetscLogGetStageLog(&stageLog);
465: StageLogSetActive(stageLog, stage, isActive);
466: return(0);
467: }
469: /*@
470: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
472: Not Collective
474: Input Parameter:
475: . stage - The stage
477: Output Parameter:
478: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
480: Level: intermediate
482: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
483: @*/
484: int PetscLogStageGetActive(int stage, PetscTruth *isActive) {
485: StageLog stageLog;
486: int ierr;
489: PetscLogGetStageLog(&stageLog);
490: StageLogGetActive(stageLog, stage, isActive);
491: return(0);
492: }
494: /*@
495: PetscLogStageSetVisible - Determines stage visibility in PetscLogPrintSummary()
497: Not Collective
499: Input Parameters:
500: + stage - The stage
501: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
503: Level: intermediate
505: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
506: @*/
507: int PetscLogStageSetVisible(int stage, PetscTruth isVisible)
508: {
509: StageLog stageLog;
510: int ierr;
513: PetscLogGetStageLog(&stageLog);
514: StageLogSetVisible(stageLog, stage, isVisible);
515: return(0);
516: }
518: /*@
519: PetscLogStageGetVisible - Returns stage visibility in PetscLogPrintSummary()
521: Not Collective
523: Input Parameter:
524: . stage - The stage
526: Output Parameter:
527: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
529: Level: intermediate
531: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogPrintSummary()
532: @*/
533: int PetscLogStageGetVisible(int stage, PetscTruth *isVisible)
534: {
535: StageLog stageLog;
536: int ierr;
539: PetscLogGetStageLog(&stageLog);
540: StageLogGetVisible(stageLog, stage, isVisible);
541: return(0);
542: }
544: /*@
545: PetscLogStageGetId - Returns the stage id when given the stage name.
547: Not Collective
549: Input Parameter:
550: . name - The stage name
552: Output Parameter:
553: . stage - The stage
555: Level: intermediate
557: .seealso: PetscLogStagePush(), PetscLogStagePop(), PreLoadBegin(), PreLoadEnd(), PreLoadStage()
558: @*/
559: int PetscLogStageGetId(const char name[], int *stage)
560: {
561: StageLog stageLog;
562: int ierr;
565: PetscLogGetStageLog(&stageLog);
566: StageLogGetStage(stageLog, name, stage);
567: return(0);
568: }
570: /*------------------------------------------------ Event Functions --------------------------------------------------*/
571: /*@C
572: PetscLogEventRegister - Registers an event name for logging operations in an application code.
574: Not Collective
576: Input Parameter:
577: + name - The name associated with the event
578: - cookie - The cookie associated to the class for this event
579:
580: Output Parameter:
581: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
583: Example of Usage:
584: .vb
585: int USER_EVENT;
586: int user_event_flops;
587: PetscLogEventRegister(&USER_EVENT,"User event name");
588: PetscLogEventBegin(USER_EVENT,0,0,0,0);
589: [code segment to monitor]
590: PetscLogFlops(user_event_flops);
591: PetscLogEventEnd(USER_EVENT,0,0,0,0);
592: .ve
594: Notes:
595: PETSc automatically logs library events if the code has been
596: compiled with -DPETSC_USE_LOG (which is the default) and -log,
597: -log_summary, or -log_all are specified. PetscLogEventRegister() is
598: intended for logging user events to supplement this PETSc
599: information.
601: PETSc can gather data for use with the utilities Upshot/Nupshot
602: (part of the MPICH distribution). If PETSc has been compiled
603: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
604: MPICH), the user can employ another command line option, -log_mpe,
605: to create a logfile, "mpe.log", which can be visualized
606: Upshot/Nupshot.
608: Level: intermediate
610: .keywords: log, event, register
611: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
612: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
613: PetscLogEventActivate(), PetscLogEventDeactivate()
614: @*/
615: int PetscLogEventRegister(int *event, const char name[],int cookie) {
616: StageLog stageLog;
617: int stage;
618: int ierr;
621: *event = PETSC_DECIDE;
622: PetscLogGetStageLog(&stageLog);
623: EventRegLogRegister(stageLog->eventLog, name, cookie, event);
624: for(stage = 0; stage < stageLog->numStages; stage++) {
625: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
626: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
627: }
628: return(0);
629: }
631: /*@
632: PetscLogEventActivate - Indicates that a particular event should be logged.
634: Not Collective
636: Input Parameter:
637: . event - The event id
639: Usage:
640: .vb
641: PetscLogEventDeactivate(VEC_SetValues);
642: [code where you do not want to log VecSetValues()]
643: PetscLogEventActivate(VEC_SetValues);
644: [code where you do want to log VecSetValues()]
645: .ve
647: Note:
648: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
649: or an event number obtained with PetscLogEventRegister().
651: Level: advanced
653: .keywords: log, event, activate
654: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
655: @*/
656: int PetscLogEventActivate(int event) {
657: StageLog stageLog;
658: int stage;
659: int ierr;
662: PetscLogGetStageLog(&stageLog);
663: StageLogGetCurrent(stageLog, &stage);
664: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
665: return(0);
666: }
668: /*@
669: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
671: Not Collective
673: Input Parameter:
674: . event - The event id
676: Usage:
677: .vb
678: PetscLogEventDeactivate(VEC_SetValues);
679: [code where you do not want to log VecSetValues()]
680: PetscLogEventActivate(VEC_SetValues);
681: [code where you do want to log VecSetValues()]
682: .ve
684: Note:
685: The event may be either a pre-defined PETSc event (found in
686: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
688: Level: advanced
690: .keywords: log, event, deactivate
691: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
692: @*/
693: int PetscLogEventDeactivate(int event) {
694: StageLog stageLog;
695: int stage;
696: int ierr;
699: PetscLogGetStageLog(&stageLog);
700: StageLogGetCurrent(stageLog, &stage);
701: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
702: return(0);
703: }
705: /*@
706: PetscLogEventSetActiveAll - Sets the event activity in every stage.
708: Not Collective
710: Input Parameters:
711: + event - The event id
712: - isActive - The activity flag determining whether the event is logged
714: Level: advanced
716: .keywords: log, event, activate
717: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
718: @*/
719: int PetscLogEventSetActiveAll(int event, PetscTruth isActive) {
720: StageLog stageLog;
721: int stage;
722: int ierr;
725: PetscLogGetStageLog(&stageLog);
726: for(stage = 0; stage < stageLog->numStages; stage++) {
727: if (isActive == PETSC_TRUE) {
728: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
729: } else {
730: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
731: }
732: }
733: return(0);
734: }
736: /*@
737: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
739: Not Collective
741: Input Parameter:
742: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
744: Level: developer
746: .keywords: log, event, activate, class
747: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
748: @*/
749: int PetscLogEventActivateClass(int cookie) {
750: StageLog stageLog;
751: int stage;
752: int ierr;
755: PetscLogGetStageLog(&stageLog);
756: StageLogGetCurrent(stageLog, &stage);
757: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
758: return(0);
759: }
761: /*@
762: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
764: Not Collective
766: Input Parameter:
767: . cookie - The event class, for example MAT_COOKIE, SNES_COOKIE, etc.
769: Level: developer
771: .keywords: log, event, deactivate, class
772: .seealso: PetscLogInfoActivate(),PetscLogInfo(),PetscLogInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
773: @*/
774: int PetscLogEventDeactivateClass(int cookie) {
775: StageLog stageLog;
776: int stage;
777: int ierr;
780: PetscLogGetStageLog(&stageLog);
781: StageLogGetCurrent(stageLog, &stage);
782: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, cookie);
783: return(0);
784: }
786: /*MC
787: PetscLogEventBegin - Logs the beginning of a user event.
789: Input Parameters:
790: + e - integer associated with the event obtained from PetscLogEventRegister()
791: - o1,o2,o3,o4 - objects associated with the event, or 0
793: Synopsis:
794: void PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
795: PetscObject o4)
797: Usage:
798: .vb
799: int USER_EVENT;
800: int user_event_flops;
801: PetscLogEventRegister(&USER_EVENT,"User event");
802: PetscLogEventBegin(USER_EVENT,0,0,0,0);
803: [code segment to monitor]
804: PetscLogFlops(user_event_flops);
805: PetscLogEventEnd(USER_EVENT,0,0,0,0);
806: .ve
808: Notes:
809: You should also register each integer event with the command
810: PetscLogEventRegister(). The source code must be compiled with
811: -DPETSC_USE_LOG, which is the default.
813: PETSc automatically logs library events if the code has been
814: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
815: specified. PetscLogEventBegin() is intended for logging user events
816: to supplement this PETSc information.
818: Level: intermediate
820: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
822: .keywords: log, event, begin
823: M*/
825: /*MC
826: PetscLogEventEnd - Log the end of a user event.
828: Input Parameters:
829: + e - integer associated with the event obtained with PetscLogEventRegister()
830: - o1,o2,o3,o4 - objects associated with the event, or 0
832: Synopsis:
833: void PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
834: PetscObject o4)
836: Usage:
837: .vb
838: int USER_EVENT;
839: int user_event_flops;
840: PetscLogEventRegister(&USER_EVENT,"User event");
841: PetscLogEventBegin(USER_EVENT,0,0,0,0);
842: [code segment to monitor]
843: PetscLogFlops(user_event_flops);
844: PetscLogEventEnd(USER_EVENT,0,0,0,0);
845: .ve
847: Notes:
848: You should also register each additional integer event with the command
849: PetscLogEventRegister(). Source code must be compiled with
850: -DPETSC_USE_LOG, which is the default.
852: PETSc automatically logs library events if the code has been
853: compiled with -DPETSC_USE_LOG, and -log, -log_summary, or -log_all are
854: specified. PetscLogEventEnd() is intended for logging user events
855: to supplement this PETSc information.
857: Level: intermediate
859: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
861: .keywords: log, event, end
862: M*/
864: /*MC
865: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
867: Input Parameters:
868: . e - integer associated with the event obtained from PetscLogEventRegister()
869: . o1,o2,o3,o4 - objects associated with the event, or 0
870: . comm - communicator the barrier takes place over
872: Synopsis:
873: void PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,
874: PetscObject o4,MPI_Comm comm)
876: Usage:
877: .vb
878: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
879: MPI_Allreduce()
880: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
881: .ve
883: Notes:
884: This is for logging the amount of time spent in a barrier for an event
885: that requires synchronization.
887: Additional Notes:
888: Synchronization events always come in pairs; for example, VEC_NormBarrier and
889: VEC_NormComm = VEC_NormBarrier + 1
891: Level: advanced
893: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
894: PetscLogEventBarrierEnd()
896: .keywords: log, event, begin, barrier
897: M*/
899: /*MC
900: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
902: Input Parameters:
903: . e - integer associated with the event obtained from PetscLogEventRegister()
904: . o1,o2,o3,o4 - objects associated with the event, or 0
905: . comm - communicator the barrier takes place over
907: Synopsis:
908: void PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,
909: PetscObject o4,MPI_Comm comm)
911: Usage:
912: .vb
913: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
914: MPI_Allreduce()
915: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
916: .ve
918: Notes:
919: This is for logging the amount of time spent in a barrier for an event
920: that requires synchronization.
922: Additional Notes:
923: Synchronization events always come in pairs; for example, VEC_NormBarrier and
924: VEC_NormComm = VEC_NormBarrier + 1
926: Level: advanced
928: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
929: PetscLogEventBarrierBegin()
931: .keywords: log, event, begin, barrier
932: M*/
934: /*------------------------------------------------ Class Functions --------------------------------------------------*/
935: /*@C
936: PetscLogClassRegister - Registers a class name for logging operations in an application code.
938: Not Collective
940: Input Parameter:
941: . name - The class name
942:
943: Output Parameter:
944: . oclass - The class id or cookie
946: Level: developer
948: .keywords: log, class, register
949: .seealso: ClassLogRegister()
950: @*/
951: int PetscLogClassRegister(int *oclass, const char name[])
952: {
953: StageLog stageLog;
954: int ierr;
957: *oclass = PETSC_DECIDE;
958: PetscLogGetStageLog(&stageLog);
959: ClassRegLogRegister(stageLog->classLog, name, oclass);
960: return(0);
961: }
963: /*------------------------------------------------ Output Functions -------------------------------------------------*/
964: /*@C
965: PetscLogDump - Dumps logs of objects to a file. This file is intended to
966: be read by petsc/bin/petscview.
968: Collective on PETSC_COMM_WORLD
970: Input Parameter:
971: . name - an optional file name
973: Options Database Keys:
974: + -log - Prints basic log information (for code compiled with PETSC_USE_LOG)
975: - -log_all - Prints extensive log information (for code compiled with PETSC_USE_LOG)
976:
977: Usage:
978: .vb
979: PetscInitialize(...);
980: PetscLogBegin(); or PetscLogAllBegin();
981: ... code ...
982: PetscLogDump(filename);
983: PetscFinalize();
984: .ve
986: Notes:
987: The default file name is
988: $ Log.<rank>
989: where <rank> is the processor number. If no name is specified,
990: this file will be used.
992: Level: advanced
994: .keywords: log, dump
995: .seealso: PetscLogBegin(), PetscLogAllBegin(), PetscLogPrintSummary()
996: @*/
997: int PetscLogDump(const char sname[]) {
998: StageLog stageLog;
999: EventPerfInfo *eventInfo;
1000: FILE *fd;
1001: char file[64], fname[64];
1002: PetscLogDouble flops, _TotalTime;
1003: int rank, curStage;
1004: int action, object, event;
1005: int ierr;
1006:
1008: /* Calculate the total elapsed time */
1009: PetscTime(_TotalTime);
1010: _TotalTime -= BaseTime;
1011: /* Open log file */
1012: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1013: if (sname != PETSC_NULL) {
1014: sprintf(file, "%s.%d", sname, rank);
1015: } else {
1016: sprintf(file, "Log.%d", rank);
1017: }
1018: PetscFixFilename(file, fname);
1019: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1020: if ((rank == 0) && (fd == PETSC_NULL)) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1021: /* Output totals */
1022: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8en", _TotalFlops, _TotalTime);
1023: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %gn", 0.0);
1024: /* Output actions */
1025: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %dn", numActions);
1026: for(action = 0; action < numActions; action++) {
1027: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %gn",
1028: actions[action].time, actions[action].action, actions[action].event, actions[action].cookie, actions[action].id1,
1029: actions[action].id2, actions[action].id3, actions[action].flops, actions[action].mem, actions[action].maxmem);
1030: }
1031: /* Output objects */
1032: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %dn", numObjects, numObjectsDestroyed);
1033: for(object = 0; object < numObjects; object++) {
1034: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %dn", objects[object].parent, (int) objects[object].mem);
1035: if (!objects[object].name[0]) {
1036: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Namen");
1037: } else {
1038: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %sn", objects[object].name);
1039: }
1040: if (objects[object].info[0] != 0) {
1041: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Infon");
1042: } else {
1043: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %sn", objects[object].info);
1044: }
1045: }
1046: /* Output events */
1047: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:n");
1048: PetscLogGetStageLog(&stageLog);
1049: StackTop(stageLog->stack, &curStage);
1050: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1051: for(event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1052: if (eventInfo[event].time != 0.0) {
1053: flops = eventInfo[event].flops/eventInfo[event].time;
1054: } else {
1055: flops = 0.0;
1056: }
1057: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16gn", event, eventInfo[event].count,
1058: eventInfo[event].flops, eventInfo[event].time, flops);
1059: }
1060: PetscFClose(PETSC_COMM_WORLD, fd);
1061: return(0);
1062: }
1064: /*@C
1065: PetscLogPrintSummary - Prints a summary of the logging.
1067: Collective over MPI_Comm
1069: Input Parameter:
1070: + comm - The MPI communicator (only one processor prints output)
1071: - file - [Optional] The output file name
1073: Options Database Keys:
1074: . -log_summary - Prints summary of log information (for code compiled with PETSC_USE_LOG)
1076: Usage:
1077: .vb
1078: PetscInitialize(...);
1079: PetscLogBegin();
1080: ... code ...
1081: PetscLogPrintSummary(MPI_Comm,filename);
1082: PetscFinalize(...);
1083: .ve
1085: Notes:
1086: By default the summary is printed to stdout.
1087: More extensive examination of the log information can be done with
1088: PetscLogDump(), which is activated by the option -log or -log_all, in
1089: combination with petsc/bin/petscview.
1091: Level: beginner
1092:
1093: .keywords: log, dump, print
1094: .seealso: PetscLogBegin(), PetscLogDump()
1095: @*/
1096: int PetscLogPrintSummary(MPI_Comm comm, const char filename[]) {
1097: FILE *fd = stdout;
1098: PetscScalar zero = 0.0;
1099: StageLog stageLog;
1100: StageInfo *stageInfo = PETSC_NULL;
1101: EventPerfInfo *eventInfo = PETSC_NULL;
1102: ClassPerfInfo *classInfo;
1103: char arch[10], hostname[64], username[16], pname[256], date[64];
1104: char *name;
1105: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1106: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1107: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1108: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1109: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1110: PetscLogDouble min, max, tot, ratio, avg, x, y;
1111: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1112: int minCt, maxCt;
1113: int numProcs, rank;
1114: PetscTruth *localStageUsed, *stageUsed;
1115: PetscTruth *localStageVisible, *stageVisible;
1116: int numStages, localNumEvents, numEvents;
1117: int stage, event, oclass;
1118: int ierr;
1119: char version[256];
1122: MPI_Comm_size(comm, &numProcs);
1123: MPI_Comm_rank(comm, &rank);
1124: /* Pop off any stages the user forgot to remove */
1125: PetscLogGetStageLog(&stageLog);
1126: StageLogGetCurrent(stageLog, &stage);
1127: while (stage >= 0) {
1128: StageLogPop(stageLog);
1129: StageLogGetCurrent(stageLog, &stage);
1130: }
1131: /* Get the total elapsed time */
1132: PetscTime(locTotalTime); locTotalTime -= BaseTime;
1133: /* Open the summary file */
1134: if (filename != PETSC_NULL) {
1135: PetscFOpen(comm, filename, "w", &fd);
1136: }
1138: PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1139: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***n");
1140: PetscFPrintf(comm, fd, "************************************************************************************************************************n");
1141: PetscFPrintf(comm, fd, "n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------nn");
1142: PetscGetArchType(arch, 10);
1143: PetscGetHostName(hostname, 64);
1144: PetscGetUserName(username, 16);
1145: PetscGetProgramName(pname, 256);
1146: PetscGetDate(date, 64);
1147: PetscGetVersion(&version);
1148: if (numProcs == 1) {
1149: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %sn", pname, arch, hostname, numProcs, username, date);
1150:
1151: } else {
1152: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %sn", pname, arch, hostname, numProcs, username, date);
1153:
1154: }
1155: PetscFPrintf(comm, fd, "Using %sn", version);
1157: /* Must preserve reduction count before we go on */
1158: red = allreduce_ct/((PetscLogDouble) numProcs);
1160: /* Calculate summary information */
1161: PetscFPrintf(comm, fd, "n Max Max/Min Avg Total n");
1162: /* Time */
1163: MPI_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1164: MPI_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1165: MPI_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1166: avg = (tot)/((PetscLogDouble) numProcs);
1167: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1168: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3en", max, ratio, avg);
1169: TotalTime = tot;
1170: /* Objects */
1171: avg = (PetscLogDouble) numObjects;
1172: MPI_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1173: MPI_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1174: MPI_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1175: avg = (tot)/((PetscLogDouble) numProcs);
1176: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1177: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3en", max, ratio, avg);
1178: /* Flops */
1179: MPI_Allreduce(&_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1180: MPI_Allreduce(&_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1181: MPI_Allreduce(&_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1182: avg = (tot)/((PetscLogDouble) numProcs);
1183: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1184: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1185: TotalFlops = tot;
1186: /* Flops/sec -- Must talk to Barry here */
1187: if (locTotalTime != 0.0) flops = _TotalFlops/locTotalTime; else flops = 0.0;
1188: MPI_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1189: MPI_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1190: MPI_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1191: avg = (tot)/((PetscLogDouble) numProcs);
1192: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1193: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1194: /* Memory */
1195: PetscTrSpace(PETSC_NULL, PETSC_NULL, &mem);
1196: if (mem > 0.0) {
1197: MPI_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1198: MPI_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1199: MPI_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1200: avg = (tot)/((PetscLogDouble) numProcs);
1201: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1202: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3en", max, ratio, tot);
1203: }
1204: /* Messages */
1205: mess = 0.5*(irecv_ct + isend_ct + recv_ct + send_ct);
1206: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1207: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1208: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1209: avg = (tot)/((PetscLogDouble) numProcs);
1210: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1211: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1212: numMessages = tot;
1213: /* Message Lengths */
1214: mess = 0.5*(irecv_len + isend_len + recv_len + send_len);
1215: MPI_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1216: MPI_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1217: MPI_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1218: if (numMessages != 0) avg = (tot)/(numMessages); else avg = 0.0;
1219: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1220: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3en", max, ratio, avg, tot);
1221: messageLength = tot;
1222: /* Reductions */
1223: MPI_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1224: MPI_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1225: MPI_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1226: if (min != 0.0) ratio = max/min; else ratio = 0.0;
1227: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5fn", max, ratio);
1228: numReductions = tot;
1229: PetscFPrintf(comm, fd, "nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)n");
1230: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flopsn");
1231: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flopsn");
1233: /* Get total number of stages --
1234: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1235: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1236: This seems best accomplished by assoicating a communicator with each stage.
1237: */
1238: MPI_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1239: PetscMalloc(numStages * sizeof(PetscTruth), &localStageUsed);
1240: PetscMalloc(numStages * sizeof(PetscTruth), &stageUsed);
1241: PetscMalloc(numStages * sizeof(PetscTruth), &localStageVisible);
1242: PetscMalloc(numStages * sizeof(PetscTruth), &stageVisible);
1243: if (numStages > 0) {
1244: stageInfo = stageLog->stageInfo;
1245: for(stage = 0; stage < numStages; stage++) {
1246: if (stage < stageLog->numStages) {
1247: localStageUsed[stage] = stageInfo[stage].used;
1248: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1249: } else {
1250: localStageUsed[stage] = PETSC_FALSE;
1251: localStageVisible[stage] = PETSC_TRUE;
1252: }
1253: }
1254: MPI_Allreduce(localStageUsed, stageUsed, numStages, MPI_INT, MPI_LOR, comm);
1255: MPI_Allreduce(localStageVisible, stageVisible, numStages, MPI_INT, MPI_LAND, comm);
1256: for(stage = 0; stage < numStages; stage++) {
1257: if (stageUsed[stage] == PETSC_TRUE) {
1258: PetscFPrintf(comm, fd, "nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --n");
1259: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total n");
1260: break;
1261: }
1262: }
1263: for(stage = 0; stage < numStages; stage++) {
1264: if (stageUsed[stage] == PETSC_FALSE) continue;
1265: if (localStageUsed[stage] == PETSC_TRUE) {
1266: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1267: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1268: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1269: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1270: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1271: name = stageInfo[stage].name;
1272: } else {
1273: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1274: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1275: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1276: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1277: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1278: name = "";
1279: }
1280: mess *= 0.5; messLen *= 0.5; red /= numProcs;
1281: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1282: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1283: /* Talk to Barry if (stageTime != 0.0) flops = (numProcs*flops)/stageTime; else flops = 0.0; */
1284: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1285: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1286: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1287: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1288: 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",
1289: stage, name, stageTime/numProcs, 100.0*fracTime, flops, 100.0*fracFlops,
1290: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1291:
1292: }
1293: }
1295: PetscFPrintf(comm, fd,
1296: "n------------------------------------------------------------------------------------------------------------------------n");
1297:
1298: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.n");
1299: PetscFPrintf(comm, fd, "Phase summary info:n");
1300: PetscFPrintf(comm, fd, " Count: number of times phase was executedn");
1301: PetscFPrintf(comm, fd, " Time and Flops/sec: Max - maximum over all processorsn");
1302: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processorsn");
1303: PetscFPrintf(comm, fd, " Mess: number of messages sentn");
1304: PetscFPrintf(comm, fd, " Avg. len: average message lengthn");
1305: PetscFPrintf(comm, fd, " Reduct: number of global reductionsn");
1306: PetscFPrintf(comm, fd, " Global: entire computationn");
1307: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().n");
1308: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phasen");
1309: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phasen");
1310: PetscFPrintf(comm, fd, " %%R - percent reductions in this phasen");
1311: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)n");
1312: PetscFPrintf(comm, fd,
1313: "------------------------------------------------------------------------------------------------------------------------n");
1314:
1316: #if defined(PETSC_USE_BOPT_g)
1317: PetscFPrintf(comm, fd, "nn");
1318: PetscFPrintf(comm, fd, " ##########################################################n");
1319: PetscFPrintf(comm, fd, " # #n");
1320: PetscFPrintf(comm, fd, " # WARNING!!! #n");
1321: PetscFPrintf(comm, fd, " # #n");
1322: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #n");
1323: PetscFPrintf(comm, fd, " # BOPT=<g,g_c++,g_complex>. To get timing results #n");
1324: PetscFPrintf(comm, fd, " # ALWAYS compile your code with an optimized version, #n");
1325: PetscFPrintf(comm, fd, " # BOPT=<O,O_c++,O_complex>; the performance will #n");
1326: PetscFPrintf(comm, fd, " # be generally two or three times faster. #n");
1327: PetscFPrintf(comm, fd, " # #n");
1328: PetscFPrintf(comm, fd, " ##########################################################nnn");
1329: #endif
1330: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1331: PetscFPrintf(comm, fd, "nn");
1332: PetscFPrintf(comm, fd, " ##########################################################n");
1333: PetscFPrintf(comm, fd, " # #n");
1334: PetscFPrintf(comm, fd, " # WARNING!!! #n");
1335: PetscFPrintf(comm, fd, " # #n");
1336: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #n");
1337: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #n");
1338: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #n");
1339: PetscFPrintf(comm, fd, " # faster, specify the flag -DPETSC_USE_FORTRAN_KERNELS #n");
1340: PetscFPrintf(comm, fd, " # in base_variables and recompile the PETSc libraries. #n");
1341: PetscFPrintf(comm, fd, " # #n");
1342: PetscFPrintf(comm, fd, " ##########################################################nnn");
1343: #endif
1345: if (!PetscPreLoadingUsed) {
1346: PetscFPrintf(comm,fd,"nn");
1347: PetscFPrintf(comm,fd," ##########################################################n");
1348: PetscFPrintf(comm,fd," # #n");
1349: PetscFPrintf(comm,fd," # WARNING!!! #n");
1350: PetscFPrintf(comm,fd," # #n");
1351: PetscFPrintf(comm,fd," # This code was run without the PreLoadinBegin() #n");
1352: PetscFPrintf(comm,fd," # macros. To get timing results we always recommend #n");
1353: PetscFPrintf(comm,fd," # preloading. otherwise timing numbers may be #n");
1354: PetscFPrintf(comm,fd," # meaningless. #n");
1355: PetscFPrintf(comm,fd," ##########################################################nnn");
1356: }
1358: /* Report events */
1359: PetscFPrintf(comm, fd,
1360: "Event Count Time (sec) Flops/sec --- Global --- --- Stage --- Totaln");
1361:
1362: PetscFPrintf(comm, fd,
1363: " Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/sn");
1364:
1365: PetscFPrintf(comm,fd,
1366: "------------------------------------------------------------------------------------------------------------------------n");
1368:
1369: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1370: for(stage = 0; stage < numStages; stage++) {
1371: if (stageVisible[stage] == PETSC_FALSE) continue;
1372: if (localStageUsed[stage] == PETSC_TRUE) {
1373: PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1374: MPI_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1375: MPI_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1376: MPI_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1377: MPI_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1378: MPI_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1379: } else {
1380: PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1381: MPI_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1382: MPI_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1383: MPI_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1384: MPI_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1385: MPI_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1386: }
1387: mess *= 0.5; messLen *= 0.5; red /= numProcs;
1389: /* Get total number of events in this stage --
1390: Currently, a single processor can register more events than another, but events must all be registered in order,
1391: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1392: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1394: Problem: If the event did not happen on proc 1, its name will not be available.
1395: Problem: Event visibility is not implemented
1396: */
1397: if (localStageUsed[stage] == PETSC_TRUE) {
1398: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1399: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1400: } else {
1401: localNumEvents = 0;
1402: }
1403: MPI_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1404: for(event = 0; event < numEvents; event++) {
1405: if ((localStageUsed[stage] == PETSC_TRUE) && (event < stageLog->stageInfo[stage].eventLog->numEvents)) {
1406: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) {
1407: flopr = eventInfo[event].flops/eventInfo[event].time;
1408: } else {
1409: flopr = 0.0;
1410: }
1411: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1412: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1413: MPI_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1414: MPI_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1415: MPI_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1416: MPI_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1417: MPI_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1418: MPI_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1419: MPI_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1420: MPI_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1421: MPI_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1422: name = stageLog->eventLog->eventInfo[event].name;
1423: } else {
1424: flopr = 0.0;
1425: MPI_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1426: MPI_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1427: MPI_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1428: MPI_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1429: MPI_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1430: MPI_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1431: MPI_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1432: MPI_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1433: MPI_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1434: MPI_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1435: MPI_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1436: name = "";
1437: }
1438: totm *= 0.5; totml *= 0.5; totr /= numProcs;
1439:
1440: if (maxCt != 0) {
1441: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1442: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1443: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1444: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1445: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1446: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1447: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1448: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1449: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1450: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1451: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1452: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1453: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1454: if (totm != 0.0) totml /= totm; else totml = 0.0;
1455: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1456: PetscFPrintf(comm, fd,
1457: "%-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.0fn",
1458: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1459: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1460: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1461: flopr/1.0e6);
1462:
1463: }
1464: }
1465: }
1467: /* Memory usage and object creation */
1468: PetscFPrintf(comm, fd,
1469: "------------------------------------------------------------------------------------------------------------------------n");
1470:
1471: PetscFPrintf(comm, fd, "n");
1472: PetscFPrintf(comm, fd, "Memory usage is given in bytes:nn");
1474: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1475: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1476: stats for stages local to processor sets.
1477: */
1478: /* We should figure out the longest object name here (now 20 characters) */
1479: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.n");
1480: for(stage = 0; stage < numStages; stage++) {
1481: if (localStageUsed[stage] == PETSC_TRUE) {
1482: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1483: PetscFPrintf(comm, fd, "n--- Event Stage %d: %snn", stage, stageInfo[stage].name);
1484: for(oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1485: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1486: PetscFPrintf(comm, fd, "%20s %5d %5d %9d %gn", stageLog->classLog->classInfo[oclass].name,
1487: classInfo[oclass].creations, classInfo[oclass].destructions, (int) classInfo[oclass].mem,
1488: classInfo[oclass].descMem);
1489:
1490: }
1491: }
1492: } else {
1493: PetscFPrintf(comm, fd, "n--- Event Stage %d: Unknownnn", stage);
1494: }
1495: }
1497: PetscFree(localStageUsed);
1498: PetscFree(stageUsed);
1499: PetscFree(localStageVisible);
1500: PetscFree(stageVisible);
1502: /* Information unrelated to this particular run */
1503: PetscFPrintf(comm, fd,
1504: "========================================================================================================================n");
1505:
1506: PetscTime(y);
1507: PetscTime(x);
1508: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1509: PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y); PetscTime(y);
1510: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %gn", (y-x)/10.0);
1511: /* MPI information */
1512: if (numProcs > 1) {
1513: MPI_Status status;
1514: int tag;
1516: MPI_Barrier(comm);
1517: PetscTime(x);
1518: MPI_Barrier(comm);
1519: MPI_Barrier(comm);
1520: MPI_Barrier(comm);
1521: MPI_Barrier(comm);
1522: MPI_Barrier(comm);
1523: PetscTime(y);
1524: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %gn", (y-x)/5.0);
1525: PetscCommGetNewTag(comm, &tag);
1526: MPI_Barrier(comm);
1527: if (rank) {
1528: MPI_Recv(0, 0, MPI_INT, rank-1, tag, comm, &status);
1529: MPI_Send(0, 0, MPI_INT, (rank+1)%numProcs, tag, comm);
1530: } else {
1531: PetscTime(x);
1532: MPI_Send(0, 0, MPI_INT, 1, tag, comm);
1533: MPI_Recv(0, 0, MPI_INT, numProcs-1, tag, comm, &status);
1534: PetscTime(y);
1535: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %gn", (y-x)/numProcs);
1536: }
1537: }
1538: /* Machine and compile information */
1539: #if defined(PETSC_USE_FORTRAN_KERNELS)
1540: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernelsn");
1541: #else
1542: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernelsn");
1543: #endif
1544: #if defined(PETSC_USE_MAT_SINGLE)
1545: PetscFPrintf(comm, fd, "Compiled with single precision matricesn");
1546: #else
1547: PetscFPrintf(comm, fd, "Compiled with double precision matrices (default)n");
1548: #endif
1549: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void *) %d",
1550: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*));
1551:
1553: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1554: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1555: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1556: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1558: /* Cleanup */
1559: PetscFPrintf(comm, fd, "n");
1560: PetscFClose(comm, fd);
1561: return(0);
1562: }
1564: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1565: /*@C
1566: PetscGetFlops - Returns the number of flops used on this processor
1567: since the program began.
1569: Not Collective
1571: Output Parameter:
1572: flops - number of floating point operations
1574: Notes:
1575: A global counter logs all PETSc flop counts. The user can use
1576: PetscLogFlops() to increment this counter to include flops for the
1577: application code.
1579: PETSc automatically logs library events if the code has been
1580: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1581: -log_summary, or -log_all are specified. PetscLogFlops() is
1582: intended for logging user flops to supplement this PETSc
1583: information.
1585: Level: intermediate
1587: .keywords: log, flops, floating point operations
1589: .seealso: PetscGetTime(), PetscLogFlops()
1590: @*/
1591: int PetscGetFlops(PetscLogDouble *flops)
1592: {
1594: *flops = _TotalFlops;
1595: return(0);
1596: }
1598: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1599: {
1600: va_list Argp;
1603: if (logObjects == PETSC_FALSE) return(0);
1604: va_start(Argp, format);
1605: #if defined(PETSC_HAVE_VPRINTF_CHAR)
1606: vsprintf(objects[obj->id].info, format, (char *) Argp);
1607: #else
1608: vsprintf(objects[obj->id].info, format, Argp);
1609: #endif
1610: va_end(Argp);
1611: return(0);
1612: }
1614: #else /* end of -DPETSC_USE_LOG section */
1616: int PetscLogObjectState(PetscObject obj, const char format[], ...)
1617: {
1619: return(0);
1620: }
1622: #endif /* PETSC_USE_LOG*/
1624: /*@
1625: PetscGetTime - Returns the current time of day in seconds. This
1626: returns wall-clock time.
1628: Not Collective
1630: Output Parameter:
1631: . v - time counter
1633: Usage:
1634: .vb
1635: PetscLogDouble v1,v2,elapsed_time;
1636: PetscGetTime(&v1);CHKERR(ierr);
1637: .... perform some calculation ...
1638: PetscGetTime(&v2);CHKERR(ierr);
1639: elapsed_time = v2 - v1;
1640: .ve
1642: Notes:
1643: Since the PETSc libraries incorporate timing of phases and operations,
1644: PetscGetTime() is intended only for timing of application codes.
1645: The options database commands -log, -log_summary, and -log_all activate
1646: PETSc library timing. See the users manual for further details.
1648: Level: intermediate
1650: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStagePush(),
1651: PetscLogStagePop(), PetscLogStageRegister(), PetscGetFlops()
1653: .keywords: get, time
1654: @*/
1655: int PetscGetTime(PetscLogDouble *t)
1656: {
1658: PetscTime(*t);
1659: return(0);
1660: }
1662: /*@
1663: PetscLogGetStageLog - This function returns the default stage logging object.
1665: Not collective
1667: Output Parameter:
1668: . stageLog - The default StageLog
1670: Level: beginner
1672: .keywords: log, stage
1673: .seealso: StageLogCreate()
1674: @*/
1675: int PetscLogGetStageLog(StageLog *stageLog)
1676: {
1679: *stageLog = _stageLog;
1680: return(0);
1681: }
1683: /*MC
1684: PetscLogFlops - Adds floating point operations to the global counter.
1686: Input Parameter:
1687: . f - flop counter
1689: Synopsis:
1690: void PetscLogFlops(int f)
1692: Usage:
1693: .vb
1694: int USER_EVENT;
1695: PetscLogEventRegister(&USER_EVENT,"User event");
1696: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1697: [code segment to monitor]
1698: PetscLogFlops(user_flops)
1699: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1700: .ve
1702: Notes:
1703: A global counter logs all PETSc flop counts. The user can use
1704: PetscLogFlops() to increment this counter to include flops for the
1705: application code.
1707: PETSc automatically logs library events if the code has been
1708: compiled with -DPETSC_USE_LOG (which is the default), and -log,
1709: -log_summary, or -log_all are specified. PetscLogFlops() is
1710: intended for logging user flops to supplement this PETSc
1711: information.
1713: Level: intermediate
1715: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1717: .keywords: log, flops, floating point operations
1718: M*/
1720: PetscTruth PetscPreLoadingUsed = PETSC_FALSE;
1721: PetscTruth PetscPreLoadingOn = PETSC_FALSE;
1723: /*MC
1724: PreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1725: to get accurate timings
1727: Input Parameter:
1728: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1729: with command line option -preload true or -preload false
1730: - name - name of first stage (lines of code timed seperately with -log_summary) to
1731: be preloaded
1733: Synopsis:
1734: void PreLoadBegin(PetscTruth flag,char *name);
1736: Usage:
1737: .vb
1738: PreLoadBegin(PETSC_TRUE,"first stage);
1739: lines of code
1740: PreLoadStage("second stage");
1741: lines of code
1742: PreLoadEnd();
1743: .ve
1745: Level: intermediate
1747: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadEnd(), PreLoadStage()
1749: Concepts: preloading
1750: Concepts: timing^accurate
1751: Concepts: paging^eliminating effects of
1754: M*/
1756: /*MC
1757: PreLoadEnd - End a segment of code that may be preloaded (run twice)
1758: to get accurate timings
1760: Synopsis:
1761: void PreLoadEnd(void);
1763: Usage:
1764: .vb
1765: PreLoadBegin(PETSC_TRUE,"first stage);
1766: lines of code
1767: PreLoadStage("second stage");
1768: lines of code
1769: PreLoadEnd();
1770: .ve
1772: Level: intermediate
1774: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadStage()
1776: M*/
1778: /*MC
1779: PreLoadStage - Start a new segment of code to be timed seperately.
1780: to get accurate timings
1782: Synopsis:
1783: void PreLoadStage(char *name);
1785: Usage:
1786: .vb
1787: PreLoadBegin(PETSC_TRUE,"first stage);
1788: lines of code
1789: PreLoadStage("second stage");
1790: lines of code
1791: PreLoadEnd();
1792: .ve
1794: Level: intermediate
1796: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PreLoadBegin(), PreLoadEnd()
1798: M*/
1800: /*----------------------------------------------- Stack Functions ---------------------------------------------------*/
1801: /*@C
1802: StackDestroy - This function destroys a stack.
1804: Not Collective
1806: Input Parameter:
1807: . stack - The stack
1809: Level: beginner
1811: .keywords: log, stack, destroy
1812: .seealso: StackCreate(), StackEmpty(), StackPush(), StackPop(), StackTop()
1813: @*/
1814: int StackDestroy(IntStack stack)
1815: {
1819: PetscFree(stack->stack);
1820: PetscFree(stack);
1821: return(0);
1822: }
1824: /*@C
1825: StackEmpty - This function determines whether any items have been pushed.
1827: Not Collective
1829: Input Parameter:
1830: . stack - The stack
1832: Output Parameter:
1833: . empty - PETSC_TRUE if the stack is empty
1835: Level: intermediate
1837: .keywords: log, stack, empty
1838: .seealso: StackCreate(), StackDestroy(), StackPush(), StackPop(), StackTop()
1839: @*/
1840: int StackEmpty(IntStack stack, PetscTruth *empty)
1841: {
1844: if (stack->top == -1) {
1845: *empty = PETSC_TRUE;
1846: } else {
1847: *empty = PETSC_FALSE;
1848: }
1849: return(0);
1850: }
1852: /*@C
1853: StackTop - This function returns the top of the stack.
1855: Not Collective
1857: Input Parameter:
1858: . stack - The stack
1860: Output Parameter:
1861: . top - The integer on top of the stack
1863: Level: intermediate
1865: .keywords: log, stack, top
1866: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackPop()
1867: @*/
1868: int StackTop(IntStack stack, int *top)
1869: {
1872: *top = stack->stack[stack->top];
1873: return(0);
1874: }
1876: /*@C
1877: StackPush - This function pushes an integer on the stack.
1879: Not Collective
1881: Input Parameters:
1882: + stack - The stack
1883: - item - The integer to push
1885: Level: intermediate
1887: .keywords: log, stack, push
1888: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPop(), StackTop()
1889: @*/
1890: int StackPush(IntStack stack, int item)
1891: {
1892: int *array;
1893: int ierr;
1896: stack->top++;
1897: if (stack->top >= stack->max) {
1898: PetscMalloc(stack->max*2 * sizeof(int), &array);
1899: PetscMemcpy(array, stack->stack, stack->max * sizeof(int));
1900: PetscFree(stack->stack);
1901: stack->stack = array;
1902: stack->max *= 2;
1903: }
1904: stack->stack[stack->top] = item;
1905: return(0);
1906: }
1908: /*@C
1909: StackPop - This function pops an integer from the stack.
1911: Not Collective
1913: Input Parameter:
1914: . stack - The stack
1916: Output Parameter:
1917: . item - The integer popped
1919: Level: intermediate
1921: .keywords: log, stack, pop
1922: .seealso: StackCreate(), StackDestroy(), StackEmpty(), StackPush(), StackTop()
1923: @*/
1924: int StackPop(IntStack stack, int *item)
1925: {
1928: if (stack->top == -1) SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Stack is empty");
1929: *item = stack->stack[stack->top--];
1930: return(0);
1931: }
1933: /*@C
1934: StackCreate - This function creates a stack.
1936: Not Collective
1938: Output Parameter:
1939: . stack - The stack
1941: Level: beginner
1943: .keywords: log, stack, pop
1944: .seealso: StackDestroy(), StackEmpty(), StackPush(), StackPop(), StackTop()
1945: @*/
1946: int StackCreate(IntStack *stack)
1947: {
1948: IntStack s;
1949: int ierr;
1953: PetscNew(struct _IntStack, &s);
1954: s->top = -1;
1955: s->max = 128;
1956: PetscMalloc(s->max * sizeof(int), &s->stack);
1957: PetscMemzero(s->stack, s->max * sizeof(int));
1958: *stack = s;
1959: return(0);
1960: }