Actual source code: classlog.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: /*@C
 11:   PetscClassRegLogCreate - This creates a `PetscClassRegLog` object.

 13:   Not collective

 15:   Input Parameter:
 16: . classLog - The `PetscClassRegLog`

 18:   Level: developer

 20:   Note:
 21:   This is a low level routine used by the logging functions in PETSc

 23: .seealso: `PetscClassRegLogDestroy()`, `PetscStageLogCreate()`
 24: @*/
 25: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
 26: {
 27:   PetscClassRegLog l;

 29:   PetscNew(&l);

 31:   l->numClasses = 0;
 32:   l->maxClasses = 100;

 34:   PetscMalloc1(l->maxClasses, &l->classInfo);

 36:   *classLog = l;
 37:   return 0;
 38: }

 40: /*@C
 41:   PetscClassRegLogDestroy - This destroys a `PetscClassRegLog` object.

 43:   Not collective

 45:   Input Parameter:
 46: . classLog - The `PetscClassRegLog`

 48:   Level: developer

 50:   Note:
 51:   This is a low level routine used by the logging functions in PETSc

 53: .seealso: `PetscClassRegLogCreate()`
 54: @*/
 55: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
 56: {
 57:   int c;

 59:   for (c = 0; c < classLog->numClasses; c++) PetscClassRegInfoDestroy(&classLog->classInfo[c]);
 60:   PetscFree(classLog->classInfo);
 61:   PetscFree(classLog);
 62:   return 0;
 63: }

 65: /*@C
 66:   PetscClassRegInfoDestroy - This destroys a `PetscClassRegInfo` object.

 68:   Not collective

 70:   Input Parameter:
 71: . c - The PetscClassRegInfo

 73:   Level: developer

 75:   Note:
 76:   This is a low level routine used by the logging functions in PETSc

 78: .seealso: `PetscStageLogDestroy()`, `EventLogDestroy()`
 79: @*/
 80: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
 81: {
 82:   PetscFree(c->name);
 83:   return 0;
 84: }

 86: /*@C
 87:   PetscClassPerfLogCreate - This creates a `PetscClassPerfLog` object.

 89:   Not collective

 91:   Input Parameter:
 92: . classLog - The `PetscClassPerfLog`

 94:   Level: developer

 96:   Note:
 97:   This is a low level routine used by the logging functions in PETSc

 99: .seealso: `PetscClassPerfLogDestroy()`, `PetscStageLogCreate()`
100: @*/
101: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
102: {
103:   PetscClassPerfLog l;

105:   PetscNew(&l);

107:   l->numClasses = 0;
108:   l->maxClasses = 100;

110:   PetscMalloc1(l->maxClasses, &l->classInfo);

112:   *classLog = l;
113:   return 0;
114: }

116: /*@C
117:   PetscClassPerfLogDestroy - This destroys a `PetscClassPerfLog` object.

119:   Not collective

121:   Input Parameter:
122: . classLog - The `PetscClassPerfLog`

124:   Level: developer

126:   Note:
127:   This is a low level routine used by the logging functions in PETSc

129: .seealso: `PetscClassPerfLogCreate()`
130: @*/
131: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
132: {
133:   PetscFree(classLog->classInfo);
134:   PetscFree(classLog);
135:   return 0;
136: }

138: /*------------------------------------------------ General Functions -------------------------------------------------*/
139: /*@C
140:   PetscClassPerfInfoClear - This clears a `PetscClassPerfInfo` object.

142:   Not collective

144:   Input Parameter:
145: . classInfo - The `PetscClassPerfInfo`

147:   Level: developer

149:   Note:
150:   This is a low level routine used by the logging functions in PETSc

152: .seealso: `PetscClassPerfLogCreate()`
153: @*/
154: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
155: {
156:   classInfo->id           = -1;
157:   classInfo->creations    = 0;
158:   classInfo->destructions = 0;
159:   classInfo->mem          = 0.0;
160:   classInfo->descMem      = 0.0;
161:   return 0;
162: }

164: /*@C
165:   PetscClassPerfLogEnsureSize - This ensures that a `PetscClassPerfLog` is at least of a certain size.

167:   Not collective

169:   Input Parameters:
170: + classLog - The `PetscClassPerfLog`
171: - size     - The size

173:   Level: developer

175:   Note:
176:   This is a low level routine used by the logging functions in PETSc

178: .seealso: `PetscClassPerfLogCreate()`
179: @*/
180: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
181: {
182:   PetscClassPerfInfo *classInfo;

184:   while (size > classLog->maxClasses) {
185:     PetscMalloc1(classLog->maxClasses * 2, &classInfo);
186:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
187:     PetscFree(classLog->classInfo);

189:     classLog->classInfo = classInfo;
190:     classLog->maxClasses *= 2;
191:   }
192:   while (classLog->numClasses < size) PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
193:   return 0;
194: }

196: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
197: /*@C
198:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

200:   Not Collective

202:   Input Parameters:
203: + classLog - The `PetscClassRegLog`
204: - cname    - The name associated with the class

206:   Output Parameter:
207: .  classid   - The classid

209:   Level: developer

211:   Note:
212:   This is a low level routine used by the logging functions in PETSc

214: .seealso: `PetscClassIdRegister()`
215: @*/
216: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
217: {
218:   PetscClassRegInfo *classInfo;
219:   char              *str;
220:   int                c;

223:   c = classLog->numClasses++;
224:   if (classLog->numClasses > classLog->maxClasses) {
225:     PetscMalloc1(classLog->maxClasses * 2, &classInfo);
226:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
227:     PetscFree(classLog->classInfo);

229:     classLog->classInfo = classInfo;
230:     classLog->maxClasses *= 2;
231:   }
232:   PetscStrallocpy(cname, &str);

234:   classLog->classInfo[c].name    = str;
235:   classLog->classInfo[c].classid = classid;
236:   return 0;
237: }

239: /*------------------------------------------------ Query Functions --------------------------------------------------*/
240: /*@C
241:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

243:   Not Collective

245:   Input Parameters:
246: + classLog - The `PetscClassRegLog`
247: - classid  - The cookie

249:   Output Parameter:
250: . oclass   - The class id

252:   Level: developer

254:   Note:
255:   This is a low level routine used by the logging functions in PETSc

257: .seealso: `PetscClassIdRegister()`, `PetscLogObjCreateDefault()`, `PetscLogObjDestroyDefault()`
258: @*/
259: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
260: {
261:   int c;

264:   for (c = 0; c < classLog->numClasses; c++) {
265:     /* Could do bisection here */
266:     if (classLog->classInfo[c].classid == classid) break;
267:   }
269:   *oclass = c;
270:   return 0;
271: }

273: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
274: /* Default object create logger */
275: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
276: {
277:   PetscStageLog     stageLog;
278:   PetscClassRegLog  classRegLog;
279:   PetscClassPerfLog classPerfLog;
280:   Action           *tmpAction;
281:   Object           *tmpObjects;
282:   PetscLogDouble    start, end;
283:   int               oclass = 0;
284:   int               stage;

286:   /* Record stage info */
287:   PetscLogGetStageLog(&stageLog);
288:   PetscStageLogGetCurrent(stageLog, &stage);
289:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
290:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
291:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
292:   classPerfLog->classInfo[oclass].creations++;
293:   /* Dynamically enlarge logging structures */
294:   if (petsc_numActions >= petsc_maxActions) {
295:     PetscTime(&start);
296:     PetscMalloc1(petsc_maxActions * 2, &tmpAction);
297:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
298:     PetscFree(petsc_actions);

300:     petsc_actions = tmpAction;
301:     petsc_maxActions *= 2;
302:     PetscTime(&end);
303:     petsc_BaseTime += (end - start);
304:   }

306:   petsc_numObjects = obj->id;
307:   /* Record the creation action */
308:   if (petsc_logActions) {
309:     PetscTime(&petsc_actions[petsc_numActions].time);
310:     petsc_actions[petsc_numActions].time -= petsc_BaseTime;
311:     petsc_actions[petsc_numActions].action  = CREATE;
312:     petsc_actions[petsc_numActions].classid = obj->classid;
313:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
314:     petsc_actions[petsc_numActions].id2     = -1;
315:     petsc_actions[petsc_numActions].id3     = -1;
316:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

318:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
319:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
320:     petsc_numActions++;
321:   }
322:   /* Record the object */
323:   if (petsc_logObjects) {
324:     petsc_objects[petsc_numObjects].parent = -1;
325:     petsc_objects[petsc_numObjects].obj    = obj;

327:     PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
328:     PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));

330:     /* Dynamically enlarge logging structures */
331:     if (petsc_numObjects >= petsc_maxObjects) {
332:       PetscTime(&start);
333:       PetscMalloc1(petsc_maxObjects * 2, &tmpObjects);
334:       PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
335:       PetscFree(petsc_objects);

337:       petsc_objects = tmpObjects;
338:       petsc_maxObjects *= 2;
339:       PetscTime(&end);
340:       petsc_BaseTime += (end - start);
341:     }
342:   }
343:   return 0;
344: }

346: /* Default object destroy logger */
347: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
348: {
349:   PetscStageLog     stageLog;
350:   PetscClassRegLog  classRegLog;
351:   PetscClassPerfLog classPerfLog;
352:   Action           *tmpAction;
353:   PetscLogDouble    start, end;
354:   int               oclass = 0;
355:   int               stage;

357:   /* Record stage info */
358:   PetscLogGetStageLog(&stageLog);
359:   PetscStageLogGetCurrent(stageLog, &stage);
360:   if (stage != -1) {
361:     /* That can happen if the log summary is output before some things are destroyed */
362:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
363:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
364:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
365:     classPerfLog->classInfo[oclass].destructions++;
366:   }
367:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
368:   petsc_numObjectsDestroyed++;
369:   /* Dynamically enlarge logging structures */
370:   if (petsc_numActions >= petsc_maxActions) {
371:     PetscTime(&start);
372:     PetscMalloc1(petsc_maxActions * 2, &tmpAction);
373:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
374:     PetscFree(petsc_actions);

376:     petsc_actions = tmpAction;
377:     petsc_maxActions *= 2;
378:     PetscTime(&end);
379:     petsc_BaseTime += (end - start);
380:   }
381:   /* Record the destruction action */
382:   if (petsc_logActions) {
383:     PetscTime(&petsc_actions[petsc_numActions].time);
384:     petsc_actions[petsc_numActions].time -= petsc_BaseTime;
385:     petsc_actions[petsc_numActions].action  = DESTROY;
386:     petsc_actions[petsc_numActions].classid = obj->classid;
387:     petsc_actions[petsc_numActions].id1     = obj->id;
388:     petsc_actions[petsc_numActions].id2     = -1;
389:     petsc_actions[petsc_numActions].id3     = -1;
390:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

392:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
393:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
394:     petsc_numActions++;
395:   }
396:   if (petsc_logObjects) {
397:     if (obj->name) PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
398:     petsc_objects[obj->id].obj = NULL;
399:   }
400:   return 0;
401: }