Actual source code: classlog.c

petsc-3.8.3 2017-12-09
Report Typos and Errors

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

 29:   PetscNew(&l);

 31:   l->numClasses = 0;
 32:   l->maxClasses = 100;

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

 36:   *classLog = l;
 37:   return(0);
 38: }

 40: /*@C
 41:   PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.

 43:   Not collective

 45:   Input Paramter:
 46: . classLog - The PetscClassRegLog

 48:   Level: developer

 50: .keywords: log, event, destroy
 51: .seealso: PetscClassRegLogCreate()
 52: @*/
 53: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
 54: {
 55:   int            c;

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

 67: /*@C
 68:   PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.

 70:   Not collective

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

 75:   Level: developer

 77: .keywords: log, class, destroy
 78: .seealso: PetscStageLogDestroy(), EventLogDestroy()
 79: @*/
 80: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
 81: {

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

 89: /*@C
 90:   PetscClassPerfLogCreate - This creates a PetscClassPerfLog object.

 92:   Not collective

 94:   Input Parameter:
 95: . classLog - The PetscClassPerfLog

 97:   Level: developer

 99: .keywords: log, class, create
100: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
101: @*/
102: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
103: {
104:   PetscClassPerfLog l;
105:   PetscErrorCode    ierr;

108:   PetscNew(&l);

110:   l->numClasses = 0;
111:   l->maxClasses = 100;

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

115:   *classLog = l;
116:   return(0);
117: }

119: /*@C
120:   PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.

122:   Not collective

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

127:   Level: developer

129: .keywords: log, event, destroy
130: .seealso: PetscClassPerfLogCreate()
131: @*/
132: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
133: {

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

142: /*------------------------------------------------ General Functions -------------------------------------------------*/
143: /*@C
144:   PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.

146:   Not collective

148:   Input Paramter:
149: . classInfo - The PetscClassPerfInfo

151:   Level: developer

153: .keywords: log, class, destroy
154: .seealso: PetscClassPerfLogCreate()
155: @*/
156: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
157: {
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: /*@C
168:   PetscClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.

170:   Not collective

172:   Input Paramters:
173: + classLog - The PetscClassPerfLog
174: - size     - The size

176:   Level: developer

178: .keywords: log, class, size, ensure
179: .seealso: PetscClassPerfLogCreate()
180: @*/
181: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
182: {
183:   PetscClassPerfInfo *classInfo;
184:   PetscErrorCode     ierr;

187:   while (size > classLog->maxClasses) {
188:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
189:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassPerfInfo));
190:     PetscFree(classLog->classInfo);

192:     classLog->classInfo   = classInfo;
193:     classLog->maxClasses *= 2;
194:   }
195:   while (classLog->numClasses < size) {
196:     PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
197:   }
198:   return(0);
199: }

201: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
202: /*@C
203:   PetscClassRegLogRegister - Registers a class for logging operations in an application code.

205:   Not Collective

207:   Input Parameters:
208: + classLog - The ClassLog
209: - cname    - The name associated with the class

211:   Output Parameter:
212: .  classid   - The classid

214:   Level: developer

216: .keywords: log, class, register
217: .seealso: PetscClassIdRegister()
218: @*/
219: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
220: {
221:   PetscClassRegInfo *classInfo;
222:   char              *str;
223:   int               c;
224:   PetscErrorCode    ierr;

228:   c = classLog->numClasses++;
229:   if (classLog->numClasses > classLog->maxClasses) {
230:     PetscMalloc1(classLog->maxClasses*2, &classInfo);
231:     PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassRegInfo));
232:     PetscFree(classLog->classInfo);

234:     classLog->classInfo   = classInfo;
235:     classLog->maxClasses *= 2;
236:   }
237:   PetscStrallocpy(cname, &str);

239:   classLog->classInfo[c].name    = str;
240:   classLog->classInfo[c].classid = classid;
241:   return(0);
242: }

244: /*------------------------------------------------ Query Functions --------------------------------------------------*/
245: /*@C
246:   PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.

248:   Not Collective

250:   Input Parameters:
251: + classLog - The PetscClassRegLog
252: - classid  - The cookie

254:   Output Parameter:
255: . oclass   - The class id

257:   Level: developer

259: .keywords: log, class, register
260: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
261: @*/
262: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
263: {
264:   int c;

268:   for (c = 0; c < classLog->numClasses; c++) {
269:     /* Could do bisection here */
270:     if (classLog->classInfo[c].classid == classid) break;
271:   }
272:   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);
273:   *oclass = c;
274:   return(0);
275: }

277: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
278: /* Default object create logger */
279: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
280: {
281:   PetscStageLog     stageLog;
282:   PetscClassRegLog  classRegLog;
283:   PetscClassPerfLog classPerfLog;
284:   Action            *tmpAction;
285:   Object            *tmpObjects;
286:   PetscLogDouble    start, end;
287:   int               oclass = 0;
288:   int               stage;
289:   PetscErrorCode    ierr;

292:   /* Record stage info */
293:   PetscLogGetStageLog(&stageLog);
294:   PetscStageLogGetCurrent(stageLog, &stage);
295:   PetscStageLogGetClassRegLog(stageLog, &classRegLog);
296:   PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
297:   PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
298:   classPerfLog->classInfo[oclass].creations++;
299:   /* Dynamically enlarge logging structures */
300:   if (petsc_numActions >= petsc_maxActions) {
301:     PetscTime(&start);
302:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
303:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
304:     PetscFree(petsc_actions);

306:     petsc_actions     = tmpAction;
307:     petsc_maxActions *= 2;
308:     PetscTime(&end);
309:     petsc_BaseTime += (end - start);
310:   }

312:   petsc_numObjects = obj->id;
313:   /* Record the creation action */
314:   if (petsc_logActions) {
315:     PetscTime(&petsc_actions[petsc_numActions].time);
316:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
317:     petsc_actions[petsc_numActions].action  = CREATE;
318:     petsc_actions[petsc_numActions].classid = obj->classid;
319:     petsc_actions[petsc_numActions].id1     = petsc_numObjects;
320:     petsc_actions[petsc_numActions].id2     = -1;
321:     petsc_actions[petsc_numActions].id3     = -1;
322:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

324:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
325:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
326:     petsc_numActions++;
327:   }
328:   /* Record the object */
329:   if (petsc_logObjects) {
330:     petsc_objects[petsc_numObjects].parent = -1;
331:     petsc_objects[petsc_numObjects].obj    = obj;

333:     PetscMemzero(petsc_objects[petsc_numObjects].name, 64 * sizeof(char));
334:     PetscMemzero(petsc_objects[petsc_numObjects].info, 64 * sizeof(char));

336:     /* Dynamically enlarge logging structures */
337:     if (petsc_numObjects >= petsc_maxObjects) {
338:       PetscTime(&start);
339:       PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
340:       PetscMemcpy(tmpObjects, petsc_objects, petsc_maxObjects * sizeof(Object));
341:       PetscFree(petsc_objects);

343:       petsc_objects     = tmpObjects;
344:       petsc_maxObjects *= 2;
345:       PetscTime(&end);
346:       petsc_BaseTime += (end - start);
347:     }
348:   }
349:   return(0);
350: }

352: /* Default object destroy logger */
353: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
354: {
355:   PetscStageLog     stageLog;
356:   PetscClassRegLog  classRegLog;
357:   PetscClassPerfLog classPerfLog;
358:   Action            *tmpAction;
359:   PetscLogDouble    start, end;
360:   int               oclass = 0;
361:   int               stage;
362:   PetscErrorCode    ierr;

365:   /* Record stage info */
366:   PetscLogGetStageLog(&stageLog);
367:   PetscStageLogGetCurrent(stageLog, &stage);
368:   if (stage != -1) {
369:     /* That can happen if the log summary is output before some things are destroyed */
370:     PetscStageLogGetClassRegLog(stageLog, &classRegLog);
371:     PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
372:     PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
373:     classPerfLog->classInfo[oclass].destructions++;
374:     classPerfLog->classInfo[oclass].mem += obj->mem;
375:   }
376:   /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
377:   petsc_numObjectsDestroyed++;
378:   /* Dynamically enlarge logging structures */
379:   if (petsc_numActions >= petsc_maxActions) {
380:     PetscTime(&start);
381:     PetscMalloc1(petsc_maxActions*2, &tmpAction);
382:     PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
383:     PetscFree(petsc_actions);

385:     petsc_actions     = tmpAction;
386:     petsc_maxActions *= 2;
387:     PetscTime(&end);
388:     petsc_BaseTime += (end - start);
389:   }
390:   /* Record the destruction action */
391:   if (petsc_logActions) {
392:     PetscTime(&petsc_actions[petsc_numActions].time);
393:     petsc_actions[petsc_numActions].time   -= petsc_BaseTime;
394:     petsc_actions[petsc_numActions].action  = DESTROY;
395:     petsc_actions[petsc_numActions].classid = obj->classid;
396:     petsc_actions[petsc_numActions].id1     = obj->id;
397:     petsc_actions[petsc_numActions].id2     = -1;
398:     petsc_actions[petsc_numActions].id3     = -1;
399:     petsc_actions[petsc_numActions].flops   = petsc_TotalFlops;

401:     PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
402:     PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
403:     petsc_numActions++;
404:   }
405:   if (petsc_logObjects) {
406:     if (obj->name) {
407:       PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
408:     }
409:     petsc_objects[obj->id].obj = NULL;
410:     petsc_objects[obj->id].mem = obj->mem;
411:   }
412:   return(0);
413: }