Actual source code: plog.c
petsc-3.7.3 2016-08-01
2: /*
3: PETSc code to log object creation and destruction and PETSc events.
5: This provides the public API used by the rest of PETSc and by users.
7: These routines use a private API that is not used elsewhere in PETSc and is not
8: accessible to users. The private API is defined in logimpl.h and the utils directory.
10: */
11: #include <petsc/private/logimpl.h> /*I "petscsys.h" I*/
12: #include <petsctime.h>
13: #include <petscviewer.h>
15: PetscErrorCode PetscLogObjectParent(PetscObject p,PetscObject c)
16: {
17: if (!c || !p) return 0;
18: c->parent = p;
19: c->parentid = p->id;
20: return 0;
21: }
23: PetscErrorCode PetscLogObjectMemory(PetscObject p,PetscLogDouble m)
24: {
25: if (!p) return 0;
26: p->mem += m;
27: return 0;
28: }
30: PetscLogEvent PETSC_LARGEST_EVENT = PETSC_EVENT;
32: #if defined(PETSC_USE_LOG)
33: #include <petscmachineinfo.h>
34: #include <petscconfiginfo.h>
36: /* used in the MPI_XXX() count macros in petsclog.h */
38: /* Action and object logging variables */
39: Action *petsc_actions = NULL;
40: Object *petsc_objects = NULL;
41: PetscBool petsc_logActions = PETSC_FALSE;
42: PetscBool petsc_logObjects = PETSC_FALSE;
43: int petsc_numActions = 0, petsc_maxActions = 100;
44: int petsc_numObjects = 0, petsc_maxObjects = 100;
45: int petsc_numObjectsDestroyed = 0;
47: /* Global counters */
48: PetscLogDouble petsc_BaseTime = 0.0;
49: PetscLogDouble petsc_TotalFlops = 0.0; /* The number of flops */
50: PetscLogDouble petsc_tmp_flops = 0.0; /* The incremental number of flops */
51: PetscLogDouble petsc_send_ct = 0.0; /* The number of sends */
52: PetscLogDouble petsc_recv_ct = 0.0; /* The number of receives */
53: PetscLogDouble petsc_send_len = 0.0; /* The total length of all sent messages */
54: PetscLogDouble petsc_recv_len = 0.0; /* The total length of all received messages */
55: PetscLogDouble petsc_isend_ct = 0.0; /* The number of immediate sends */
56: PetscLogDouble petsc_irecv_ct = 0.0; /* The number of immediate receives */
57: PetscLogDouble petsc_isend_len = 0.0; /* The total length of all immediate send messages */
58: PetscLogDouble petsc_irecv_len = 0.0; /* The total length of all immediate receive messages */
59: PetscLogDouble petsc_wait_ct = 0.0; /* The number of waits */
60: PetscLogDouble petsc_wait_any_ct = 0.0; /* The number of anywaits */
61: PetscLogDouble petsc_wait_all_ct = 0.0; /* The number of waitalls */
62: PetscLogDouble petsc_sum_of_waits_ct = 0.0; /* The total number of waits */
63: PetscLogDouble petsc_allreduce_ct = 0.0; /* The number of reductions */
64: PetscLogDouble petsc_gather_ct = 0.0; /* The number of gathers and gathervs */
65: PetscLogDouble petsc_scatter_ct = 0.0; /* The number of scatters and scattervs */
67: /* Logging functions */
68: PetscErrorCode (*PetscLogPHC)(PetscObject) = NULL;
69: PetscErrorCode (*PetscLogPHD)(PetscObject) = NULL;
70: PetscErrorCode (*PetscLogPLB)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
71: PetscErrorCode (*PetscLogPLE)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject) = NULL;
73: /* Tracing event logging variables */
74: FILE *petsc_tracefile = NULL;
75: int petsc_tracelevel = 0;
76: const char *petsc_traceblanks = " ";
77: char petsc_tracespace[128] = " ";
78: PetscLogDouble petsc_tracetime = 0.0;
79: static PetscBool PetscLogInitializeCalled = PETSC_FALSE;
81: /*---------------------------------------------- General Functions --------------------------------------------------*/
84: /*@C
85: PetscLogDestroy - Destroys the object and event logging data and resets the global counters.
87: Not Collective
89: Notes:
90: This routine should not usually be used by programmers. Instead employ
91: PetscLogStagePush() and PetscLogStagePop().
93: Level: developer
95: .keywords: log, destroy
96: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogStagePush(), PlogStagePop()
97: @*/
98: PetscErrorCode PetscLogDestroy(void)
99: {
100: PetscStageLog stageLog;
104: PetscFree(petsc_actions);
105: PetscFree(petsc_objects);
106: PetscLogSet(NULL, NULL);
108: /* Resetting phase */
109: PetscLogGetStageLog(&stageLog);
110: PetscStageLogDestroy(stageLog);
112: petsc_TotalFlops = 0.0;
113: petsc_numActions = 0;
114: petsc_numObjects = 0;
115: petsc_numObjectsDestroyed = 0;
116: petsc_maxActions = 100;
117: petsc_maxObjects = 100;
118: petsc_actions = NULL;
119: petsc_objects = NULL;
120: petsc_logActions = PETSC_FALSE;
121: petsc_logObjects = PETSC_FALSE;
122: petsc_BaseTime = 0.0;
123: petsc_TotalFlops = 0.0;
124: petsc_tmp_flops = 0.0;
125: petsc_send_ct = 0.0;
126: petsc_recv_ct = 0.0;
127: petsc_send_len = 0.0;
128: petsc_recv_len = 0.0;
129: petsc_isend_ct = 0.0;
130: petsc_irecv_ct = 0.0;
131: petsc_isend_len = 0.0;
132: petsc_irecv_len = 0.0;
133: petsc_wait_ct = 0.0;
134: petsc_wait_any_ct = 0.0;
135: petsc_wait_all_ct = 0.0;
136: petsc_sum_of_waits_ct = 0.0;
137: petsc_allreduce_ct = 0.0;
138: petsc_gather_ct = 0.0;
139: petsc_scatter_ct = 0.0;
140: PETSC_LARGEST_EVENT = PETSC_EVENT;
141: PetscLogPHC = NULL;
142: PetscLogPHD = NULL;
143: petsc_tracefile = NULL;
144: petsc_tracelevel = 0;
145: petsc_traceblanks = " ";
146: petsc_tracespace[0] = ' '; petsc_tracespace[1] = 0;
147: petsc_tracetime = 0.0;
148: PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
149: PETSC_OBJECT_CLASSID = 0;
150: petsc_stageLog = 0;
151: PetscLogInitializeCalled = PETSC_FALSE;
152: return(0);
153: }
157: /*@C
158: PetscLogSet - Sets the logging functions called at the beginning and ending of every event.
160: Not Collective
162: Input Parameters:
163: + b - The function called at beginning of event
164: - e - The function called at end of event
166: Level: developer
168: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogTraceBegin()
169: @*/
170: PetscErrorCode PetscLogSet(PetscErrorCode (*b)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject),
171: PetscErrorCode (*e)(PetscLogEvent, int, PetscObject, PetscObject, PetscObject, PetscObject))
172: {
174: PetscLogPLB = b;
175: PetscLogPLE = e;
176: return(0);
177: }
179: #if defined(PETSC_HAVE_PAPI)
180: #include <papi.h>
181: int PAPIEventSet = PAPI_NULL;
182: #endif
184: /*------------------------------------------- Initialization Functions ----------------------------------------------*/
187: /*
188: The data structures for logging are always created even if no logging is turned on. This is so events etc can
189: be registered in the code before the actually logging is turned on.
190: */
191: PetscErrorCode PetscLogInitialize(void)
192: {
193: int stage;
194: PetscBool opt;
198: if (PetscLogInitializeCalled) return(0);
199: PetscLogInitializeCalled = PETSC_TRUE;
201: PetscOptionsHasName(NULL,NULL, "-log_exclude_actions", &opt);
202: if (opt) petsc_logActions = PETSC_FALSE;
203: PetscOptionsHasName(NULL,NULL, "-log_exclude_objects", &opt);
204: if (opt) petsc_logObjects = PETSC_FALSE;
205: if (petsc_logActions) {
206: PetscMalloc1(petsc_maxActions, &petsc_actions);
207: }
208: if (petsc_logObjects) {
209: PetscMalloc1(petsc_maxObjects, &petsc_objects);
210: }
211: PetscLogPHC = PetscLogObjCreateDefault;
212: PetscLogPHD = PetscLogObjDestroyDefault;
213: /* Setup default logging structures */
214: PetscStageLogCreate(&petsc_stageLog);
215: PetscStageLogRegister(petsc_stageLog, "Main Stage", &stage);
216: #if defined(PETSC_HAVE_PAPI)
217: PAPI_library_init(PAPI_VER_CURRENT);
218: if (ierr != PAPI_VER_CURRENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot initialize PAPI");
219: PAPI_query_event(PAPI_FP_INS);
220: PAPI_create_eventset(&PAPIEventSet);
221: PAPI_add_event(PAPIEventSet,PAPI_FP_INS);
222: PAPI_start(PAPIEventSet);
223: #endif
225: /* All processors sync here for more consistent logging */
226: MPI_Barrier(PETSC_COMM_WORLD);
227: PetscTime(&petsc_BaseTime);
228: PetscLogStagePush(stage);
229: return(0);
230: }
234: /*@C
235: PetscLogDefaultBegin - Turns on logging of objects and events. This logs flop
236: rates and object creation and should not slow programs down too much.
237: This routine may be called more than once.
239: Logically Collective over PETSC_COMM_WORLD
241: Options Database Keys:
242: . -log_view [viewertype:filename:viewerformat] - Prints summary of flop and timing information to the
243: screen (for code configured with --with-log=1 (which is the default))
245: Usage:
246: .vb
247: PetscInitialize(...);
248: PetscLogDefaultBegin();
249: ... code ...
250: PetscLogView(viewer); or PetscLogDump();
251: PetscFinalize();
252: .ve
254: Notes:
255: PetscLogView(viewer) or PetscLogDump() actually cause the printing of
256: the logging information.
258: Level: advanced
260: .keywords: log, begin
261: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogTraceBegin()
262: @*/
263: PetscErrorCode PetscLogDefaultBegin(void)
264: {
268: PetscLogSet(PetscLogEventBeginDefault, PetscLogEventEndDefault);
269: return(0);
270: }
274: /*@C
275: PetscLogAllBegin - Turns on extensive logging of objects and events. Logs
276: all events. This creates large log files and slows the program down.
278: Logically Collective on PETSC_COMM_WORLD
280: Options Database Keys:
281: . -log_all - Prints extensive log information
283: Usage:
284: .vb
285: PetscInitialize(...);
286: PetscLogAllBegin();
287: ... code ...
288: PetscLogDump(filename);
289: PetscFinalize();
290: .ve
292: Notes:
293: A related routine is PetscLogDefaultBegin() (with the options key -log), which is
294: intended for production runs since it logs only flop rates and object
295: creation (and shouldn't significantly slow the programs).
297: Level: advanced
299: .keywords: log, all, begin
300: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogTraceBegin()
301: @*/
302: PetscErrorCode PetscLogAllBegin(void)
303: {
307: PetscLogSet(PetscLogEventBeginComplete, PetscLogEventEndComplete);
308: return(0);
309: }
313: /*@
314: PetscLogTraceBegin - Activates trace logging. Every time a PETSc event
315: begins or ends, the event name is printed.
317: Logically Collective on PETSC_COMM_WORLD
319: Input Parameter:
320: . file - The file to print trace in (e.g. stdout)
322: Options Database Key:
323: . -log_trace [filename] - Activates PetscLogTraceBegin()
325: Notes:
326: PetscLogTraceBegin() prints the processor number, the execution time (sec),
327: then "Event begin:" or "Event end:" followed by the event name.
329: PetscLogTraceBegin() allows tracing of all PETSc calls, which is useful
330: to determine where a program is hanging without running in the
331: debugger. Can be used in conjunction with the -info option.
333: Level: intermediate
335: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogView(), PetscLogDefaultBegin()
336: @*/
337: PetscErrorCode PetscLogTraceBegin(FILE *file)
338: {
342: petsc_tracefile = file;
344: PetscLogSet(PetscLogEventBeginTrace, PetscLogEventEndTrace);
345: return(0);
346: }
350: /*@
351: PetscLogActions - Determines whether actions are logged for the graphical viewer.
353: Not Collective
355: Input Parameter:
356: . flag - PETSC_TRUE if actions are to be logged
358: Level: intermediate
360: Note: Logging of actions continues to consume more memory as the program
361: runs. Long running programs should consider turning this feature off.
363: Options Database Keys:
364: . -log_exclude_actions - Turns off actions logging
366: .keywords: log, stage, register
367: .seealso: PetscLogStagePush(), PetscLogStagePop()
368: @*/
369: PetscErrorCode PetscLogActions(PetscBool flag)
370: {
372: petsc_logActions = flag;
373: return(0);
374: }
378: /*@
379: PetscLogObjects - Determines whether objects are logged for the graphical viewer.
381: Not Collective
383: Input Parameter:
384: . flag - PETSC_TRUE if objects are to be logged
386: Level: intermediate
388: Note: Logging of objects continues to consume more memory as the program
389: runs. Long running programs should consider turning this feature off.
391: Options Database Keys:
392: . -log_exclude_objects - Turns off objects logging
394: .keywords: log, stage, register
395: .seealso: PetscLogStagePush(), PetscLogStagePop()
396: @*/
397: PetscErrorCode PetscLogObjects(PetscBool flag)
398: {
400: petsc_logObjects = flag;
401: return(0);
402: }
404: /*------------------------------------------------ Stage Functions --------------------------------------------------*/
407: /*@C
408: PetscLogStageRegister - Attaches a charactor string name to a logging stage.
410: Not Collective
412: Input Parameter:
413: . sname - The name to associate with that stage
415: Output Parameter:
416: . stage - The stage number
418: Level: intermediate
420: .keywords: log, stage, register
421: .seealso: PetscLogStagePush(), PetscLogStagePop()
422: @*/
423: PetscErrorCode PetscLogStageRegister(const char sname[],PetscLogStage *stage)
424: {
425: PetscStageLog stageLog;
426: PetscLogEvent event;
430: PetscLogGetStageLog(&stageLog);
431: PetscStageLogRegister(stageLog, sname, stage);
432: /* Copy events already changed in the main stage, this sucks */
433: EventPerfLogEnsureSize(stageLog->stageInfo[*stage].eventLog, stageLog->eventLog->numEvents);
434: for (event = 0; event < stageLog->eventLog->numEvents; event++) {
435: EventPerfInfoCopy(&stageLog->stageInfo[0].eventLog->eventInfo[event],&stageLog->stageInfo[*stage].eventLog->eventInfo[event]);
436: }
437: ClassPerfLogEnsureSize(stageLog->stageInfo[*stage].classLog, stageLog->classLog->numClasses);
438: return(0);
439: }
443: /*@C
444: PetscLogStagePush - This function pushes a stage on the stack.
446: Not Collective
448: Input Parameter:
449: . stage - The stage on which to log
451: Usage:
452: If the option -log_sumary is used to run the program containing the
453: following code, then 2 sets of summary data will be printed during
454: PetscFinalize().
455: .vb
456: PetscInitialize(int *argc,char ***args,0,0);
457: [stage 0 of code]
458: PetscLogStagePush(1);
459: [stage 1 of code]
460: PetscLogStagePop();
461: PetscBarrier(...);
462: [more stage 0 of code]
463: PetscFinalize();
464: .ve
466: Notes:
467: Use PetscLogStageRegister() to register a stage.
469: Level: intermediate
471: .keywords: log, push, stage
472: .seealso: PetscLogStagePop(), PetscLogStageRegister(), PetscBarrier()
473: @*/
474: PetscErrorCode PetscLogStagePush(PetscLogStage stage)
475: {
476: PetscStageLog stageLog;
480: PetscLogGetStageLog(&stageLog);
481: PetscStageLogPush(stageLog, stage);
482: return(0);
483: }
487: /*@C
488: PetscLogStagePop - This function pops a stage from the stack.
490: Not Collective
492: Usage:
493: If the option -log_sumary is used to run the program containing the
494: following code, then 2 sets of summary data will be printed during
495: PetscFinalize().
496: .vb
497: PetscInitialize(int *argc,char ***args,0,0);
498: [stage 0 of code]
499: PetscLogStagePush(1);
500: [stage 1 of code]
501: PetscLogStagePop();
502: PetscBarrier(...);
503: [more stage 0 of code]
504: PetscFinalize();
505: .ve
507: Notes:
508: Use PetscLogStageRegister() to register a stage.
510: Level: intermediate
512: .keywords: log, pop, stage
513: .seealso: PetscLogStagePush(), PetscLogStageRegister(), PetscBarrier()
514: @*/
515: PetscErrorCode PetscLogStagePop(void)
516: {
517: PetscStageLog stageLog;
521: PetscLogGetStageLog(&stageLog);
522: PetscStageLogPop(stageLog);
523: return(0);
524: }
528: /*@
529: PetscLogStageSetActive - Determines stage activity for PetscLogEventBegin() and PetscLogEventEnd().
531: Not Collective
533: Input Parameters:
534: + stage - The stage
535: - isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
537: Level: intermediate
539: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
540: @*/
541: PetscErrorCode PetscLogStageSetActive(PetscLogStage stage, PetscBool isActive)
542: {
543: PetscStageLog stageLog;
547: PetscLogGetStageLog(&stageLog);
548: PetscStageLogSetActive(stageLog, stage, isActive);
549: return(0);
550: }
554: /*@
555: PetscLogStageGetActive - Returns stage activity for PetscLogEventBegin() and PetscLogEventEnd().
557: Not Collective
559: Input Parameter:
560: . stage - The stage
562: Output Parameter:
563: . isActive - The activity flag, PETSC_TRUE for logging, else PETSC_FALSE (defaults to PETSC_TRUE)
565: Level: intermediate
567: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
568: @*/
569: PetscErrorCode PetscLogStageGetActive(PetscLogStage stage, PetscBool *isActive)
570: {
571: PetscStageLog stageLog;
575: PetscLogGetStageLog(&stageLog);
576: PetscStageLogGetActive(stageLog, stage, isActive);
577: return(0);
578: }
582: /*@
583: PetscLogStageSetVisible - Determines stage visibility in PetscLogView()
585: Not Collective
587: Input Parameters:
588: + stage - The stage
589: - isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
591: Level: intermediate
593: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
594: @*/
595: PetscErrorCode PetscLogStageSetVisible(PetscLogStage stage, PetscBool isVisible)
596: {
597: PetscStageLog stageLog;
601: PetscLogGetStageLog(&stageLog);
602: PetscStageLogSetVisible(stageLog, stage, isVisible);
603: return(0);
604: }
608: /*@
609: PetscLogStageGetVisible - Returns stage visibility in PetscLogView()
611: Not Collective
613: Input Parameter:
614: . stage - The stage
616: Output Parameter:
617: . isVisible - The visibility flag, PETSC_TRUE to print, else PETSC_FALSE (defaults to PETSC_TRUE)
619: Level: intermediate
621: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscLogView()
622: @*/
623: PetscErrorCode PetscLogStageGetVisible(PetscLogStage stage, PetscBool *isVisible)
624: {
625: PetscStageLog stageLog;
629: PetscLogGetStageLog(&stageLog);
630: PetscStageLogGetVisible(stageLog, stage, isVisible);
631: return(0);
632: }
636: /*@C
637: PetscLogStageGetId - Returns the stage id when given the stage name.
639: Not Collective
641: Input Parameter:
642: . name - The stage name
644: Output Parameter:
645: . stage - The stage, , or -1 if no stage with that name exists
647: Level: intermediate
649: .seealso: PetscLogStagePush(), PetscLogStagePop(), PetscPreLoadBegin(), PetscPreLoadEnd(), PetscPreLoadStage()
650: @*/
651: PetscErrorCode PetscLogStageGetId(const char name[], PetscLogStage *stage)
652: {
653: PetscStageLog stageLog;
657: PetscLogGetStageLog(&stageLog);
658: PetscStageLogGetStage(stageLog, name, stage);
659: return(0);
660: }
662: /*------------------------------------------------ Event Functions --------------------------------------------------*/
665: /*@C
666: PetscLogEventRegister - Registers an event name for logging operations in an application code.
668: Not Collective
670: Input Parameter:
671: + name - The name associated with the event
672: - classid - The classid associated to the class for this event, obtain either with
673: PetscClassIdRegister() or use a predefined one such as KSP_CLASSID, SNES_CLASSID, the predefined ones
674: are only available in C code
676: Output Parameter:
677: . event - The event id for use with PetscLogEventBegin() and PetscLogEventEnd().
679: Example of Usage:
680: .vb
681: PetscLogEvent USER_EVENT;
682: PetscClassId classid;
683: PetscLogDouble user_event_flops;
684: PetscClassIdRegister("class name",&classid);
685: PetscLogEventRegister("User event name",classid,&USER_EVENT);
686: PetscLogEventBegin(USER_EVENT,0,0,0,0);
687: [code segment to monitor]
688: PetscLogFlops(user_event_flops);
689: PetscLogEventEnd(USER_EVENT,0,0,0,0);
690: .ve
692: Notes:
693: PETSc automatically logs library events if the code has been
694: configured with --with-log (which is the default) and
695: -log_view or -log_all is specified. PetscLogEventRegister() is
696: intended for logging user events to supplement this PETSc
697: information.
699: PETSc can gather data for use with the utilities Jumpshot
700: (part of the MPICH distribution). If PETSc has been compiled
701: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
702: MPICH), the user can employ another command line option, -log_mpe,
703: to create a logfile, "mpe.log", which can be visualized
704: Jumpshot.
706: The classid is associated with each event so that classes of events
707: can be disabled simultaneously, such as all matrix events. The user
708: can either use an existing classid, such as MAT_CLASSID, or create
709: their own as shown in the example.
711: If an existing event with the same name exists, its event handle is
712: returned instead of creating a new event.
714: Level: intermediate
716: .keywords: log, event, register
717: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(),
718: PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
719: PetscLogEventActivate(), PetscLogEventDeactivate(), PetscClassIdRegister()
720: @*/
721: PetscErrorCode PetscLogEventRegister(const char name[],PetscClassId classid,PetscLogEvent *event)
722: {
723: PetscStageLog stageLog;
724: int stage;
728: *event = PETSC_DECIDE;
729: PetscLogGetStageLog(&stageLog);
730: EventRegLogGetEvent(stageLog->eventLog, name, event);
731: if (*event > 0) return(0);
732: EventRegLogRegister(stageLog->eventLog, name, classid, event);
733: for (stage = 0; stage < stageLog->numStages; stage++) {
734: EventPerfLogEnsureSize(stageLog->stageInfo[stage].eventLog, stageLog->eventLog->numEvents);
735: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
736: }
737: return(0);
738: }
742: /*@
743: PetscLogEventActivate - Indicates that a particular event should be logged.
745: Not Collective
747: Input Parameter:
748: . event - The event id
750: Usage:
751: .vb
752: PetscLogEventDeactivate(VEC_SetValues);
753: [code where you do not want to log VecSetValues()]
754: PetscLogEventActivate(VEC_SetValues);
755: [code where you do want to log VecSetValues()]
756: .ve
758: Note:
759: The event may be either a pre-defined PETSc event (found in include/petsclog.h)
760: or an event number obtained with PetscLogEventRegister().
762: Level: advanced
764: .keywords: log, event, activate
765: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventDeactivate()
766: @*/
767: PetscErrorCode PetscLogEventActivate(PetscLogEvent event)
768: {
769: PetscStageLog stageLog;
770: int stage;
774: PetscLogGetStageLog(&stageLog);
775: PetscStageLogGetCurrent(stageLog, &stage);
776: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
777: return(0);
778: }
782: /*@
783: PetscLogEventDeactivate - Indicates that a particular event should not be logged.
785: Not Collective
787: Input Parameter:
788: . event - The event id
790: Usage:
791: .vb
792: PetscLogEventDeactivate(VEC_SetValues);
793: [code where you do not want to log VecSetValues()]
794: PetscLogEventActivate(VEC_SetValues);
795: [code where you do want to log VecSetValues()]
796: .ve
798: Note:
799: The event may be either a pre-defined PETSc event (found in
800: include/petsclog.h) or an event number obtained with PetscLogEventRegister()).
802: Level: advanced
804: .keywords: log, event, deactivate
805: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate()
806: @*/
807: PetscErrorCode PetscLogEventDeactivate(PetscLogEvent event)
808: {
809: PetscStageLog stageLog;
810: int stage;
814: PetscLogGetStageLog(&stageLog);
815: PetscStageLogGetCurrent(stageLog, &stage);
816: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
817: return(0);
818: }
822: /*@
823: PetscLogEventSetActiveAll - Sets the event activity in every stage.
825: Not Collective
827: Input Parameters:
828: + event - The event id
829: - isActive - The activity flag determining whether the event is logged
831: Level: advanced
833: .keywords: log, event, activate
834: .seealso: PetscLogEventMPEDeactivate(),PetscLogEventMPEActivate(),PlogEventActivate(),PlogEventDeactivate()
835: @*/
836: PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent event, PetscBool isActive)
837: {
838: PetscStageLog stageLog;
839: int stage;
843: PetscLogGetStageLog(&stageLog);
844: for (stage = 0; stage < stageLog->numStages; stage++) {
845: if (isActive) {
846: EventPerfLogActivate(stageLog->stageInfo[stage].eventLog, event);
847: } else {
848: EventPerfLogDeactivate(stageLog->stageInfo[stage].eventLog, event);
849: }
850: }
851: return(0);
852: }
856: /*@
857: PetscLogEventActivateClass - Activates event logging for a PETSc object class.
859: Not Collective
861: Input Parameter:
862: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.
864: Level: developer
866: .keywords: log, event, activate, class
867: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventDeactivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
868: @*/
869: PetscErrorCode PetscLogEventActivateClass(PetscClassId classid)
870: {
871: PetscStageLog stageLog;
872: int stage;
876: PetscLogGetStageLog(&stageLog);
877: PetscStageLogGetCurrent(stageLog, &stage);
878: EventPerfLogActivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
879: return(0);
880: }
884: /*@
885: PetscLogEventDeactivateClass - Deactivates event logging for a PETSc object class.
887: Not Collective
889: Input Parameter:
890: . classid - The event class, for example MAT_CLASSID, SNES_CLASSID, etc.
892: Level: developer
894: .keywords: log, event, deactivate, class
895: .seealso: PetscInfoActivate(),PetscInfo(),PetscInfoAllow(),PetscLogEventActivateClass(), PetscLogEventActivate(),PetscLogEventDeactivate()
896: @*/
897: PetscErrorCode PetscLogEventDeactivateClass(PetscClassId classid)
898: {
899: PetscStageLog stageLog;
900: int stage;
904: PetscLogGetStageLog(&stageLog);
905: PetscStageLogGetCurrent(stageLog, &stage);
906: EventPerfLogDeactivateClass(stageLog->stageInfo[stage].eventLog, stageLog->eventLog, classid);
907: return(0);
908: }
910: /*MC
911: PetscLogEventBegin - Logs the beginning of a user event.
913: Synopsis:
914: #include <petsclog.h>
915: PetscErrorCode PetscLogEventBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
917: Not Collective
919: Input Parameters:
920: + e - integer associated with the event obtained from PetscLogEventRegister()
921: - o1,o2,o3,o4 - objects associated with the event, or 0
924: Fortran Synopsis:
925: void PetscLogEventBegin(int e,PetscErrorCode ierr)
927: Usage:
928: .vb
929: PetscLogEvent USER_EVENT;
930: PetscLogDouble user_event_flops;
931: PetscLogEventRegister("User event",0,&USER_EVENT);
932: PetscLogEventBegin(USER_EVENT,0,0,0,0);
933: [code segment to monitor]
934: PetscLogFlops(user_event_flops);
935: PetscLogEventEnd(USER_EVENT,0,0,0,0);
936: .ve
938: Notes:
939: You need to register each integer event with the command
940: PetscLogEventRegister().
942: Level: intermediate
944: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops()
946: .keywords: log, event, begin
947: M*/
949: /*MC
950: PetscLogEventEnd - Log the end of a user event.
952: Synopsis:
953: #include <petsclog.h>
954: PetscErrorCode PetscLogEventEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4)
956: Not Collective
958: Input Parameters:
959: + e - integer associated with the event obtained with PetscLogEventRegister()
960: - o1,o2,o3,o4 - objects associated with the event, or 0
963: Fortran Synopsis:
964: void PetscLogEventEnd(int e,PetscErrorCode ierr)
966: Usage:
967: .vb
968: PetscLogEvent USER_EVENT;
969: PetscLogDouble user_event_flops;
970: PetscLogEventRegister("User event",0,&USER_EVENT,);
971: PetscLogEventBegin(USER_EVENT,0,0,0,0);
972: [code segment to monitor]
973: PetscLogFlops(user_event_flops);
974: PetscLogEventEnd(USER_EVENT,0,0,0,0);
975: .ve
977: Notes:
978: You should also register each additional integer event with the command
979: PetscLogEventRegister().
981: Level: intermediate
983: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogFlops()
985: .keywords: log, event, end
986: M*/
988: /*MC
989: PetscLogEventBarrierBegin - Logs the time in a barrier before an event.
991: Synopsis:
992: #include <petsclog.h>
993: PetscErrorCode PetscLogEventBarrierBegin(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)
995: Not Collective
997: Input Parameters:
998: . e - integer associated with the event obtained from PetscLogEventRegister()
999: . o1,o2,o3,o4 - objects associated with the event, or 0
1000: . comm - communicator the barrier takes place over
1003: Usage:
1004: .vb
1005: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1006: MPIU_Allreduce()
1007: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1008: .ve
1010: Notes:
1011: This is for logging the amount of time spent in a barrier for an event
1012: that requires synchronization.
1014: Additional Notes:
1015: Synchronization events always come in pairs; for example, VEC_NormBarrier and
1016: VEC_NormComm = VEC_NormBarrier + 1
1018: Level: advanced
1020: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1021: PetscLogEventBarrierEnd()
1023: .keywords: log, event, begin, barrier
1024: M*/
1026: /*MC
1027: PetscLogEventBarrierEnd - Logs the time in a barrier before an event.
1029: Synopsis:
1030: #include <petsclog.h>
1031: PetscErrorCode PetscLogEventBarrierEnd(int e,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4,MPI_Comm comm)
1033: Logically Collective on MPI_Comm
1035: Input Parameters:
1036: . e - integer associated with the event obtained from PetscLogEventRegister()
1037: . o1,o2,o3,o4 - objects associated with the event, or 0
1038: . comm - communicator the barrier takes place over
1041: Usage:
1042: .vb
1043: PetscLogEventBarrierBegin(VEC_NormBarrier,0,0,0,0,comm);
1044: MPIU_Allreduce()
1045: PetscLogEventBarrierEnd(VEC_NormBarrier,0,0,0,0,comm);
1046: .ve
1048: Notes:
1049: This is for logging the amount of time spent in a barrier for an event
1050: that requires synchronization.
1052: Additional Notes:
1053: Synchronization events always come in pairs; for example, VEC_NormBarrier and
1054: VEC_NormComm = VEC_NormBarrier + 1
1056: Level: advanced
1058: .seealso: PetscLogEventRegister(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventBegin(),
1059: PetscLogEventBarrierBegin()
1061: .keywords: log, event, begin, barrier
1062: M*/
1066: /*@C
1067: PetscLogEventGetId - Returns the event id when given the event name.
1069: Not Collective
1071: Input Parameter:
1072: . name - The event name
1074: Output Parameter:
1075: . event - The event, or -1 if no event with that name exists
1077: Level: intermediate
1079: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStageGetId()
1080: @*/
1081: PetscErrorCode PetscLogEventGetId(const char name[], PetscLogEvent *event)
1082: {
1083: PetscStageLog stageLog;
1087: PetscLogGetStageLog(&stageLog);
1088: EventRegLogGetEvent(stageLog->eventLog, name, event);
1089: return(0);
1090: }
1093: /*------------------------------------------------ Output Functions -------------------------------------------------*/
1096: /*@C
1097: PetscLogDump - Dumps logs of objects to a file. This file is intended to
1098: be read by bin/petscview. This program no longer exists.
1100: Collective on PETSC_COMM_WORLD
1102: Input Parameter:
1103: . name - an optional file name
1105: Usage:
1106: .vb
1107: PetscInitialize(...);
1108: PetscLogDefaultBegin(); or PetscLogAllBegin();
1109: ... code ...
1110: PetscLogDump(filename);
1111: PetscFinalize();
1112: .ve
1114: Notes:
1115: The default file name is
1116: $ Log.<rank>
1117: where <rank> is the processor number. If no name is specified,
1118: this file will be used.
1120: Level: advanced
1122: .keywords: log, dump
1123: .seealso: PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogView()
1124: @*/
1125: PetscErrorCode PetscLogDump(const char sname[])
1126: {
1127: PetscStageLog stageLog;
1128: PetscEventPerfInfo *eventInfo;
1129: FILE *fd;
1130: char file[PETSC_MAX_PATH_LEN], fname[PETSC_MAX_PATH_LEN];
1131: PetscLogDouble flops, _TotalTime;
1132: PetscMPIInt rank;
1133: int action, object, curStage;
1134: PetscLogEvent event;
1135: PetscErrorCode ierr;
1138: /* Calculate the total elapsed time */
1139: PetscTime(&_TotalTime);
1140: _TotalTime -= petsc_BaseTime;
1141: /* Open log file */
1142: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1143: if (sname) sprintf(file, "%s.%d", sname, rank);
1144: else sprintf(file, "Log.%d", rank);
1145: PetscFixFilename(file, fname);
1146: PetscFOpen(PETSC_COMM_WORLD, fname, "w", &fd);
1147: if ((!rank) && (!fd)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open file: %s", fname);
1148: /* Output totals */
1149: PetscFPrintf(PETSC_COMM_WORLD, fd, "Total Flops %14e %16.8e\n", petsc_TotalFlops, _TotalTime);
1150: PetscFPrintf(PETSC_COMM_WORLD, fd, "Clock Resolution %g\n", 0.0);
1151: /* Output actions */
1152: if (petsc_logActions) {
1153: PetscFPrintf(PETSC_COMM_WORLD, fd, "Actions accomplished %d\n", petsc_numActions);
1154: for (action = 0; action < petsc_numActions; action++) {
1155: PetscFPrintf(PETSC_COMM_WORLD, fd, "%g %d %d %d %d %d %d %g %g %g\n",
1156: petsc_actions[action].time, petsc_actions[action].action, (int)petsc_actions[action].event, (int)petsc_actions[action].classid, petsc_actions[action].id1,
1157: petsc_actions[action].id2, petsc_actions[action].id3, petsc_actions[action].flops, petsc_actions[action].mem, petsc_actions[action].maxmem);
1158: }
1159: }
1160: /* Output objects */
1161: if (petsc_logObjects) {
1162: PetscFPrintf(PETSC_COMM_WORLD, fd, "Objects created %d destroyed %d\n", petsc_numObjects, petsc_numObjectsDestroyed);
1163: for (object = 0; object < petsc_numObjects; object++) {
1164: PetscFPrintf(PETSC_COMM_WORLD, fd, "Parent ID: %d Memory: %d\n", petsc_objects[object].parent, (int) petsc_objects[object].mem);
1165: if (!petsc_objects[object].name[0]) {
1166: PetscFPrintf(PETSC_COMM_WORLD, fd,"No Name\n");
1167: } else {
1168: PetscFPrintf(PETSC_COMM_WORLD, fd, "Name: %s\n", petsc_objects[object].name);
1169: }
1170: if (petsc_objects[object].info[0] != 0) {
1171: PetscFPrintf(PETSC_COMM_WORLD, fd, "No Info\n");
1172: } else {
1173: PetscFPrintf(PETSC_COMM_WORLD, fd, "Info: %s\n", petsc_objects[object].info);
1174: }
1175: }
1176: }
1177: /* Output events */
1178: PetscFPrintf(PETSC_COMM_WORLD, fd, "Event log:\n");
1179: PetscLogGetStageLog(&stageLog);
1180: PetscIntStackTop(stageLog->stack, &curStage);
1181: eventInfo = stageLog->stageInfo[curStage].eventLog->eventInfo;
1182: for (event = 0; event < stageLog->stageInfo[curStage].eventLog->numEvents; event++) {
1183: if (eventInfo[event].time != 0.0) flops = eventInfo[event].flops/eventInfo[event].time;
1184: else flops = 0.0;
1185: PetscFPrintf(PETSC_COMM_WORLD, fd, "%d %16d %16g %16g %16g\n", event, eventInfo[event].count,
1186: eventInfo[event].flops, eventInfo[event].time, flops);
1187: }
1188: PetscFClose(PETSC_COMM_WORLD, fd);
1189: return(0);
1190: }
1194: /*
1195: PetscLogView_Detailed - Each process prints the times for its own events
1197: */
1198: PetscErrorCode PetscLogView_Detailed(PetscViewer viewer)
1199: {
1200: MPI_Comm comm = PetscObjectComm((PetscObject) viewer);
1201: PetscEventPerfInfo *eventInfo = NULL;
1202: PetscLogDouble locTotalTime, numRed, maxMem;
1203: PetscStageLog stageLog;
1204: int numStages,numEvents,stage,event;
1205: PetscMPIInt rank,size;
1206: PetscErrorCode ierr;
1209: MPI_Comm_size(comm, &size);
1210: MPI_Comm_rank(comm, &rank);
1211: /* Must preserve reduction count before we go on */
1212: numRed = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1213: /* Get the total elapsed time */
1214: PetscTime(&locTotalTime); locTotalTime -= petsc_BaseTime;
1215: PetscViewerASCIIPrintf(viewer,"numProcs = %d\n",size);
1216: PetscViewerASCIIPrintf(viewer,"LocalTimes = {}\n");
1217: PetscViewerASCIIPrintf(viewer,"LocalFlops = {}\n");
1218: PetscViewerASCIIPrintf(viewer,"LocalMessageLens = {}\n");
1219: PetscViewerASCIIPrintf(viewer,"LocalMessages = {}\n");
1220: PetscViewerASCIIPrintf(viewer,"LocalReductions = {}\n");
1221: PetscViewerASCIIPrintf(viewer,"LocalObjects = {}\n");
1222: PetscViewerASCIIPrintf(viewer,"LocalMemory = {}\n");
1223: PetscLogGetStageLog(&stageLog);
1224: MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1225: PetscViewerASCIIPrintf(viewer,"Stages = {}\n");
1226: for (stage=0; stage<numStages; stage++) {
1227: PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"] = {}\n",stageLog->stageInfo[stage].name);
1228: PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"summary\"] = {}\n",stageLog->stageInfo[stage].name);
1229: MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1230: for (event = 0; event < numEvents; event++) {
1231: PetscViewerASCIIPrintf(viewer,"Stages[\"%s\"][\"%s\"] = {}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name);
1232: }
1233: }
1234: PetscViewerASCIIPushSynchronized(viewer);
1235: PetscViewerASCIISynchronizedPrintf(viewer,"LocalTimes[%d] = %g\n",rank,locTotalTime);
1236: PetscViewerASCIISynchronizedPrintf(viewer,"LocalFlops[%d] = %g\n",rank,petsc_TotalFlops);
1237: PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessageLens[%d] = %g\n",rank,(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len));
1238: PetscViewerASCIISynchronizedPrintf(viewer,"LocalMessages[%d] = %g\n",rank,(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct));
1239: PetscViewerASCIISynchronizedPrintf(viewer,"LocalReductions[%d] = %g\n",rank,numRed);
1240: PetscViewerASCIISynchronizedPrintf(viewer,"LocalObjects[%d] = %g\n",rank,petsc_numObjects);
1241: PetscMallocGetMaximumUsage(&maxMem);
1242: PetscViewerASCIISynchronizedPrintf(viewer,"LocalMemory[%d] = %g\n",rank,maxMem);
1243: PetscViewerFlush(viewer);
1244: for (stage=0; stage<numStages; stage++) {
1245: PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"summary\"][%d] = {\"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flops\" : %g}\n",
1246: stageLog->stageInfo[stage].name,rank,
1247: stageLog->stageInfo[stage].perfInfo.time,stageLog->stageInfo[stage].perfInfo.numMessages,stageLog->stageInfo[stage].perfInfo.messageLength,
1248: stageLog->stageInfo[stage].perfInfo.numReductions,stageLog->stageInfo[stage].perfInfo.flops);
1249: MPIU_Allreduce(&stageLog->stageInfo[stage].eventLog->numEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1250: for (event = 0; event < numEvents; event++) {
1251: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1252: PetscViewerASCIISynchronizedPrintf(viewer,"Stages[\"%s\"][\"%s\"][%d] = {\"count\" : %D, \"time\" : %g, \"numMessages\" : %g, \"messageLength\" : %g, \"numReductions\" : %g, \"flops\" : %g}\n",stageLog->stageInfo[stage].name,stageLog->eventLog->eventInfo[event].name,rank,
1253: eventInfo[event].count, eventInfo[event].time,eventInfo[event].numMessages, eventInfo[event].messageLength,
1254: eventInfo[event].numReductions,eventInfo[event].flops);
1255: }
1256: }
1257: PetscViewerFlush(viewer);
1258: PetscViewerASCIIPopSynchronized(viewer);
1259: return(0);
1260: }
1264: PetscErrorCode PetscLogView_Default(PetscViewer viewer)
1265: {
1266: FILE *fd;
1267: PetscLogDouble zero = 0.0;
1268: PetscStageLog stageLog;
1269: PetscStageInfo *stageInfo = NULL;
1270: PetscEventPerfInfo *eventInfo = NULL;
1271: PetscClassPerfInfo *classInfo;
1272: char arch[128],hostname[128],username[128],pname[PETSC_MAX_PATH_LEN],date[128];
1273: const char *name;
1274: PetscLogDouble locTotalTime, TotalTime, TotalFlops;
1275: PetscLogDouble numMessages, messageLength, avgMessLen, numReductions;
1276: PetscLogDouble stageTime, flops, flopr, mem, mess, messLen, red;
1277: PetscLogDouble fracTime, fracFlops, fracMessages, fracLength, fracReductions, fracMess, fracMessLen, fracRed;
1278: PetscLogDouble fracStageTime, fracStageFlops, fracStageMess, fracStageMessLen, fracStageRed;
1279: PetscLogDouble min, max, tot, ratio, avg, x, y;
1280: PetscLogDouble minf, maxf, totf, ratf, mint, maxt, tott, ratt, ratCt, totm, totml, totr;
1281: PetscMPIInt minCt, maxCt;
1282: PetscMPIInt size, rank;
1283: PetscBool *localStageUsed, *stageUsed;
1284: PetscBool *localStageVisible, *stageVisible;
1285: int numStages, localNumEvents, numEvents;
1286: int stage, oclass;
1287: PetscLogEvent event;
1288: PetscErrorCode ierr;
1289: char version[256];
1290: MPI_Comm comm;
1293: PetscObjectGetComm((PetscObject)viewer,&comm);
1294: PetscViewerASCIIGetPointer(viewer,&fd);
1295: MPI_Comm_size(comm, &size);
1296: MPI_Comm_rank(comm, &rank);
1297: /* Get the total elapsed time */
1298: PetscTime(&locTotalTime); locTotalTime -= petsc_BaseTime;
1300: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1301: PetscFPrintf(comm, fd, "*** WIDEN YOUR WINDOW TO 120 CHARACTERS. Use 'enscript -r -fCourier9' to print this document ***\n");
1302: PetscFPrintf(comm, fd, "************************************************************************************************************************\n");
1303: PetscFPrintf(comm, fd, "\n---------------------------------------------- PETSc Performance Summary: ----------------------------------------------\n\n");
1304: PetscGetArchType(arch,sizeof(arch));
1305: PetscGetHostName(hostname,sizeof(hostname));
1306: PetscGetUserName(username,sizeof(username));
1307: PetscGetProgramName(pname,sizeof(pname));
1308: PetscGetDate(date,sizeof(date));
1309: PetscGetVersion(version,sizeof(version));
1310: if (size == 1) {
1311: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processor, by %s %s\n", pname, arch, hostname, size, username, date);
1312: } else {
1313: PetscFPrintf(comm,fd,"%s on a %s named %s with %d processors, by %s %s\n", pname, arch, hostname, size, username, date);
1314: }
1316: PetscFPrintf(comm, fd, "Using %s\n", version);
1318: /* Must preserve reduction count before we go on */
1319: red = petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
1321: /* Calculate summary information */
1322: PetscFPrintf(comm, fd, "\n Max Max/Min Avg Total \n");
1323: /* Time */
1324: MPIU_Allreduce(&locTotalTime, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1325: MPIU_Allreduce(&locTotalTime, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1326: MPIU_Allreduce(&locTotalTime, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1327: avg = (tot)/((PetscLogDouble) size);
1328: if (min != 0.0) ratio = max/min;
1329: else ratio = 0.0;
1330: PetscFPrintf(comm, fd, "Time (sec): %5.3e %10.5f %5.3e\n", max, ratio, avg);
1331: TotalTime = tot;
1332: /* Objects */
1333: avg = (PetscLogDouble) petsc_numObjects;
1334: MPIU_Allreduce(&avg, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1335: MPIU_Allreduce(&avg, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1336: MPIU_Allreduce(&avg, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1337: avg = (tot)/((PetscLogDouble) size);
1338: if (min != 0.0) ratio = max/min;
1339: else ratio = 0.0;
1340: PetscFPrintf(comm, fd, "Objects: %5.3e %10.5f %5.3e\n", max, ratio, avg);
1341: /* Flops */
1342: MPIU_Allreduce(&petsc_TotalFlops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1343: MPIU_Allreduce(&petsc_TotalFlops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1344: MPIU_Allreduce(&petsc_TotalFlops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1345: avg = (tot)/((PetscLogDouble) size);
1346: if (min != 0.0) ratio = max/min;
1347: else ratio = 0.0;
1348: PetscFPrintf(comm, fd, "Flops: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1349: TotalFlops = tot;
1350: /* Flops/sec -- Must talk to Barry here */
1351: if (locTotalTime != 0.0) flops = petsc_TotalFlops/locTotalTime;
1352: else flops = 0.0;
1353: MPIU_Allreduce(&flops, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1354: MPIU_Allreduce(&flops, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1355: MPIU_Allreduce(&flops, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1356: avg = (tot)/((PetscLogDouble) size);
1357: if (min != 0.0) ratio = max/min;
1358: else ratio = 0.0;
1359: PetscFPrintf(comm, fd, "Flops/sec: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1360: /* Memory */
1361: PetscMallocGetMaximumUsage(&mem);
1362: if (mem > 0.0) {
1363: MPIU_Allreduce(&mem, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1364: MPIU_Allreduce(&mem, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1365: MPIU_Allreduce(&mem, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1366: avg = (tot)/((PetscLogDouble) size);
1367: if (min != 0.0) ratio = max/min;
1368: else ratio = 0.0;
1369: PetscFPrintf(comm, fd, "Memory: %5.3e %10.5f %5.3e\n", max, ratio, tot);
1370: }
1371: /* Messages */
1372: mess = 0.5*(petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct);
1373: MPIU_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1374: MPIU_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1375: MPIU_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1376: avg = (tot)/((PetscLogDouble) size);
1377: if (min != 0.0) ratio = max/min;
1378: else ratio = 0.0;
1379: PetscFPrintf(comm, fd, "MPI Messages: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1380: numMessages = tot;
1381: /* Message Lengths */
1382: mess = 0.5*(petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len);
1383: MPIU_Allreduce(&mess, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1384: MPIU_Allreduce(&mess, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1385: MPIU_Allreduce(&mess, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1386: if (numMessages != 0) avg = (tot)/(numMessages);
1387: else avg = 0.0;
1388: if (min != 0.0) ratio = max/min;
1389: else ratio = 0.0;
1390: PetscFPrintf(comm, fd, "MPI Message Lengths: %5.3e %10.5f %5.3e %5.3e\n", max, ratio, avg, tot);
1391: messageLength = tot;
1392: /* Reductions */
1393: MPIU_Allreduce(&red, &min, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1394: MPIU_Allreduce(&red, &max, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1395: MPIU_Allreduce(&red, &tot, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1396: if (min != 0.0) ratio = max/min;
1397: else ratio = 0.0;
1398: PetscFPrintf(comm, fd, "MPI Reductions: %5.3e %10.5f\n", max, ratio);
1399: numReductions = red; /* wrong because uses count from process zero */
1400: PetscFPrintf(comm, fd, "\nFlop counting convention: 1 flop = 1 real number operation of type (multiply/divide/add/subtract)\n");
1401: PetscFPrintf(comm, fd, " e.g., VecAXPY() for real vectors of length N --> 2N flops\n");
1402: PetscFPrintf(comm, fd, " and VecAXPY() for complex vectors of length N --> 8N flops\n");
1404: /* Get total number of stages --
1405: Currently, a single processor can register more stages than another, but stages must all be registered in order.
1406: We can removed this requirement if necessary by having a global stage numbering and indirection on the stage ID.
1407: This seems best accomplished by assoicating a communicator with each stage.
1408: */
1409: PetscLogGetStageLog(&stageLog);
1410: MPIU_Allreduce(&stageLog->numStages, &numStages, 1, MPI_INT, MPI_MAX, comm);
1411: PetscMalloc1(numStages, &localStageUsed);
1412: PetscMalloc1(numStages, &stageUsed);
1413: PetscMalloc1(numStages, &localStageVisible);
1414: PetscMalloc1(numStages, &stageVisible);
1415: if (numStages > 0) {
1416: stageInfo = stageLog->stageInfo;
1417: for (stage = 0; stage < numStages; stage++) {
1418: if (stage < stageLog->numStages) {
1419: localStageUsed[stage] = stageInfo[stage].used;
1420: localStageVisible[stage] = stageInfo[stage].perfInfo.visible;
1421: } else {
1422: localStageUsed[stage] = PETSC_FALSE;
1423: localStageVisible[stage] = PETSC_TRUE;
1424: }
1425: }
1426: MPIU_Allreduce(localStageUsed, stageUsed, numStages, MPIU_BOOL, MPI_LOR, comm);
1427: MPIU_Allreduce(localStageVisible, stageVisible, numStages, MPIU_BOOL, MPI_LAND, comm);
1428: for (stage = 0; stage < numStages; stage++) {
1429: if (stageUsed[stage]) {
1430: PetscFPrintf(comm, fd, "\nSummary of Stages: ----- Time ------ ----- Flops ----- --- Messages --- -- Message Lengths -- -- Reductions --\n");
1431: PetscFPrintf(comm, fd, " Avg %%Total Avg %%Total counts %%Total Avg %%Total counts %%Total \n");
1432: break;
1433: }
1434: }
1435: for (stage = 0; stage < numStages; stage++) {
1436: if (!stageUsed[stage]) continue;
1437: if (localStageUsed[stage]) {
1438: MPIU_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1439: MPIU_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1440: MPIU_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1441: MPIU_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1442: MPIU_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1443: name = stageInfo[stage].name;
1444: } else {
1445: MPIU_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1446: MPIU_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1447: MPIU_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1448: MPIU_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1449: MPIU_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1450: name = "";
1451: }
1452: mess *= 0.5; messLen *= 0.5; red /= size;
1453: if (TotalTime != 0.0) fracTime = stageTime/TotalTime; else fracTime = 0.0;
1454: if (TotalFlops != 0.0) fracFlops = flops/TotalFlops; else fracFlops = 0.0;
1455: /* Talk to Barry if (stageTime != 0.0) flops = (size*flops)/stageTime; else flops = 0.0; */
1456: if (numMessages != 0.0) fracMessages = mess/numMessages; else fracMessages = 0.0;
1457: if (numMessages != 0.0) avgMessLen = messLen/numMessages; else avgMessLen = 0.0;
1458: if (messageLength != 0.0) fracLength = messLen/messageLength; else fracLength = 0.0;
1459: if (numReductions != 0.0) fracReductions = red/numReductions; else fracReductions = 0.0;
1460: 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",
1461: stage, name, stageTime/size, 100.0*fracTime, flops, 100.0*fracFlops,
1462: mess, 100.0*fracMessages, avgMessLen, 100.0*fracLength, red, 100.0*fracReductions);
1463: }
1464: }
1466: PetscFPrintf(comm, fd,"\n------------------------------------------------------------------------------------------------------------------------\n");
1467: PetscFPrintf(comm, fd, "See the 'Profiling' chapter of the users' manual for details on interpreting output.\n");
1468: PetscFPrintf(comm, fd, "Phase summary info:\n");
1469: PetscFPrintf(comm, fd, " Count: number of times phase was executed\n");
1470: PetscFPrintf(comm, fd, " Time and Flops: Max - maximum over all processors\n");
1471: PetscFPrintf(comm, fd, " Ratio - ratio of maximum to minimum over all processors\n");
1472: PetscFPrintf(comm, fd, " Mess: number of messages sent\n");
1473: PetscFPrintf(comm, fd, " Avg. len: average message length (bytes)\n");
1474: PetscFPrintf(comm, fd, " Reduct: number of global reductions\n");
1475: PetscFPrintf(comm, fd, " Global: entire computation\n");
1476: PetscFPrintf(comm, fd, " Stage: stages of a computation. Set stages with PetscLogStagePush() and PetscLogStagePop().\n");
1477: PetscFPrintf(comm, fd, " %%T - percent time in this phase %%F - percent flops in this phase\n");
1478: PetscFPrintf(comm, fd, " %%M - percent messages in this phase %%L - percent message lengths in this phase\n");
1479: PetscFPrintf(comm, fd, " %%R - percent reductions in this phase\n");
1480: PetscFPrintf(comm, fd, " Total Mflop/s: 10e-6 * (sum of flops over all processors)/(max time over all processors)\n");
1481: PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");
1483: #if defined(PETSC_USE_DEBUG)
1484: PetscFPrintf(comm, fd, "\n\n");
1485: PetscFPrintf(comm, fd, " ##########################################################\n");
1486: PetscFPrintf(comm, fd, " # #\n");
1487: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1488: PetscFPrintf(comm, fd, " # #\n");
1489: PetscFPrintf(comm, fd, " # This code was compiled with a debugging option, #\n");
1490: PetscFPrintf(comm, fd, " # To get timing results run ./configure #\n");
1491: PetscFPrintf(comm, fd, " # using --with-debugging=no, the performance will #\n");
1492: PetscFPrintf(comm, fd, " # be generally two or three times faster. #\n");
1493: PetscFPrintf(comm, fd, " # #\n");
1494: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1495: #endif
1496: #if defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_FORTRAN_KERNELS)
1497: PetscFPrintf(comm, fd, "\n\n");
1498: PetscFPrintf(comm, fd, " ##########################################################\n");
1499: PetscFPrintf(comm, fd, " # #\n");
1500: PetscFPrintf(comm, fd, " # WARNING!!! #\n");
1501: PetscFPrintf(comm, fd, " # #\n");
1502: PetscFPrintf(comm, fd, " # The code for various complex numbers numerical #\n");
1503: PetscFPrintf(comm, fd, " # kernels uses C++, which generally is not well #\n");
1504: PetscFPrintf(comm, fd, " # optimized. For performance that is about 4-5 times #\n");
1505: PetscFPrintf(comm, fd, " # faster, specify --with-fortran-kernels=1 #\n");
1506: PetscFPrintf(comm, fd, " # when running ./configure.py. #\n");
1507: PetscFPrintf(comm, fd, " # #\n");
1508: PetscFPrintf(comm, fd, " ##########################################################\n\n\n");
1509: #endif
1511: /* Report events */
1512: PetscFPrintf(comm, fd,"Event Count Time (sec) Flops --- Global --- --- Stage --- Total\n");
1513: PetscFPrintf(comm, fd," Max Ratio Max Ratio Max Ratio Mess Avg len Reduct %%T %%F %%M %%L %%R %%T %%F %%M %%L %%R Mflop/s\n");
1514: PetscFPrintf(comm,fd,"------------------------------------------------------------------------------------------------------------------------\n");
1516: /* Problem: The stage name will not show up unless the stage executed on proc 1 */
1517: for (stage = 0; stage < numStages; stage++) {
1518: if (!stageVisible[stage]) continue;
1519: if (localStageUsed[stage]) {
1520: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1521: MPIU_Allreduce(&stageInfo[stage].perfInfo.time, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1522: MPIU_Allreduce(&stageInfo[stage].perfInfo.flops, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1523: MPIU_Allreduce(&stageInfo[stage].perfInfo.numMessages, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1524: MPIU_Allreduce(&stageInfo[stage].perfInfo.messageLength, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1525: MPIU_Allreduce(&stageInfo[stage].perfInfo.numReductions, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1526: } else {
1527: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1528: MPIU_Allreduce(&zero, &stageTime, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1529: MPIU_Allreduce(&zero, &flops, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1530: MPIU_Allreduce(&zero, &mess, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1531: MPIU_Allreduce(&zero, &messLen, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1532: MPIU_Allreduce(&zero, &red, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1533: }
1534: mess *= 0.5; messLen *= 0.5; red /= size;
1536: /* Get total number of events in this stage --
1537: Currently, a single processor can register more events than another, but events must all be registered in order,
1538: just like stages. We can removed this requirement if necessary by having a global event numbering and indirection
1539: on the event ID. This seems best accomplished by assoicating a communicator with each stage.
1541: Problem: If the event did not happen on proc 1, its name will not be available.
1542: Problem: Event visibility is not implemented
1543: */
1544: if (localStageUsed[stage]) {
1545: eventInfo = stageLog->stageInfo[stage].eventLog->eventInfo;
1546: localNumEvents = stageLog->stageInfo[stage].eventLog->numEvents;
1547: } else localNumEvents = 0;
1548: MPIU_Allreduce(&localNumEvents, &numEvents, 1, MPI_INT, MPI_MAX, comm);
1549: for (event = 0; event < numEvents; event++) {
1550: if (localStageUsed[stage] && (event < stageLog->stageInfo[stage].eventLog->numEvents) && (eventInfo[event].depth == 0)) {
1551: if ((eventInfo[event].count > 0) && (eventInfo[event].time > 0.0)) flopr = eventInfo[event].flops;
1552: else flopr = 0.0;
1554: MPIU_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1555: MPIU_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1556: MPIU_Allreduce(&eventInfo[event].flops, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1557: MPIU_Allreduce(&eventInfo[event].time, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1558: MPIU_Allreduce(&eventInfo[event].time, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1559: MPIU_Allreduce(&eventInfo[event].time, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1560: MPIU_Allreduce(&eventInfo[event].numMessages, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1561: MPIU_Allreduce(&eventInfo[event].messageLength, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1562: MPIU_Allreduce(&eventInfo[event].numReductions, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1563: MPIU_Allreduce(&eventInfo[event].count, &minCt, 1, MPI_INT, MPI_MIN, comm);
1564: MPIU_Allreduce(&eventInfo[event].count, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1565: name = stageLog->eventLog->eventInfo[event].name;
1566: } else {
1567: flopr = 0.0;
1568: MPIU_Allreduce(&flopr, &minf, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1569: MPIU_Allreduce(&flopr, &maxf, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1570: MPIU_Allreduce(&zero, &totf, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1571: MPIU_Allreduce(&zero, &mint, 1, MPIU_PETSCLOGDOUBLE, MPI_MIN, comm);
1572: MPIU_Allreduce(&zero, &maxt, 1, MPIU_PETSCLOGDOUBLE, MPI_MAX, comm);
1573: MPIU_Allreduce(&zero, &tott, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1574: MPIU_Allreduce(&zero, &totm, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1575: MPIU_Allreduce(&zero, &totml, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1576: MPIU_Allreduce(&zero, &totr, 1, MPIU_PETSCLOGDOUBLE, MPI_SUM, comm);
1577: MPIU_Allreduce(&ierr, &minCt, 1, MPI_INT, MPI_MIN, comm);
1578: MPIU_Allreduce(&ierr, &maxCt, 1, MPI_INT, MPI_MAX, comm);
1579: name = "";
1580: }
1581: if (mint < 0.0) {
1582: PetscFPrintf(comm, fd, "WARNING!!! Minimum time %g over all processors for %s is negative! This happens\n on some machines whose times cannot handle too rapid calls.!\n artificially changing minimum to zero.\n",mint,name);
1583: mint = 0;
1584: }
1585: if (minf < 0.0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Minimum flops %g over all processors for %s is negative! Not possible!",minf,name);
1586: totm *= 0.5; totml *= 0.5; totr /= size;
1588: if (maxCt != 0) {
1589: if (minCt != 0) ratCt = ((PetscLogDouble) maxCt)/minCt; else ratCt = 0.0;
1590: if (mint != 0.0) ratt = maxt/mint; else ratt = 0.0;
1591: if (minf != 0.0) ratf = maxf/minf; else ratf = 0.0;
1592: if (TotalTime != 0.0) fracTime = tott/TotalTime; else fracTime = 0.0;
1593: if (TotalFlops != 0.0) fracFlops = totf/TotalFlops; else fracFlops = 0.0;
1594: if (stageTime != 0.0) fracStageTime = tott/stageTime; else fracStageTime = 0.0;
1595: if (flops != 0.0) fracStageFlops = totf/flops; else fracStageFlops = 0.0;
1596: if (numMessages != 0.0) fracMess = totm/numMessages; else fracMess = 0.0;
1597: if (messageLength != 0.0) fracMessLen = totml/messageLength; else fracMessLen = 0.0;
1598: if (numReductions != 0.0) fracRed = totr/numReductions; else fracRed = 0.0;
1599: if (mess != 0.0) fracStageMess = totm/mess; else fracStageMess = 0.0;
1600: if (messLen != 0.0) fracStageMessLen = totml/messLen; else fracStageMessLen = 0.0;
1601: if (red != 0.0) fracStageRed = totr/red; else fracStageRed = 0.0;
1602: if (totm != 0.0) totml /= totm; else totml = 0.0;
1603: if (maxt != 0.0) flopr = totf/maxt; else flopr = 0.0;
1604: if (fracStageTime > 1.00) PetscFPrintf(comm, fd,"Warning -- total time of event greater than time of entire stage -- something is wrong with the timer\n");
1605: PetscFPrintf(comm, fd,
1606: "%-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",
1607: name, maxCt, ratCt, maxt, ratt, maxf, ratf, totm, totml, totr,
1608: 100.0*fracTime, 100.0*fracFlops, 100.0*fracMess, 100.0*fracMessLen, 100.0*fracRed,
1609: 100.0*fracStageTime, 100.0*fracStageFlops, 100.0*fracStageMess, 100.0*fracStageMessLen, 100.0*fracStageRed,
1610: PetscAbsReal(flopr/1.0e6));
1611: }
1612: }
1613: }
1615: /* Memory usage and object creation */
1616: PetscFPrintf(comm, fd, "------------------------------------------------------------------------------------------------------------------------\n");
1617: PetscFPrintf(comm, fd, "\n");
1618: PetscFPrintf(comm, fd, "Memory usage is given in bytes:\n\n");
1620: /* Right now, only stages on the first processor are reported here, meaning only objects associated with
1621: the global communicator, or MPI_COMM_SELF for proc 1. We really should report global stats and then
1622: stats for stages local to processor sets.
1623: */
1624: /* We should figure out the longest object name here (now 20 characters) */
1625: PetscFPrintf(comm, fd, "Object Type Creations Destructions Memory Descendants' Mem.\n");
1626: PetscFPrintf(comm, fd, "Reports information only for process 0.\n");
1627: for (stage = 0; stage < numStages; stage++) {
1628: if (localStageUsed[stage]) {
1629: classInfo = stageLog->stageInfo[stage].classLog->classInfo;
1630: PetscFPrintf(comm, fd, "\n--- Event Stage %d: %s\n\n", stage, stageInfo[stage].name);
1631: for (oclass = 0; oclass < stageLog->stageInfo[stage].classLog->numClasses; oclass++) {
1632: if ((classInfo[oclass].creations > 0) || (classInfo[oclass].destructions > 0)) {
1633: PetscFPrintf(comm, fd, "%20s %5d %5d %11.0f %g\n", stageLog->classLog->classInfo[oclass].name,
1634: classInfo[oclass].creations, classInfo[oclass].destructions, classInfo[oclass].mem,
1635: classInfo[oclass].descMem);
1636: }
1637: }
1638: } else {
1639: PetscFPrintf(comm, fd, "\n--- Event Stage %d: Unknown\n\n", stage);
1640: }
1641: }
1643: PetscFree(localStageUsed);
1644: PetscFree(stageUsed);
1645: PetscFree(localStageVisible);
1646: PetscFree(stageVisible);
1648: /* Information unrelated to this particular run */
1649: PetscFPrintf(comm, fd, "========================================================================================================================\n");
1650: PetscTime(&y);
1651: PetscTime(&x);
1652: PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1653: PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y); PetscTime(&y);
1654: PetscFPrintf(comm,fd,"Average time to get PetscTime(): %g\n", (y-x)/10.0);
1655: /* MPI information */
1656: if (size > 1) {
1657: MPI_Status status;
1658: PetscMPIInt tag;
1659: MPI_Comm newcomm;
1661: MPI_Barrier(comm);
1662: PetscTime(&x);
1663: MPI_Barrier(comm);
1664: MPI_Barrier(comm);
1665: MPI_Barrier(comm);
1666: MPI_Barrier(comm);
1667: MPI_Barrier(comm);
1668: PetscTime(&y);
1669: PetscFPrintf(comm, fd, "Average time for MPI_Barrier(): %g\n", (y-x)/5.0);
1670: PetscCommDuplicate(comm,&newcomm, &tag);
1671: MPI_Barrier(comm);
1672: if (rank) {
1673: MPI_Recv(0, 0, MPI_INT, rank-1, tag, newcomm, &status);
1674: MPI_Send(0, 0, MPI_INT, (rank+1)%size, tag, newcomm);
1675: } else {
1676: PetscTime(&x);
1677: MPI_Send(0, 0, MPI_INT, 1, tag, newcomm);
1678: MPI_Recv(0, 0, MPI_INT, size-1, tag, newcomm, &status);
1679: PetscTime(&y);
1680: PetscFPrintf(comm,fd,"Average time for zero size MPI_Send(): %g\n", (y-x)/size);
1681: }
1682: PetscCommDestroy(&newcomm);
1683: }
1684: PetscOptionsView(NULL,viewer);
1686: /* Machine and compile information */
1687: #if defined(PETSC_USE_FORTRAN_KERNELS)
1688: PetscFPrintf(comm, fd, "Compiled with FORTRAN kernels\n");
1689: #else
1690: PetscFPrintf(comm, fd, "Compiled without FORTRAN kernels\n");
1691: #endif
1692: #if defined(PETSC_USE_REAL_SINGLE)
1693: PetscFPrintf(comm, fd, "Compiled with single precision PetscScalar and PetscReal\n");
1694: #elif defined(PETSC_USE_LONGDOUBLE)
1695: PetscFPrintf(comm, fd, "Compiled with long double precision PetscScalar and PetscReal\n");
1696: #endif
1698: #if defined(PETSC_USE_REAL_MAT_SINGLE)
1699: PetscFPrintf(comm, fd, "Compiled with single precision matrices\n");
1700: #else
1701: PetscFPrintf(comm, fd, "Compiled with full precision matrices (default)\n");
1702: #endif
1703: PetscFPrintf(comm, fd, "sizeof(short) %d sizeof(int) %d sizeof(long) %d sizeof(void*) %d sizeof(PetscScalar) %d sizeof(PetscInt) %d\n",
1704: (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(void*),(int) sizeof(PetscScalar),(int) sizeof(PetscInt));
1706: PetscFPrintf(comm, fd, "Configure options: %s",petscconfigureoptions);
1707: PetscFPrintf(comm, fd, "%s", petscmachineinfo);
1708: PetscFPrintf(comm, fd, "%s", petsccompilerinfo);
1709: PetscFPrintf(comm, fd, "%s", petsccompilerflagsinfo);
1710: PetscFPrintf(comm, fd, "%s", petsclinkerinfo);
1712: /* Cleanup */
1713: PetscFPrintf(comm, fd, "\n");
1714: return(0);
1715: }
1717: PetscErrorCode PetscLogView_Nested(PetscViewer);
1721: /*@C
1722: PetscLogView - Prints a summary of the logging.
1724: Collective over MPI_Comm
1726: Input Parameter:
1727: . viewer - an ASCII viewer
1729: Options Database Keys:
1730: + -log_view [:filename] - Prints summary of log information
1731: . -log_view :filename.py:ascii_info_detail - Saves logging information from each process as a Python file
1732: . -log_view :filename.xml:ascii_xml - Saves a summary of the logging information in a nested format, use a browser to open this file, for example on
1733: Apple MacOS systems use open -a Safari filename.xml
1734: . -log_all - Saves a file Log.rank for each MPI process with details of each step of the computation
1735: - -log_trace [filename] - Displays a trace of what each process is doing
1737: Notes:
1738: It is possible to control the logging programatically but we recommend using the options database approach whenever possible
1739: By default the summary is printed to stdout.
1741: Before calling this routine you must have called either PetscLogDefaultBegin() or PetscLogNestedBegin()
1743: If PETSc is configured with --with-logging=0 then this functionality is not available
1745: The nested XML format was kindly donated by Koos Huijssen and Christiaan M. Klaij MARITIME RESEARCH INSTITUTE NETHERLANDS
1747: Level: beginner
1749: .keywords: log, dump, print
1750: .seealso: PetscLogDefaultBegin(), PetscLogDump()
1751: @*/
1752: PetscErrorCode PetscLogView(PetscViewer viewer)
1753: {
1754: PetscErrorCode ierr;
1755: PetscBool isascii;
1756: PetscViewerFormat format;
1757: int stage, lastStage;
1758: PetscStageLog stageLog;
1761: if (!PetscLogPLB) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Must use -log_summary or PetscLogDefaultBegin() before calling this routine");
1762: /* Pop off any stages the user forgot to remove */
1763: lastStage = 0;
1764: PetscLogGetStageLog(&stageLog);
1765: PetscStageLogGetCurrent(stageLog, &stage);
1766: while (stage >= 0) {
1767: lastStage = stage;
1768: PetscStageLogPop(stageLog);
1769: PetscStageLogGetCurrent(stageLog, &stage);
1770: }
1771: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
1772: if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Currently can only view logging to ASCII");
1773: PetscViewerGetFormat(viewer,&format);
1774: if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO) {
1775: PetscLogView_Default(viewer);
1776: } else if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
1777: PetscLogView_Detailed(viewer);
1778: } else if (format == PETSC_VIEWER_ASCII_XML) {
1779: PetscLogView_Nested(viewer);
1780: }
1781: PetscStageLogPush(stageLog, lastStage);
1782: return(0);
1783: }
1787: /*@C
1788: PetscLogViewFromOptions - Processes command line options to determine if/how a PetscLog is to be viewed.
1790: Collective on PETSC_COMM_WORLD
1792: Not normally called by user
1794: Level: intermediate
1796: @*/
1797: PetscErrorCode PetscLogViewFromOptions(void)
1798: {
1799: PetscErrorCode ierr;
1800: PetscViewer viewer;
1801: PetscBool flg;
1802: PetscViewerFormat format;
1805: PetscOptionsGetViewer(PETSC_COMM_WORLD,NULL,"-log_view",&viewer,&format,&flg);
1806: if (flg) {
1807: PetscViewerPushFormat(viewer,format);
1808: PetscLogView(viewer);
1809: PetscViewerPopFormat(viewer);
1810: PetscViewerDestroy(&viewer);
1811: }
1812: return(0);
1813: }
1817: /*----------------------------------------------- Counter Functions -------------------------------------------------*/
1820: /*@C
1821: PetscGetFlops - Returns the number of flops used on this processor
1822: since the program began.
1824: Not Collective
1826: Output Parameter:
1827: flops - number of floating point operations
1829: Notes:
1830: A global counter logs all PETSc flop counts. The user can use
1831: PetscLogFlops() to increment this counter to include flops for the
1832: application code.
1834: Level: intermediate
1836: .keywords: log, flops, floating point operations
1838: .seealso: PetscTime(), PetscLogFlops()
1839: @*/
1840: PetscErrorCode PetscGetFlops(PetscLogDouble *flops)
1841: {
1843: *flops = petsc_TotalFlops;
1844: return(0);
1845: }
1849: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
1850: {
1852: size_t fullLength;
1853: va_list Argp;
1856: if (!petsc_logObjects) return(0);
1857: va_start(Argp, format);
1858: PetscVSNPrintf(petsc_objects[obj->id].info, 64,format,&fullLength, Argp);
1859: va_end(Argp);
1860: return(0);
1861: }
1864: /*MC
1865: PetscLogFlops - Adds floating point operations to the global counter.
1867: Synopsis:
1868: #include <petsclog.h>
1869: PetscErrorCode PetscLogFlops(PetscLogDouble f)
1871: Not Collective
1873: Input Parameter:
1874: . f - flop counter
1877: Usage:
1878: .vb
1879: PetscLogEvent USER_EVENT;
1880: PetscLogEventRegister("User event",0,&USER_EVENT);
1881: PetscLogEventBegin(USER_EVENT,0,0,0,0);
1882: [code segment to monitor]
1883: PetscLogFlops(user_flops)
1884: PetscLogEventEnd(USER_EVENT,0,0,0,0);
1885: .ve
1887: Notes:
1888: A global counter logs all PETSc flop counts. The user can use
1889: PetscLogFlops() to increment this counter to include flops for the
1890: application code.
1892: Level: intermediate
1894: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscGetFlops()
1896: .keywords: log, flops, floating point operations
1897: M*/
1899: /*MC
1900: PetscPreLoadBegin - Begin a segment of code that may be preloaded (run twice)
1901: to get accurate timings
1903: Synopsis:
1904: #include <petsclog.h>
1905: void PetscPreLoadBegin(PetscBool flag,char *name);
1907: Not Collective
1909: Input Parameter:
1910: + flag - PETSC_TRUE to run twice, PETSC_FALSE to run once, may be overridden
1911: with command line option -preload true or -preload false
1912: - name - name of first stage (lines of code timed separately with -log_summary) to
1913: be preloaded
1915: Usage:
1916: .vb
1917: PetscPreLoadBegin(PETSC_TRUE,"first stage);
1918: lines of code
1919: PetscPreLoadStage("second stage");
1920: lines of code
1921: PetscPreLoadEnd();
1922: .ve
1924: Notes: Only works in C/C++, not Fortran
1926: Flags available within the macro.
1927: + PetscPreLoadingUsed - true if we are or have done preloading
1928: . PetscPreLoadingOn - true if it is CURRENTLY doing preload
1929: . PetscPreLoadIt - 0 for the first computation (with preloading turned off it is only 0) 1 for the second
1930: - PetscPreLoadMax - number of times it will do the computation, only one when preloading is turned on
1931: The first two variables are available throughout the program, the second two only between the PetscPreLoadBegin()
1932: and PetscPreLoadEnd()
1934: Level: intermediate
1936: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadEnd(), PetscPreLoadStage()
1938: Concepts: preloading
1939: Concepts: timing^accurate
1940: Concepts: paging^eliminating effects of
1943: M*/
1945: /*MC
1946: PetscPreLoadEnd - End a segment of code that may be preloaded (run twice)
1947: to get accurate timings
1949: Synopsis:
1950: #include <petsclog.h>
1951: void PetscPreLoadEnd(void);
1953: Not Collective
1955: Usage:
1956: .vb
1957: PetscPreLoadBegin(PETSC_TRUE,"first stage);
1958: lines of code
1959: PetscPreLoadStage("second stage");
1960: lines of code
1961: PetscPreLoadEnd();
1962: .ve
1964: Notes: only works in C/C++ not fortran
1966: Level: intermediate
1968: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadStage()
1970: M*/
1972: /*MC
1973: PetscPreLoadStage - Start a new segment of code to be timed separately.
1974: to get accurate timings
1976: Synopsis:
1977: #include <petsclog.h>
1978: void PetscPreLoadStage(char *name);
1980: Not Collective
1982: Usage:
1983: .vb
1984: PetscPreLoadBegin(PETSC_TRUE,"first stage);
1985: lines of code
1986: PetscPreLoadStage("second stage");
1987: lines of code
1988: PetscPreLoadEnd();
1989: .ve
1991: Notes: only works in C/C++ not fortran
1993: Level: intermediate
1995: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscPreLoadBegin(), PetscPreLoadEnd()
1997: M*/
2000: #else /* end of -DPETSC_USE_LOG section */
2004: PetscErrorCode PetscLogObjectState(PetscObject obj, const char format[], ...)
2005: {
2007: return(0);
2008: }
2010: #endif /* PETSC_USE_LOG*/
2013: PetscClassId PETSC_LARGEST_CLASSID = PETSC_SMALLEST_CLASSID;
2014: PetscClassId PETSC_OBJECT_CLASSID = 0;
2018: /*@C
2019: PetscClassIdRegister - Registers a new class name for objects and logging operations in an application code.
2021: Not Collective
2023: Input Parameter:
2024: . name - The class name
2026: Output Parameter:
2027: . oclass - The class id or classid
2029: Level: developer
2031: .keywords: log, class, register
2033: @*/
2034: PetscErrorCode PetscClassIdRegister(const char name[],PetscClassId *oclass)
2035: {
2036: #if defined(PETSC_USE_LOG)
2037: PetscStageLog stageLog;
2038: PetscInt stage;
2040: #endif
2043: *oclass = ++PETSC_LARGEST_CLASSID;
2044: #if defined(PETSC_USE_LOG)
2045: PetscLogGetStageLog(&stageLog);
2046: PetscClassRegLogRegister(stageLog->classLog, name, *oclass);
2047: for (stage = 0; stage < stageLog->numStages; stage++) {
2048: ClassPerfLogEnsureSize(stageLog->stageInfo[stage].classLog, stageLog->classLog->numClasses);
2049: }
2050: #endif
2051: return(0);
2052: }
2054: #if defined(PETSC_USE_LOG) && defined(PETSC_HAVE_MPE)
2055: #include <mpe.h>
2057: PetscBool PetscBeganMPE = PETSC_FALSE;
2059: PETSC_INTERN PetscErrorCode PetscLogEventBeginMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2060: PETSC_INTERN PetscErrorCode PetscLogEventEndMPE(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
2064: /*@C
2065: PetscLogMPEBegin - Turns on MPE logging of events. This creates large log files
2066: and slows the program down.
2068: Collective over PETSC_COMM_WORLD
2070: Options Database Keys:
2071: . -log_mpe - Prints extensive log information
2073: Notes:
2074: A related routine is PetscLogDefaultBegin() (with the options key -log_summary), which is
2075: intended for production runs since it logs only flop rates and object
2076: creation (and should not significantly slow the programs).
2078: Level: advanced
2080: Concepts: logging^MPE
2081: Concepts: logging^message passing
2083: .seealso: PetscLogDump(), PetscLogDefaultBegin(), PetscLogAllBegin(), PetscLogEventActivate(),
2084: PetscLogEventDeactivate()
2085: @*/
2086: PetscErrorCode PetscLogMPEBegin(void)
2087: {
2091: /* Do MPE initialization */
2092: if (!MPE_Initialized_logging()) { /* This function exists in mpich 1.1.2 and higher */
2093: PetscInfo(0,"Initializing MPE.\n");
2094: MPE_Init_log();
2096: PetscBeganMPE = PETSC_TRUE;
2097: } else {
2098: PetscInfo(0,"MPE already initialized. Not attempting to reinitialize.\n");
2099: }
2100: PetscLogSet(PetscLogEventBeginMPE, PetscLogEventEndMPE);
2101: return(0);
2102: }
2106: /*@C
2107: PetscLogMPEDump - Dumps the MPE logging info to file for later use with Jumpshot.
2109: Collective over PETSC_COMM_WORLD
2111: Level: advanced
2113: .seealso: PetscLogDump(), PetscLogAllBegin(), PetscLogMPEBegin()
2114: @*/
2115: PetscErrorCode PetscLogMPEDump(const char sname[])
2116: {
2117: char name[PETSC_MAX_PATH_LEN];
2121: if (PetscBeganMPE) {
2122: PetscInfo(0,"Finalizing MPE.\n");
2123: if (sname) {
2124: PetscStrcpy(name,sname);
2125: } else {
2126: PetscGetProgramName(name,PETSC_MAX_PATH_LEN);
2127: }
2128: MPE_Finish_log(name);
2129: } else {
2130: PetscInfo(0,"Not finalizing MPE (not started by PETSc).\n");
2131: }
2132: return(0);
2133: }
2135: #define PETSC_RGB_COLORS_MAX 39
2136: static const char *PetscLogMPERGBColors[PETSC_RGB_COLORS_MAX] = {
2137: "OliveDrab: ",
2138: "BlueViolet: ",
2139: "CadetBlue: ",
2140: "CornflowerBlue: ",
2141: "DarkGoldenrod: ",
2142: "DarkGreen: ",
2143: "DarkKhaki: ",
2144: "DarkOliveGreen: ",
2145: "DarkOrange: ",
2146: "DarkOrchid: ",
2147: "DarkSeaGreen: ",
2148: "DarkSlateGray: ",
2149: "DarkTurquoise: ",
2150: "DeepPink: ",
2151: "DarkKhaki: ",
2152: "DimGray: ",
2153: "DodgerBlue: ",
2154: "GreenYellow: ",
2155: "HotPink: ",
2156: "IndianRed: ",
2157: "LavenderBlush: ",
2158: "LawnGreen: ",
2159: "LemonChiffon: ",
2160: "LightCoral: ",
2161: "LightCyan: ",
2162: "LightPink: ",
2163: "LightSalmon: ",
2164: "LightSlateGray: ",
2165: "LightYellow: ",
2166: "LimeGreen: ",
2167: "MediumPurple: ",
2168: "MediumSeaGreen: ",
2169: "MediumSlateBlue:",
2170: "MidnightBlue: ",
2171: "MintCream: ",
2172: "MistyRose: ",
2173: "NavajoWhite: ",
2174: "NavyBlue: ",
2175: "OliveDrab: "
2176: };
2180: /*@C
2181: PetscLogMPEGetRGBColor - This routine returns a rgb color useable with PetscLogEventRegister()
2183: Not collective. Maybe it should be?
2185: Output Parameter
2186: . str - character string representing the color
2188: Level: developer
2190: .keywords: log, mpe , color
2191: .seealso: PetscLogEventRegister
2192: @*/
2193: PetscErrorCode PetscLogMPEGetRGBColor(const char *str[])
2194: {
2195: static int idx = 0;
2198: *str = PetscLogMPERGBColors[idx];
2199: idx = (idx + 1)% PETSC_RGB_COLORS_MAX;
2200: return(0);
2201: }
2203: #endif /* PETSC_USE_LOG && PETSC_HAVE_MPE */