xref: /petsc/include/petsclog.h (revision bd975ad32acea07b91e379cff2cb675d0f3c7746)
1 /* $Id: petsclog.h,v 1.155 2001/09/06 14:51:20 bsmith Exp $ */
2 
3 /*
4     Defines profile/logging in PETSc.
5 */
6 
7 #if !defined(__PetscLog_H)
8 #define __PetscLog_H
9 #include "petsc.h"
10 
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;
20 
21 /* Events for the Petsc standard library */
22 extern int PETSC_Barrier;
23 
24 /* Global flop counter */
25 extern PetscLogDouble _TotalFlops;
26 
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 */
32 
33 #if defined(PETSC_USE_LOG)  /* --- Logging is turned on --------------------------------*/
34 
35 /*
36    Flop counting:  We count each arithmetic operation (e.g., addition, multiplication) separately.
37 
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  */
47 
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
53 
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,"");
62 
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,"");
66 
67 #else
68 #define PETSC_LOG_EVENT_MPE_BEGIN(e)
69 #define PETSC_LOG_EVENT_MPE_END(e)
70 #endif
71 
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);
76 
77 #define PetscLogObjectParent(p,c) \
78   if (c) {\
79     PetscValidHeader((PetscObject)(c));\
80     PetscValidHeader((PetscObject)(p));\
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);}
87 #define PetscLogObjectMemory(p,m)    {PetscValidHeader((PetscObject)p);((PetscObject)(p))->mem += (m);}
88 /* Initialization functions */
89 EXTERN int PetscLogBegin(void);
90 EXTERN int PetscLogAllBegin(void);
91 EXTERN int PetscLogTraceBegin(FILE *);
92 EXTERN int PetscLogActions(PetscTruth);
93 EXTERN int PetscLogObjects(PetscTruth);
94 /* General functions */
95 EXTERN int PetscLogGetRGBColor(char **);
96 EXTERN int PetscLogDestroy(void);
97 EXTERN int PetscLogSet(int (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
98                    int (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject));
99 EXTERN int PetscLogObjectState(PetscObject, const char[], ...)  PETSC_PRINTF_FORMAT_CHECK(2,3);
100 /* Output functions */
101 EXTERN int PetscLogPrintSummary(MPI_Comm, const char[]);
102 EXTERN int PetscLogDump(const char[]);
103 /* Counter functions */
104 EXTERN int PetscGetFlops(PetscLogDouble *);
105 /* Stage functions */
106 EXTERN int PetscLogStageRegister(int *, const char[]);
107 EXTERN int PetscLogStagePush(int);
108 EXTERN int PetscLogStagePop(void);
109 EXTERN int PetscLogStageSetActive(int, PetscTruth);
110 EXTERN int PetscLogStageGetActive(int, PetscTruth *);
111 EXTERN int PetscLogStageSetVisible(int, PetscTruth);
112 EXTERN int PetscLogStageGetVisible(int, PetscTruth *);
113 EXTERN int PetscLogStageGetId(const char [], int *);
114 /* Event functions */
115 EXTERN int PetscLogEventRegister(int *, const char[], int);
116 EXTERN int PetscLogEventActivate(int);
117 EXTERN int PetscLogEventDeactivate(int);
118 EXTERN int PetscLogEventActivateClass(int);
119 EXTERN int PetscLogEventDeactivateClass(int);
120 /* Class functions */
121 EXTERN int PetscLogClassRegister(int *, const char []);
122 
123 /* Global counters */
124 extern PetscLogDouble irecv_ct,  isend_ct,  recv_ct,  send_ct;
125 extern PetscLogDouble irecv_len, isend_len, recv_len, send_len;
126 extern PetscLogDouble allreduce_ct;
127 extern PetscLogDouble wait_ct, wait_any_ct, wait_all_ct, sum_of_waits_ct;
128 extern int            PETSC_DUMMY, PETSC_DUMMY_SIZE;
129 
130 /* We must make these structures available if we are to access the event
131    activation flags in the PetscLogEventBegin/End() macros. If we forced a
132    function call each time, we could leave these structures in plog.h
133 */
134 /* Default log */
135 typedef struct _StageLog *StageLog;
136 extern StageLog _stageLog;
137 
138 /* A simple stack (should replace) */
139 typedef struct _IntStack *IntStack;
140 
141 /* The structures for logging performance */
142 typedef struct _EventPerfInfo {
143   int            id;            /* The integer identifying this section */
144   PetscTruth     active;        /* The flag to activate logging */
145   PetscTruth     visible;       /* The flag to print info in summary */
146   int            depth;         /* The nesting depth of the event call */
147   int            count;         /* The number of times this section was executed */
148   PetscLogDouble flops;         /* The flops used in this section */
149   PetscLogDouble time;          /* The time taken for this section */
150   PetscLogDouble numMessages;   /* The number of messages in this section */
151   PetscLogDouble messageLength; /* The total message lengths in this section */
152   PetscLogDouble numReductions; /* The number of reductions in this section */
153 } EventPerfInfo;
154 
155 typedef struct _ClassPerfInfo {
156   int            id;           /* The integer identifying this class */
157   int            creations;    /* The number of objects of this class created */
158   int            destructions; /* The number of objects of this class destroyed */
159   PetscLogDouble mem;          /* The total memory allocated by objects of this class */
160   PetscLogDouble descMem;      /* The total memory allocated by descendents of these objects */
161 } ClassPerfInfo;
162 
163 /* The structures for logging registration */
164 typedef struct _ClassRegInfo {
165   char *name;   /* The class name */
166   int   cookie; /* The integer identifying this class */
167 } ClassRegInfo;
168 
169 typedef struct _EventRegInfo {
170   char *name;   /* The name of this event */
171   int   cookie; /* The class id for this event (should maybe give class ID instead) */
172 #if defined (PETSC_HAVE_MPE)
173   int   mpe_id_begin; /* MPE IDs that define the event */
174   int   mpe_id_end;
175 #endif
176 } EventRegInfo;
177 
178 /* The structure for logging events */
179 typedef int PetscEvent;
180 
181 typedef struct _EventRegLog *EventRegLog;
182 struct _EventRegLog {
183   int           numEvents; /* The number of registered events */
184   int           maxEvents; /* The maximum number of events */
185   EventRegInfo *eventInfo; /* The registration information for each event */
186 };
187 
188 typedef struct _EventPerfLog *EventPerfLog;
189 struct _EventPerfLog {
190   int            numEvents; /* The number of logging events */
191   int            maxEvents; /* The maximum number of events */
192   EventPerfInfo *eventInfo; /* The performance information for each event */
193 };
194 
195 /* The structure for logging class information */
196 typedef struct _ClassRegLog *ClassRegLog;
197 struct _ClassRegLog {
198   int           numClasses; /* The number of classes registered */
199   int           maxClasses; /* The maximum number of classes */
200   ClassRegInfo *classInfo;  /* The structure for class information (cookies are monotonicly increasing) */
201 };
202 
203 typedef struct _ClassPerfLog *ClassPerfLog;
204 struct _ClassPerfLog {
205   int            numClasses; /* The number of logging classes */
206   int            maxClasses; /* The maximum number of classes */
207   ClassPerfInfo *classInfo;  /* The structure for class information (cookies are monotonicly increasing) */
208 };
209 
210 /* The structures for logging in stages */
211 typedef struct _StageInfo {
212   char         *name;     /* The stage name */
213   PetscTruth    used;     /* The stage was pushed on this processor */
214   EventPerfInfo perfInfo; /* The stage performance information */
215   EventPerfLog  eventLog; /* The event information for this stage */
216   ClassPerfLog  classLog; /* The class information for this stage */
217 } StageInfo;
218 
219 struct _StageLog {
220   /* Size information */
221   int         numStages; /* The number of registered stages */
222   int         maxStages; /* The maximum number of stages */
223   /* Runtime information */
224   IntStack    stack;     /* The stack for active stages */
225   int         curStage;  /* The current stage (only used in macros so we don't call StackTop) */
226   /* Stage specific information */
227   StageInfo  *stageInfo; /* The information for each stage */
228   EventRegLog eventLog;  /* The registered events */
229   ClassRegLog classLog;  /* The registered classes */
230 };
231 
232 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0; \
233 {\
234   int _2_ierr;\
235   if (_PetscLogPLB && \
236       _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && \
237       _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {\
238     _2_ierr = PetscLogEventBegin((e),o1,o2,o3,o4);CHKERRQ(_2_ierr);\
239     _2_ierr = MPI_Barrier(cm);CHKERRQ(_2_ierr);\
240     _2_ierr = PetscLogEventEnd((e),o1,o2,o3,o4);CHKERRQ(_2_ierr);\
241   }\
242   _2_ierr = PetscLogEventBegin((e)+1,o1,o2,o3,o4);CHKERRQ(_2_ierr);\
243 }
244 
245 #define PetscLogEventBegin(e,o1,o2,o3,o4) 0; \
246 {\
247   if (_PetscLogPLB && \
248       _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && \
249       _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {\
250     (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));\
251   }\
252   PETSC_LOG_EVENT_MPE_BEGIN(e); \
253 }
254 
255 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4)
256 
257 #define PetscLogEventEnd(e,o1,o2,o3,o4) 0; \
258 {\
259   if (_PetscLogPLE && \
260       _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && \
261       _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {\
262     (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));\
263   }\
264   PETSC_LOG_EVENT_MPE_END(e); \
265 }
266 
267 /* Creation and destruction functions */
268 EXTERN int StageLogCreate(StageLog *);
269 EXTERN int StageLogDestroy(StageLog);
270 /* Registration functions */
271 EXTERN int StageLogRegister(StageLog, const char [], int *);
272 /* Runtime functions */
273 EXTERN int PetscLogGetStageLog(StageLog *);
274 EXTERN int StageLogPush(StageLog, int);
275 EXTERN int StageLogPop(StageLog);
276 EXTERN int StageLogGetCurrent(StageLog, int *);
277 EXTERN int StageLogSetActive(StageLog, int, PetscTruth);
278 EXTERN int StageLogGetActive(StageLog, int, PetscTruth *);
279 EXTERN int StageLogSetVisible(StageLog, int, PetscTruth);
280 EXTERN int StageLogGetVisible(StageLog, int, PetscTruth *);
281 EXTERN int StageLogGetStage(StageLog, const char [], int *);
282 
283 /*
284      This does not work for MPI-Uni because our src/mpiuni/mpi.h file
285    uses macros to defined the MPI operations.
286 
287      It does not work correctly from HP-UX because it processes the
288    macros in a way that sometimes it double counts, hence
289    PETSC_HAVE_BROKEN_RECURSIVE_MACRO
290 
291      It does not work with Windows NT because winmpich lacks MPI_Type_size()
292 */
293 #if !defined(_petsc_mpi_uni) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO) && !defined (PETSC_HAVE_MPI_MISSING_TYPESIZE)
294 /*
295    Logging of MPI activities
296 */
297 
298 #define TypeSize(buff,count,type) \
299 (\
300   MPI_Type_size(type,&PETSC_DUMMY_SIZE),buff += ((PetscLogDouble) ((count)*PETSC_DUMMY_SIZE))\
301 )
302 
303 #define MPI_Irecv(buf,count, datatype,source,tag,comm,request) \
304 (\
305   PETSC_DUMMY = MPI_Irecv(buf,count, datatype,source,tag,comm,request),\
306   irecv_ct++,TypeSize(irecv_len,count,datatype),PETSC_DUMMY\
307 )
308 
309 #define MPI_Isend(buf,count, datatype,dest,tag,comm,request) \
310 (\
311   PETSC_DUMMY = MPI_Isend(buf,count, datatype,dest,tag,comm,request),\
312   isend_ct++,  TypeSize(isend_len,count,datatype),PETSC_DUMMY\
313 )
314 
315 #define MPI_Startall_irecv(count,number,requests) \
316 (\
317   PETSC_DUMMY = MPI_Startall(number,requests),\
318   irecv_ct += (PetscLogDouble)(number),irecv_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY\
319 )
320 
321 #define MPI_Startall_isend(count,number,requests) \
322 (\
323   PETSC_DUMMY = MPI_Startall(number,requests),\
324   isend_ct += (PetscLogDouble)(number),isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY\
325 )
326 
327 #define MPI_Start_isend(count, requests) \
328 (\
329   PETSC_DUMMY = MPI_Start(requests),\
330   isend_ct++,isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY\
331 )
332 
333 #define MPI_Recv(buf,count, datatype,source,tag,comm,status) \
334 (\
335   PETSC_DUMMY = MPI_Recv(buf,count, datatype,source,tag,comm,status),\
336   recv_ct++,TypeSize(recv_len,count,datatype),PETSC_DUMMY\
337 )
338 
339 #define MPI_Send(buf,count, datatype,dest,tag,comm) \
340 (\
341   PETSC_DUMMY = MPI_Send(buf,count, datatype,dest,tag,comm),\
342   send_ct++, TypeSize(send_len,count,datatype),PETSC_DUMMY\
343 )
344 
345 #define MPI_Wait(request,status) \
346 (\
347   wait_ct++,sum_of_waits_ct++,\
348   MPI_Wait(request,status)\
349 )
350 
351 #define MPI_Waitany(a,b,c,d) \
352 (\
353   wait_any_ct++,sum_of_waits_ct++,\
354   MPI_Waitany(a,b,c,d)\
355 )
356 
357 #define MPI_Waitall(count,array_of_requests,array_of_statuses) \
358 (\
359   wait_all_ct++,sum_of_waits_ct += (PetscLogDouble) (count),\
360   MPI_Waitall(count,array_of_requests,array_of_statuses)\
361 )
362 
363 #define MPI_Allreduce(sendbuf, recvbuf,count,datatype,op,comm) \
364 (\
365   allreduce_ct++,MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm)\
366 )
367 
368 #else
369 
370 #define MPI_Startall_irecv(count,number,requests) \
371 (\
372   MPI_Startall(number,requests)\
373 )
374 
375 #define MPI_Startall_isend(count,number,requests) \
376 (\
377   MPI_Startall(number,requests)\
378 )
379 
380 #define MPI_Start_isend(count, requests) \
381 (\
382   MPI_Start(requests)\
383 )
384 
385 #endif /* !_petsc_mpi_uni && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */
386 
387 #else  /* ---Logging is turned off --------------------------------------------*/
388 
389 #define PetscLogFlops(n) 0
390 
391 /*
392      With logging turned off, then MPE has to be turned off
393 */
394 #define PetscLogMPEBegin()         0
395 #define PetscLogMPEDump(a)         0
396 
397 #define PetscLogEventActivate(a)   0
398 #define PetscLogEventDeactivate(a) 0
399 
400 #define PetscLogEventActivateClass(a)   0
401 #define PetscLogEventDeactivateClass(a) 0
402 
403 #define _PetscLogPLB                        0
404 #define _PetscLogPLE                        0
405 #define _PetscLogPHC                        0
406 #define _PetscLogPHD                        0
407 #define PetscGetFlops(a)                (*(a) = 0.0,0)
408 #define PetscLogEventBegin(e,o1,o2,o3,o4)   0
409 #define PetscLogEventEnd(e,o1,o2,o3,o4)     0
410 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0
411 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm)   0
412 #define PetscLogObjectParent(p,c)
413 #define PetscLogObjectParents(p,n,c)
414 #define PetscLogObjectCreate(h)
415 #define PetscLogObjectDestroy(h)
416 #define PetscLogObjectMemory(p,m)
417 #define PetscLogDestroy()                   0
418 #define PetscLogStagePush(a)                0
419 #define PetscLogStagePop()                  0
420 #define PetscLogStageRegister(a,b)          0
421 #define PetscLogStagePrint(a,flg)           0
422 #define PetscLogPrintSummary(comm,file)     0
423 #define PetscLogBegin()                     0
424 #define PetscLogTraceBegin(file)            0
425 #define PetscLogSet(lb,le)                  0
426 #define PetscLogAllBegin()                  0
427 #define PetscLogDump(c)                     0
428 #define PetscLogEventRegister(a,b,c)        0
429 EXTERN int PetscLogObjectState(PetscObject,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3);
430 
431 /* If PETSC_USE_LOG is NOT defined, these still need to be! */
432 #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests)
433 #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests)
434 #define MPI_Start_isend(count,requests) MPI_Start(requests)
435 
436 /* Creation and destruction functions */
437 #define StageLogCreate(stageLog)                     0
438 #define StageLogDestroy(stageLog)                    0
439 /* Registration functions */
440 #define StageLogRegister(stageLog, name, stage)      0
441 /* Runtime functions */
442 #define PetscLogGetStageLog(stageLog)                0
443 #define StageLogPush(stageLog, stage)                0
444 #define StageLogPop(stageLog)                        0
445 #define StageLogGetCurrent(stageLog, stage)          0
446 #define StageLogSetActive(stageLog, stage, active)   0
447 #define StageLogGetActive(stageLog, stage, active)   0
448 #define StageLogSetVisible(stageLog, stage, visible) 0
449 #define StageLogGetVisible(stageLog, stage, visible) 0
450 #define StageLogGetStage(stageLog, name, stage)      0
451 
452 #endif   /* PETSC_USE_LOG */
453 
454 extern PetscTruth PetscPreLoadingUsed;       /* true if we are or have done preloading */
455 extern PetscTruth PetscPreLoadingOn;         /* true if we are currently in a preloading calculation */
456 
457 #define PreLoadBegin(flag,name) \
458 {\
459   PetscTruth PreLoading = flag;\
460   int        PreLoadMax,PreLoadIt,_stageNum,_3_ierr;\
461   _3_ierr = PetscOptionsGetLogical(PETSC_NULL,"-preload",&PreLoading,PETSC_NULL);CHKERRQ(_3_ierr);\
462   PreLoadMax = (int)(PreLoading);\
463   PetscPreLoadingUsed = PreLoading ? PETSC_TRUE : PetscPreLoadingUsed;\
464   for (PreLoadIt=0; PreLoadIt<=PreLoadMax; PreLoadIt++) {\
465     PetscPreLoadingOn = PreLoading;\
466     _3_ierr = PetscBarrier(PETSC_NULL);CHKERRQ(_3_ierr);\
467     if (PreLoadIt>0) {\
468       _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
469     } else {\
470       _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\
471     }\
472     _3_ierr = PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\
473     _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
474 
475 #define PreLoadEnd() \
476     _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\
477     PreLoading = PETSC_FALSE;\
478   }\
479 }
480 
481 #define PreLoadStage(name) \
482   _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\
483   if (PreLoadIt>0) {\
484     _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
485   } else {\
486     _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\
487   }\
488   _3_ierr = PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\
489   _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
490 #endif
491