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;
 25:   PetscErrorCode   ierr;
 28:   PetscNew(&l);
 30:   l->numClasses = 0;
 31:   l->maxClasses = 100;
 33:   PetscMalloc1(l->maxClasses, &l->classInfo);
 35:   *classLog = l;
 36:   return(0);
 37: }
 39: /*@C
 40:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.
 42:   Not collective
 44:   Input Parameter:
 45: . classLog - The PetscClassRegLog
 47:   Level: developer
 49: .seealso: PetscClassRegLogCreate()
 50: @*/
 51: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
 52: {
 53:   int            c;
 57:   for (c = 0; c < classLog->numClasses; c++) {
 58:     PetscClassRegInfoDestroy(&classLog->classInfo[c]);
 59:   }
 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: .seealso: PetscStageLogDestroy(), EventLogDestroy()
 76: @*/
 77: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
 78: {
 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: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
 97: @*/
 98: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
 99: {
100:   PetscClassPerfLog l;
101:   PetscErrorCode    ierr;
104:   PetscNew(&l);
106:   l->numClasses = 0;
107:   l->maxClasses = 100;
109:   PetscMalloc1(l->maxClasses, &l->classInfo);
111:   *classLog = l;
112:   return(0);
113: }
115: /*@C
116:   PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.
118:   Not collective
120:   Input Parameter:
121: . classLog - The PetscClassPerfLog
123:   Level: developer
125: .seealso: PetscClassPerfLogCreate()
126: @*/
127: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
128: {
132:   PetscFree(classLog->classInfo);
133:   PetscFree(classLog);
134:   return(0);
135: }
137: /*------------------------------------------------ General Functions -------------------------------------------------*/
138: /*@C
139:   PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.
141:   Not collective
143:   Input Parameter:
144: . classInfo - The PetscClassPerfInfo
146:   Level: developer
148: .seealso: PetscClassPerfLogCreate()
149: @*/
150: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
151: {
153:   classInfo->id           = -1;
154:   classInfo->creations    = 0;
155:   classInfo->destructions = 0;
156:   classInfo->mem          = 0.0;
157:   classInfo->descMem      = 0.0;
158:   return(0);
159: }
161: /*@C
162:   PetscClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.
164:   Not collective
166:   Input Parameters:
167: + classLog - The PetscClassPerfLog
168: - size     - The size
170:   Level: developer
172: .seealso: PetscClassPerfLogCreate()
173: @*/
174: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
175: {
176:   PetscClassPerfInfo *classInfo;
177:   PetscErrorCode     ierr;
180:   while (size > classLog->maxClasses) {
181:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
182:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
183:     PetscFree(classLog->classInfo);
185:     classLog->classInfo   = classInfo;
186:     classLog->maxClasses *= 2;
187:   }
188:   while (classLog->numClasses < size) {
189:     PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
190:   }
191:   return(0);
192: }
194: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
195: /*@C
196:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.
198:   Not Collective
200:   Input Parameters:
201: + classLog - The ClassLog
202: - cname    - The name associated with the class
204:   Output Parameter:
205: .  classid   - The classid
207:   Level: developer
209: .seealso: PetscClassIdRegister()
210: @*/
211: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
212: {
213:   PetscClassRegInfo *classInfo;
214:   char              *str;
215:   int               c;
216:   PetscErrorCode    ierr;
220:   c = classLog->numClasses++;
221:   if (classLog->numClasses > classLog->maxClasses) {
222:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
223:     PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
224:     PetscFree(classLog->classInfo);
226:     classLog->classInfo   = classInfo;
227:     classLog->maxClasses *= 2;
228:   }
229:   PetscStrallocpy(cname, &str);
231:   classLog->classInfo[c].name    = str;
232:   classLog->classInfo[c].classid = classid;
233:   return(0);
234: }
236: /*------------------------------------------------ Query Functions --------------------------------------------------*/
237: /*@C
238:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.
240:   Not Collective
242:   Input Parameters:
243: + classLog - The PetscClassRegLog
244: - classid  - The cookie
246:   Output Parameter:
247: . oclass   - The class id
249:   Level: developer
251: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
252: @*/
253: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
254: {
255:   int c;
259:   for (c = 0; c < classLog->numClasses; c++) {
260:     /* Could do bisection here */
261:     if (classLog->classInfo[c].classid == classid) break;
262:   }
263:   if (c >= classLog->numClasses) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid object classid %d\nThis could happen if you compile with PETSC_HAVE_DYNAMIC_LIBRARIES, but link with static libraries.", classid);
264:   *oclass = c;
265:   return(0);
266: }
268: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
269: /* Default object create logger */
270: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
271: {
272:   PetscStageLog     stageLog;
273:   PetscClassRegLog  classRegLog;
274:   PetscClassPerfLog classPerfLog;
275:   Action            *tmpAction;
276:   Object            *tmpObjects;
277:   PetscLogDouble    start, end;
278:   int               oclass = 0;
279:   int               stage;
280:   PetscErrorCode    ierr;
283:   /* Record stage info */
284:   PetscLogGetStageLog(&stageLog);
285:   PetscStageLogGetCurrent(stageLog, &stage);
286:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
287:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
288:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
289:   classPerfLog->classInfo[oclass].creations++;
290:   /* Dynamically enlarge logging structures */
291:   if (petsc_numActions >= petsc_maxActions) {
292:     PetscTime(&start);
293:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
294:     PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
295:     PetscFree(petsc_actions);
297:     petsc_actions     = tmpAction;
298:     petsc_maxActions *= 2;
299:     PetscTime(&end);
300:     petsc_BaseTime += (end - start);
301:   }
303:   petsc_numObjects = obj->id;
304:   /* Record the creation action */
305:   if (petsc_logActions) {
306:     PetscTime(&petsc_actions[petsc_numActions].time);
307:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
308:     petsc_actions[petsc_numActions].action  = CREATE;
309:     petsc_actions[petsc_numActions].classid = obj->classid;
310:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
311:     petsc_actions[petsc_numActions].id2     = -1;
312:     petsc_actions[petsc_numActions].id3     = -1;
313:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;
315:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
316:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
317:     petsc_numActions++;
318:   }
319:   /* Record the object */
320:   if (petsc_logObjects) {
321:     petsc_objects[petsc_numObjects].parent = -1;
322:     petsc_objects[petsc_numObjects].obj    = obj;
324:     PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
325:     PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));
327:     /* Dynamically enlarge logging structures */
328:     if (petsc_numObjects >= petsc_maxObjects) {
329:       PetscTime(&start);
330:       PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
331:       PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
332:       PetscFree(petsc_objects);
334:       petsc_objects     = tmpObjects;
335:       petsc_maxObjects *= 2;
336:       PetscTime(&end);
337:       petsc_BaseTime += (end - start);
338:     }
339:   }
340:   return(0);
341: }
343: /* Default object destroy logger */
344: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
345: {
346:   PetscStageLog     stageLog;
347:   PetscClassRegLog  classRegLog;
348:   PetscClassPerfLog classPerfLog;
349:   Action            *tmpAction;
350:   PetscLogDouble    start, end;
351:   int               oclass = 0;
352:   int               stage;
353:   PetscErrorCode    ierr;
356:   /* Record stage info */
357:   PetscLogGetStageLog(&stageLog);
358:   PetscStageLogGetCurrent(stageLog, &stage);
359:   if (stage != -1) {
360:     /* That can happen if the log summary is output before some things are destroyed */
361:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
362:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
363:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
364:     classPerfLog->classInfo[oclass].destructions++;
365:     classPerfLog->classInfo[oclass].mem += obj->mem;
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) {
398:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
399:     }
400:     petsc_objects[obj->id].obj = NULL;
401:     petsc_objects[obj->id].mem = obj->mem;
402:   }
403:   return(0);
404: }