Actual source code: stagelog.c
2: /*
3: This defines part of the private API for logging performance information. It is intended to be used only by the
4: PETSc PetscLog...() interface and not elsewhere, nor by users. Hence the prototypes for these functions are NOT
5: in the public PETSc include files.
7: */
8: #include <petsc/private/logimpl.h>
10: PetscStageLog petsc_stageLog = NULL;
12: /*@C
13: PetscLogGetStageLog - This function returns the default stage logging object.
15: Not collective
17: Output Parameter:
18: . stageLog - The default PetscStageLog
20: Level: developer
22: Developer Notes:
23: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
25: .seealso: PetscStageLogCreate()
26: @*/
27: PetscErrorCode PetscLogGetStageLog(PetscStageLog *stageLog)
28: {
31: if (!petsc_stageLog) {
32: fprintf(stderr, "PETSC ERROR: Logging has not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
33: PETSCABORT(MPI_COMM_WORLD, PETSC_ERR_SUP);
34: }
35: *stageLog = petsc_stageLog;
36: return(0);
37: }
39: /*@C
40: PetscStageLogGetCurrent - This function returns the stage from the top of the stack.
42: Not Collective
44: Input Parameter:
45: . stageLog - The PetscStageLog
47: Output Parameter:
48: . stage - The current stage
50: Notes:
51: If no stage is currently active, stage is set to -1.
53: Level: developer
55: Developer Notes:
56: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
58: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
59: @*/
60: PetscErrorCode PetscStageLogGetCurrent(PetscStageLog stageLog, int *stage)
61: {
62: PetscBool empty;
66: PetscIntStackEmpty(stageLog->stack, &empty);
67: if (empty) {
68: *stage = -1;
69: } else {
70: PetscIntStackTop(stageLog->stack, stage);
71: }
72: if (*stage != stageLog->curStage) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Inconsistency in stage log: stage %d should be %d", *stage, stageLog->curStage);
73: return(0);
74: }
76: /*@C
77: PetscStageLogGetEventPerfLog - This function returns the PetscEventPerfLog for the given stage.
79: Not Collective
81: Input Parameters:
82: + stageLog - The PetscStageLog
83: - stage - The stage
85: Output Parameter:
86: . eventLog - The PetscEventPerfLog
88: Level: developer
90: Developer Notes:
91: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
93: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
94: @*/
95: PetscErrorCode PetscStageLogGetEventPerfLog(PetscStageLog stageLog, int stage, PetscEventPerfLog *eventLog)
96: {
99: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
100: *eventLog = stageLog->stageInfo[stage].eventLog;
101: return(0);
102: }
104: /*@C
105: PetscStageInfoDestroy - This destroys a PetscStageInfo object.
107: Not collective
109: Input Parameter:
110: . stageInfo - The PetscStageInfo
112: Level: developer
114: .seealso: PetscStageLogCreate()
115: @*/
116: PetscErrorCode PetscStageInfoDestroy(PetscStageInfo *stageInfo)
117: {
121: PetscFree(stageInfo->name);
122: PetscEventPerfLogDestroy(stageInfo->eventLog);
123: PetscClassPerfLogDestroy(stageInfo->classLog);
124: return(0);
125: }
127: /*@C
128: PetscStageLogDestroy - This destroys a PetscStageLog object.
130: Not collective
132: Input Parameter:
133: . stageLog - The PetscStageLog
135: Level: developer
137: .seealso: PetscStageLogCreate()
138: @*/
139: PetscErrorCode PetscStageLogDestroy(PetscStageLog stageLog)
140: {
141: int stage;
145: if (!stageLog) return(0);
146: PetscIntStackDestroy(stageLog->stack);
147: PetscEventRegLogDestroy(stageLog->eventLog);
148: PetscClassRegLogDestroy(stageLog->classLog);
149: for (stage = 0; stage < stageLog->numStages; stage++) {
150: PetscStageInfoDestroy(&stageLog->stageInfo[stage]);
151: }
152: PetscFree(stageLog->stageInfo);
153: PetscFree(stageLog);
154: return(0);
155: }
157: /*@C
158: PetscStageLogRegister - Registers a stage name for logging operations in an application code.
160: Not Collective
162: Input Parameter:
163: + stageLog - The PetscStageLog
164: - sname - the name to associate with that stage
166: Output Parameter:
167: . stage - The stage index
169: Level: developer
171: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscStageLogCreate()
172: @*/
173: PetscErrorCode PetscStageLogRegister(PetscStageLog stageLog, const char sname[], int *stage)
174: {
175: PetscStageInfo *stageInfo;
176: int s;
182: /* Check stage already registered */
183: for (s = 0; s < stageLog->numStages; ++s) {
184: PetscBool same;
186: PetscStrcmp(stageLog->stageInfo[s].name, sname, &same);
187: if (same) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Duplicate stage name given: %s", sname);
188: }
189: /* Create new stage */
190: s = stageLog->numStages++;
191: if (stageLog->numStages > stageLog->maxStages) {
192: PetscMalloc1(stageLog->maxStages*2, &stageInfo);
193: PetscArraycpy(stageInfo, stageLog->stageInfo, stageLog->maxStages);
194: PetscFree(stageLog->stageInfo);
195: stageLog->stageInfo = stageInfo;
196: stageLog->maxStages *= 2;
197: }
198: /* Setup new stage info */
199: stageInfo = &stageLog->stageInfo[s];
200: PetscMemzero(stageInfo,sizeof(PetscStageInfo));
201: PetscStrallocpy(sname,&stageInfo->name);
202: stageInfo->used = PETSC_FALSE;
203: stageInfo->perfInfo.active = PETSC_TRUE;
204: stageInfo->perfInfo.visible = PETSC_TRUE;
205: PetscEventPerfLogCreate(&stageInfo->eventLog);
206: PetscClassPerfLogCreate(&stageInfo->classLog);
207: *stage = s;
208: return(0);
209: }
211: /*@C
212: PetscStageLogPush - This function pushes a stage on the stack.
214: Not Collective
216: Input Parameters:
217: + stageLog - The PetscStageLog
218: - stage - The stage to log
220: Database Options:
221: . -log_view - Activates logging
223: Usage:
224: If the option -log_sumary is used to run the program containing the
225: following code, then 2 sets of summary data will be printed during
226: PetscFinalize().
227: .vb
228: PetscInitialize(int *argc,char ***args,0,0);
229: [stage 0 of code]
230: PetscStageLogPush(stageLog,1);
231: [stage 1 of code]
232: PetscStageLogPop(stageLog);
233: PetscBarrier(...);
234: [more stage 0 of code]
235: PetscFinalize();
236: .ve
238: Notes:
239: Use PetscLogStageRegister() to register a stage. All previous stages are
240: accumulating time and flops, but events will only be logged in this stage.
242: Level: developer
244: .seealso: PetscStageLogPop(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
245: @*/
246: PetscErrorCode PetscStageLogPush(PetscStageLog stageLog, int stage)
247: {
248: int curStage = 0;
249: PetscBool empty;
253: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
255: /* Record flops/time of previous stage */
256: PetscIntStackEmpty(stageLog->stack, &empty);
257: if (!empty) {
258: PetscIntStackTop(stageLog->stack, &curStage);
259: if (stageLog->stageInfo[curStage].perfInfo.active) {
260: PetscTimeAdd(&stageLog->stageInfo[curStage].perfInfo.time);
261: stageLog->stageInfo[curStage].perfInfo.flops += petsc_TotalFlops;
262: stageLog->stageInfo[curStage].perfInfo.numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
263: stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
264: stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
265: }
266: }
267: /* Activate the stage */
268: PetscIntStackPush(stageLog->stack, stage);
270: stageLog->stageInfo[stage].used = PETSC_TRUE;
271: stageLog->stageInfo[stage].perfInfo.count++;
272: stageLog->curStage = stage;
273: /* Subtract current quantities so that we obtain the difference when we pop */
274: if (stageLog->stageInfo[stage].perfInfo.active) {
275: PetscTimeSubtract(&stageLog->stageInfo[stage].perfInfo.time);
276: stageLog->stageInfo[stage].perfInfo.flops -= petsc_TotalFlops;
277: stageLog->stageInfo[stage].perfInfo.numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
278: stageLog->stageInfo[stage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
279: stageLog->stageInfo[stage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
280: }
281: return(0);
282: }
284: /*@C
285: PetscStageLogPop - This function pops a stage from the stack.
287: Not Collective
289: Input Parameter:
290: . stageLog - The PetscStageLog
292: Usage:
293: If the option -log_sumary is used to run the program containing the
294: following code, then 2 sets of summary data will be printed during
295: PetscFinalize().
296: .vb
297: PetscInitialize(int *argc,char ***args,0,0);
298: [stage 0 of code]
299: PetscStageLogPush(stageLog,1);
300: [stage 1 of code]
301: PetscStageLogPop(stageLog);
302: PetscBarrier(...);
303: [more stage 0 of code]
304: PetscFinalize();
305: .ve
307: Notes:
308: Use PetscStageLogRegister() to register a stage.
310: Level: developer
312: .seealso: PetscStageLogPush(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
313: @*/
314: PetscErrorCode PetscStageLogPop(PetscStageLog stageLog)
315: {
316: int curStage;
317: PetscBool empty;
321: /* Record flops/time of current stage */
322: PetscIntStackPop(stageLog->stack, &curStage);
323: if (stageLog->stageInfo[curStage].perfInfo.active) {
324: PetscTimeAdd(&stageLog->stageInfo[curStage].perfInfo.time);
325: stageLog->stageInfo[curStage].perfInfo.flops += petsc_TotalFlops;
326: stageLog->stageInfo[curStage].perfInfo.numMessages += petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
327: stageLog->stageInfo[curStage].perfInfo.messageLength += petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
328: stageLog->stageInfo[curStage].perfInfo.numReductions += petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
329: }
330: PetscIntStackEmpty(stageLog->stack, &empty);
331: if (!empty) {
332: /* Subtract current quantities so that we obtain the difference when we pop */
333: PetscIntStackTop(stageLog->stack, &curStage);
334: if (stageLog->stageInfo[curStage].perfInfo.active) {
335: PetscTimeSubtract(&stageLog->stageInfo[curStage].perfInfo.time);
336: stageLog->stageInfo[curStage].perfInfo.flops -= petsc_TotalFlops;
337: stageLog->stageInfo[curStage].perfInfo.numMessages -= petsc_irecv_ct + petsc_isend_ct + petsc_recv_ct + petsc_send_ct;
338: stageLog->stageInfo[curStage].perfInfo.messageLength -= petsc_irecv_len + petsc_isend_len + petsc_recv_len + petsc_send_len;
339: stageLog->stageInfo[curStage].perfInfo.numReductions -= petsc_allreduce_ct + petsc_gather_ct + petsc_scatter_ct;
340: }
341: stageLog->curStage = curStage;
342: } else stageLog->curStage = -1;
343: return(0);
344: }
347: /*@C
348: PetscStageLogGetClassRegLog - This function returns the PetscClassRegLog for the given stage.
350: Not Collective
352: Input Parameters:
353: . stageLog - The PetscStageLog
355: Output Parameter:
356: . classLog - The PetscClassRegLog
358: Level: developer
360: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
361: @*/
362: PetscErrorCode PetscStageLogGetClassRegLog(PetscStageLog stageLog, PetscClassRegLog *classLog)
363: {
366: *classLog = stageLog->classLog;
367: return(0);
368: }
370: /*@C
371: PetscStageLogGetEventRegLog - This function returns the PetscEventRegLog.
373: Not Collective
375: Input Parameters:
376: . stageLog - The PetscStageLog
378: Output Parameter:
379: . eventLog - The PetscEventRegLog
381: Level: developer
383: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
384: @*/
385: PetscErrorCode PetscStageLogGetEventRegLog(PetscStageLog stageLog, PetscEventRegLog *eventLog)
386: {
389: *eventLog = stageLog->eventLog;
390: return(0);
391: }
393: /*@C
394: PetscStageLogGetClassPerfLog - This function returns the PetscClassPerfLog for the given stage.
396: Not Collective
398: Input Parameters:
399: + stageLog - The PetscStageLog
400: - stage - The stage
402: Output Parameter:
403: . classLog - The PetscClassPerfLog
405: Level: developer
407: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
408: @*/
409: PetscErrorCode PetscStageLogGetClassPerfLog(PetscStageLog stageLog, int stage, PetscClassPerfLog *classLog)
410: {
413: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
414: *classLog = stageLog->stageInfo[stage].classLog;
415: return(0);
416: }
419: /*@C
420: PetscStageLogSetActive - This function determines whether events will be logged during this state.
422: Not Collective
424: Input Parameters:
425: + stageLog - The PetscStageLog
426: . stage - The stage to log
427: - isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)
429: Level: developer
431: .seealso: PetscStageLogGetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
432: @*/
433: PetscErrorCode PetscStageLogSetActive(PetscStageLog stageLog, int stage, PetscBool isActive)
434: {
436: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
437: stageLog->stageInfo[stage].perfInfo.active = isActive;
438: return(0);
439: }
441: /*@C
442: PetscStageLogGetActive - This function returns whether events will be logged suring this stage.
444: Not Collective
446: Input Parameters:
447: + stageLog - The PetscStageLog
448: - stage - The stage to log
450: Output Parameter:
451: . isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)
453: Level: developer
455: .seealso: PetscStageLogSetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
456: @*/
457: PetscErrorCode PetscStageLogGetActive(PetscStageLog stageLog, int stage, PetscBool *isActive)
458: {
460: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
462: *isActive = stageLog->stageInfo[stage].perfInfo.active;
463: return(0);
464: }
466: /*@C
467: PetscStageLogSetVisible - This function determines whether a stage is printed during PetscLogView()
469: Not Collective
471: Input Parameters:
472: + stageLog - The PetscStageLog
473: . stage - The stage to log
474: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
476: Database Options:
477: . -log_view - Activates log summary
479: Level: developer
481: .seealso: PetscStageLogGetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
482: @*/
483: PetscErrorCode PetscStageLogSetVisible(PetscStageLog stageLog, int stage, PetscBool isVisible)
484: {
486: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
487: stageLog->stageInfo[stage].perfInfo.visible = isVisible;
488: return(0);
489: }
491: /*@C
492: PetscStageLogGetVisible - This function returns whether a stage is printed during PetscLogView()
494: Not Collective
496: Input Parameters:
497: + stageLog - The PetscStageLog
498: - stage - The stage to log
500: Output Parameter:
501: . isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
503: Database Options:
504: . -log_view - Activates log summary
506: Level: developer
508: .seealso: PetscStageLogSetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
509: @*/
510: PetscErrorCode PetscStageLogGetVisible(PetscStageLog stageLog, int stage, PetscBool *isVisible)
511: {
513: if ((stage < 0) || (stage >= stageLog->numStages)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
515: *isVisible = stageLog->stageInfo[stage].perfInfo.visible;
516: return(0);
517: }
519: /*@C
520: PetscStageLogGetStage - This function returns the stage id given the stage name.
522: Not Collective
524: Input Parameters:
525: + stageLog - The PetscStageLog
526: - name - The stage name
528: Output Parameter:
529: . stage - The stage id, or -1 if it does not exist
531: Level: developer
533: .seealso: PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
534: @*/
535: PetscErrorCode PetscStageLogGetStage(PetscStageLog stageLog, const char name[], PetscLogStage *stage)
536: {
537: PetscBool match;
538: int s;
544: *stage = -1;
545: for (s = 0; s < stageLog->numStages; s++) {
546: PetscStrcasecmp(stageLog->stageInfo[s].name, name, &match);
547: if (match) {
548: *stage = s;
549: break;
550: }
551: }
552: return(0);
553: }
555: /*@C
556: PetscStageLogCreate - This creates a PetscStageLog object.
558: Not collective
560: Input Parameter:
561: . stageLog - The PetscStageLog
563: Level: developer
565: .seealso: PetscStageLogCreate()
566: @*/
567: PetscErrorCode PetscStageLogCreate(PetscStageLog *stageLog)
568: {
569: PetscStageLog l;
573: PetscNew(&l);
575: l->numStages = 0;
576: l->maxStages = 10;
577: l->curStage = -1;
579: PetscIntStackCreate(&l->stack);
580: PetscMalloc1(l->maxStages, &l->stageInfo);
581: PetscEventRegLogCreate(&l->eventLog);
582: PetscClassRegLogCreate(&l->classLog);
584: *stageLog = l;
585: return(0);
586: }