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: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
 21: @*/
 22: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
 23: {
 24:   PetscClassRegLog l;

 26:   PetscNew(&l);

 28:   l->numClasses = 0;
 29:   l->maxClasses = 100;

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

 33:   *classLog = l;
 34:   return 0;
 35: }

 37: /*@C
 38:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.

 40:   Not collective

 42:   Input Parameter:
 43: . classLog - The PetscClassRegLog

 45:   Level: developer

 47: .seealso: PetscClassRegLogCreate()
 48: @*/
 49: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
 50: {
 51:   int            c;

 53:   for (c = 0; c < classLog->numClasses; c++) {
 54:     PetscClassRegInfoDestroy(&classLog->classInfo[c]);
 55:   }
 56:   PetscFree(classLog->classInfo);
 57:   PetscFree(classLog);
 58:   return 0;
 59: }

 61: /*@C
 62:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

 64:   Not collective

 66:   Input Parameter:
 67: . c - The PetscClassRegInfo

 69:   Level: developer

 71: .seealso: PetscStageLogDestroy(), EventLogDestroy()
 72: @*/
 73: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
 74: {
 75:   PetscFree(c->name);
 76:   return 0;
 77: }

 79: /*@C
 80:   PetscClassPerfLogCreate - This creates a PetscClassPerfLog object.

 82:   Not collective

 84:   Input Parameter:
 85: . classLog - The PetscClassPerfLog

 87:   Level: developer

 89: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
 90: @*/
 91: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
 92: {
 93:   PetscClassPerfLog l;

 95:   PetscNew(&l);

 97:   l->numClasses = 0;
 98:   l->maxClasses = 100;

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

102:   *classLog = l;
103:   return 0;
104: }

106: /*@C
107:   PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

109:   Not collective

111:   Input Parameter:
112: . classLog - The PetscClassPerfLog

114:   Level: developer

116: .seealso: PetscClassPerfLogCreate()
117: @*/
118: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
119: {
120:   PetscFree(classLog->classInfo);
121:   PetscFree(classLog);
122:   return 0;
123: }

125: /*------------------------------------------------ General Functions -------------------------------------------------*/
126: /*@C
127:   PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.

129:   Not collective

131:   Input Parameter:
132: . classInfo - The PetscClassPerfInfo

134:   Level: developer

136: .seealso: PetscClassPerfLogCreate()
137: @*/
138: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
139: {
140:   classInfo->id           = -1;
141:   classInfo->creations    = 0;
142:   classInfo->destructions = 0;
143:   classInfo->mem          = 0.0;
144:   classInfo->descMem      = 0.0;
145:   return 0;
146: }

148: /*@C
149:   PetscClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.

151:   Not collective

153:   Input Parameters:
154: + classLog - The PetscClassPerfLog
155: - size     - The size

157:   Level: developer

159: .seealso: PetscClassPerfLogCreate()
160: @*/
161: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
162: {
163:   PetscClassPerfInfo *classInfo;

165:   while (size > classLog->maxClasses) {
166:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
167:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
168:     PetscFree(classLog->classInfo);

170:     classLog->classInfo   = classInfo;
171:     classLog->maxClasses *= 2;
172:   }
173:   while (classLog->numClasses < size) {
174:     PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
175:   }
176:   return 0;
177: }

179: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
180: /*@C
181:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

183:   Not Collective

185:   Input Parameters:
186: + classLog - The ClassLog
187: - cname    - The name associated with the class

189:   Output Parameter:
190: .  classid   - The classid

192:   Level: developer

194: .seealso: PetscClassIdRegister()
195: @*/
196: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
197: {
198:   PetscClassRegInfo *classInfo;
199:   char              *str;
200:   int               c;

203:   c = classLog->numClasses++;
204:   if (classLog->numClasses > classLog->maxClasses) {
205:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
206:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
207:     PetscFree(classLog->classInfo);

209:     classLog->classInfo   = classInfo;
210:     classLog->maxClasses *= 2;
211:   }
212:   PetscStrallocpy(cname, &str);

214:   classLog->classInfo[c].name    = str;
215:   classLog->classInfo[c].classid = classid;
216:   return 0;
217: }

219: /*------------------------------------------------ Query Functions --------------------------------------------------*/
220: /*@C
221:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

223:   Not Collective

225:   Input Parameters:
226: + classLog - The PetscClassRegLog
227: - classid  - The cookie

229:   Output Parameter:
230: . oclass   - The class id

232:   Level: developer

234: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
235: @*/
236: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
237: {
238:   int c;

241:   for (c = 0; c < classLog->numClasses; c++) {
242:     /* Could do bisection here */
243:     if (classLog->classInfo[c].classid == classid) break;
244:   }
246:   *oclass = c;
247:   return 0;
248: }

250: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
251: /* Default object create logger */
252: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
253: {
254:   PetscStageLog     stageLog;
255:   PetscClassRegLog  classRegLog;
256:   PetscClassPerfLog classPerfLog;
257:   Action            *tmpAction;
258:   Object            *tmpObjects;
259:   PetscLogDouble    start, end;
260:   int               oclass = 0;
261:   int               stage;

263:   /* Record stage info */
264:   PetscLogGetStageLog(&stageLog);
265:   PetscStageLogGetCurrent(stageLog, &stage);
266:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
267:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
268:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
269:   classPerfLog->classInfo[oclass].creations++;
270:   /* Dynamically enlarge logging structures */
271:   if (petsc_numActions >= petsc_maxActions) {
272:     PetscTime(&start);
273:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
274:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
275:     PetscFree(petsc_actions);

277:     petsc_actions     = tmpAction;
278:     petsc_maxActions *= 2;
279:     PetscTime(&end);
280:     petsc_BaseTime += (end - start);
281:   }

283:   petsc_numObjects = obj->id;
284:   /* Record the creation action */
285:   if (petsc_logActions) {
286:     PetscTime(&petsc_actions[petsc_numActions].time);
287:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
288:     petsc_actions[petsc_numActions].action  = CREATE;
289:     petsc_actions[petsc_numActions].classid = obj->classid;
290:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
291:     petsc_actions[petsc_numActions].id2     = -1;
292:     petsc_actions[petsc_numActions].id3     = -1;
293:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

295:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
296:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
297:     petsc_numActions++;
298:   }
299:   /* Record the object */
300:   if (petsc_logObjects) {
301:     petsc_objects[petsc_numObjects].parent = -1;
302:     petsc_objects[petsc_numObjects].obj    = obj;

304:     PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
305:     PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));

307:     /* Dynamically enlarge logging structures */
308:     if (petsc_numObjects >= petsc_maxObjects) {
309:       PetscTime(&start);
310:       PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
311:       PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
312:       PetscFree(petsc_objects);

314:       petsc_objects     = tmpObjects;
315:       petsc_maxObjects *= 2;
316:       PetscTime(&end);
317:       petsc_BaseTime += (end - start);
318:     }
319:   }
320:   return 0;
321: }

323: /* Default object destroy logger */
324: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
325: {
326:   PetscStageLog     stageLog;
327:   PetscClassRegLog  classRegLog;
328:   PetscClassPerfLog classPerfLog;
329:   Action            *tmpAction;
330:   PetscLogDouble    start, end;
331:   int               oclass = 0;
332:   int               stage;

334:   /* Record stage info */
335:   PetscLogGetStageLog(&stageLog);
336:   PetscStageLogGetCurrent(stageLog, &stage);
337:   if (stage != -1) {
338:     /* That can happen if the log summary is output before some things are destroyed */
339:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
340:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
341:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
342:     classPerfLog->classInfo[oclass].destructions++;
343:     classPerfLog->classInfo[oclass].mem += obj->mem;
344:   }
345:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
346:   petsc_numObjectsDestroyed++;
347:   /* Dynamically enlarge logging structures */
348:   if (petsc_numActions >= petsc_maxActions) {
349:     PetscTime(&start);
350:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
351:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
352:     PetscFree(petsc_actions);

354:     petsc_actions     = tmpAction;
355:     petsc_maxActions *= 2;
356:     PetscTime(&end);
357:     petsc_BaseTime += (end - start);
358:   }
359:   /* Record the destruction action */
360:   if (petsc_logActions) {
361:     PetscTime(&petsc_actions[petsc_numActions].time);
362:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
363:     petsc_actions[petsc_numActions].action  = DESTROY;
364:     petsc_actions[petsc_numActions].classid = obj->classid;
365:     petsc_actions[petsc_numActions].id1     = obj->id;
366:     petsc_actions[petsc_numActions].id2     = -1;
367:     petsc_actions[petsc_numActions].id3     = -1;
368:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

370:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
371:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
372:     petsc_numActions++;
373:   }
374:   if (petsc_logObjects) {
375:     if (obj->name) {
376:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
377:     }
378:     petsc_objects[obj->id].obj = NULL;
379:     petsc_objects[obj->id].mem = obj->mem;
380:   }
381:   return 0;
382: }