Actual source code: classLog.c
2: #include petsc.h
3: #include src/sys/src/plog/ptime.h
4: #include plog.h
6: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
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 _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: if (c->name) {
86: PetscFree(c->name);
87: }
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 _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.
212: A prefered cookie is given on input, and the actual cookie is returned on output. If
213: the user has no preference, PETSC_DECIDE will cause the cookie to be automatically
214: assigned, and unique in this ClassLog.
216: Not Collective
218: Input Parameters:
219: + classLog - The ClassLog
220: . cname - The name associated with the class
221: - cookie - The prefered cookie (or PETSC_DECIDE), and the actual cookie on output
223: Level: developer
225: .keywords: log, class, register
226: .seealso: PetscLogClassRegister()
227: @*/
228: PetscErrorCode ClassRegLogRegister(ClassRegLog classLog, const char cname[], PetscCookie *cookie)
229: {
230: ClassRegInfo *classInfo;
231: char *str;
232: int c;
238: c = classLog->numClasses++;
239: if (classLog->numClasses > classLog->maxClasses) {
240: PetscMalloc(classLog->maxClasses*2 * sizeof(ClassRegInfo), &classInfo);
241: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(ClassRegInfo));
242: PetscFree(classLog->classInfo);
243: classLog->classInfo = classInfo;
244: classLog->maxClasses *= 2;
245: }
246: PetscStrallocpy(cname, &str);
247: classLog->classInfo[c].name = str;
248: if (*cookie == PETSC_DECIDE) {
249: classLog->classInfo[c].cookie = ++PETSC_LARGEST_COOKIE;
250: } else if (*cookie >= 0) {
251: classLog->classInfo[c].cookie = *cookie;
252: /* Need to check here for montonicity and insert if necessary */
253: } else {
254: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Invalid suggested cookie %d", (int)*cookie);
255: }
256: *cookie = classLog->classInfo[c].cookie;
257: return(0);
258: }
260: /*------------------------------------------------ Query Functions --------------------------------------------------*/
263: /*@C
264: ClassRegLogGetClass - This function returns the class corresponding to a given cookie.
266: Not Collective
268: Input Parameters:
269: + classLog - The ClassRegLog
270: - cookie - The cookie
271:
272: Output Parameter:
273: . oclass - The class id
275: Level: developer
277: .keywords: log, class, register
278: .seealso: PetscLogClassRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
279: @*/
280: PetscErrorCode ClassRegLogGetClass(ClassRegLog classLog, PetscCookie cookie, int *oclass)
281: {
282: int c;
286: for(c = 0; c < classLog->numClasses; c++) {
287: /* Could do bisection here */
288: if (classLog->classInfo[c].cookie == cookie) break;
289: }
290: if (c >= classLog->numClasses) SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid object cookie %d", cookie);
291: *oclass = c;
292: return(0);
293: }
295: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
296: /* Default object create logger */
299: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
300: {
301: StageLog stageLog;
302: ClassRegLog classRegLog;
303: ClassPerfLog classPerfLog;
304: Action *tmpAction;
305: Object *tmpObjects;
306: PetscLogDouble start, end;
307: int oclass;
308: int stage;
312: /* Record stage info */
313: PetscLogGetStageLog(&stageLog);
314: StageLogGetCurrent(stageLog, &stage);
315: StageLogGetClassRegLog(stageLog, &classRegLog);
316: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
317: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
318: classPerfLog->classInfo[oclass].creations++;
319: /* Dynamically enlarge logging structures */
320: if (numActions >= maxActions) {
321: PetscTime(start);
322: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
323: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
324: PetscFree(actions);
325: actions = tmpAction;
326: maxActions *= 2;
327: PetscTime(end);
328: BaseTime += (end - start);
329: }
330: /* Record the creation action */
331: if (logActions) {
332: PetscTime(actions[numActions].time);
333: actions[numActions].time -= BaseTime;
334: actions[numActions].action = CREATE;
335: actions[numActions].cookie = obj->cookie;
336: actions[numActions].id1 = numObjects;
337: actions[numActions].id2 = -1;
338: actions[numActions].id3 = -1;
339: actions[numActions].flops = _TotalFlops;
340: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
341: numActions++;
342: }
343: /* Record the object */
344: if (logObjects) {
345: objects[numObjects].parent = -1;
346: objects[numObjects].obj = obj;
347: PetscMemzero(objects[numObjects].name, 64 * sizeof(char));
348: PetscMemzero(objects[numObjects].info, 64 * sizeof(char));
349: numObjects++;
350: }
351: obj->id = numObjects;
352: /* Dynamically enlarge logging structures */
353: if (numObjects >= maxObjects) {
354: PetscTime(start);
355: PetscMalloc(maxObjects*2 * sizeof(Object), &tmpObjects);
356: PetscMemcpy(tmpObjects, objects, maxObjects * sizeof(Object));
357: PetscFree(objects);
358: objects = tmpObjects;
359: maxObjects *= 2;
360: PetscTime(end);
361: BaseTime += (end - start);
362: }
363: return(0);
364: }
366: /* Default object destroy logger */
369: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
370: {
371: StageLog stageLog;
372: ClassRegLog classRegLog;
373: ClassPerfLog classPerfLog;
374: Action *tmpAction;
375: PetscLogDouble start, end;
376: int oclass;
377: int stage;
381: /* Record stage info */
382: PetscLogGetStageLog(&stageLog);
383: StageLogGetCurrent(stageLog, &stage);
384: StageLogGetClassRegLog(stageLog, &classRegLog);
385: StageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
386: ClassRegLogGetClass(classRegLog, obj->cookie, &oclass);
387: classPerfLog->classInfo[oclass].destructions++;
388: classPerfLog->classInfo[oclass].mem += obj->mem;
389: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
390: numObjectsDestroyed++;
391: /* Dynamically enlarge logging structures */
392: if (numActions >= maxActions) {
393: PetscTime(start);
394: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
395: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
396: PetscFree(actions);
397: actions = tmpAction;
398: maxActions *= 2;
399: PetscTime(end);
400: BaseTime += (end - start);
401: }
402: /* Record the destruction action */
403: if (logActions) {
404: PetscTime(actions[numActions].time);
405: actions[numActions].time -= BaseTime;
406: actions[numActions].action = DESTROY;
407: actions[numActions].cookie = obj->cookie;
408: actions[numActions].id1 = obj->id;
409: actions[numActions].id2 = -1;
410: actions[numActions].id3 = -1;
411: actions[numActions].flops = _TotalFlops;
412: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &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: }