Actual source code: classLog.c
1: #define PETSC_DLL
3: #include ../src/sys/plog/plog.h
5: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
6: /* Note: these functions do not have prototypes in a public directory, so they are considered "internal" and not exported. */
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 _n_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: PetscFree(c->name);
86: return(0);
87: }
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: PetscErrorCode ClassPerfLogCreate(ClassPerfLog *classLog)
105: {
106: ClassPerfLog l;
110: PetscNew(struct _n_ClassPerfLog, &l);
111: l->numClasses = 0;
112: l->maxClasses = 100;
113: PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
114: *classLog = l;
115: return(0);
116: }
120: /*@C
121: ClassPerfLogDestroy - This destroys a ClassPerfLog object.
123: Not collective
125: Input Paramter:
126: . classLog - The ClassPerfLog
128: Level: beginner
130: .keywords: log, event, destroy
131: .seealso: ClassPerfLogCreate()
132: @*/
133: PetscErrorCode ClassPerfLogDestroy(ClassPerfLog classLog)
134: {
138: PetscFree(classLog->classInfo);
139: PetscFree(classLog);
140: return(0);
141: }
143: /*------------------------------------------------ General Functions -------------------------------------------------*/
146: /*@C
147: ClassPerfInfoClear - This clears a ClassPerfInfo object.
149: Not collective
151: Input Paramter:
152: . classInfo - The ClassPerfInfo
154: Level: beginner
156: .keywords: log, class, destroy
157: .seealso: ClassPerfLogCreate()
158: @*/
159: PetscErrorCode ClassPerfInfoClear(ClassPerfInfo *classInfo)
160: {
162: classInfo->id = -1;
163: classInfo->creations = 0;
164: classInfo->destructions = 0;
165: classInfo->mem = 0.0;
166: classInfo->descMem = 0.0;
167: return(0);
168: }
172: /*@C
173: ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.
175: Not collective
177: Input Paramters:
178: + classLog - The ClassPerfLog
179: - size - The size
181: Level: intermediate
183: .keywords: log, class, size, ensure
184: .seealso: ClassPerfLogCreate()
185: @*/
186: PetscErrorCode ClassPerfLogEnsureSize(ClassPerfLog classLog, int size)
187: {
188: ClassPerfInfo *classInfo;
192: while(size > classLog->maxClasses) {
193: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
194: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
195: PetscFree(classLog->classInfo);
196: classLog->classInfo = classInfo;
197: classLog->maxClasses *= 2;
198: }
199: while(classLog->numClasses < size) {
200: ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
201: }
202: return(0);
203: }
205: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
208: /*@C
209: ClassRegLogRegister - Registers a class for logging operations in an application code.
211: Not Collective
213: Input Parameters:
214: + classLog - The ClassLog
215: - cname - The name associated with the class
217: Output Parameter:
218: . cookie - The cookie
220: Level: developer
222: .keywords: log, class, register
223: .seealso: PetscCookieRegister()
224: @*/
225: PetscErrorCode ClassRegLogRegister(ClassRegLog classLog, const char cname[], PetscCookie cookie)
226: {
227: ClassRegInfo *classInfo;
228: char *str;
229: int c;
234: c = classLog->numClasses++;
235: if (classLog->numClasses > classLog->maxClasses) {
236: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
237: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
238: PetscFree(classLog->classInfo);
239: classLog->classInfo = classInfo;
240: classLog->maxClasses *= 2;
241: }
242: PetscStrallocpy(cname, &str);
243: classLog->classInfo[c].name = str;
244: classLog->classInfo[c].cookie = cookie;
245: return(0);
246: }
248: /*------------------------------------------------ Query Functions --------------------------------------------------*/
251: /*@C
252: ClassRegLogGetClass - This function returns the class corresponding to a given cookie.
254: Not Collective
256: Input Parameters:
257: + classLog - The ClassRegLog
258: - cookie - The cookie
259:
260: Output Parameter:
261: . oclass - The class id
263: Level: developer
265: .keywords: log, class, register
266: .seealso: PetscCookieRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
267: @*/
268: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
269: {
270: int c;
274: for(c = 0; c < classLog->numClasses; c++) {
275: /* Could do bisection here */
276: if (classLog->classInfo[c].cookie == cookie) break;
277: }
278: if (c >= classLog->numClasses) {
279: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d\nThis often happens if you compile with PETSC_USE_DYNAMIC_LIBRARIES, but link with static libraries.", cookie);
280: }
281: *oclass = c;
282: return(0);
283: }
285: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
286: /* Default object create logger */
289: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
290: {
291: StageLog stageLog;
292: ClassRegLog classRegLog;
293: ClassPerfLog classPerfLog;
294: Action *tmpAction;
295: Object *tmpObjects;
296: PetscLogDouble start, end;
297: int oclass = 0;
298: int stage;
302: /* Record stage info */
303: PetscLogGetStageLog(&stageLog);
304: StageLogGetCurrent(stageLog, &stage);
305: StageLogGetClassRegLog(stageLog, &classRegLog);
306: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
307: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
308: classPerfLog->classInfo[oclass].creations++;
309: /* Dynamically enlarge logging structures */
310: if (numActions >= maxActions) {
311: PetscTime(start);
312: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
313: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
314: PetscFree(actions);
315: actions = tmpAction;
316: maxActions *= 2;
317: PetscTime(end);
318: BaseTime += (end - start);
319: }
321: numObjects = obj->id;
322: /* Record the creation action */
323: if (logActions) {
324: PetscTime(actions[numActions].time);
325: actions[numActions].time -= BaseTime;
326: actions[numActions].action = CREATE;
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: PetscMallocGetCurrentUsage(&actions[numActions].mem);
333: PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
334: numActions++;
335: }
336: /* Record the object */
337: if (logObjects) {
338: objects[numObjects].parent = -1;
339: objects[numObjects].obj = obj;
340: PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
341: PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
343: /* Dynamically enlarge logging structures */
344: if (numObjects >= maxObjects) {
345: PetscTime(start);
346: PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
347: PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
348: PetscFree(objects);
349: objects = tmpObjects;
350: maxObjects *= 2;
351: PetscTime(end);
352: BaseTime += (end - start);
353: }
354: }
355: return(0);
356: }
358: /* Default object destroy logger */
361: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
362: {
363: StageLog stageLog;
364: ClassRegLog classRegLog;
365: ClassPerfLog classPerfLog;
366: Action *tmpAction;
367: PetscLogDouble start, end;
368: int oclass = 0;
369: int stage;
373: /* Record stage info */
374: PetscLogGetStageLog(&stageLog);
375: StageLogGetCurrent(stageLog, &stage);
376: if (stage != -1) {
377: /* That can happen if the log summary is output before some things are destroyed */
378: StageLogGetClassRegLog(stageLog, &classRegLog);
379: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
380: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
381: classPerfLog->classInfo[oclass].destructions++;
382: classPerfLog->classInfo[oclass].mem += obj->mem;
383: }
384: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
385: numObjectsDestroyed++;
386: /* Dynamically enlarge logging structures */
387: if (numActions >= maxActions) {
388: PetscTime(start);
389: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
390: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
391: PetscFree(actions);
392: actions = tmpAction;
393: maxActions *= 2;
394: PetscTime(end);
395: BaseTime += (end - start);
396: }
397: /* Record the destruction action */
398: if (logActions) {
399: PetscTime(actions[numActions].time);
400: actions[numActions].time -= BaseTime;
401: actions[numActions].action = DESTROY;
402: actions[numActions].cookie = obj->cookie;
403: actions[numActions].id1 = obj->id;
404: actions[numActions].id2 = -1;
405: actions[numActions].id3 = -1;
406: actions[numActions].flops = _TotalFlops;
407: PetscMallocGetCurrentUsage(&actions[numActions].mem);
408: PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
409: numActions++;
410: }
411: if (logObjects) {
412: if (obj->name) {
413: PetscStrncpy(objects[obj->id].name, obj->name, 64);
414: }
415: objects[obj->id].obj = PETSC_NULL;
416: objects[obj->id].mem = obj->mem;
417: }
418: return(0);
419: }