Actual source code: classlog.c
petsc-3.14.6 2021-03-30
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;
25: PetscErrorCode ierr;
28: PetscNew(&l);
30: l->numClasses = 0;
31: l->maxClasses = 100;
33: PetscMalloc1(l->maxClasses, &l->classInfo);
35: *classLog = l;
36: return(0);
37: }
39: /*@C
40: PetscClassRegLogDestroy - This destroys a PetscClassRegLog object.
42: Not collective
44: Input Parameter:
45: . classLog - The PetscClassRegLog
47: Level: developer
49: .seealso: PetscClassRegLogCreate()
50: @*/
51: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
52: {
53: int c;
57: for (c = 0; c < classLog->numClasses; c++) {
58: PetscClassRegInfoDestroy(&classLog->classInfo[c]);
59: }
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: .seealso: PetscStageLogDestroy(), EventLogDestroy()
76: @*/
77: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
78: {
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: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
97: @*/
98: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
99: {
100: PetscClassPerfLog l;
101: PetscErrorCode ierr;
104: PetscNew(&l);
106: l->numClasses = 0;
107: l->maxClasses = 100;
109: PetscMalloc1(l->maxClasses, &l->classInfo);
111: *classLog = l;
112: return(0);
113: }
115: /*@C
116: PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.
118: Not collective
120: Input Parameter:
121: . classLog - The PetscClassPerfLog
123: Level: developer
125: .seealso: PetscClassPerfLogCreate()
126: @*/
127: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
128: {
132: PetscFree(classLog->classInfo);
133: PetscFree(classLog);
134: return(0);
135: }
137: /*------------------------------------------------ General Functions -------------------------------------------------*/
138: /*@C
139: PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.
141: Not collective
143: Input Parameter:
144: . classInfo - The PetscClassPerfInfo
146: Level: developer
148: .seealso: PetscClassPerfLogCreate()
149: @*/
150: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
151: {
153: classInfo->id = -1;
154: classInfo->creations = 0;
155: classInfo->destructions = 0;
156: classInfo->mem = 0.0;
157: classInfo->descMem = 0.0;
158: return(0);
159: }
161: /*@C
162: PetscClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.
164: Not collective
166: Input Parameters:
167: + classLog - The PetscClassPerfLog
168: - size - The size
170: Level: developer
172: .seealso: PetscClassPerfLogCreate()
173: @*/
174: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
175: {
176: PetscClassPerfInfo *classInfo;
177: PetscErrorCode ierr;
180: while (size > classLog->maxClasses) {
181: PetscMalloc1(classLog->maxClasses*2, &classInfo);
182: PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
183: PetscFree(classLog->classInfo);
185: classLog->classInfo = classInfo;
186: classLog->maxClasses *= 2;
187: }
188: while (classLog->numClasses < size) {
189: PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
190: }
191: return(0);
192: }
194: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
195: /*@C
196: PetscClassRegLogRegister - Registers a class for logging operations in an application code.
198: Not Collective
200: Input Parameters:
201: + classLog - The ClassLog
202: - cname - The name associated with the class
204: Output Parameter:
205: . classid - The classid
207: Level: developer
209: .seealso: PetscClassIdRegister()
210: @*/
211: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
212: {
213: PetscClassRegInfo *classInfo;
214: char *str;
215: int c;
216: PetscErrorCode ierr;
220: c = classLog->numClasses++;
221: if (classLog->numClasses > classLog->maxClasses) {
222: PetscMalloc1(classLog->maxClasses*2, &classInfo);
223: PetscArraycpy(classInfo, classLog->classInfo, classLog->maxClasses);
224: PetscFree(classLog->classInfo);
226: classLog->classInfo = classInfo;
227: classLog->maxClasses *= 2;
228: }
229: PetscStrallocpy(cname, &str);
231: classLog->classInfo[c].name = str;
232: classLog->classInfo[c].classid = classid;
233: return(0);
234: }
236: /*------------------------------------------------ Query Functions --------------------------------------------------*/
237: /*@C
238: PetscClassRegLogGetClass - This function returns the class corresponding to a given classid.
240: Not Collective
242: Input Parameters:
243: + classLog - The PetscClassRegLog
244: - classid - The cookie
246: Output Parameter:
247: . oclass - The class id
249: Level: developer
251: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
252: @*/
253: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
254: {
255: int c;
259: for (c = 0; c < classLog->numClasses; c++) {
260: /* Could do bisection here */
261: if (classLog->classInfo[c].classid == classid) break;
262: }
263: if (c >= classLog->numClasses) SETERRQ1(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);
264: *oclass = c;
265: return(0);
266: }
268: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
269: /* Default object create logger */
270: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
271: {
272: PetscStageLog stageLog;
273: PetscClassRegLog classRegLog;
274: PetscClassPerfLog classPerfLog;
275: Action *tmpAction;
276: Object *tmpObjects;
277: PetscLogDouble start, end;
278: int oclass = 0;
279: int stage;
280: PetscErrorCode ierr;
283: /* Record stage info */
284: PetscLogGetStageLog(&stageLog);
285: PetscStageLogGetCurrent(stageLog, &stage);
286: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
287: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
288: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
289: classPerfLog->classInfo[oclass].creations++;
290: /* Dynamically enlarge logging structures */
291: if (petsc_numActions >= petsc_maxActions) {
292: PetscTime(&start);
293: PetscMalloc1(petsc_maxActions*2, &tmpAction);
294: PetscArraycpy(tmpAction, petsc_actions, petsc_maxActions);
295: PetscFree(petsc_actions);
297: petsc_actions = tmpAction;
298: petsc_maxActions *= 2;
299: PetscTime(&end);
300: petsc_BaseTime += (end - start);
301: }
303: petsc_numObjects = obj->id;
304: /* Record the creation action */
305: if (petsc_logActions) {
306: PetscTime(&petsc_actions[petsc_numActions].time);
307: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
308: petsc_actions[petsc_numActions].action = CREATE;
309: petsc_actions[petsc_numActions].classid = obj->classid;
310: petsc_actions[petsc_numActions].id1 = petsc_numObjects;
311: petsc_actions[petsc_numActions].id2 = -1;
312: petsc_actions[petsc_numActions].id3 = -1;
313: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
315: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
316: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
317: petsc_numActions++;
318: }
319: /* Record the object */
320: if (petsc_logObjects) {
321: petsc_objects[petsc_numObjects].parent = -1;
322: petsc_objects[petsc_numObjects].obj = obj;
324: PetscMemzero(petsc_objects[petsc_numObjects].name, sizeof(petsc_objects[0].name));
325: PetscMemzero(petsc_objects[petsc_numObjects].info, sizeof(petsc_objects[0].info));
327: /* Dynamically enlarge logging structures */
328: if (petsc_numObjects >= petsc_maxObjects) {
329: PetscTime(&start);
330: PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
331: PetscArraycpy(tmpObjects, petsc_objects, petsc_maxObjects);
332: PetscFree(petsc_objects);
334: petsc_objects = tmpObjects;
335: petsc_maxObjects *= 2;
336: PetscTime(&end);
337: petsc_BaseTime += (end - start);
338: }
339: }
340: return(0);
341: }
343: /* Default object destroy logger */
344: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
345: {
346: PetscStageLog stageLog;
347: PetscClassRegLog classRegLog;
348: PetscClassPerfLog classPerfLog;
349: Action *tmpAction;
350: PetscLogDouble start, end;
351: int oclass = 0;
352: int stage;
353: PetscErrorCode ierr;
356: /* Record stage info */
357: PetscLogGetStageLog(&stageLog);
358: PetscStageLogGetCurrent(stageLog, &stage);
359: if (stage != -1) {
360: /* That can happen if the log summary is output before some things are destroyed */
361: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
362: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
363: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
364: classPerfLog->classInfo[oclass].destructions++;
365: classPerfLog->classInfo[oclass].mem += obj->mem;
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) {
398: PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
399: }
400: petsc_objects[obj->id].obj = NULL;
401: petsc_objects[obj->id].mem = obj->mem;
402: }
403: return(0);
404: }