Actual source code: classLog.c
petsc-3.3-p7 2013-05-11
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> /*I "petscsys.h" I*/
12: /*@C
13: PetscClassRegLogCreate - This creates a PetscClassRegLog object.
15: Not collective
17: Input Parameter:
18: . classLog - The PetscClassRegLog
20: Level: developer
22: .keywords: log, class, create
23: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
24: @*/
25: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
26: {
27: PetscClassRegLog l;
31: PetscNew(struct _n_PetscClassRegLog, &l);
32: l->numClasses = 0;
33: l->maxClasses = 100;
34: PetscMalloc(l->maxClasses * sizeof(PetscClassRegInfo), &l->classInfo);
35: *classLog = l;
36: return(0);
37: }
41: /*@C
42: PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.
44: Not collective
46: Input Paramter:
47: . classLog - The PetscClassRegLog
49: Level: developer
51: .keywords: log, event, destroy
52: .seealso: PetscClassRegLogCreate()
53: @*/
54: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
55: {
56: int c;
60: for(c = 0; c < classLog->numClasses; c++) {
61: PetscClassRegInfoDestroy(&classLog->classInfo[c]);
62: }
63: PetscFree(classLog->classInfo);
64: PetscFree(classLog);
65: return(0);
66: }
70: /*@C
71: PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.
73: Not collective
75: Input Parameter:
76: . c - The PetscClassRegInfo
78: Level: developer
80: .keywords: log, class, destroy
81: .seealso: PetscStageLogDestroy(), EventLogDestroy()
82: @*/
83: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
84: {
88: PetscFree(c->name);
89: return(0);
90: }
94: /*@C
95: ClassPerfLogCreate - This creates a PetscClassPerfLog object.
97: Not collective
99: Input Parameter:
100: . classLog - The PetscClassPerfLog
102: Level: developer
104: .keywords: log, class, create
105: .seealso: ClassPerfLogDestroy(), PetscStageLogCreate()
106: @*/
107: PetscErrorCode ClassPerfLogCreate(PetscClassPerfLog *classLog)
108: {
109: PetscClassPerfLog l;
113: PetscNew(struct _n_PetscClassPerfLog, &l);
114: l->numClasses = 0;
115: l->maxClasses = 100;
116: PetscMalloc(l->maxClasses * sizeof(PetscClassPerfInfo), &l->classInfo);
117: *classLog = l;
118: return(0);
119: }
123: /*@C
124: ClassPerfLogDestroy - This destroys a PetscClassPerfLog object.
126: Not collective
128: Input Paramter:
129: . classLog - The PetscClassPerfLog
131: Level: developer
133: .keywords: log, event, destroy
134: .seealso: ClassPerfLogCreate()
135: @*/
136: PetscErrorCode ClassPerfLogDestroy(PetscClassPerfLog classLog)
137: {
141: PetscFree(classLog->classInfo);
142: PetscFree(classLog);
143: return(0);
144: }
146: /*------------------------------------------------ General Functions -------------------------------------------------*/
149: /*@C
150: ClassPerfInfoClear - This clears a PetscClassPerfInfo object.
152: Not collective
154: Input Paramter:
155: . classInfo - The PetscClassPerfInfo
157: Level: developer
159: .keywords: log, class, destroy
160: .seealso: ClassPerfLogCreate()
161: @*/
162: PetscErrorCode ClassPerfInfoClear(PetscClassPerfInfo *classInfo)
163: {
165: classInfo->id = -1;
166: classInfo->creations = 0;
167: classInfo->destructions = 0;
168: classInfo->mem = 0.0;
169: classInfo->descMem = 0.0;
170: return(0);
171: }
175: /*@C
176: ClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.
178: Not collective
180: Input Paramters:
181: + classLog - The PetscClassPerfLog
182: - size - The size
184: Level: developer
186: .keywords: log, class, size, ensure
187: .seealso: ClassPerfLogCreate()
188: @*/
189: PetscErrorCode ClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
190: {
191: PetscClassPerfInfo *classInfo;
195: while(size > classLog->maxClasses) {
196: PetscMalloc(classLog->maxClasses*2 * sizeof(PetscClassPerfInfo), &classInfo);
197: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassPerfInfo));
198: PetscFree(classLog->classInfo);
199: classLog->classInfo = classInfo;
200: classLog->maxClasses *= 2;
201: }
202: while(classLog->numClasses < size) {
203: ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
204: }
205: return(0);
206: }
208: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
211: /*@C
212: PetscClassRegLogRegister - Registers a class for logging operations in an application code.
214: Not Collective
216: Input Parameters:
217: + classLog - The ClassLog
218: - cname - The name associated with the class
220: Output Parameter:
221: . classid - The classid
223: Level: developer
225: .keywords: log, class, register
226: .seealso: PetscClassIdRegister()
227: @*/
228: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
229: {
230: PetscClassRegInfo *classInfo;
231: char *str;
232: int c;
237: c = classLog->numClasses++;
238: if (classLog->numClasses > classLog->maxClasses) {
239: PetscMalloc(classLog->maxClasses*2 * sizeof(PetscClassRegInfo), &classInfo);
240: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassRegInfo));
241: PetscFree(classLog->classInfo);
242: classLog->classInfo = classInfo;
243: classLog->maxClasses *= 2;
244: }
245: PetscStrallocpy(cname, &str);
246: classLog->classInfo[c].name = str;
247: classLog->classInfo[c].classid = classid;
248: return(0);
249: }
251: /*------------------------------------------------ Query Functions --------------------------------------------------*/
254: /*@C
255: PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.
257: Not Collective
259: Input Parameters:
260: + classLog - The PetscClassRegLog
261: - cookie - The cookie
262:
263: Output Parameter:
264: . oclass - The class id
266: Level: developer
268: .keywords: log, class, register
269: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
270: @*/
271: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
272: {
273: int c;
277: for(c = 0; c < classLog->numClasses; c++) {
278: /* Could do bisection here */
279: if (classLog->classInfo[c].classid == classid) break;
280: }
281: if (c >= classLog->numClasses) {
282: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid object classid %d\nThis often happens if you compile with PETSC_USE_DYNAMIC_LIBRARIES, but link with static libraries.", classid);
283: }
284: *oclass = c;
285: return(0);
286: }
288: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
289: /* Default object create logger */
292: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
293: {
294: PetscStageLog stageLog;
295: PetscClassRegLog classRegLog;
296: PetscClassPerfLog classPerfLog;
297: Action *tmpAction;
298: Object *tmpObjects;
299: PetscLogDouble start, end;
300: int oclass = 0;
301: int stage;
305: /* Record stage info */
306: PetscLogGetStageLog(&stageLog);
307: PetscStageLogGetCurrent(stageLog, &stage);
308: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
309: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
310: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
311: classPerfLog->classInfo[oclass].creations++;
312: /* Dynamically enlarge logging structures */
313: if (petsc_numActions >= petsc_maxActions) {
314: PetscTime(start);
315: PetscMalloc(petsc_maxActions*2 * sizeof(Action), &tmpAction);
316: PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
317: PetscFree(petsc_actions);
318: petsc_actions = tmpAction;
319: petsc_maxActions *= 2;
320: PetscTime(end);
321: petsc_BaseTime += (end - start);
322: }
324: petsc_numObjects = obj->id;
325: /* Record the creation action */
326: if (petsc_logActions) {
327: PetscTime(petsc_actions[petsc_numActions].time);
328: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
329: petsc_actions[petsc_numActions].action = CREATE;
330: petsc_actions[petsc_numActions].classid = obj->classid;
331: petsc_actions[petsc_numActions].id1 = petsc_numObjects;
332: petsc_actions[petsc_numActions].id2 = -1;
333: petsc_actions[petsc_numActions].id3 = -1;
334: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
335: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
336: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
337: petsc_numActions++;
338: }
339: /* Record the object */
340: if (petsc_logObjects) {
341: petsc_objects[petsc_numObjects].parent = -1;
342: petsc_objects[petsc_numObjects].obj = obj;
343: PetscMemzero(petsc_objects[petsc_numObjects].name, 64 * sizeof(char));
344: PetscMemzero(petsc_objects[petsc_numObjects].info, 64 * sizeof(char));
346: /* Dynamically enlarge logging structures */
347: if (petsc_numObjects >= petsc_maxObjects) {
348: PetscTime(start);
349: PetscMalloc(petsc_maxObjects*2 * sizeof(Object), &tmpObjects);
350: PetscMemcpy(tmpObjects, petsc_objects, petsc_maxObjects * sizeof(Object));
351: PetscFree(petsc_objects);
352: petsc_objects = tmpObjects;
353: petsc_maxObjects *= 2;
354: PetscTime(end);
355: petsc_BaseTime += (end - start);
356: }
357: }
358: return(0);
359: }
361: /* Default object destroy logger */
364: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
365: {
366: PetscStageLog stageLog;
367: PetscClassRegLog classRegLog;
368: PetscClassPerfLog classPerfLog;
369: Action *tmpAction;
370: PetscLogDouble start, end;
371: int oclass = 0;
372: int stage;
376: /* Record stage info */
377: PetscLogGetStageLog(&stageLog);
378: PetscStageLogGetCurrent(stageLog, &stage);
379: if (stage != -1) {
380: /* That can happen if the log summary is output before some things are destroyed */
381: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
382: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
383: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
384: classPerfLog->classInfo[oclass].destructions++;
385: classPerfLog->classInfo[oclass].mem += obj->mem;
386: }
387: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
388: petsc_numObjectsDestroyed++;
389: /* Dynamically enlarge logging structures */
390: if (petsc_numActions >= petsc_maxActions) {
391: PetscTime(start);
392: PetscMalloc(petsc_maxActions*2 * sizeof(Action), &tmpAction);
393: PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
394: PetscFree(petsc_actions);
395: petsc_actions = tmpAction;
396: petsc_maxActions *= 2;
397: PetscTime(end);
398: petsc_BaseTime += (end - start);
399: }
400: /* Record the destruction action */
401: if (petsc_logActions) {
402: PetscTime(petsc_actions[petsc_numActions].time);
403: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
404: petsc_actions[petsc_numActions].action = DESTROY;
405: petsc_actions[petsc_numActions].classid = obj->classid;
406: petsc_actions[petsc_numActions].id1 = obj->id;
407: petsc_actions[petsc_numActions].id2 = -1;
408: petsc_actions[petsc_numActions].id3 = -1;
409: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
410: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
411: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
412: petsc_numActions++;
413: }
414: if (petsc_logObjects) {
415: if (obj->name) {
416: PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
417: }
418: petsc_objects[obj->id].obj = PETSC_NULL;
419: petsc_objects[obj->id].mem = obj->mem;
420: }
421: return(0);
422: }