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: #undef __FUNCT__
10: /*@C
11: ClassRegLogCreate - This creates a ClassRegLog object.
13: Not collective
15: Input Parameter:
16: . classLog - The ClassRegLog
18: Level: beginner
20: .keywords: log, class, create
21: .seealso: ClassRegLogDestroy(), StageLogCreate()
22: @*/
23: int ClassRegLogCreate(ClassRegLog *classLog) {
24: ClassRegLog l;
25: int ierr;
28: PetscNew(struct _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: }
36: #undef __FUNCT__
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: int ClassRegLogDestroy(ClassRegLog classLog) {
52: int c;
56: for(c = 0; c < classLog->numClasses; c++) {
57: ClassRegInfoDestroy(&classLog->classInfo[c]);
58: }
59: PetscFree(classLog->classInfo);
60: PetscFree(classLog);
61: return(0);
62: }
64: #undef __FUNCT__
66: /*@C
67: ClassRegInfoDestroy - This destroys a ClassRegInfo object.
69: Not collective
71: Input Parameter:
72: . c - The ClassRegInfo
74: Level: beginner
76: .keywords: log, class, destroy
77: .seealso: StageLogDestroy(), EventLogDestroy()
78: @*/
79: int ClassRegInfoDestroy(ClassRegInfo *c) {
83: if (c->name != PETSC_NULL) {
84: PetscFree(c->name);
85: }
86: return(0);
87: }
89: #undef __FUNCT__
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: int ClassPerfLogCreate(ClassPerfLog *classLog) {
105: ClassPerfLog l;
106: int ierr;
109: PetscNew(struct _ClassPerfLog, &l);
110: l->numClasses = 0;
111: l->maxClasses = 100;
112: PetscMalloc(l->maxClasses * sizeof(ClassPerfInfo), &l->classInfo);
113: *classLog = l;
114: return(0);
115: }
117: #undef __FUNCT__
119: /*@C
120: ClassPerfLogDestroy - This destroys a ClassPerfLog object.
122: Not collective
124: Input Paramter:
125: . classLog - The ClassPerfLog
127: Level: beginner
129: .keywords: log, event, destroy
130: .seealso: ClassPerfLogCreate()
131: @*/
132: int ClassPerfLogDestroy(ClassPerfLog classLog) {
136: PetscFree(classLog->classInfo);
137: PetscFree(classLog);
138: return(0);
139: }
141: /*------------------------------------------------ General Functions -------------------------------------------------*/
142: #undef __FUNCT__
144: /*@C
145: ClassPerfInfoClear - This clears a ClassPerfInfo object.
147: Not collective
149: Input Paramter:
150: . classInfo - The ClassPerfInfo
152: Level: beginner
154: .keywords: log, class, destroy
155: .seealso: ClassPerfLogCreate()
156: @*/
157: int ClassPerfInfoClear(ClassPerfInfo *classInfo) {
159: classInfo->id = -1;
160: classInfo->creations = 0;
161: classInfo->destructions = 0;
162: classInfo->mem = 0.0;
163: classInfo->descMem = 0.0;
164: return(0);
165: }
167: #undef __FUNCT__
169: /*@C
170: ClassPerfLogEnsureSize - This ensures that a ClassPerfLog is at least of a certain size.
172: Not collective
174: Input Paramters:
175: + classLog - The ClassPerfLog
176: - size - The size
178: Level: intermediate
180: .keywords: log, class, size, ensure
181: .seealso: ClassPerfLogCreate()
182: @*/
183: int ClassPerfLogEnsureSize(ClassPerfLog classLog, int size) {
184: ClassPerfInfo *classInfo;
185: int ierr;
188: while(size > classLog->maxClasses) {
189: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassPerfInfo), &classInfo);
190: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassPerfInfo));
191: PetscFree(classLog->classInfo);
192: classLog->classInfo = classInfo;
193: classLog->maxClasses *= 2;
194: }
195: while(classLog->numClasses < size) {
196: ClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
197: }
198: return(0);
199: }
201: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
202: #undef __FUNCT__
204: /*@C
205: ClassRegLogRegister - Registers a class for logging operations in an application code.
206: A prefered cookie is given on input, and the actual cookie is returned on output. If
207: the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
208: assigned, and unique in this ClassLog.
210: Not Collective
212: Input Parameters:
213: + classLog - The ClassLog
214: . cname - The name associated with the class
215: - cookie - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output
217: Level: developer
219: .keywords: log, class, register
220: .seealso: PetscLogClassRegister()
221: @*/
222: int ClassRegLogRegister(ClassRegLog classLog, const char cname[], int *cookie) {
223: ClassRegInfo *classInfo;
224: char *str;
225: int c;
226: int ierr;
231: c = classLog->numClasses++;
232: if (classLog->numClasses > classLog->maxClasses) {
233: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
234: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
235: PetscFree(classLog->classInfo);
236: classLog->classInfo = classInfo;
237: classLog->maxClasses *= 2;
238: }
239: PetscStrallocpy(cname, &str);
240: classLog->classInfo[c].name = str;
241: if (*cookie == PETSC_DECIDE) {
242: classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
243: } else if (*cookie >= 0) {
244: classLog->classInfo[c].cookie = *cookie;
245: /* Need to check here for montonicity and insert if necessary */
246: } else {
247: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", *cookie);
248: }
249: *cookie = classLog->classInfo[c].cookie;
250: return(0);
251: }
253: /*------------------------------------------------ Query Functions --------------------------------------------------*/
254: #undef __FUNCT__
256: /*@C
257: ClassRegLogGetClass - This function returns the class corresponding to a given cookie.
259: Not Collective
261: Input Parameters:
262: + classLog - The ClassRegLog
263: - cookie - The cookie
264:
265: Output Parameter:
266: . oclass - The class id
268: Level: developer
270: .keywords: log, class, register
271: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
272: @*/
273: int ClassRegLogGetClass(ClassRegLog classLog, int cookie, int *oclass) {
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) SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d", cookie);
283: *oclass = c;
284: return(0);
285: }
287: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
288: /* Default object create logger */
289: #undef __FUNCT__
291: int PetscLogObjCreateDefault(PetscObject obj) {
292: StageLog stageLog;
293: ClassRegLog classRegLog;
294: ClassPerfLog classPerfLog;
295: Action *tmpAction;
296: Object *tmpObjects;
297: PetscLogDouble start, end;
298: int oclass;
299: int stage;
300: int ierr;
303: /* Record stage info */
304: PetscLogGetStageLog(&stageLog);
305: StageLogGetCurrent(stageLog, &stage);
306: StageLogGetClassRegLog(stageLog, &classRegLog);
307: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
308: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
309: classPerfLog->classInfo[oclass].creations++;
310: /* Dynamically enlarge logging structures */
311: if (numActions >= maxActions) {
312: PetscTime(start);
313: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
314: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
315: PetscFree(actions);
316: actions = tmpAction;
317: maxActions *= 2;
318: PetscTime(end);
319: BaseTime += (end - start);
320: }
321: /* Record the creation action */
322: if (logActions == PETSC_TRUE) {
323: PetscTime(actions[numActions].time);
324: actions[numActions].time -= BaseTime;
325: actions[numActions].action = CREATE;
326: actions[numActions].event = obj->type;
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: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
333: numActions++;
334: }
335: /* Record the object */
336: if (logObjects == PETSC_TRUE) {
337: objects[numObjects].parent = -1;
338: objects[numObjects].obj = obj;
339: PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
340: PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
341: numObjects++;
342: }
343: obj->id = numObjects;
344: /* Dynamically enlarge logging structures */
345: if (numObjects >= maxObjects) {
346: PetscTime(start);
347: PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
348: PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
349: PetscFree(objects);
350: objects = tmpObjects;
351: maxObjects *= 2;
352: PetscTime(end);
353: BaseTime += (end - start);
354: }
355: return(0);
356: }
358: /* Default object destroy logger */
359: #undef __FUNCT__
361: int PetscLogObjDestroyDefault(PetscObject obj) {
362: StageLog stageLog;
363: ClassRegLog classRegLog;
364: ClassPerfLog classPerfLog;
365: Action *tmpAction;
366: PetscLogDouble start, end;
367: int oclass, pclass;
368: PetscObject parent;
369: PetscTruth exists;
370: int stage;
371: int ierr;
374: /* Record stage info */
375: PetscLogGetStageLog(&stageLog);
376: StageLogGetCurrent(stageLog, &stage);
377: StageLogGetClassRegLog(stageLog, &classRegLog);
378: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
379: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
380: classPerfLog->classInfo[oclass].destructions++;
381: classPerfLog->classInfo[oclass].mem += obj->mem;
382: /* Credit all ancestors with your memory */
383: parent = obj->parent;
384: while (parent != PETSC_NULL) {
385: PetscObjectExists(parent, &exists);
386: if (exists == PETSC_FALSE) break;
387: ClassRegLogGetClass(classRegLog, parent->cookie, &pclass);
388: classPerfLog->classInfo[pclass].descMem += obj->mem;
389: parent = parent->parent;
390: }
391: numObjectsDestroyed++;
392: /* Dynamically enlarge logging structures */
393: if (numActions >= maxActions) {
394: PetscTime(start);
395: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
396: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
397: PetscFree(actions);
398: actions = tmpAction;
399: maxActions *= 2;
400: PetscTime(end);
401: BaseTime += (end - start);
402: }
403: /* Record the destruction action */
404: if (logActions == PETSC_TRUE) {
405: PetscTime(actions[numActions].time);
406: actions[numActions].time -= BaseTime;
407: actions[numActions].action = DESTROY;
408: actions[numActions].event = obj->type;
409: actions[numActions].cookie = obj->cookie;
410: actions[numActions].id1 = obj->id;
411: actions[numActions].id2 = -1;
412: actions[numActions].id3 = -1;
413: actions[numActions].flops = _TotalFlops;
414: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
415: numActions++;
416: }
417: if (logObjects == PETSC_TRUE) {
418: if (obj->parent != PETSC_NULL) {
419: PetscObjectExists(obj->parent, &exists);
420: if (exists == PETSC_TRUE) {
421: objects[obj->id].parent = obj->parent->id;
422: } else {
423: objects[obj->id].parent = -1;
424: }
425: } else {
426: objects[obj->id].parent = -1;
427: }
428: if (obj->name != PETSC_NULL) {
429: PetscStrncpy(objects[obj->id].name, obj->name, 64);
430: }
431: objects[obj->id].obj = PETSC_NULL;
432: objects[obj->id].mem = obj->mem;
433: }
434: return(0);
435: }