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