Actual source code: classLog.c

  1: /* $Id: classLog.c,v 1.3 2001/01/27 21:42:08 knepley Exp $ */

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

  7: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
  8: #undef __FUNCT__  
 10: /*@C
 11:   ClassRegLogCreate - This creates a ClassRegLog object.

 13:   Not collective

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

 18:   Level: beginner

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

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

 36: #undef __FUNCT__
 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: int ClassRegLogDestroy(ClassRegLog classLog) {
 52:   int c;

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

 64: #undef __FUNCT__  
 66: /*@C
 67:   ClassRegInfoDestroy - This destroys a ClassRegInfo object.

 69:   Not collective

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

 74:   Level: beginner

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

 83:   if (c->name != PETSC_NULL) {
 84:     PetscFree(c->name);
 85:   }
 86:   return(0);
 87: }

 89: #undef __FUNCT__  
 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: int ClassPerfLogCreate(ClassPerfLog *classLog) {
105:   ClassPerfLog l;
106:   int          ierr;

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

117: #undef __FUNCT__
119: /*@C
120:   ClassPerfLogDestroy - This destroys a ClassPerfLog object.

122:   Not collective

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

127:   Level: beginner

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

136:   PetscFree(classLog->classInfo);
137:   PetscFree(classLog);
138:   return(0);
139: }

141: /*------------------------------------------------ General Functions -------------------------------------------------*/
142: #undef __FUNCT__  
144: /*@C
145:   ClassPerfInfoClear - This clears a ClassPerfInfo object.

147:   Not collective

149:   Input Paramter:
150: . classInfo - The ClassPerfInfo

152:   Level: beginner

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

167: #undef __FUNCT__  
169: /*@C
170:   ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.

172:   Not collective

174:   Input Paramters:
175: + classLog - The ClassPerfLog
176: - size     - The size

178:   Level: intermediate

180: .keywords: log, class, size, ensure
181: .seealso: ClassPerfLogCreate()
182: @*/
183: int ClassPerfLogEnsureSize(ClassPerfLog classLog, int size) {
184:   ClassPerfInfo *classInfo;
185:   int            ierr;

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

201: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
202: #undef __FUNCT__  
204: /*@C
205:   ClassRegLogRegister - Registers a class for logging operations in an application code.
206:   A prefered cookie is given on input, and the actual cookie is returned on output. If
207:   the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
208:   assigned, and unique in this ClassLog.

210:   Not Collective

212:   Input Parameters:
213: + classLog - The ClassLog
214: . cname    - The name associated with the class
215: - cookie   - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output

217:   Level: developer

219: .keywords: log, class, register
220: .seealso: PetscLogClassRegister()
221: @*/
222: int ClassRegLogRegister(ClassRegLog classLog, const char cname[], int *cookie) {
223:   ClassRegInfo *classInfo;
224:   char         *str;
225:   int           c;
226:   int           ierr;

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

253: /*------------------------------------------------ Query Functions --------------------------------------------------*/
254: #undef __FUNCT__  
256: /*@C
257:   ClassRegLogGetClass - This function returns the class corresponding to a given cookie.

259:   Not Collective

261:   Input Parameters:
262: + classLog - The ClassRegLog
263: - cookie   - The cookie
264:             
265:   Output Parameter:
266: . oclass   - The class id

268:   Level: developer

270: .keywords: log, class, register
271: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
272: @*/
273: int ClassRegLogGetClass(ClassRegLog classLog, int cookie, int *oclass) {
274:   int c;

278:   for(c = 0; c < classLog->numClasses; c++) {
279:     /* Could do bisection here */
280:     if (classLog->classInfo[c].cookie == cookie) break;
281:   }
282:   if (c >= classLog->numClasses) SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d", cookie);
283:   *oclass = c;
284:   return(0);
285: }

287: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
288: /* Default object create logger */
289: #undef __FUNCT__  
291: int PetscLogObjCreateDefault(PetscObject obj) {
292:   StageLog       stageLog;
293:   ClassRegLog    classRegLog;
294:   ClassPerfLog   classPerfLog;
295:   Action        *tmpAction;
296:   Object        *tmpObjects;
297:   PetscLogDouble start, end;
298:   int            oclass;
299:   int            stage;
300:   int            ierr;

303:   /* Record stage info */
304:   PetscLogGetStageLog(&stageLog);
305:   StageLogGetCurrent(stageLog, &stage);
306:   StageLogGetClassRegLog(stageLog, &classRegLog);
307:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
308:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
309:   classPerfLog->classInfo[oclass].creations++;
310:   /* Dynamically enlarge logging structures */
311:   if (numActions >= maxActions) {
312:     PetscTime(start);
313:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
314:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
315:     PetscFree(actions);
316:     actions     = tmpAction;
317:     maxActions *= 2;
318:     PetscTime(end);
319:     BaseTime += (end - start);
320:   }
321:   /* Record the creation action */
322:   if (logActions == PETSC_TRUE) {
323:     PetscTime(actions[numActions].time);
324:     actions[numActions].time  -= BaseTime;
325:     actions[numActions].action = CREATE;
326:     actions[numActions].event  = obj->type;
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:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
333:     numActions++;
334:   }
335:   /* Record the object */
336:   if (logObjects == PETSC_TRUE) {
337:     objects[numObjects].parent = -1;
338:     objects[numObjects].obj    = obj;
339:     PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
340:     PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
341:     numObjects++;
342:   }
343:   obj->id = numObjects;
344:   /* Dynamically enlarge logging structures */
345:   if (numObjects >= maxObjects) {
346:     PetscTime(start);
347:     PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
348:     PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
349:     PetscFree(objects);
350:     objects     = tmpObjects;
351:     maxObjects *= 2;
352:     PetscTime(end);
353:     BaseTime += (end - start);
354:   }
355:   return(0);
356: }

358: /* Default object destroy logger */
359: #undef __FUNCT__  
361: int PetscLogObjDestroyDefault(PetscObject obj) {
362:   StageLog       stageLog;
363:   ClassRegLog    classRegLog;
364:   ClassPerfLog   classPerfLog;
365:   Action        *tmpAction;
366:   PetscLogDouble start, end;
367:   int            oclass, pclass;
368:   PetscObject    parent;
369:   PetscTruth     exists;
370:   int            stage;
371:   int            ierr;

374:   /* Record stage info */
375:   PetscLogGetStageLog(&stageLog);
376:   StageLogGetCurrent(stageLog, &stage);
377:   StageLogGetClassRegLog(stageLog, &classRegLog);
378:   StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
379:   ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
380:   classPerfLog->classInfo[oclass].destructions++;
381:   classPerfLog->classInfo[oclass].mem += obj->mem;
382:   /* Credit all ancestors with your memory */
383:   parent = obj->parent;
384:   while (parent != PETSC_NULL) {
385:     PetscObjectExists(parent, &exists);
386:     if (exists == PETSC_FALSE) break;
387:     ClassRegLogGetClass(classRegLog, parent->cookie, &pclass);
388:     classPerfLog->classInfo[pclass].descMem += obj->mem;
389:     parent = parent->parent;
390:   }
391:   numObjectsDestroyed++;
392:   /* Dynamically enlarge logging structures */
393:   if (numActions >= maxActions) {
394:     PetscTime(start);
395:     PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
396:     PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
397:     PetscFree(actions);
398:     actions     = tmpAction;
399:     maxActions *= 2;
400:     PetscTime(end);
401:     BaseTime += (end - start);
402:   }
403:   /* Record the destruction action */
404:   if (logActions == PETSC_TRUE) {
405:     PetscTime(actions[numActions].time);
406:     actions[numActions].time  -= BaseTime;
407:     actions[numActions].action = DESTROY;
408:     actions[numActions].event  = obj->type;
409:     actions[numActions].cookie = obj->cookie;
410:     actions[numActions].id1    = obj->id;
411:     actions[numActions].id2    = -1;
412:     actions[numActions].id3    = -1;
413:     actions[numActions].flops  = _TotalFlops;
414:     PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
415:     numActions++;
416:   }
417:   if (logObjects == PETSC_TRUE) {
418:     if (obj->parent != PETSC_NULL) {
419:       PetscObjectExists(obj->parent, &exists);
420:       if (exists == PETSC_TRUE) {
421:         objects[obj->id].parent = obj->parent->id;
422:       } else {
423:         objects[obj->id].parent = -1;
424:       }
425:     } else {
426:       objects[obj->id].parent   = -1;
427:     }
428:     if (obj->name != PETSC_NULL) {
429:       PetscStrncpy(objects[obj->id].name, obj->name, 64);
430:     }
431:     objects[obj->id].obj      = PETSC_NULL;
432:     objects[obj->id].mem      = obj->mem;
433:   }
434:   return(0);
435: }