Actual source code: classLog.c
1: #define PETSC_DLL
3: #include petsc.h
4: #include petsctime.h
5: #include src/sys/plog/plog.h
7: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
8: /* Note: these functions do not have prototypes in a public directory, so they are considered "internal" and not exported. */
11: /*@C
12: ClassRegLogCreate - This creates a ClassRegLog object.
14: Not collective
16: Input Parameter:
17: . classLog - The ClassRegLog
19: Level: beginner
21: .keywords: log, class, create
22: .seealso: ClassRegLogDestroy(), StageLogCreate()
23: @*/
24: PetscErrorCode ClassRegLogCreate(ClassRegLog *classLog)
25: {
26: ClassRegLog l;
30: PetscNew(struct _n_ClassRegLog, &l);
31: l->numClasses = 0;
32: l->maxClasses = 100;
33: PetscMalloc(l->maxClasses * sizeof(ClassRegInfo), &l->classInfo);
34: *classLog = l;
35: return(0);
36: }
40: /*@C
41: ClassRegLogDestroy - This destroys a ClassRegLog object.
43: Not collective
45: Input Paramter:
46: . classLog - The ClassRegLog
48: Level: beginner
50: .keywords: log, event, destroy
51: .seealso: ClassRegLogCreate()
52: @*/
53: PetscErrorCode ClassRegLogDestroy(ClassRegLog classLog)\
54: {
55: int c;
59: for(c = 0; c < classLog->numClasses; c++) {
60: ClassRegInfoDestroy(&classLog->classInfo[c]);
61: }
62: PetscFree(classLog->classInfo);
63: PetscFree(classLog);
64: return(0);
65: }
69: /*@C
70: ClassRegInfoDestroy - This destroys a ClassRegInfo object.
72: Not collective
74: Input Parameter:
75: . c - The ClassRegInfo
77: Level: beginner
79: .keywords: log, class, destroy
80: .seealso: StageLogDestroy(), EventLogDestroy()
81: @*/
82: PetscErrorCode ClassRegInfoDestroy(ClassRegInfo *c)
83: {
87: PetscFree(c->name);
88: return(0);
89: }
93: /*@C
94: ClassPerfLogCreate - This creates a ClassPerfLog object.
96: Not collective
98: Input Parameter:
99: . classLog - The ClassPerfLog
101: Level: beginner
103: .keywords: log, class, create
104: .seealso: ClassPerfLogDestroy(), StageLogCreate()
105: @*/
106: PetscErrorCode ClassPerfLogCreate(ClassPerfLog *classLog)
107: {
108: ClassPerfLog l;
112: PetscNew(struct _n_ClassPerfLog, &l);
113: l->numClasses = 0;
114: l->maxClasses = 100;
115: PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
116: *classLog = l;
117: return(0);
118: }
122: /*@C
123: ClassPerfLogDestroy - This destroys a ClassPerfLog object.
125: Not collective
127: Input Paramter:
128: . classLog - The ClassPerfLog
130: Level: beginner
132: .keywords: log, event, destroy
133: .seealso: ClassPerfLogCreate()
134: @*/
135: PetscErrorCode ClassPerfLogDestroy(ClassPerfLog classLog)
136: {
140: PetscFree(classLog->classInfo);
141: PetscFree(classLog);
142: return(0);
143: }
145: /*------------------------------------------------ General Functions -------------------------------------------------*/
148: /*@C
149: ClassPerfInfoClear - This clears a ClassPerfInfo object.
151: Not collective
153: Input Paramter:
154: . classInfo - The ClassPerfInfo
156: Level: beginner
158: .keywords: log, class, destroy
159: .seealso: ClassPerfLogCreate()
160: @*/
161: PetscErrorCode ClassPerfInfoClear(ClassPerfInfo *classInfo)
162: {
164: classInfo->id = -1;
165: classInfo->creations = 0;
166: classInfo->destructions = 0;
167: classInfo->mem = 0.0;
168: classInfo->descMem = 0.0;
169: return(0);
170: }
174: /*@C
175: ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.
177: Not collective
179: Input Paramters:
180: + classLog - The ClassPerfLog
181: - size - The size
183: Level: intermediate
185: .keywords: log, class, size, ensure
186: .seealso: ClassPerfLogCreate()
187: @*/
188: PetscErrorCode ClassPerfLogEnsureSize(ClassPerfLog classLog, int size)
189: {
190: ClassPerfInfo *classInfo;
194: while(size > classLog->maxClasses) {
195: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
196: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
197: PetscFree(classLog->classInfo);
198: classLog->classInfo = classInfo;
199: classLog->maxClasses *= 2;
200: }
201: while(classLog->numClasses < size) {
202: ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
203: }
204: return(0);
205: }
207: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
210: /*@C
211: ClassRegLogRegister - Registers a class for logging operations in an application code.
213: Not Collective
215: Input Parameters:
216: + classLog - The ClassLog
217: - cname - The name associated with the class
219: Output Parameter:
220: . cookie - The cookie
222: Level: developer
224: .keywords: log, class, register
225: .seealso: PetscLogClassRegister()
226: @*/
227: PetscErrorCode ClassRegLogRegister(ClassRegLog classLog, const char cname[], PetscCookie *cookie)
228: {
229: ClassRegInfo *classInfo;
230: char *str;
231: int c;
237: c = classLog->numClasses++;
238: if (classLog->numClasses > classLog->maxClasses) {
239: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
240: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
241: PetscFree(classLog->classInfo);
242: classLog->classInfo = classInfo;
243: classLog->maxClasses *= 2;
244: }
245: PetscStrallocpy(cname, &str);
246: classLog->classInfo[c].name = str;
247: PetscCookieRegister(cookie);
248: classLog->classInfo[c].cookie = *cookie;
249: return(0);
250: }
252: /*------------------------------------------------ Query Functions --------------------------------------------------*/
255: /*@C
256: ClassRegLogGetClass - This function returns the class corresponding to a given cookie.
258: Not Collective
260: Input Parameters:
261: + classLog - The ClassRegLog
262: - cookie - The cookie
263:
264: Output Parameter:
265: . oclass - The class id
267: Level: developer
269: .keywords: log, class, register
270: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
271: @*/
272: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
273: {
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) {
283: 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);
284: }
285: *oclass = c;
286: return(0);
287: }
289: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
290: /* Default object create logger */
293: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
294: {
295: StageLog stageLog;
296: ClassRegLog classRegLog;
297: ClassPerfLog classPerfLog;
298: Action *tmpAction;
299: Object *tmpObjects;
300: PetscLogDouble start, end;
301: int oclass;
302: int stage;
306: /* Record stage info */
307: PetscLogGetStageLog(&stageLog);
308: StageLogGetCurrent(stageLog, &stage);
309: StageLogGetClassRegLog(stageLog, &classRegLog);
310: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
311: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
312: classPerfLog->classInfo[oclass].creations++;
313: /* Dynamically enlarge logging structures */
314: if (numActions >= maxActions) {
315: PetscTime(start);
316: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
317: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
318: PetscFree(actions);
319: actions = tmpAction;
320: maxActions *= 2;
321: PetscTime(end);
322: BaseTime += (end - start);
323: }
325: numObjects = obj->id;
326: /* Record the creation action */
327: if (logActions) {
328: PetscTime(actions[numActions].time);
329: actions[numActions].time -= BaseTime;
330: actions[numActions].action = CREATE;
331: actions[numActions].cookie = obj->cookie;
332: actions[numActions].id1 = numObjects;
333: actions[numActions].id2 = -1;
334: actions[numActions].id3 = -1;
335: actions[numActions].flops = _TotalFlops;
336: PetscMallocGetCurrentUsage(&actions[numActions].mem);
337: PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
338: numActions++;
339: }
340: /* Record the object */
341: if (logObjects) {
342: objects[numObjects].parent = -1;
343: objects[numObjects].obj = obj;
344: PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
345: PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
347: /* Dynamically enlarge logging structures */
348: if (numObjects >= maxObjects) {
349: PetscTime(start);
350: PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
351: PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
352: PetscFree(objects);
353: objects = tmpObjects;
354: maxObjects *= 2;
355: PetscTime(end);
356: BaseTime += (end - start);
357: }
358: }
359: return(0);
360: }
362: /* Default object destroy logger */
365: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
366: {
367: StageLog stageLog;
368: ClassRegLog classRegLog;
369: ClassPerfLog classPerfLog;
370: Action *tmpAction;
371: PetscLogDouble start, end;
372: int oclass;
373: int stage;
377: /* Record stage info */
378: PetscLogGetStageLog(&stageLog);
379: StageLogGetCurrent(stageLog, &stage);
380: if (stage != -1) {
381: /* That can happen if the log summary is output before some things are destroyed */
382: StageLogGetClassRegLog(stageLog, &classRegLog);
383: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
384: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
385: classPerfLog->classInfo[oclass].destructions++;
386: classPerfLog->classInfo[oclass].mem += obj->mem;
387: }
388: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
389: numObjectsDestroyed++;
390: /* Dynamically enlarge logging structures */
391: if (numActions >= maxActions) {
392: PetscTime(start);
393: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
394: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
395: PetscFree(actions);
396: actions = tmpAction;
397: maxActions *= 2;
398: PetscTime(end);
399: BaseTime += (end - start);
400: }
401: /* Record the destruction action */
402: if (logActions) {
403: PetscTime(actions[numActions].time);
404: actions[numActions].time -= BaseTime;
405: actions[numActions].action = DESTROY;
406: actions[numActions].cookie = obj->cookie;
407: actions[numActions].id1 = obj->id;
408: actions[numActions].id2 = -1;
409: actions[numActions].id3 = -1;
410: actions[numActions].flops = _TotalFlops;
411: PetscMallocGetCurrentUsage(&actions[numActions].mem);
412: PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
413: numActions++;
414: }
415: if (logObjects) {
416: if (obj->name) {
417: PetscStrncpy(objects[obj->id].name, obj->name, 64);
418: }
419: objects[obj->id].obj = PETSC_NULL;
420: objects[obj->id].mem = obj->mem;
421: }
422: return(0);
423: }