Actual source code: classLog.c

  1: #define PETSC_DLL

 3:  #include ../src/sys/plog/plog.h

  5: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
  6: /* Note: these functions do not have prototypes in a public directory, so they are considered "internal" and not exported. */
  9: /*@C
 10:   ClassRegLogCreate - This creates a ClassRegLog object.

 12:   Not collective

 14:   Input Parameter:
 15: . classLog - The ClassRegLog

 17:   Level: beginner

 19: .keywords: log, class, create
 20: .seealso: ClassRegLogDestroy(), StageLogCreate()
 21: @*/
 22: PetscErrorCode ClassRegLogCreate(ClassRegLog *classLog)
 23: {
 24:   ClassRegLog l;

 28:   PetscNew(struct _n_ClassRegLog, &l);
 29:   l->numClasses = 0;
 30:   l->maxClasses = 100;
 31:   PetscMalloc(l->maxClasses * sizeof(ClassRegInfo), &l->classInfo);
 32:   *classLog = l;
 33:   return(0);
 34: }

 38: /*@C
 39:   ClassRegLogDestroy - This destroys a ClassRegLog object.

 41:   Not collective

 43:   Input Paramter:
 44: . classLog - The ClassRegLog

 46:   Level: beginner

 48: .keywords: log, event, destroy
 49: .seealso: ClassRegLogCreate()
 50: @*/
 51: PetscErrorCode ClassRegLogDestroy(ClassRegLog classLog)\
 52: {
 53:   int c;

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

 67: /*@C
 68:   ClassRegInfoDestroy - This destroys a ClassRegInfo object.

 70:   Not collective

 72:   Input Parameter:
 73: . c - The ClassRegInfo

 75:   Level: beginner

 77: .keywords: log, class, destroy
 78: .seealso: StageLogDestroy(), EventLogDestroy()
 79: @*/
 80: PetscErrorCode ClassRegInfoDestroy(ClassRegInfo *c)
 81: {

 85:   PetscFree(c->name);
 86:   return(0);
 87: }

 91: /*@C
 92:   ClassPerfLogCreate - This creates a ClassPerfLog object.

 94:   Not collective

 96:   Input Parameter:
 97: . classLog - The ClassPerfLog

 99:   Level: beginner

101: .keywords: log, class, create
102: .seealso: ClassPerfLogDestroy(), StageLogCreate()
103: @*/
104: PetscErrorCode ClassPerfLogCreate(ClassPerfLog *classLog)
105: {
106:   ClassPerfLog l;

110:   PetscNew(struct _n_ClassPerfLog, &l);
111:   l->numClasses = 0;
112:   l->maxClasses = 100;
113:   PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
114:   *classLog = l;
115:   return(0);
116: }

120: /*@C
121:   ClassPerfLogDestroy - This destroys a ClassPerfLog object.

123:   Not collective

125:   Input Paramter:
126: . classLog - The ClassPerfLog

128:   Level: beginner

130: .keywords: log, event, destroy
131: .seealso: ClassPerfLogCreate()
132: @*/
133: PetscErrorCode ClassPerfLogDestroy(ClassPerfLog classLog)
134: {

138:   PetscFree(classLog->classInfo);
139:   PetscFree(classLog);
140:   return(0);
141: }

143: /*------------------------------------------------ General Functions -------------------------------------------------*/
146: /*@C
147:   ClassPerfInfoClear - This clears a ClassPerfInfo object.

149:   Not collective

151:   Input Paramter:
152: . classInfo - The ClassPerfInfo

154:   Level: beginner

156: .keywords: log, class, destroy
157: .seealso: ClassPerfLogCreate()
158: @*/
159: PetscErrorCode ClassPerfInfoClear(ClassPerfInfo *classInfo)
160: {
162:   classInfo->id           = -1;
163:   classInfo->creations    = 0;
164:   classInfo->destructions = 0;
165:   classInfo->mem          = 0.0;
166:   classInfo->descMem      = 0.0;
167:   return(0);
168: }

172: /*@C
173:   ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.

175:   Not collective

177:   Input Paramters:
178: + classLog - The ClassPerfLog
179: - size     - The size

181:   Level: intermediate

183: .keywords: log, class, size, ensure
184: .seealso: ClassPerfLogCreate()
185: @*/
186: PetscErrorCode ClassPerfLogEnsureSize(ClassPerfLog classLog, int size)
187: {
188:   ClassPerfInfo *classInfo;

192:   while(size > classLog->maxClasses) {
193:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
194:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
195:     PetscFree(classLog->classInfo);
196:     classLog->classInfo   = classInfo;
197:     classLog->maxClasses *= 2;
198:   }
199:   while(classLog->numClasses < size) {
200:     ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
201:   }
202:   return(0);
203: }

205: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
208: /*@C
209:   ClassRegLogRegister - Registers a class for logging operations in an application code.

211:   Not Collective

213:   Input Parameters:
214: + classLog - The ClassLog
215: - cname    - The name associated with the class

217:   Output Parameter:
218: .  cookie   - The cookie

220:   Level: developer

222: .keywords: log, class, register
223: .seealso: PetscCookieRegister()
224: @*/
225: PetscErrorCode ClassRegLogRegister(ClassRegLog classLog, const char cname[], PetscCookie cookie)
226: {
227:   ClassRegInfo *classInfo;
228:   char         *str;
229:   int           c;

234:   c = classLog->numClasses++;
235:   if (classLog->numClasses > classLog->maxClasses) {
236:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
237:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
238:     PetscFree(classLog->classInfo);
239:     classLog->classInfo   = classInfo;
240:     classLog->maxClasses *= 2;
241:   }
242:   PetscStrallocpy(cname, &str);
243:   classLog->classInfo[c].name     = str;
244:   classLog->classInfo[c].cookie = cookie;
245:   return(0);
246: }

248: /*------------------------------------------------ Query Functions --------------------------------------------------*/
251: /*@C
252:   ClassRegLogGetClass - This function returns the class corresponding to a given cookie.

254:   Not Collective

256:   Input Parameters:
257: + classLog - The ClassRegLog
258: - cookie   - The cookie
259:             
260:   Output Parameter:
261: . oclass   - The class id

263:   Level: developer

265: .keywords: log, class, register
266: .seealso: PetscCookieRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
267: @*/
268: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
269: {
270:   int c;

274:   for(c = 0; c < classLog->numClasses; c++) {
275:     /* Could do bisection here */
276:     if (classLog->classInfo[c].cookie == cookie) break;
277:   }
278:   if (c >= classLog->numClasses) {
279:     SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d\nThis often happens if you compile with PETSC_USE_DYNAMIC_LIBRARIES, but link with static libraries.", cookie);
280:   }
281:   *oclass = c;
282:   return(0);
283: }

285: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
286: /* Default object create logger */
289: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
290: {
291:   StageLog       stageLog;
292:   ClassRegLog    classRegLog;
293:   ClassPerfLog   classPerfLog;
294:   Action        *tmpAction;
295:   Object        *tmpObjects;
296:   PetscLogDouble start, end;
297:   int            oclass = 0;
298:   int            stage;

302:   /* Record stage info */
303:   PetscLogGetStageLog(&stageLog);
304:   StageLogGetCurrent(stageLog, &stage);
305:   StageLogGetClassRegLog(stageLog, &classRegLog);
306:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
307:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
308:   classPerfLog->classInfo[oclass].creations++;
309:   /* Dynamically enlarge logging structures */
310:   if (numActions >= maxActions) {
311:     PetscTime(start);
312:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
313:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
314:     PetscFree(actions);
315:     actions     = tmpAction;
316:     maxActions *= 2;
317:     PetscTime(end);
318:     BaseTime += (end - start);
319:   }

321:   numObjects = obj->id;
322:   /* Record the creation action */
323:   if (logActions) {
324:     PetscTime(actions[numActions].time);
325:     actions[numActions].time  -= BaseTime;
326:     actions[numActions].action = CREATE;
327:     actions[numActions].cookie = obj->cookie;
328:     actions[numActions].id1    = numObjects;
329:     actions[numActions].id2    = -1;
330:     actions[numActions].id3    = -1;
331:     actions[numActions].flops  = _TotalFlops;
332:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
333:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
334:     numActions++;
335:   }
336:   /* Record the object */
337:   if (logObjects) {
338:     objects[numObjects].parent = -1;
339:     objects[numObjects].obj    = obj;
340:     PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
341:     PetscMemzero(objects[numObjects].info, 64 * sizeof(char));

343:   /* Dynamically enlarge logging structures */
344:     if (numObjects >= maxObjects) {
345:       PetscTime(start);
346:       PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
347:       PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
348:       PetscFree(objects);
349:       objects     = tmpObjects;
350:       maxObjects *= 2;
351:       PetscTime(end);
352:       BaseTime += (end - start);
353:     }
354:   }
355:   return(0);
356: }

358: /* Default object destroy logger */
361: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
362: {
363:   StageLog       stageLog;
364:   ClassRegLog    classRegLog;
365:   ClassPerfLog   classPerfLog;
366:   Action        *tmpAction;
367:   PetscLogDouble start, end;
368:   int            oclass = 0;
369:   int            stage;

373:   /* Record stage info */
374:   PetscLogGetStageLog(&stageLog);
375:   StageLogGetCurrent(stageLog, &stage);
376:   if (stage != -1) {
377:     /* That can happen if the log summary is output before some things are destroyed */
378:     StageLogGetClassRegLog(stageLog, &classRegLog);
379:     StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
380:     ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
381:     classPerfLog->classInfo[oclass].destructions++;
382:     classPerfLog->classInfo[oclass].mem += obj->mem;
383:   }
384:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
385:   numObjectsDestroyed++;
386:   /* Dynamically enlarge logging structures */
387:   if (numActions >= maxActions) {
388:     PetscTime(start);
389:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
390:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
391:     PetscFree(actions);
392:     actions     = tmpAction;
393:     maxActions *= 2;
394:     PetscTime(end);
395:     BaseTime += (end - start);
396:   }
397:   /* Record the destruction action */
398:   if (logActions) {
399:     PetscTime(actions[numActions].time);
400:     actions[numActions].time  -= BaseTime;
401:     actions[numActions].action = DESTROY;
402:     actions[numActions].cookie = obj->cookie;
403:     actions[numActions].id1    = obj->id;
404:     actions[numActions].id2    = -1;
405:     actions[numActions].id3    = -1;
406:     actions[numActions].flops  = _TotalFlops;
407:     PetscMallocGetCurrentUsage(&actions[numActions].mem);
408:     PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
409:     numActions++;
410:   }
411:   if (logObjects) {
412:     if (obj->name) {
413:       PetscStrncpy(objects[obj->id].name, obj->name, 64);
414:     }
415:     objects[obj->id].obj      = PETSC_NULL;
416:     objects[obj->id].mem      = obj->mem;
417:   }
418:   return(0);
419: }