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: PetscFunctionBegin;
30: PetscCall(PetscNew(&l));
32: l->numClasses = 0;
33: l->maxClasses = 100;
35: PetscCall(PetscMalloc1(l->maxClasses, &l->classInfo));
37: *classLog = l;
38: PetscFunctionReturn(PETSC_SUCCESS);
39: }
41: /*@C
42: PetscClassRegLogDestroy - This destroys a `PetscClassRegLog` object.
44: Not Collective
46: Input Parameter:
47: . classLog - The `PetscClassRegLog`
49: Level: developer
51: Note:
52: This is a low level routine used by the logging functions in PETSc
54: .seealso: `PetscClassRegLogCreate()`
55: @*/
56: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
57: {
58: int c;
60: PetscFunctionBegin;
61: for (c = 0; c < classLog->numClasses; c++) PetscCall(PetscClassRegInfoDestroy(&classLog->classInfo[c]));
62: PetscCall(PetscFree(classLog->classInfo));
63: PetscCall(PetscFree(classLog));
64: PetscFunctionReturn(PETSC_SUCCESS);
65: }
67: /*@C
68: PetscClassRegInfoDestroy - This destroys a `PetscClassRegInfo` object.
70: Not Collective
72: Input Parameter:
73: . c - The PetscClassRegInfo
75: Level: developer
77: Note:
78: This is a low level routine used by the logging functions in PETSc
80: .seealso: `PetscStageLogDestroy()`, `EventLogDestroy()`
81: @*/
82: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
83: {
84: PetscFunctionBegin;
85: PetscCall(PetscFree(c->name));
86: PetscFunctionReturn(PETSC_SUCCESS);
87: }
89: /*@C
90: PetscClassPerfLogCreate - This creates a `PetscClassPerfLog` object.
92: Not Collective
94: Input Parameter:
95: . classLog - The `PetscClassPerfLog`
97: Level: developer
99: Note:
100: This is a low level routine used by the logging functions in PETSc
102: .seealso: `PetscClassPerfLogDestroy()`, `PetscStageLogCreate()`
103: @*/
104: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
105: {
106: PetscClassPerfLog l;
108: PetscFunctionBegin;
109: PetscCall(PetscNew(&l));
111: l->numClasses = 0;
112: l->maxClasses = 100;
114: PetscCall(PetscMalloc1(l->maxClasses, &l->classInfo));
116: *classLog = l;
117: PetscFunctionReturn(PETSC_SUCCESS);
118: }
120: /*@C
121: PetscClassPerfLogDestroy - This destroys a `PetscClassPerfLog` object.
123: Not Collective
125: Input Parameter:
126: . classLog - The `PetscClassPerfLog`
128: Level: developer
130: Note:
131: This is a low level routine used by the logging functions in PETSc
133: .seealso: `PetscClassPerfLogCreate()`
134: @*/
135: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
136: {
137: PetscFunctionBegin;
138: PetscCall(PetscFree(classLog->classInfo));
139: PetscCall(PetscFree(classLog));
140: PetscFunctionReturn(PETSC_SUCCESS);
141: }
143: /*------------------------------------------------ General Functions -------------------------------------------------*/
144: /*@C
145: PetscClassPerfInfoClear - This clears a `PetscClassPerfInfo` object.
147: Not Collective
149: Input Parameter:
150: . classInfo - The `PetscClassPerfInfo`
152: Level: developer
154: Note:
155: This is a low level routine used by the logging functions in PETSc
157: .seealso: `PetscClassPerfLogCreate()`
158: @*/
159: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
160: {
161: PetscFunctionBegin;
162: classInfo->id = -1;
163: classInfo->creations = 0;
164: classInfo->destructions = 0;
165: classInfo->mem = 0.0;
166: classInfo->descMem = 0.0;
167: PetscFunctionReturn(PETSC_SUCCESS);
168: }
170: /*@C
171: PetscClassPerfLogEnsureSize - This ensures that a `PetscClassPerfLog` is at least of a certain size.
173: Not Collective
175: Input Parameters:
176: + classLog - The `PetscClassPerfLog`
177: - size - The size
179: Level: developer
181: Note:
182: This is a low level routine used by the logging functions in PETSc
184: .seealso: `PetscClassPerfLogCreate()`
185: @*/
186: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
187: {
188: PetscClassPerfInfo *classInfo;
190: PetscFunctionBegin;
191: while (size > classLog->maxClasses) {
192: PetscCall(PetscMalloc1(classLog->maxClasses * 2, &classInfo));
193: PetscCall(PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses));
194: PetscCall(PetscFree(classLog->classInfo));
196: classLog->classInfo = classInfo;
197: classLog->maxClasses *= 2;
198: }
199: while (classLog->numClasses < size) PetscCall(PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]));
200: PetscFunctionReturn(PETSC_SUCCESS);
201: }
203: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
204: /*@C
205: PetscClassRegLogRegister - Registers a class for logging operations in an application code.
207: Not Collective
209: Input Parameters:
210: + classLog - The `PetscClassRegLog`
211: - cname - The name associated with the class
213: Output Parameter:
214: . classid - The classid
216: Level: developer
218: Note:
219: This is a low level routine used by the logging functions in PETSc
221: .seealso: `PetscClassIdRegister()`
222: @*/
223: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
224: {
225: PetscClassRegInfo *classInfo;
226: int c;
228: PetscFunctionBegin;
230: c = classLog->numClasses++;
231: if (classLog->numClasses > classLog->maxClasses) {
232: PetscCall(PetscMalloc1(classLog->maxClasses * 2, &classInfo));
233: PetscCall(PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses));
234: PetscCall(PetscFree(classLog->classInfo));
236: classLog->classInfo = classInfo;
237: classLog->maxClasses *= 2;
238: }
239: PetscCall(PetscStrallocpy(cname, &(classLog->classInfo[c].name)));
240: classLog->classInfo[c].classid = classid;
241: PetscFunctionReturn(PETSC_SUCCESS);
242: }
244: /*------------------------------------------------ Query Functions --------------------------------------------------*/
245: /*@C
246: PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.
248: Not Collective
250: Input Parameters:
251: + classLog - The `PetscClassRegLog`
252: - classid - The cookie
254: Output Parameter:
255: . oclass - The class id
257: Level: developer
259: Note:
260: This is a low level routine used by the logging functions in PETSc
262: .seealso: `PetscClassIdRegister()`, `PetscLogObjCreateDefault()`, `PetscLogObjDestroyDefault()`
263: @*/
264: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
265: {
266: int c;
268: PetscFunctionBegin;
270: for (c = 0; c < classLog->numClasses; c++) {
271: /* Could do bisection here */
272: if (classLog->classInfo[c].classid == classid) break;
273: }
274: PetscCheck(c < classLog->numClasses, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid object classid %d\nThis could happen if you compile with PETSC_HAVE_DYNAMIC_LIBRARIES, but link with static libraries.", classid);
275: *oclass = c;
276: PetscFunctionReturn(PETSC_SUCCESS);
277: }
279: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
280: /* Default object create logger */
281: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
282: {
283: PetscStageLog stageLog;
284: PetscClassRegLog classRegLog;
285: PetscClassPerfLog classPerfLog;
286: Action *tmpAction;
287: Object *tmpObjects;
288: PetscLogDouble start, end;
289: int oclass = 0;
290: int stage;
292: PetscFunctionBegin;
293: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
294: /* Record stage info */
295: PetscCall(PetscLogGetStageLog(&stageLog));
296: PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
297: PetscCall(PetscStageLogGetClassRegLog(stageLog, &classRegLog));
298: PetscCall(PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog));
299: PetscCall(PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass));
300: classPerfLog->classInfo[oclass].creations++;
301: /* Dynamically enlarge logging structures */
302: if (petsc_numActions >= petsc_maxActions) {
303: PetscCall(PetscTime(&start));
304: PetscCall(PetscMalloc1(petsc_maxActions * 2, &tmpAction));
305: PetscCall(PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions));
306: PetscCall(PetscFree(petsc_actions));
308: petsc_actions = tmpAction;
309: petsc_maxActions *= 2;
310: PetscCall(PetscTime(&end));
311: petsc_BaseTime += (end - start);
312: }
314: petsc_numObjects = obj->id;
315: /* Record the creation action */
316: if (petsc_logActions) {
317: PetscCall(PetscTime(&petsc_actions[petsc_numActions].time));
318: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
319: petsc_actions[petsc_numActions].action = CREATE;
320: petsc_actions[petsc_numActions].classid = obj->classid;
321: petsc_actions[petsc_numActions].id1 = petsc_numObjects;
322: petsc_actions[petsc_numActions].id2 = -1;
323: petsc_actions[petsc_numActions].id3 = -1;
324: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
326: PetscCall(PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem));
327: PetscCall(PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem));
328: petsc_numActions++;
329: }
330: /* Record the object */
331: if (petsc_logObjects) {
332: petsc_objects[petsc_numObjects].parent = -1;
333: petsc_objects[petsc_numObjects].obj = obj;
335: PetscCall(PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name)));
336: PetscCall(PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info)));
338: /* Dynamically enlarge logging structures */
339: if (petsc_numObjects >= petsc_maxObjects) {
340: PetscCall(PetscTime(&start));
341: PetscCall(PetscMalloc1(petsc_maxObjects * 2, &tmpObjects));
342: PetscCall(PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects));
343: PetscCall(PetscFree(petsc_objects));
345: petsc_objects = tmpObjects;
346: petsc_maxObjects *= 2;
347: PetscCall(PetscTime(&end));
348: petsc_BaseTime += (end - start);
349: }
350: }
351: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
352: PetscFunctionReturn(PETSC_SUCCESS);
353: }
355: /* Default object destroy logger */
356: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
357: {
358: PetscStageLog stageLog;
359: PetscClassRegLog classRegLog;
360: PetscClassPerfLog classPerfLog;
361: Action *tmpAction;
362: PetscLogDouble start, end;
363: int oclass = 0;
364: int stage;
366: PetscFunctionBegin;
367: /* Record stage info */
368: PetscCall(PetscSpinlockLock(&PetscLogSpinLock));
369: PetscCall(PetscLogGetStageLog(&stageLog));
370: PetscCall(PetscStageLogGetCurrent(stageLog, &stage));
371: if (stage != -1) {
372: /* That can happen if the log summary is output before some things are destroyed */
373: PetscCall(PetscStageLogGetClassRegLog(stageLog, &classRegLog));
374: PetscCall(PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog));
375: PetscCall(PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass));
376: classPerfLog->classInfo[oclass].destructions++;
377: }
378: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
379: petsc_numObjectsDestroyed++;
380: /* Dynamically enlarge logging structures */
381: if (petsc_numActions >= petsc_maxActions) {
382: PetscCall(PetscTime(&start));
383: PetscCall(PetscMalloc1(petsc_maxActions * 2, &tmpAction));
384: PetscCall(PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions));
385: PetscCall(PetscFree(petsc_actions));
387: petsc_actions = tmpAction;
388: petsc_maxActions *= 2;
389: PetscCall(PetscTime(&end));
390: petsc_BaseTime += (end - start);
391: }
392: /* Record the destruction action */
393: if (petsc_logActions) {
394: PetscCall(PetscTime(&petsc_actions[petsc_numActions].time));
395: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
396: petsc_actions[petsc_numActions].action = DESTROY;
397: petsc_actions[petsc_numActions].classid = obj->classid;
398: petsc_actions[petsc_numActions].id1 = obj->id;
399: petsc_actions[petsc_numActions].id2 = -1;
400: petsc_actions[petsc_numActions].id3 = -1;
401: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
403: PetscCall(PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem));
404: PetscCall(PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem));
405: petsc_numActions++;
406: }
407: if (petsc_logObjects) {
408: if (obj->name) PetscCall(PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64));
409: petsc_objects[obj->id].obj = NULL;
410: }
411: PetscCall(PetscSpinlockUnlock(&PetscLogSpinLock));
412: PetscFunctionReturn(PETSC_SUCCESS);
413: }