Actual source code: classLog.c

 2:  #include petsc.h
 3:  #include src/sys/src/plog/ptime.h
 4:  #include plog.h

  6: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
  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 _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:   if (c->name) {
 86:     PetscFree(c->name);
 87:   }
 88:   return(0);
 89: }

 93: /*@C
 94:   ClassPerfLogCreate - This creates a ClassPerfLog object.

 96:   Not collective

 98:   Input Parameter:
 99: . classLog - The ClassPerfLog

101:   Level: beginner

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

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

122: /*@C
123:   ClassPerfLogDestroy - This destroys a ClassPerfLog object.

125:   Not collective

127:   Input Paramter:
128: . classLog - The ClassPerfLog

130:   Level: beginner

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

140:   PetscFree(classLog->classInfo);
141:   PetscFree(classLog);
142:   return(0);
143: }

145: /*------------------------------------------------ General Functions -------------------------------------------------*/
148: /*@C
149:   ClassPerfInfoClear - This clears a ClassPerfInfo object.

151:   Not collective

153:   Input Paramter:
154: . classInfo - The ClassPerfInfo

156:   Level: beginner

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

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

177:   Not collective

179:   Input Paramters:
180: + classLog - The ClassPerfLog
181: - size     - The size

183:   Level: intermediate

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

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

207: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
210: /*@C
211:   ClassRegLogRegister - Registers a class for logging operations in an application code.
212:   A prefered cookie is given on input, and the actual cookie is returned on output. If
213:   the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
214:   assigned, and unique in this ClassLog.

216:   Not Collective

218:   Input Parameters:
219: + classLog - The ClassLog
220: . cname    - The name associated with the class
221: - cookie   - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output

223:   Level: developer

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

238:   c = classLog->numClasses++;
239:   if (classLog->numClasses > classLog->maxClasses) {
240:     PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
241:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
242:     PetscFree(classLog->classInfo);
243:     classLog->classInfo   = classInfo;
244:     classLog->maxClasses *= 2;
245:   }
246:   PetscStrallocpy(cname, &str);
247:   classLog->classInfo[c].name     = str;
248:   if (*cookie == PETSC_DECIDE) {
249:     classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
250:   } else if (*cookie >= 0) {
251:     classLog->classInfo[c].cookie = *cookie;
252:     /* Need to check here for montonicity and insert if necessary */
253:   } else {
254:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", (int)*cookie);
255:   }
256:   *cookie = classLog->classInfo[c].cookie;
257:   return(0);
258: }

260: /*------------------------------------------------ Query Functions --------------------------------------------------*/
263: /*@C
264:   ClassRegLogGetClass - This function returns the class corresponding to a given cookie.

266:   Not Collective

268:   Input Parameters:
269: + classLog - The ClassRegLog
270: - cookie   - The cookie
271:             
272:   Output Parameter:
273: . oclass   - The class id

275:   Level: developer

277: .keywords: log, class, register
278: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
279: @*/
280: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
281: {
282:   int c;

286:   for(c = 0; c < classLog->numClasses; c++) {
287:     /* Could do bisection here */
288:     if (classLog->classInfo[c].cookie == cookie) break;
289:   }
290:   if (c >= classLog->numClasses) SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d", cookie);
291:   *oclass = c;
292:   return(0);
293: }

295: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
296: /* Default object create logger */
299: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
300: {
301:   StageLog       stageLog;
302:   ClassRegLog    classRegLog;
303:   ClassPerfLog   classPerfLog;
304:   Action        *tmpAction;
305:   Object        *tmpObjects;
306:   PetscLogDouble start, end;
307:   int            oclass;
308:   int            stage;

312:   /* Record stage info */
313:   PetscLogGetStageLog(&stageLog);
314:   StageLogGetCurrent(stageLog, &stage);
315:   StageLogGetClassRegLog(stageLog, &classRegLog);
316:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
317:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
318:   classPerfLog->classInfo[oclass].creations++;
319:   /* Dynamically enlarge logging structures */
320:   if (numActions >= maxActions) {
321:     PetscTime(start);
322:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
323:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
324:     PetscFree(actions);
325:     actions     = tmpAction;
326:     maxActions *= 2;
327:     PetscTime(end);
328:     BaseTime += (end - start);
329:   }
330:   /* Record the creation action */
331:   if (logActions) {
332:     PetscTime(actions[numActions].time);
333:     actions[numActions].time  -= BaseTime;
334:     actions[numActions].action = CREATE;
335:     actions[numActions].cookie = obj->cookie;
336:     actions[numActions].id1    = numObjects;
337:     actions[numActions].id2    = -1;
338:     actions[numActions].id3    = -1;
339:     actions[numActions].flops  = _TotalFlops;
340:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
341:     numActions++;
342:   }
343:   /* Record the object */
344:   if (logObjects) {
345:     objects[numObjects].parent = -1;
346:     objects[numObjects].obj    = obj;
347:     PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
348:     PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
349:     numObjects++;
350:   }
351:   obj->id = numObjects;
352:   /* Dynamically enlarge logging structures */
353:   if (numObjects >= maxObjects) {
354:     PetscTime(start);
355:     PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
356:     PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
357:     PetscFree(objects);
358:     objects     = tmpObjects;
359:     maxObjects *= 2;
360:     PetscTime(end);
361:     BaseTime += (end - start);
362:   }
363:   return(0);
364: }

366: /* Default object destroy logger */
369: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
370: {
371:   StageLog       stageLog;
372:   ClassRegLog    classRegLog;
373:   ClassPerfLog   classPerfLog;
374:   Action        *tmpAction;
375:   PetscLogDouble start, end;
376:   int            oclass;
377:   int            stage;

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