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 Parameters:
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: }

346: /*@C
347:   PetscStageLogGetClassRegLog - This function returns the PetscClassRegLog for the given stage.

349:   Not Collective

351:   Input Parameters:
352: . stageLog - The PetscStageLog

354:   Output Parameter:
355: . classLog - The PetscClassRegLog

357:   Level: developer

359: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
360: @*/
361: PetscErrorCode  PetscStageLogGetClassRegLog(PetscStageLog stageLog, PetscClassRegLog *classLog)
362: {
365:   *classLog = stageLog->classLog;
366:   return(0);
367: }

369: /*@C
370:   PetscStageLogGetEventRegLog - This function returns the PetscEventRegLog.

372:   Not Collective

374:   Input Parameters:
375: . stageLog - The PetscStageLog

377:   Output Parameter:
378: . eventLog - The PetscEventRegLog

380:   Level: developer

382: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
383: @*/
384: PetscErrorCode  PetscStageLogGetEventRegLog(PetscStageLog stageLog, PetscEventRegLog *eventLog)
385: {
388:   *eventLog = stageLog->eventLog;
389:   return(0);
390: }

392: /*@C
393:   PetscStageLogGetClassPerfLog - This function returns the PetscClassPerfLog for the given stage.

395:   Not Collective

397:   Input Parameters:
398: + stageLog - The PetscStageLog
399: - stage    - The stage

401:   Output Parameter:
402: . classLog - The PetscClassPerfLog

404:   Level: developer

406: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
407: @*/
408: PetscErrorCode  PetscStageLogGetClassPerfLog(PetscStageLog stageLog, int stage, PetscClassPerfLog *classLog)
409: {
412:   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);
413:   *classLog = stageLog->stageInfo[stage].classLog;
414:   return(0);
415: }

417: /*@C
418:   PetscStageLogSetActive - This function determines whether events will be logged during this state.

420:   Not Collective

422:   Input Parameters:
423: + stageLog - The PetscStageLog
424: . stage    - The stage to log
425: - isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)

427:   Level: developer

429: .seealso: PetscStageLogGetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
430: @*/
431: PetscErrorCode  PetscStageLogSetActive(PetscStageLog stageLog, int stage, PetscBool isActive)
432: {
434:   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);
435:   stageLog->stageInfo[stage].perfInfo.active = isActive;
436:   return(0);
437: }

439: /*@C
440:   PetscStageLogGetActive - This function returns whether events will be logged suring this stage.

442:   Not Collective

444:   Input Parameters:
445: + stageLog - The PetscStageLog
446: - stage    - The stage to log

448:   Output Parameter:
449: . isActive - The activity flag, PETSC_TRUE for logging, otherwise PETSC_FALSE (default is PETSC_TRUE)

451:   Level: developer

453: .seealso: PetscStageLogSetActive(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
454: @*/
455: PetscErrorCode  PetscStageLogGetActive(PetscStageLog stageLog, int stage, PetscBool  *isActive)
456: {
458:   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);
460:   *isActive = stageLog->stageInfo[stage].perfInfo.active;
461:   return(0);
462: }

464: /*@C
465:   PetscStageLogSetVisible - This function determines whether a stage is printed during PetscLogView()

467:   Not Collective

469:   Input Parameters:
470: + stageLog  - The PetscStageLog
471: . stage     - The stage to log
472: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

474:   Database Options:
475: . -log_view - Activates log summary

477:   Level: developer

479: .seealso: PetscStageLogGetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
480: @*/
481: PetscErrorCode  PetscStageLogSetVisible(PetscStageLog stageLog, int stage, PetscBool isVisible)
482: {
484:   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);
485:   stageLog->stageInfo[stage].perfInfo.visible = isVisible;
486:   return(0);
487: }

489: /*@C
490:   PetscStageLogGetVisible - This function returns whether a stage is printed during PetscLogView()

492:   Not Collective

494:   Input Parameters:
495: + stageLog  - The PetscStageLog
496: - stage     - The stage to log

498:   Output Parameter:
499: . isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)

501:   Database Options:
502: . -log_view - Activates log summary

504:   Level: developer

506: .seealso: PetscStageLogSetVisible(), PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
507: @*/
508: PetscErrorCode  PetscStageLogGetVisible(PetscStageLog stageLog, int stage, PetscBool  *isVisible)
509: {
511:   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);
513:   *isVisible = stageLog->stageInfo[stage].perfInfo.visible;
514:   return(0);
515: }

517: /*@C
518:   PetscStageLogGetStage - This function returns the stage id given the stage name.

520:   Not Collective

522:   Input Parameters:
523: + stageLog - The PetscStageLog
524: - name     - The stage name

526:   Output Parameter:
527: . stage    - The stage id, or -1 if it does not exist

529:   Level: developer

531: .seealso: PetscStageLogGetCurrent(), PetscStageLogRegister(), PetscLogGetStageLog()
532: @*/
533: PetscErrorCode  PetscStageLogGetStage(PetscStageLog stageLog, const char name[], PetscLogStage *stage)
534: {
535:   PetscBool      match;
536:   int            s;

542:   *stage = -1;
543:   for (s = 0; s < stageLog->numStages; s++) {
544:     PetscStrcasecmp(stageLog->stageInfo[s].name, name, &match);
545:     if (match) {
546:       *stage = s;
547:       break;
548:     }
549:   }
550:   return(0);
551: }

553: /*@C
554:   PetscStageLogCreate - This creates a PetscStageLog object.

556:   Not collective

558:   Input Parameter:
559: . stageLog - The PetscStageLog

561:   Level: developer

563: .seealso: PetscStageLogCreate()
564: @*/
565: PetscErrorCode  PetscStageLogCreate(PetscStageLog *stageLog)
566: {
567:   PetscStageLog  l;

571:   PetscNew(&l);

573:   l->numStages = 0;
574:   l->maxStages = 10;
575:   l->curStage  = -1;

577:   PetscIntStackCreate(&l->stack);
578:   PetscMalloc1(l->maxStages, &l->stageInfo);
579:   PetscEventRegLogCreate(&l->eventLog);
580:   PetscClassRegLogCreate(&l->classLog);

582:   *stageLog = l;
583:   return(0);
584: }