Actual source code: classlog.c
2: /*
3: This defines part of the private API for logging performance information. It is intended to be used only by the
4: PETSc PetscLog...() interface and not elsewhere, nor by users. Hence the prototypes for these functions are NOT
5: in the public PETSc include files.
7: */
8: #include <petsc/private/logimpl.h>
10: /*@C
11: PetscClassRegLogCreate - This creates a PetscClassRegLog object.
13: Not collective
15: Input Parameter:
16: . classLog - The PetscClassRegLog
18: Level: developer
20: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
21: @*/
22: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
23: {
24: PetscClassRegLog l;
26: PetscNew(&l);
28: l->numClasses = 0;
29: l->maxClasses = 100;
31: PetscMalloc1(l->maxClasses, &l->classInfo);
33: *classLog = l;
34: return 0;
35: }
37: /*@C
38: PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.
40: Not collective
42: Input Parameter:
43: . classLog - The PetscClassRegLog
45: Level: developer
47: .seealso: PetscClassRegLogCreate()
48: @*/
49: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
50: {
51: int c;
53: for (c = 0; c < classLog->numClasses; c++) {
54: PetscClassRegInfoDestroy(&classLog->classInfo[c]);
55: }
56: PetscFree(classLog->classInfo);
57: PetscFree(classLog);
58: return 0;
59: }
61: /*@C
62: PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.
64: Not collective
66: Input Parameter:
67: . c - The PetscClassRegInfo
69: Level: developer
71: .seealso: PetscStageLogDestroy(), EventLogDestroy()
72: @*/
73: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
74: {
75: PetscFree(c->name);
76: return 0;
77: }
79: /*@C
80: PetscClassPerfLogCreate - This creates a PetscClassPerfLog object.
82: Not collective
84: Input Parameter:
85: . classLog - The PetscClassPerfLog
87: Level: developer
89: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
90: @*/
91: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
92: {
93: PetscClassPerfLog l;
95: PetscNew(&l);
97: l->numClasses = 0;
98: l->maxClasses = 100;
100: PetscMalloc1(l->maxClasses, &l->classInfo);
102: *classLog = l;
103: return 0;
104: }
106: /*@C
107: PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.
109: Not collective
111: Input Parameter:
112: . classLog - The PetscClassPerfLog
114: Level: developer
116: .seealso: PetscClassPerfLogCreate()
117: @*/
118: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
119: {
120: PetscFree(classLog->classInfo);
121: PetscFree(classLog);
122: return 0;
123: }
125: /*------------------------------------------------ General Functions -------------------------------------------------*/
126: /*@C
127: PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.
129: Not collective
131: Input Parameter:
132: . classInfo - The PetscClassPerfInfo
134: Level: developer
136: .seealso: PetscClassPerfLogCreate()
137: @*/
138: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
139: {
140: classInfo->id = -1;
141: classInfo->creations = 0;
142: classInfo->destructions = 0;
143: classInfo->mem = 0.0;
144: classInfo->descMem = 0.0;
145: return 0;
146: }
148: /*@C
149: PetscClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.
151: Not collective
153: Input Parameters:
154: + classLog - The PetscClassPerfLog
155: - size - The size
157: Level: developer
159: .seealso: PetscClassPerfLogCreate()
160: @*/
161: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
162: {
163: PetscClassPerfInfo *classInfo;
165: while (size > classLog->maxClasses) {
166: PetscMalloc1(classLog->maxClasses*2, &classInfo);
167: PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
168: PetscFree(classLog->classInfo);
170: classLog->classInfo = classInfo;
171: classLog->maxClasses *= 2;
172: }
173: while (classLog->numClasses < size) {
174: PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
175: }
176: return 0;
177: }
179: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
180: /*@C
181: PetscClassRegLogRegister - Registers a class for logging operations in an application code.
183: Not Collective
185: Input Parameters:
186: + classLog - The ClassLog
187: - cname - The name associated with the class
189: Output Parameter:
190: . classid - The classid
192: Level: developer
194: .seealso: PetscClassIdRegister()
195: @*/
196: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
197: {
198: PetscClassRegInfo *classInfo;
199: char *str;
200: int c;
203: c = classLog->numClasses++;
204: if (classLog->numClasses > classLog->maxClasses) {
205: PetscMalloc1(classLog->maxClasses*2, &classInfo);
206: PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
207: PetscFree(classLog->classInfo);
209: classLog->classInfo = classInfo;
210: classLog->maxClasses *= 2;
211: }
212: PetscStrallocpy(cname, &str);
214: classLog->classInfo[c].name = str;
215: classLog->classInfo[c].classid = classid;
216: return 0;
217: }
219: /*------------------------------------------------ Query Functions --------------------------------------------------*/
220: /*@C
221: PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.
223: Not Collective
225: Input Parameters:
226: + classLog - The PetscClassRegLog
227: - classid - The cookie
229: Output Parameter:
230: . oclass - The class id
232: Level: developer
234: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
235: @*/
236: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
237: {
238: int c;
241: for (c = 0; c < classLog->numClasses; c++) {
242: /* Could do bisection here */
243: if (classLog->classInfo[c].classid == classid) break;
244: }
246: *oclass = c;
247: return 0;
248: }
250: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
251: /* Default object create logger */
252: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
253: {
254: PetscStageLog stageLog;
255: PetscClassRegLog classRegLog;
256: PetscClassPerfLog classPerfLog;
257: Action *tmpAction;
258: Object *tmpObjects;
259: PetscLogDouble start, end;
260: int oclass = 0;
261: int stage;
263: /* Record stage info */
264: PetscLogGetStageLog(&stageLog);
265: PetscStageLogGetCurrent(stageLog, &stage);
266: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
267: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
268: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
269: classPerfLog->classInfo[oclass].creations++;
270: /* Dynamically enlarge logging structures */
271: if (petsc_numActions >= petsc_maxActions) {
272: PetscTime(&start);
273: PetscMalloc1(petsc_maxActions*2, &tmpAction);
274: PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
275: PetscFree(petsc_actions);
277: petsc_actions = tmpAction;
278: petsc_maxActions *= 2;
279: PetscTime(&end);
280: petsc_BaseTime += (end - start);
281: }
283: petsc_numObjects = obj->id;
284: /* Record the creation action */
285: if (petsc_logActions) {
286: PetscTime(&petsc_actions[petsc_numActions].time);
287: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
288: petsc_actions[petsc_numActions].action = CREATE;
289: petsc_actions[petsc_numActions].classid = obj->classid;
290: petsc_actions[petsc_numActions].id1 = petsc_numObjects;
291: petsc_actions[petsc_numActions].id2 = -1;
292: petsc_actions[petsc_numActions].id3 = -1;
293: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
295: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
296: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
297: petsc_numActions++;
298: }
299: /* Record the object */
300: if (petsc_logObjects) {
301: petsc_objects[petsc_numObjects].parent = -1;
302: petsc_objects[petsc_numObjects].obj = obj;
304: PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
305: PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));
307: /* Dynamically enlarge logging structures */
308: if (petsc_numObjects >= petsc_maxObjects) {
309: PetscTime(&start);
310: PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
311: PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
312: PetscFree(petsc_objects);
314: petsc_objects = tmpObjects;
315: petsc_maxObjects *= 2;
316: PetscTime(&end);
317: petsc_BaseTime += (end - start);
318: }
319: }
320: return 0;
321: }
323: /* Default object destroy logger */
324: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
325: {
326: PetscStageLog stageLog;
327: PetscClassRegLog classRegLog;
328: PetscClassPerfLog classPerfLog;
329: Action *tmpAction;
330: PetscLogDouble start, end;
331: int oclass = 0;
332: int stage;
334: /* Record stage info */
335: PetscLogGetStageLog(&stageLog);
336: PetscStageLogGetCurrent(stageLog, &stage);
337: if (stage != -1) {
338: /* That can happen if the log summary is output before some things are destroyed */
339: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
340: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
341: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
342: classPerfLog->classInfo[oclass].destructions++;
343: classPerfLog->classInfo[oclass].mem += obj->mem;
344: }
345: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
346: petsc_numObjectsDestroyed++;
347: /* Dynamically enlarge logging structures */
348: if (petsc_numActions >= petsc_maxActions) {
349: PetscTime(&start);
350: PetscMalloc1(petsc_maxActions*2, &tmpAction);
351: PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
352: PetscFree(petsc_actions);
354: petsc_actions = tmpAction;
355: petsc_maxActions *= 2;
356: PetscTime(&end);
357: petsc_BaseTime += (end - start);
358: }
359: /* Record the destruction action */
360: if (petsc_logActions) {
361: PetscTime(&petsc_actions[petsc_numActions].time);
362: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
363: petsc_actions[petsc_numActions].action = DESTROY;
364: petsc_actions[petsc_numActions].classid = obj->classid;
365: petsc_actions[petsc_numActions].id1 = obj->id;
366: petsc_actions[petsc_numActions].id2 = -1;
367: petsc_actions[petsc_numActions].id3 = -1;
368: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
370: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
371: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
372: petsc_numActions++;
373: }
374: if (petsc_logObjects) {
375: if (obj->name) {
376: PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
377: }
378: petsc_objects[obj->id].obj = NULL;
379: petsc_objects[obj->id].mem = obj->mem;
380: }
381: return 0;
382: }