Actual source code: petsclog.h
1: /* $Id: petsclog.h,v 1.155 2001/09/06 14:51:20 bsmith Exp $ */
3: /*
4: Defines profile/logging in PETSc.
5: */
9: #include petsc.h
11: /*
12: Each PETSc object class has it's own cookie (internal integer in the
13: data structure used for error checking). These are all defined by an offset
14: from the lowest one, PETSC_COOKIE.
15: */
16: #define PETSC_COOKIE 1211211
17: extern int PETSC_LARGEST_COOKIE;
18: #define PETSC_EVENT 1311311
19: extern int PETSC_LARGEST_EVENT;
21: /* Events for the Petsc standard library */
22: extern int PETSC_Barrier;
24: /* Global flop counter */
25: extern PetscLogDouble _TotalFlops;
27: /* General logging of information; different from event logging */
28: EXTERN int PetscLogInfo(void*,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3);
29: EXTERN int PetscLogInfoDeactivateClass(int);
30: EXTERN int PetscLogInfoActivateClass(int);
31: extern PetscTruth PetscLogPrintInfo; /* if true, indicates PetscLogInfo() is turned on */
33: #if defined(PETSC_USE_LOG) /* --- Logging is turned on --------------------------------*/
35: /*
36: Flop counting: We count each arithmetic operation (e.g., addition, multiplication) separately.
38: For the complex numbers version, note that
39: 1 complex addition = 2 flops
40: 1 complex multiplication = 6 flops,
41: where we define 1 flop as that for a double precision scalar. We roughly approximate
42: flop counting for complex numbers by multiplying the total flops by 4; this corresponds
43: to the assumption that we're counting mostly additions and multiplications -- and
44: roughly the same number of each. More accurate counting could be done by distinguishing
45: among the various arithmetic operations.
46: */
48: #if defined(PETSC_USE_COMPLEX)
49: #define PetscLogFlops(n) (_TotalFlops += (4*n),0)
50: #else
51: #define PetscLogFlops(n) (_TotalFlops += (n),0)
52: #endif
54: #if defined (PETSC_HAVE_MPE)
55: #include "mpe.h"
56: EXTERN int PetscLogMPEBegin(void);
57: EXTERN int PetscLogMPEDump(const char[]);
58: extern PetscTruth UseMPE;
59: #define PETSC_LOG_EVENT_MPE_BEGIN(e)
60: if(UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active)
61: MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_begin,0,"");
63: #define PETSC_LOG_EVENT_MPE_END(e)
64: if(UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active)
65: MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_end,0,"");
67: #else
68: #define PETSC_LOG_EVENT_MPE_BEGIN(e)
69: #define PETSC_LOG_EVENT_MPE_END(e)
70: #endif
72: EXTERN int (*_PetscLogPLB)(int,int,PetscObject,PetscObject,PetscObject,PetscObject);
73: EXTERN int (*_PetscLogPLE)(int,int,PetscObject,PetscObject,PetscObject,PetscObject);
74: EXTERN int (*_PetscLogPHC)(PetscObject);
75: EXTERN int (*_PetscLogPHD)(PetscObject);
77: #define PetscLogObjectParent(p,c)
78: if (c) {
81: ((PetscObject)(c))->parent = (PetscObject)(p);
82: ((PetscObject)(c))->parentid = ((PetscObject)p)->id;
83: }
84: #define PetscLogObjectParents(p,n,d) {int _i; for (_i=0; _i<n; _i++) PetscLogObjectParent(p,(d)[_i]);}
85: #define PetscLogObjectCreate(h) {if (_PetscLogPHC) (*_PetscLogPHC)((PetscObject)h);}
86: #define PetscLogObjectDestroy(h) {if (_PetscLogPHD) (*_PetscLogPHD)((PetscObject)h);}
88: /* Initialization functions */
89: EXTERN int PetscLogBegin(void);
90: EXTERN int PetscLogAllBegin(void);
91: EXTERN int PetscLogTraceBegin(FILE *);
92: /* General functions */
93: EXTERN int PetscLogGetRGBColor(char **);
94: EXTERN int PetscLogDestroy(void);
95: EXTERN int PetscLogSet(int (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
96: int (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject));
97: EXTERN int PetscLogObjectState(PetscObject, const char[], ...) PETSC_PRINTF_FORMAT_CHECK(2,3);
98: /* Output functions */
99: EXTERN int PetscLogPrintSummary(MPI_Comm, const char[]);
100: EXTERN int PetscLogDump(const char[]);
101: /* Counter functions */
102: EXTERN int PetscGetFlops(PetscLogDouble *);
103: /* Stage functions */
104: EXTERN int PetscLogStageRegister(int *, const char[]);
105: EXTERN int PetscLogStagePush(int);
106: EXTERN int PetscLogStagePop(void);
107: EXTERN int PetscLogStageSetActive(int, PetscTruth);
108: EXTERN int PetscLogStageGetActive(int, PetscTruth *);
109: EXTERN int PetscLogStageSetVisible(int, PetscTruth);
110: EXTERN int PetscLogStageGetVisible(int, PetscTruth *);
111: EXTERN int PetscLogStageGetId(const char [], int *);
112: /* Event functions */
113: EXTERN int PetscLogEventRegister(int *, const char[], int);
114: EXTERN int PetscLogEventActivate(int);
115: EXTERN int PetscLogEventDeactivate(int);
116: EXTERN int PetscLogEventActivateClass(int);
117: EXTERN int PetscLogEventDeactivateClass(int);
118: /* Class functions */
119: EXTERN int PetscLogClassRegister(int *, const char []);
121: /* Global counters */
122: extern PetscLogDouble irecv_ct, isend_ct, recv_ct, send_ct;
123: extern PetscLogDouble irecv_len, isend_len, recv_len, send_len;
124: extern PetscLogDouble allreduce_ct;
125: extern PetscLogDouble wait_ct, wait_any_ct, wait_all_ct, sum_of_waits_ct;
126: extern int PETSC_DUMMY, PETSC_DUMMY_SIZE;
128: /* We must make these structures available if we are to access the event
129: activation flags in the PetscLogEventBegin/End() macros. If we forced a
130: function call each time, we could leave these structures in plog.h
131: */
132: /* Default log */
133: typedef struct _StageLog *StageLog;
134: extern StageLog _stageLog;
136: /* A simple stack (should replace) */
137: typedef struct _IntStack *IntStack;
139: /* The structures for logging performance */
140: typedef struct _EventPerfInfo {
141: int id; /* The integer identifying this section */
142: PetscTruth active; /* The flag to activate logging */
143: PetscTruth visible; /* The flag to print info in summary */
144: int depth; /* The nesting depth of the event call */
145: int count; /* The number of times this section was executed */
146: PetscLogDouble flops; /* The flops used in this section */
147: PetscLogDouble time; /* The time taken for this section */
148: PetscLogDouble numMessages; /* The number of messages in this section */
149: PetscLogDouble messageLength; /* The total message lengths in this section */
150: PetscLogDouble numReductions; /* The number of reductions in this section */
151: } EventPerfInfo;
153: typedef struct _ClassPerfInfo {
154: int id; /* The integer identifying this class */
155: int creations; /* The number of objects of this class created */
156: int destructions; /* The number of objects of this class destroyed */
157: PetscLogDouble mem; /* The total memory allocated by objects of this class */
158: PetscLogDouble descMem; /* The total memory allocated by descendents of these objects */
159: } ClassPerfInfo;
161: /* The structures for logging registration */
162: typedef struct _ClassRegInfo {
163: char *name; /* The class name */
164: int cookie; /* The integer identifying this class */
165: } ClassRegInfo;
167: typedef struct _EventRegInfo {
168: char *name; /* The name of this event */
169: int cookie; /* The class id for this event (should maybe give class ID instead) */
170: #if defined (PETSC_HAVE_MPE)
171: int mpe_id_begin; /* MPE IDs that define the event */
172: int mpe_id_end;
173: #endif
174: } EventRegInfo;
176: /* The structure for logging events */
177: typedef int PetscEvent;
179: typedef struct _EventRegLog *EventRegLog;
180: struct _EventRegLog {
181: int numEvents; /* The number of registered events */
182: int maxEvents; /* The maximum number of events */
183: EventRegInfo *eventInfo; /* The registration information for each event */
184: };
186: typedef struct _EventPerfLog *EventPerfLog;
187: struct _EventPerfLog {
188: int numEvents; /* The number of logging events */
189: int maxEvents; /* The maximum number of events */
190: EventPerfInfo *eventInfo; /* The performance information for each event */
191: };
193: /* The structure for logging class information */
194: typedef struct _ClassRegLog *ClassRegLog;
195: struct _ClassRegLog {
196: int numClasses; /* The number of classes registered */
197: int maxClasses; /* The maximum number of classes */
198: ClassRegInfo *classInfo; /* The structure for class information (cookies are monotonicly increasing) */
199: };
201: typedef struct _ClassPerfLog *ClassPerfLog;
202: struct _ClassPerfLog {
203: int numClasses; /* The number of logging classes */
204: int maxClasses; /* The maximum number of classes */
205: ClassPerfInfo *classInfo; /* The structure for class information (cookies are monotonicly increasing) */
206: };
208: /* The structures for logging in stages */
209: typedef struct _StageInfo {
210: char *name; /* The stage name */
211: PetscTruth used; /* The stage was pushed on this processor */
212: EventPerfInfo perfInfo; /* The stage performance information */
213: EventPerfLog eventLog; /* The event information for this stage */
214: ClassPerfLog classLog; /* The class information for this stage */
215: } StageInfo;
217: struct _StageLog {
218: /* Size information */
219: int numStages; /* The number of registered stages */
220: int maxStages; /* The maximum number of stages */
221: /* Runtime information */
222: IntStack stack; /* The stack for active stages */
223: int curStage; /* The current stage (only used in macros so we don't call StackTop) */
224: /* Stage specific information */
225: StageInfo *stageInfo; /* The information for each stage */
226: EventRegLog eventLog; /* The registered events */
227: ClassRegLog classLog; /* The registered classes */
228: };
230: #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0;
231: {
232: int _2_ierr;
233: if (_PetscLogPLB &&
234: _stageLog->stageInfo[_stageLog->curStage].perfInfo.active &&
235: _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {
236: _2_PetscLogEventBegin((e),o1,o2,o3,o4);CHKERRQ(_2_ierr);
237: _2_MPI_Barrier(cm);CHKERRQ(_2_ierr);
238: _2_PetscLogEventEnd((e),o1,o2,o3,o4);CHKERRQ(_2_ierr);
239: }
240: _2_PetscLogEventBegin((e)+1,o1,o2,o3,o4);CHKERRQ(_2_ierr);
241: }
243: #define PetscLogEventBegin(e,o1,o2,o3,o4) 0;
244: {
245: if (_PetscLogPLB &&
246: _stageLog->stageInfo[_stageLog->curStage].perfInfo.active &&
247: _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {
248: (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));
249: }
250: PETSC_LOG_EVENT_MPE_BEGIN(e);
251: }
253: #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4)
255: #define PetscLogEventEnd(e,o1,o2,o3,o4) 0;
256: {
257: if (_PetscLogPLE &&
258: _stageLog->stageInfo[_stageLog->curStage].perfInfo.active &&
259: _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {
260: (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));
261: }
262: PETSC_LOG_EVENT_MPE_END(e);
263: }
265: /*
266: This does not work for MPI-Uni because our src/mpiuni/mpi.h file
267: uses macros to defined the MPI operations.
269: It does not work correctly from HP-UX because it processes the
270: macros in a way that sometimes it double counts, hence
271: PETSC_HAVE_BROKEN_RECURSIVE_MACRO
273: It does not work with Windows NT because winmpich lacks MPI_Type_size()
274: */
275: #if !defined(_petsc_mpi_uni) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO) && !defined (PETSC_HAVE_MPI_MISSING_TYPESIZE)
276: /*
277: Logging of MPI activities
278: */
280: #define TypeSize(buff,count,type)
281: (
282: MPI_Type_size(type,&PETSC_DUMMY_SIZE),buff += ((PetscLogDouble) ((count)*PETSC_DUMMY_SIZE))
283: )
285: #define MPI_Irecv(buf,count, datatype,source,tag,comm,request)
286: (
287: PETSC_DUMMY = MPI_Irecv(buf,count, datatype,source,tag,comm,request),
288: irecv_ct++,TypeSize(irecv_len,count,datatype),PETSC_DUMMY
289: )
291: #define MPI_Isend(buf,count, datatype,dest,tag,comm,request)
292: (
293: PETSC_DUMMY = MPI_Isend(buf,count, datatype,dest,tag,comm,request),
294: isend_ct++, TypeSize(isend_len,count,datatype),PETSC_DUMMY
295: )
297: #define MPI_Startall_irecv(count,number,requests)
298: (
299: PETSC_DUMMY = MPI_Startall(number,requests),
300: irecv_ct += (PetscLogDouble)(number),irecv_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY
301: )
303: #define MPI_Startall_isend(count,number,requests)
304: (
305: PETSC_DUMMY = MPI_Startall(number,requests),
306: isend_ct += (PetscLogDouble)(number),isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY
307: )
309: #define MPI_Start_isend(count, requests)
310: (
311: PETSC_DUMMY = MPI_Start(requests),
312: isend_ct++,isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY
313: )
315: #define MPI_Recv(buf,count, datatype,source,tag,comm,status)
316: (
317: PETSC_DUMMY = MPI_Recv(buf,count, datatype,source,tag,comm,status),
318: recv_ct++,TypeSize(recv_len,count,datatype),PETSC_DUMMY
319: )
321: #define MPI_Send(buf,count, datatype,dest,tag,comm)
322: (
323: PETSC_DUMMY = MPI_Send(buf,count, datatype,dest,tag,comm),
324: send_ct++, TypeSize(send_len,count,datatype),PETSC_DUMMY
325: )
327: #define MPI_Wait(request,status)
328: (
329: wait_ct++,sum_of_waits_ct++,
330: MPI_Wait(request,status)
331: )
333: #define MPI_Waitany(a,b,c,d)
334: (
335: wait_any_ct++,sum_of_waits_ct++,
336: MPI_Waitany(a,b,c,d)
337: )
339: #define MPI_Waitall(count,array_of_requests,array_of_statuses)
340: (
341: wait_all_ct++,sum_of_waits_ct += (PetscLogDouble) (count),
342: MPI_Waitall(count,array_of_requests,array_of_statuses)
343: )
345: #define MPI_Allreduce(sendbuf, recvbuf,count,datatype,op,comm)
346: (
347: allreduce_ct++,MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm)
348: )
350: #else
352: #define MPI_Startall_irecv(count,number,requests)
353: (
354: MPI_Startall(number,requests)
355: )
357: #define MPI_Startall_isend(count,number,requests)
358: (
359: MPI_Startall(number,requests)
360: )
362: #define MPI_Start_isend(count, requests)
363: (
364: MPI_Start(requests)
365: )
367: #endif /* !_petsc_mpi_uni && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */
369: #else /* ---Logging is turned off --------------------------------------------*/
371: #define PetscLogFlops(n) 0
373: /*
374: With logging turned off, then MPE has to be turned off
375: */
376: #define PetscLogMPEBegin() 0
377: #define PetscLogMPEDump(a) 0
379: #define PetscLogEventActivate(a) 0
380: #define PetscLogEventDeactivate(a) 0
382: #define PetscLogEventActivateClass(a) 0
383: #define PetscLogEventDeactivateClass(a) 0
385: #define _PetscLogPLB 0
386: #define _PetscLogPLE 0
387: #define _PetscLogPHC 0
388: #define _PetscLogPHD 0
389: #define PetscGetFlops(a) (*(a) = 0.0,0)
390: #define PetscLogEventBegin(e,o1,o2,o3,o4) 0
391: #define PetscLogEventEnd(e,o1,o2,o3,o4) 0
392: #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0
393: #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) 0
394: #define PetscLogObjectParent(p,c)
395: #define PetscLogObjectParents(p,n,c)
396: #define PetscLogObjectCreate(h)
397: #define PetscLogObjectDestroy(h)
398: #define PetscLogObjectMemory(p,m)
399: #define PetscLogDestroy() 0
400: #define PetscLogStagePush(a) 0
401: #define PetscLogStagePop() 0
402: #define PetscLogStageRegister(a,b) 0
403: #define PetscLogStagePrint(a,flg) 0
404: #define PetscLogPrintSummary(comm,file) 0
405: #define PetscLogBegin() 0
406: #define PetscLogTraceBegin(file) 0
407: #define PetscLogSet(lb,le) 0
408: #define PetscLogAllBegin() 0
409: #define PetscLogDump(c) 0
410: #define PetscLogEventRegister(a,b,c) 0
411: EXTERN int PetscLogObjectState(PetscObject,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3);
413: /* If PETSC_USE_LOG is NOT defined, these still need to be! */
414: #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests)
415: #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests)
416: #define MPI_Start_isend(count,requests) MPI_Start(requests)
418: #endif /* PETSC_USE_LOG */
420: extern PetscTruth PetscPreLoadingUsed; /* true if we are or have done preloading */
421: extern PetscTruth PetscPreLoadingOn; /* true if we are currently in a preloading calculation */
423: #define PreLoadBegin(flag,name)
424: {
425: PetscTruth PreLoading = flag;
426: int PreLoadMax,PreLoadIt,_stageNum,_3_ierr;
427: _3_PetscOptionsGetLogical(PETSC_NULL,"-preload",&PreLoading,PETSC_NULL);CHKERRQ(_3_ierr);
428: PreLoadMax = (int)(PreLoading);
429: PetscPreLoadingUsed = PreLoading ? PETSC_TRUE : PetscPreLoadingUsed;
430: for (PreLoadIt=0; PreLoadIt<=PreLoadMax; PreLoadIt++) {
431: PetscPreLoadingOn = PreLoading;
432: _3_PetscBarrier(PETSC_NULL);CHKERRQ(_3_ierr);
433: if (PreLoadIt>0) {
434: _3_PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);
435: } else {
436: _3_PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);
437: }
438: _3_PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));
439: _3_PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
441: #define PreLoadEnd()
442: _3_PetscLogStagePop();CHKERRQ(_3_ierr);
443: PreLoading = PETSC_FALSE;
444: }
445: }
447: #define PreLoadStage(name)
448: _3_PetscLogStagePop();CHKERRQ(_3_ierr);
449: if (PreLoadIt>0) {
450: _3_PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);
451: } else {
452: _3_PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);
453: }
454: _3_PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));
455: _3_PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
456: #endif