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: Note:
21: This is a low level routine used by the logging functions in PETSc
23: .seealso: `PetscClassRegLogDestroy()`, `PetscStageLogCreate()`
24: @*/
25: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
26: {
27: PetscClassRegLog l;
29: PetscNew(&l);
31: l->numClasses = 0;
32: l->maxClasses = 100;
34: PetscMalloc1(l->maxClasses, &l->classInfo);
36: *classLog = l;
37: return 0;
38: }
40: /*@C
41: PetscClassRegLogDestroy - This destroys a `PetscClassRegLog` object.
43: Not collective
45: Input Parameter:
46: . classLog - The `PetscClassRegLog`
48: Level: developer
50: Note:
51: This is a low level routine used by the logging functions in PETSc
53: .seealso: `PetscClassRegLogCreate()`
54: @*/
55: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
56: {
57: int c;
59: for (c = 0; c < classLog->numClasses; c++) PetscClassRegInfoDestroy(&classLog->classInfo[c]);
60: PetscFree(classLog->classInfo);
61: PetscFree(classLog);
62: return 0;
63: }
65: /*@C
66: PetscClassRegInfoDestroy - This destroys a `PetscClassRegInfo` object.
68: Not collective
70: Input Parameter:
71: . c - The PetscClassRegInfo
73: Level: developer
75: Note:
76: This is a low level routine used by the logging functions in PETSc
78: .seealso: `PetscStageLogDestroy()`, `EventLogDestroy()`
79: @*/
80: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
81: {
82: PetscFree(c->name);
83: return 0;
84: }
86: /*@C
87: PetscClassPerfLogCreate - This creates a `PetscClassPerfLog` object.
89: Not collective
91: Input Parameter:
92: . classLog - The `PetscClassPerfLog`
94: Level: developer
96: Note:
97: This is a low level routine used by the logging functions in PETSc
99: .seealso: `PetscClassPerfLogDestroy()`, `PetscStageLogCreate()`
100: @*/
101: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
102: {
103: PetscClassPerfLog l;
105: PetscNew(&l);
107: l->numClasses = 0;
108: l->maxClasses = 100;
110: PetscMalloc1(l->maxClasses, &l->classInfo);
112: *classLog = l;
113: return 0;
114: }
116: /*@C
117: PetscClassPerfLogDestroy - This destroys a `PetscClassPerfLog` object.
119: Not collective
121: Input Parameter:
122: . classLog - The `PetscClassPerfLog`
124: Level: developer
126: Note:
127: This is a low level routine used by the logging functions in PETSc
129: .seealso: `PetscClassPerfLogCreate()`
130: @*/
131: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
132: {
133: PetscFree(classLog->classInfo);
134: PetscFree(classLog);
135: return 0;
136: }
138: /*------------------------------------------------ General Functions -------------------------------------------------*/
139: /*@C
140: PetscClassPerfInfoClear - This clears a `PetscClassPerfInfo` object.
142: Not collective
144: Input Parameter:
145: . classInfo - The `PetscClassPerfInfo`
147: Level: developer
149: Note:
150: This is a low level routine used by the logging functions in PETSc
152: .seealso: `PetscClassPerfLogCreate()`
153: @*/
154: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
155: {
156: classInfo->id = -1;
157: classInfo->creations = 0;
158: classInfo->destructions = 0;
159: classInfo->mem = 0.0;
160: classInfo->descMem = 0.0;
161: return 0;
162: }
164: /*@C
165: PetscClassPerfLogEnsureSize - This ensures that a `PetscClassPerfLog` is at least of a certain size.
167: Not collective
169: Input Parameters:
170: + classLog - The `PetscClassPerfLog`
171: - size - The size
173: Level: developer
175: Note:
176: This is a low level routine used by the logging functions in PETSc
178: .seealso: `PetscClassPerfLogCreate()`
179: @*/
180: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
181: {
182: PetscClassPerfInfo *classInfo;
184: while (size > classLog->maxClasses) {
185: PetscMalloc1(classLog->maxClasses * 2, &classInfo);
186: PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
187: PetscFree(classLog->classInfo);
189: classLog->classInfo = classInfo;
190: classLog->maxClasses *= 2;
191: }
192: while (classLog->numClasses < size) PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
193: return 0;
194: }
196: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
197: /*@C
198: PetscClassRegLogRegister - Registers a class for logging operations in an application code.
200: Not Collective
202: Input Parameters:
203: + classLog - The `PetscClassRegLog`
204: - cname - The name associated with the class
206: Output Parameter:
207: . classid - The classid
209: Level: developer
211: Note:
212: This is a low level routine used by the logging functions in PETSc
214: .seealso: `PetscClassIdRegister()`
215: @*/
216: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
217: {
218: PetscClassRegInfo *classInfo;
219: char *str;
220: int c;
223: c = classLog->numClasses++;
224: if (classLog->numClasses > classLog->maxClasses) {
225: PetscMalloc1(classLog->maxClasses * 2, &classInfo);
226: PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
227: PetscFree(classLog->classInfo);
229: classLog->classInfo = classInfo;
230: classLog->maxClasses *= 2;
231: }
232: PetscStrallocpy(cname, &str);
234: classLog->classInfo[c].name = str;
235: classLog->classInfo[c].classid = classid;
236: return 0;
237: }
239: /*------------------------------------------------ Query Functions --------------------------------------------------*/
240: /*@C
241: PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.
243: Not Collective
245: Input Parameters:
246: + classLog - The `PetscClassRegLog`
247: - classid - The cookie
249: Output Parameter:
250: . oclass - The class id
252: Level: developer
254: Note:
255: This is a low level routine used by the logging functions in PETSc
257: .seealso: `PetscClassIdRegister()`, `PetscLogObjCreateDefault()`, `PetscLogObjDestroyDefault()`
258: @*/
259: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
260: {
261: int c;
264: for (c = 0; c < classLog->numClasses; c++) {
265: /* Could do bisection here */
266: if (classLog->classInfo[c].classid == classid) break;
267: }
269: *oclass = c;
270: return 0;
271: }
273: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
274: /* Default object create logger */
275: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
276: {
277: PetscStageLog stageLog;
278: PetscClassRegLog classRegLog;
279: PetscClassPerfLog classPerfLog;
280: Action *tmpAction;
281: Object *tmpObjects;
282: PetscLogDouble start, end;
283: int oclass = 0;
284: int stage;
286: /* Record stage info */
287: PetscLogGetStageLog(&stageLog);
288: PetscStageLogGetCurrent(stageLog, &stage);
289: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
290: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
291: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
292: classPerfLog->classInfo[oclass].creations++;
293: /* Dynamically enlarge logging structures */
294: if (petsc_numActions >= petsc_maxActions) {
295: PetscTime(&start);
296: PetscMalloc1(petsc_maxActions * 2, &tmpAction);
297: PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
298: PetscFree(petsc_actions);
300: petsc_actions = tmpAction;
301: petsc_maxActions *= 2;
302: PetscTime(&end);
303: petsc_BaseTime += (end - start);
304: }
306: petsc_numObjects = obj->id;
307: /* Record the creation action */
308: if (petsc_logActions) {
309: PetscTime(&petsc_actions[petsc_numActions].time);
310: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
311: petsc_actions[petsc_numActions].action = CREATE;
312: petsc_actions[petsc_numActions].classid = obj->classid;
313: petsc_actions[petsc_numActions].id1 = petsc_numObjects;
314: petsc_actions[petsc_numActions].id2 = -1;
315: petsc_actions[petsc_numActions].id3 = -1;
316: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
318: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
319: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
320: petsc_numActions++;
321: }
322: /* Record the object */
323: if (petsc_logObjects) {
324: petsc_objects[petsc_numObjects].parent = -1;
325: petsc_objects[petsc_numObjects].obj = obj;
327: PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
328: PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));
330: /* Dynamically enlarge logging structures */
331: if (petsc_numObjects >= petsc_maxObjects) {
332: PetscTime(&start);
333: PetscMalloc1(petsc_maxObjects * 2, &tmpObjects);
334: PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
335: PetscFree(petsc_objects);
337: petsc_objects = tmpObjects;
338: petsc_maxObjects *= 2;
339: PetscTime(&end);
340: petsc_BaseTime += (end - start);
341: }
342: }
343: return 0;
344: }
346: /* Default object destroy logger */
347: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
348: {
349: PetscStageLog stageLog;
350: PetscClassRegLog classRegLog;
351: PetscClassPerfLog classPerfLog;
352: Action *tmpAction;
353: PetscLogDouble start, end;
354: int oclass = 0;
355: int stage;
357: /* Record stage info */
358: PetscLogGetStageLog(&stageLog);
359: PetscStageLogGetCurrent(stageLog, &stage);
360: if (stage != -1) {
361: /* That can happen if the log summary is output before some things are destroyed */
362: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
363: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
364: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
365: classPerfLog->classInfo[oclass].destructions++;
366: }
367: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
368: petsc_numObjectsDestroyed++;
369: /* Dynamically enlarge logging structures */
370: if (petsc_numActions >= petsc_maxActions) {
371: PetscTime(&start);
372: PetscMalloc1(petsc_maxActions * 2, &tmpAction);
373: PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
374: PetscFree(petsc_actions);
376: petsc_actions = tmpAction;
377: petsc_maxActions *= 2;
378: PetscTime(&end);
379: petsc_BaseTime += (end - start);
380: }
381: /* Record the destruction action */
382: if (petsc_logActions) {
383: PetscTime(&petsc_actions[petsc_numActions].time);
384: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
385: petsc_actions[petsc_numActions].action = DESTROY;
386: petsc_actions[petsc_numActions].classid = obj->classid;
387: petsc_actions[petsc_numActions].id1 = obj->id;
388: petsc_actions[petsc_numActions].id2 = -1;
389: petsc_actions[petsc_numActions].id3 = -1;
390: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
392: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
393: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
394: petsc_numActions++;
395: }
396: if (petsc_logObjects) {
397: if (obj->name) PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
398: petsc_objects[obj->id].obj = NULL;
399: }
400: return 0;
401: }