Actual source code: classLog.c
1: /* $Id: classLog.c,v 1.3 2001/01/27 21:42:08 knepley Exp $ */
3: #include petsc.h
4: #include src/sys/src/plog/ptime.h
5: #include plog.h
7: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
8: /*@C
9: ClassRegLogCreate - This creates a ClassRegLog object.
11: Not collective
13: Input Parameter:
14: . classLog - The ClassRegLog
16: Level: beginner
18: .keywords: log, class, create
19: .seealso: ClassRegLogDestroy(), StageLogCreate()
20: @*/
21: int ClassRegLogCreate(ClassRegLog *classLog) {
22: ClassRegLog l;
23: int ierr;
26: PetscNew(struct _ClassRegLog, &l);
27: l->numClasses = 0;
28: l->maxClasses = 100;
29: PetscMalloc(l->maxClasses * sizeof(ClassRegInfo), &l->classInfo);
30: *classLog = l;
31: return(0);
32: }
34: /*@C
35: ClassRegLogDestroy - This destroys a ClassRegLog object.
37: Not collective
39: Input Paramter:
40: . classLog - The ClassRegLog
42: Level: beginner
44: .keywords: log, event, destroy
45: .seealso: ClassRegLogCreate()
46: @*/
47: int ClassRegLogDestroy(ClassRegLog classLog) {
48: int c;
52: for(c = 0; c < classLog->numClasses; c++) {
53: ClassRegInfoDestroy(&classLog->classInfo[c]);
54: }
55: PetscFree(classLog->classInfo);
56: PetscFree(classLog);
57: return(0);
58: }
60: /*@C
61: ClassRegInfoDestroy - This destroys a ClassRegInfo object.
63: Not collective
65: Input Parameter:
66: . c - The ClassRegInfo
68: Level: beginner
70: .keywords: log, class, destroy
71: .seealso: StageLogDestroy(), EventLogDestroy()
72: @*/
73: int ClassRegInfoDestroy(ClassRegInfo *c) {
77: if (c->name != PETSC_NULL) {
78: PetscFree(c->name);
79: }
80: return(0);
81: }
83: /*@C
84: ClassPerfLogCreate - This creates a ClassPerfLog object.
86: Not collective
88: Input Parameter:
89: . classLog - The ClassPerfLog
91: Level: beginner
93: .keywords: log, class, create
94: .seealso: ClassPerfLogDestroy(), StageLogCreate()
95: @*/
96: int ClassPerfLogCreate(ClassPerfLog *classLog) {
97: ClassPerfLog l;
98: int ierr;
101: PetscNew(struct _ClassPerfLog, &l);
102: l->numClasses = 0;
103: l->maxClasses = 100;
104: PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
105: *classLog = l;
106: return(0);
107: }
109: /*@C
110: ClassPerfLogDestroy - This destroys a ClassPerfLog object.
112: Not collective
114: Input Paramter:
115: . classLog - The ClassPerfLog
117: Level: beginner
119: .keywords: log, event, destroy
120: .seealso: ClassPerfLogCreate()
121: @*/
122: int ClassPerfLogDestroy(ClassPerfLog classLog) {
126: PetscFree(classLog->classInfo);
127: PetscFree(classLog);
128: return(0);
129: }
131: /*------------------------------------------------ General Functions -------------------------------------------------*/
132: /*@C
133: ClassPerfInfoClear - This clears a ClassPerfInfo object.
135: Not collective
137: Input Paramter:
138: . classInfo - The ClassPerfInfo
140: Level: beginner
142: .keywords: log, class, destroy
143: .seealso: ClassPerfLogCreate()
144: @*/
145: int ClassPerfInfoClear(ClassPerfInfo *classInfo) {
147: classInfo->id = -1;
148: classInfo->creations = 0;
149: classInfo->destructions = 0;
150: classInfo->mem = 0.0;
151: classInfo->descMem = 0.0;
152: return(0);
153: }
155: /*@C
156: ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.
158: Not collective
160: Input Paramters:
161: + classLog - The ClassPerfLog
162: - size - The size
164: Level: intermediate
166: .keywords: log, class, size, ensure
167: .seealso: ClassPerfLogCreate()
168: @*/
169: int ClassPerfLogEnsureSize(ClassPerfLog classLog, int size) {
170: ClassPerfInfo *classInfo;
171: int ierr;
174: while(size > classLog->maxClasses) {
175: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
176: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
177: PetscFree(classLog->classInfo);
178: classLog->classInfo = classInfo;
179: classLog->maxClasses *= 2;
180: }
181: while(classLog->numClasses < size) {
182: ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
183: }
184: return(0);
185: }
187: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
188: /*@C
189: ClassRegLogRegister - Registers a class for logging operations in an application code.
190: A prefered cookie is given on input, and the actual cookie is returned on output. If
191: the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
192: assigned, and unique in this ClassLog.
194: Not Collective
196: Input Parameters:
197: + classLog - The ClassLog
198: . cname - The name associated with the class
199: - cookie - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output
201: Level: developer
203: .keywords: log, class, register
204: .seealso: PetscLogClassRegister()
205: @*/
206: int ClassRegLogRegister(ClassRegLog classLog, const char cname[], int *cookie) {
207: ClassRegInfo *classInfo;
208: char *str;
209: int c;
210: int ierr;
215: c = classLog->numClasses++;
216: if (classLog->numClasses > classLog->maxClasses) {
217: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
218: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
219: PetscFree(classLog->classInfo);
220: classLog->classInfo = classInfo;
221: classLog->maxClasses *= 2;
222: }
223: PetscStrallocpy(cname, &str);
224: classLog->classInfo[c].name = str;
225: if (*cookie == PETSC_DECIDE) {
226: classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
227: } else if (*cookie >= 0) {
228: classLog->classInfo[c].cookie = *cookie;
229: /* Need to check here for montonicity and insert if necessary */
230: } else {
231: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", *cookie);
232: }
233: *cookie = classLog->classInfo[c].cookie;
234: return(0);
235: }
237: /*------------------------------------------------ Query Functions --------------------------------------------------*/
238: /*@C
239: ClassRegLogGetClass - This function returns the class corresponding to a given cookie.
241: Not Collective
243: Input Parameters:
244: + classLog - The ClassRegLog
245: - cookie - The cookie
246:
247: Output Parameter:
248: . oclass - The class id
250: Level: developer
252: .keywords: log, class, register
253: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
254: @*/
255: int ClassRegLogGetClass(ClassRegLog classLog, int cookie, int *oclass) {
256: int c;
260: for(c = 0; c < classLog->numClasses; c++) {
261: /* Could do bisection here */
262: if (classLog->classInfo[c].cookie == cookie) break;
263: }
264: if (c >= classLog->numClasses) SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d", cookie);
265: *oclass = c;
266: return(0);
267: }
269: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
270: /* Default object create logger */
271: int PetscLogObjCreateDefault(PetscObject obj) {
272: StageLog stageLog;
273: ClassRegLog classRegLog;
274: ClassPerfLog classPerfLog;
275: Action *tmpAction;
276: Object *tmpObjects;
277: PetscLogDouble start, end;
278: int oclass;
279: int stage;
280: int ierr;
283: /* Record stage info */
284: PetscLogGetStageLog(&stageLog);
285: StageLogGetCurrent(stageLog, &stage);
286: StageLogGetClassRegLog(stageLog, &classRegLog);
287: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
288: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
289: classPerfLog->classInfo[oclass].creations++;
290: /* Dynamically enlarge logging structures */
291: if (numActions >= maxActions) {
292: PetscTime(start);
293: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
294: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
295: PetscFree(actions);
296: actions = tmpAction;
297: maxActions *= 2;
298: PetscTime(end);
299: BaseTime += (end - start);
300: }
301: /* Record the creation action */
302: if (logActions == PETSC_TRUE) {
303: PetscTime(actions[numActions].time);
304: actions[numActions].time -= BaseTime;
305: actions[numActions].action = CREATE;
306: actions[numActions].event = obj->type;
307: actions[numActions].cookie = obj->cookie;
308: actions[numActions].id1 = numObjects;
309: actions[numActions].id2 = -1;
310: actions[numActions].id3 = -1;
311: actions[numActions].flops = _TotalFlops;
312: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
313: numActions++;
314: }
315: /* Record the object */
316: if (logObjects == PETSC_TRUE) {
317: objects[numObjects].parent = -1;
318: objects[numObjects].obj = obj;
319: PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
320: PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
321: numObjects++;
322: }
323: obj->id = numObjects;
324: /* Dynamically enlarge logging structures */
325: if (numObjects >= maxObjects) {
326: PetscTime(start);
327: PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
328: PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
329: PetscFree(objects);
330: objects = tmpObjects;
331: maxObjects *= 2;
332: PetscTime(end);
333: BaseTime += (end - start);
334: }
335: return(0);
336: }
338: /* Default object destroy logger */
339: int PetscLogObjDestroyDefault(PetscObject obj) {
340: StageLog stageLog;
341: ClassRegLog classRegLog;
342: ClassPerfLog classPerfLog;
343: Action *tmpAction;
344: PetscLogDouble start, end;
345: int oclass, pclass;
346: PetscObject parent;
347: PetscTruth exists;
348: int stage;
349: int ierr;
352: /* Record stage info */
353: PetscLogGetStageLog(&stageLog);
354: StageLogGetCurrent(stageLog, &stage);
355: StageLogGetClassRegLog(stageLog, &classRegLog);
356: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
357: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
358: classPerfLog->classInfo[oclass].destructions++;
359: classPerfLog->classInfo[oclass].mem += obj->mem;
360: /* Credit all ancestors with your memory */
361: parent = obj->parent;
362: while (parent != PETSC_NULL) {
363: PetscObjectExists(parent, &exists);
364: if (exists == PETSC_FALSE) break;
365: ClassRegLogGetClass(classRegLog, parent->cookie, &pclass);
366: classPerfLog->classInfo[pclass].descMem += obj->mem;
367: parent = parent->parent;
368: }
369: numObjectsDestroyed++;
370: /* Dynamically enlarge logging structures */
371: if (numActions >= maxActions) {
372: PetscTime(start);
373: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
374: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
375: PetscFree(actions);
376: actions = tmpAction;
377: maxActions *= 2;
378: PetscTime(end);
379: BaseTime += (end - start);
380: }
381: /* Record the destruction action */
382: if (logActions == PETSC_TRUE) {
383: PetscTime(actions[numActions].time);
384: actions[numActions].time -= BaseTime;
385: actions[numActions].action = DESTROY;
386: actions[numActions].event = obj->type;
387: actions[numActions].cookie = obj->cookie;
388: actions[numActions].id1 = obj->id;
389: actions[numActions].id2 = -1;
390: actions[numActions].id3 = -1;
391: actions[numActions].flops = _TotalFlops;
392: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
393: numActions++;
394: }
395: if (logObjects == PETSC_TRUE) {
396: if (obj->parent != PETSC_NULL) {
397: PetscObjectExists(obj->parent, &exists);
398: if (exists == PETSC_TRUE) {
399: objects[obj->id].parent = obj->parent->id;
400: } else {
401: objects[obj->id].parent = -1;
402: }
403: } else {
404: objects[obj->id].parent = -1;
405: }
406: if (obj->name != PETSC_NULL) {
407: PetscStrncpy(objects[obj->id].name, obj->name, 64);
408: }
409: objects[obj->id].obj = PETSC_NULL;
410: objects[obj->id].mem = obj->mem;
411: }
412: return(0);
413: }