Actual source code: classLog.c
1: #define PETSC_DLL
3: #include petsc.h
4: #include src/sys/src/plog/ptime.h
5: #include 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 _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: if (c->name) {
88: PetscFree(c->name);
89: }
90: return(0);
91: }
95: /*@C
96: ClassPerfLogCreate - This creates a ClassPerfLog object.
98: Not collective
100: Input Parameter:
101: . classLog - The ClassPerfLog
103: Level: beginner
105: .keywords: log, class, create
106: .seealso: ClassPerfLogDestroy(), StageLogCreate()
107: @*/
108: PetscErrorCode ClassPerfLogCreate(ClassPerfLog *classLog)
109: {
110: ClassPerfLog l;
114: PetscNew(struct _ClassPerfLog, &l);
115: l->numClasses = 0;
116: l->maxClasses = 100;
117: PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
118: *classLog = l;
119: return(0);
120: }
124: /*@C
125: ClassPerfLogDestroy - This destroys a ClassPerfLog object.
127: Not collective
129: Input Paramter:
130: . classLog - The ClassPerfLog
132: Level: beginner
134: .keywords: log, event, destroy
135: .seealso: ClassPerfLogCreate()
136: @*/
137: PetscErrorCode ClassPerfLogDestroy(ClassPerfLog classLog)
138: {
142: PetscFree(classLog->classInfo);
143: PetscFree(classLog);
144: return(0);
145: }
147: /*------------------------------------------------ General Functions -------------------------------------------------*/
150: /*@C
151: ClassPerfInfoClear - This clears a ClassPerfInfo object.
153: Not collective
155: Input Paramter:
156: . classInfo - The ClassPerfInfo
158: Level: beginner
160: .keywords: log, class, destroy
161: .seealso: ClassPerfLogCreate()
162: @*/
163: PetscErrorCode ClassPerfInfoClear(ClassPerfInfo *classInfo)
164: {
166: classInfo->id = -1;
167: classInfo->creations = 0;
168: classInfo->destructions = 0;
169: classInfo->mem = 0.0;
170: classInfo->descMem = 0.0;
171: return(0);
172: }
176: /*@C
177: ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.
179: Not collective
181: Input Paramters:
182: + classLog - The ClassPerfLog
183: - size - The size
185: Level: intermediate
187: .keywords: log, class, size, ensure
188: .seealso: ClassPerfLogCreate()
189: @*/
190: PetscErrorCode ClassPerfLogEnsureSize(ClassPerfLog classLog, int size)
191: {
192: ClassPerfInfo *classInfo;
196: while(size > classLog->maxClasses) {
197: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
198: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
199: PetscFree(classLog->classInfo);
200: classLog->classInfo = classInfo;
201: classLog->maxClasses *= 2;
202: }
203: while(classLog->numClasses < size) {
204: ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
205: }
206: return(0);
207: }
209: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
212: /*@C
213: ClassRegLogRegister - Registers a class for logging operations in an application code.
214: A prefered cookie is given on input, and the actual cookie is returned on output. If
215: the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
216: assigned, and unique in this ClassLog.
218: Not Collective
220: Input Parameters:
221: + classLog - The ClassLog
222: . cname - The name associated with the class
223: - cookie - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output
225: Level: developer
227: .keywords: log, class, register
228: .seealso: PetscLogClassRegister()
229: @*/
230: PetscErrorCode ClassRegLogRegister(ClassRegLog classLog, const char cname[], PetscCookie *cookie)
231: {
232: ClassRegInfo *classInfo;
233: char *str;
234: int c;
240: c = classLog->numClasses++;
241: if (classLog->numClasses > classLog->maxClasses) {
242: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
243: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
244: PetscFree(classLog->classInfo);
245: classLog->classInfo = classInfo;
246: classLog->maxClasses *= 2;
247: }
248: PetscStrallocpy(cname, &str);
249: classLog->classInfo[c].name = str;
250: if (*cookie == PETSC_DECIDE) {
251: classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
252: } else if (*cookie >= 0) {
253: classLog->classInfo[c].cookie = *cookie;
254: /* Need to check here for montonicity and insert if necessary */
255: } else {
256: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", (int)*cookie);
257: }
258: *cookie = classLog->classInfo[c].cookie;
259: return(0);
260: }
262: /*------------------------------------------------ Query Functions --------------------------------------------------*/
265: /*@C
266: ClassRegLogGetClass - This function returns the class corresponding to a given cookie.
268: Not Collective
270: Input Parameters:
271: + classLog - The ClassRegLog
272: - cookie - The cookie
273:
274: Output Parameter:
275: . oclass - The class id
277: Level: developer
279: .keywords: log, class, register
280: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
281: @*/
282: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
283: {
284: int c;
288: for(c = 0; c < classLog->numClasses; c++) {
289: /* Could do bisection here */
290: if (classLog->classInfo[c].cookie == cookie) break;
291: }
292: if (c >= classLog->numClasses) {
293: 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);
294: }
295: *oclass = c;
296: return(0);
297: }
299: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
300: /* Default object create logger */
303: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
304: {
305: StageLog stageLog;
306: ClassRegLog classRegLog;
307: ClassPerfLog classPerfLog;
308: Action *tmpAction;
309: Object *tmpObjects;
310: PetscLogDouble start, end;
311: int oclass;
312: int stage;
316: /* Record stage info */
317: PetscLogGetStageLog(&stageLog);
318: StageLogGetCurrent(stageLog, &stage);
319: StageLogGetClassRegLog(stageLog, &classRegLog);
320: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
321: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
322: classPerfLog->classInfo[oclass].creations++;
323: /* Dynamically enlarge logging structures */
324: if (numActions >= maxActions) {
325: PetscTime(start);
326: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
327: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
328: PetscFree(actions);
329: actions = tmpAction;
330: maxActions *= 2;
331: PetscTime(end);
332: BaseTime += (end - start);
333: }
335: numObjects = obj->id;
336: /* Record the creation action */
337: if (logActions) {
338: PetscTime(actions[numActions].time);
339: actions[numActions].time -= BaseTime;
340: actions[numActions].action = CREATE;
341: actions[numActions].cookie = obj->cookie;
342: actions[numActions].id1 = numObjects;
343: actions[numActions].id2 = -1;
344: actions[numActions].id3 = -1;
345: actions[numActions].flops = _TotalFlops;
346: PetscMallocGetCurrentUsage(&actions[numActions].mem);
347: PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
348: numActions++;
349: }
350: /* Record the object */
351: if (logObjects) {
352: objects[numObjects].parent = -1;
353: objects[numObjects].obj = obj;
354: PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
355: PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
357: /* Dynamically enlarge logging structures */
358: if (numObjects >= maxObjects) {
359: PetscTime(start);
360: PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
361: PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
362: PetscFree(objects);
363: objects = tmpObjects;
364: maxObjects *= 2;
365: PetscTime(end);
366: BaseTime += (end - start);
367: }
368: }
369: return(0);
370: }
372: /* Default object destroy logger */
375: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
376: {
377: StageLog stageLog;
378: ClassRegLog classRegLog;
379: ClassPerfLog classPerfLog;
380: Action *tmpAction;
381: PetscLogDouble start, end;
382: int oclass;
383: int stage;
387: /* Record stage info */
388: PetscLogGetStageLog(&stageLog);
389: StageLogGetCurrent(stageLog, &stage);
390: StageLogGetClassRegLog(stageLog, &classRegLog);
391: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
392: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
393: classPerfLog->classInfo[oclass].destructions++;
394: classPerfLog->classInfo[oclass].mem += obj->mem;
395: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
396: numObjectsDestroyed++;
397: /* Dynamically enlarge logging structures */
398: if (numActions >= maxActions) {
399: PetscTime(start);
400: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
401: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
402: PetscFree(actions);
403: actions = tmpAction;
404: maxActions *= 2;
405: PetscTime(end);
406: BaseTime += (end - start);
407: }
408: /* Record the destruction action */
409: if (logActions) {
410: PetscTime(actions[numActions].time);
411: actions[numActions].time -= BaseTime;
412: actions[numActions].action = DESTROY;
413: actions[numActions].cookie = obj->cookie;
414: actions[numActions].id1 = obj->id;
415: actions[numActions].id2 = -1;
416: actions[numActions].id3 = -1;
417: actions[numActions].flops = _TotalFlops;
418: PetscMallocGetCurrentUsage(&actions[numActions].mem);
419: PetscMallocGetMaximumUsage(&actions[numActions].maxmem);
420: numActions++;
421: }
422: if (logObjects) {
423: if (obj->name) {
424: PetscStrncpy(objects[obj->id].name, obj->name, 64);
425: }
426: objects[obj->id].obj = PETSC_NULL;
427: objects[obj->id].mem = obj->mem;
428: }
429: return(0);
430: }