Actual source code: classlog.c
petsc-3.11.4 2019-09-28
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: .keywords: log, class, create
21: .seealso: PetscClassRegLogDestroy(), PetscStageLogCreate()
22: @*/
23: PetscErrorCode PetscClassRegLogCreate(PetscClassRegLog *classLog)
24: {
25: PetscClassRegLog l;
26: PetscErrorCode ierr;
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 Paramter:
46: . classLog - The PetscClassRegLog
48: Level: developer
50: .keywords: log, event, destroy
51: .seealso: PetscClassRegLogCreate()
52: @*/
53: PetscErrorCode PetscClassRegLogDestroy(PetscClassRegLog classLog)
54: {
55: int c;
59: for (c = 0; c < classLog->numClasses; c++) {
60: PetscClassRegInfoDestroy(&classLog->classInfo[c]);
61: }
62: PetscFree(classLog->classInfo);
63: PetscFree(classLog);
64: return(0);
65: }
67: /*@C
68: PetscClassRegInfoDestroy - This destroys a PetscClassRegInfo object.
70: Not collective
72: Input Parameter:
73: . c - The PetscClassRegInfo
75: Level: developer
77: .keywords: log, class, destroy
78: .seealso: PetscStageLogDestroy(), EventLogDestroy()
79: @*/
80: PetscErrorCode PetscClassRegInfoDestroy(PetscClassRegInfo *c)
81: {
85: PetscFree(c->name);
86: return(0);
87: }
89: /*@C
90: PetscClassPerfLogCreate - This creates a PetscClassPerfLog object.
92: Not collective
94: Input Parameter:
95: . classLog - The PetscClassPerfLog
97: Level: developer
99: .keywords: log, class, create
100: .seealso: PetscClassPerfLogDestroy(), PetscStageLogCreate()
101: @*/
102: PetscErrorCode PetscClassPerfLogCreate(PetscClassPerfLog *classLog)
103: {
104: PetscClassPerfLog l;
105: PetscErrorCode ierr;
108: PetscNew(&l);
110: l->numClasses = 0;
111: l->maxClasses = 100;
113: PetscMalloc1(l->maxClasses, &l->classInfo);
115: *classLog = l;
116: return(0);
117: }
119: /*@C
120: PetscClassPerfLogDestroy - This destroys a PetscClassPerfLog object.
122: Not collective
124: Input Paramter:
125: . classLog - The PetscClassPerfLog
127: Level: developer
129: .keywords: log, event, destroy
130: .seealso: PetscClassPerfLogCreate()
131: @*/
132: PetscErrorCode PetscClassPerfLogDestroy(PetscClassPerfLog classLog)
133: {
137: PetscFree(classLog->classInfo);
138: PetscFree(classLog);
139: return(0);
140: }
142: /*------------------------------------------------ General Functions -------------------------------------------------*/
143: /*@C
144: PetscClassPerfInfoClear - This clears a PetscClassPerfInfo object.
146: Not collective
148: Input Paramter:
149: . classInfo - The PetscClassPerfInfo
151: Level: developer
153: .keywords: log, class, destroy
154: .seealso: PetscClassPerfLogCreate()
155: @*/
156: PetscErrorCode PetscClassPerfInfoClear(PetscClassPerfInfo *classInfo)
157: {
159: classInfo->id = -1;
160: classInfo->creations = 0;
161: classInfo->destructions = 0;
162: classInfo->mem = 0.0;
163: classInfo->descMem = 0.0;
164: return(0);
165: }
167: /*@C
168: PetscClassPerfLogEnsureSize - This ensures that a PetscClassPerfLog is at least of a certain size.
170: Not collective
172: Input Paramters:
173: + classLog - The PetscClassPerfLog
174: - size - The size
176: Level: developer
178: .keywords: log, class, size, ensure
179: .seealso: PetscClassPerfLogCreate()
180: @*/
181: PetscErrorCode PetscClassPerfLogEnsureSize(PetscClassPerfLog classLog, int size)
182: {
183: PetscClassPerfInfo *classInfo;
184: PetscErrorCode ierr;
187: while (size > classLog->maxClasses) {
188: PetscMalloc1(classLog->maxClasses*2, &classInfo);
189: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassPerfInfo));
190: PetscFree(classLog->classInfo);
192: classLog->classInfo = classInfo;
193: classLog->maxClasses *= 2;
194: }
195: while (classLog->numClasses < size) {
196: PetscClassPerfInfoClear(&classLog->classInfo[classLog->numClasses++]);
197: }
198: return(0);
199: }
201: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
202: /*@C
203: PetscClassRegLogRegister - Registers a class for logging operations in an application code.
205: Not Collective
207: Input Parameters:
208: + classLog - The ClassLog
209: - cname - The name associated with the class
211: Output Parameter:
212: . classid - The classid
214: Level: developer
216: .keywords: log, class, register
217: .seealso: PetscClassIdRegister()
218: @*/
219: PetscErrorCode PetscClassRegLogRegister(PetscClassRegLog classLog, const char cname[], PetscClassId classid)
220: {
221: PetscClassRegInfo *classInfo;
222: char *str;
223: int c;
224: PetscErrorCode ierr;
228: c = classLog->numClasses++;
229: if (classLog->numClasses > classLog->maxClasses) {
230: PetscMalloc1(classLog->maxClasses*2, &classInfo);
231: PetscMemcpy(classInfo, classLog->classInfo, classLog->maxClasses * sizeof(PetscClassRegInfo));
232: PetscFree(classLog->classInfo);
234: classLog->classInfo = classInfo;
235: classLog->maxClasses *= 2;
236: }
237: PetscStrallocpy(cname, &str);
239: classLog->classInfo[c].name = str;
240: classLog->classInfo[c].classid = classid;
241: return(0);
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: .keywords: log, class, register
260: .seealso: PetscClassIdRegister(), PetscLogObjCreateDefault(), PetscLogObjDestroyDefault()
261: @*/
262: PetscErrorCode PetscClassRegLogGetClass(PetscClassRegLog classLog, PetscClassId classid, int *oclass)
263: {
264: int c;
268: for (c = 0; c < classLog->numClasses; c++) {
269: /* Could do bisection here */
270: if (classLog->classInfo[c].classid == classid) break;
271: }
272: 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);
273: *oclass = c;
274: return(0);
275: }
277: /*----------------------------------------------- Logging Functions -------------------------------------------------*/
278: /* Default object create logger */
279: PetscErrorCode PetscLogObjCreateDefault(PetscObject obj)
280: {
281: PetscStageLog stageLog;
282: PetscClassRegLog classRegLog;
283: PetscClassPerfLog classPerfLog;
284: Action *tmpAction;
285: Object *tmpObjects;
286: PetscLogDouble start, end;
287: int oclass = 0;
288: int stage;
289: PetscErrorCode ierr;
292: /* Record stage info */
293: PetscLogGetStageLog(&stageLog);
294: PetscStageLogGetCurrent(stageLog, &stage);
295: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
296: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
297: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
298: classPerfLog->classInfo[oclass].creations++;
299: /* Dynamically enlarge logging structures */
300: if (petsc_numActions >= petsc_maxActions) {
301: PetscTime(&start);
302: PetscMalloc1(petsc_maxActions*2, &tmpAction);
303: PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
304: PetscFree(petsc_actions);
306: petsc_actions = tmpAction;
307: petsc_maxActions *= 2;
308: PetscTime(&end);
309: petsc_BaseTime += (end - start);
310: }
312: petsc_numObjects = obj->id;
313: /* Record the creation action */
314: if (petsc_logActions) {
315: PetscTime(&petsc_actions[petsc_numActions].time);
316: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
317: petsc_actions[petsc_numActions].action = CREATE;
318: petsc_actions[petsc_numActions].classid = obj->classid;
319: petsc_actions[petsc_numActions].id1 = petsc_numObjects;
320: petsc_actions[petsc_numActions].id2 = -1;
321: petsc_actions[petsc_numActions].id3 = -1;
322: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
324: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
325: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
326: petsc_numActions++;
327: }
328: /* Record the object */
329: if (petsc_logObjects) {
330: petsc_objects[petsc_numObjects].parent = -1;
331: petsc_objects[petsc_numObjects].obj = obj;
333: PetscMemzero(petsc_objects[petsc_numObjects].name, 64 * sizeof(char));
334: PetscMemzero(petsc_objects[petsc_numObjects].info, 64 * sizeof(char));
336: /* Dynamically enlarge logging structures */
337: if (petsc_numObjects >= petsc_maxObjects) {
338: PetscTime(&start);
339: PetscMalloc1(petsc_maxObjects*2, &tmpObjects);
340: PetscMemcpy(tmpObjects, petsc_objects, petsc_maxObjects * sizeof(Object));
341: PetscFree(petsc_objects);
343: petsc_objects = tmpObjects;
344: petsc_maxObjects *= 2;
345: PetscTime(&end);
346: petsc_BaseTime += (end - start);
347: }
348: }
349: return(0);
350: }
352: /* Default object destroy logger */
353: PetscErrorCode PetscLogObjDestroyDefault(PetscObject obj)
354: {
355: PetscStageLog stageLog;
356: PetscClassRegLog classRegLog;
357: PetscClassPerfLog classPerfLog;
358: Action *tmpAction;
359: PetscLogDouble start, end;
360: int oclass = 0;
361: int stage;
362: PetscErrorCode ierr;
365: /* Record stage info */
366: PetscLogGetStageLog(&stageLog);
367: PetscStageLogGetCurrent(stageLog, &stage);
368: if (stage != -1) {
369: /* That can happen if the log summary is output before some things are destroyed */
370: PetscStageLogGetClassRegLog(stageLog, &classRegLog);
371: PetscStageLogGetClassPerfLog(stageLog, stage, &classPerfLog);
372: PetscClassRegLogGetClass(classRegLog, obj->classid, &oclass);
373: classPerfLog->classInfo[oclass].destructions++;
374: classPerfLog->classInfo[oclass].mem += obj->mem;
375: }
376: /* Cannot Credit all ancestors with your memory because they may have already been destroyed*/
377: petsc_numObjectsDestroyed++;
378: /* Dynamically enlarge logging structures */
379: if (petsc_numActions >= petsc_maxActions) {
380: PetscTime(&start);
381: PetscMalloc1(petsc_maxActions*2, &tmpAction);
382: PetscMemcpy(tmpAction, petsc_actions, petsc_maxActions * sizeof(Action));
383: PetscFree(petsc_actions);
385: petsc_actions = tmpAction;
386: petsc_maxActions *= 2;
387: PetscTime(&end);
388: petsc_BaseTime += (end - start);
389: }
390: /* Record the destruction action */
391: if (petsc_logActions) {
392: PetscTime(&petsc_actions[petsc_numActions].time);
393: petsc_actions[petsc_numActions].time -= petsc_BaseTime;
394: petsc_actions[petsc_numActions].action = DESTROY;
395: petsc_actions[petsc_numActions].classid = obj->classid;
396: petsc_actions[petsc_numActions].id1 = obj->id;
397: petsc_actions[petsc_numActions].id2 = -1;
398: petsc_actions[petsc_numActions].id3 = -1;
399: petsc_actions[petsc_numActions].flops = petsc_TotalFlops;
401: PetscMallocGetCurrentUsage(&petsc_actions[petsc_numActions].mem);
402: PetscMallocGetMaximumUsage(&petsc_actions[petsc_numActions].maxmem);
403: petsc_numActions++;
404: }
405: if (petsc_logObjects) {
406: if (obj->name) {
407: PetscStrncpy(petsc_objects[obj->id].name, obj->name, 64);
408: }
409: petsc_objects[obj->id].obj = NULL;
410: petsc_objects[obj->id].mem = obj->mem;
411: }
412: return(0);
413: }