xref: /petsc/include/petsclog.h (revision 0700a8246d308f50502909ba325e6169d3ee27eb)
1 /*
2     Defines profile/logging in PETSc.
3 */
4 
5 #if !defined(__PetscLog_H)
6 #define __PetscLog_H
7 #include "petscsys.h"
8 PETSC_EXTERN_CXX_BEGIN
9 
10 #define PETSC_EVENT  1311311
11 extern PetscLogEvent PETSC_LARGEST_EVENT;
12 
13 /* Global flop counter */
14 extern PetscLogDouble PETSC_DLLEXPORT _TotalFlops;
15 extern PetscLogDouble petsc_tmp_flops;
16 
17 /* General logging of information; different from event logging */
18 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscInfo_Private(const char[],void*,const char[],...) PETSC_PRINTF_FORMAT_CHECK(3,4);
19 #if defined(PETSC_USE_INFO)
20 #define PetscInfo(A,S)                       PetscInfo_Private(__FUNCT__,A,S)
21 #define PetscInfo1(A,S,a1)                   PetscInfo_Private(__FUNCT__,A,S,a1)
22 #define PetscInfo2(A,S,a1,a2)                PetscInfo_Private(__FUNCT__,A,S,a1,a2)
23 #define PetscInfo3(A,S,a1,a2,a3)             PetscInfo_Private(__FUNCT__,A,S,a1,a2,a3)
24 #define PetscInfo4(A,S,a1,a2,a3,a4)          PetscInfo_Private(__FUNCT__,A,S,a1,a2,a3,a4)
25 #define PetscInfo5(A,S,a1,a2,a3,a4,a5)       PetscInfo_Private(__FUNCT__,A,S,a1,a2,a3,a4,a5)
26 #define PetscInfo6(A,S,a1,a2,a3,a4,a5,a6)    PetscInfo_Private(__FUNCT__,A,S,a1,a2,a3,a4,a5,a6)
27 #define PetscInfo7(A,S,a1,a2,a3,a4,a5,a6,a7) PetscInfo_Private(__FUNCT__,A,S,a1,a2,a3,a4,a5,a6,a7)
28 #else
29 #define PetscInfo(A,S)                       0
30 #define PetscInfo1(A,S,a1)                   0
31 #define PetscInfo2(A,S,a1,a2)                0
32 #define PetscInfo3(A,S,a1,a2,a3)             0
33 #define PetscInfo4(A,S,a1,a2,a3,a4)          0
34 #define PetscInfo5(A,S,a1,a2,a3,a4,a5)       0
35 #define PetscInfo6(A,S,a1,a2,a3,a4,a5,a6)    0
36 #define PetscInfo7(A,S,a1,a2,a3,a4,a5,a6,a7) 0
37 #endif
38 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscInfoDeactivateClass(PetscClassId);
39 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscInfoActivateClass(PetscClassId);
40 extern PetscTruth     PETSC_DLLEXPORT PetscLogPrintInfo;  /* if true, indicates PetscInfo() is turned on */
41 
42 /* We must make these structures available if we are to access the event
43    activation flags in the PetscLogEventBegin/End() macros. If we forced a
44    function call each time, we could make these private.
45 */
46 
47 /* The class naming scheme procedes as follows:
48 
49    Event:
50      Events are a class which describes certain blocks of executable
51      code. The corresponding instantiations of events are Actions.
52 
53    Class:
54      Classes are the classes representing Petsc structures. The
55      corresponding instantiations are called Objects.
56 
57    StageLog:
58      This type holds information about stages of computation. These
59      are understood to be chunks encompassing several events, or
60      alternatively, as a covering (possibly nested) of the timeline.
61 
62    StageInfo:
63      The information about each stage. This log contains an
64      EventPerfLog and a ClassPerfLog.
65 
66    EventRegLog:
67      This type holds the information generated for each event as
68      it is registered. This information does not change and thus is
69      stored separately from performance information.
70 
71    EventPerfLog:
72      This type holds the performance information logged for each
73      event. Usually this information is logged for only one stage.
74 
75    ClassRegLog:
76      This type holds the information generated for each class as
77      it is registered. This information does not change and thus is
78      stored separately from performance information.
79 
80    ClassPerfLog:
81      This class holds information describing class/object usage during
82      a run. Usually this information is logged for only one stage.
83 */
84 
85 /* Default log */
86 typedef struct _n_StageLog *StageLog;
87 extern PETSC_DLLEXPORT StageLog _stageLog;
88 
89 /* A simple stack (should replace) */
90 typedef struct _n_IntStack *IntStack;
91 
92 /* The structures for logging performance */
93 typedef struct {
94   int            id;            /* The integer identifying this section */
95   PetscTruth     active;        /* The flag to activate logging */
96   PetscTruth     visible;       /* The flag to print info in summary */
97   int            depth;         /* The nesting depth of the event call */
98   int            count;         /* The number of times this section was executed */
99   PetscLogDouble flops;         /* The flops used in this section */
100   PetscLogDouble time;          /* The time taken for this section */
101   PetscLogDouble numMessages;   /* The number of messages in this section */
102   PetscLogDouble messageLength; /* The total message lengths in this section */
103   PetscLogDouble numReductions; /* The number of reductions in this section */
104 } EventPerfInfo;
105 
106 typedef struct {
107   PetscClassId   id;           /* The integer identifying this class */
108   int            creations;    /* The number of objects of this class created */
109   int            destructions; /* The number of objects of this class destroyed */
110   PetscLogDouble mem;          /* The total memory allocated by objects of this class */
111   PetscLogDouble descMem;      /* The total memory allocated by descendents of these objects */
112 } ClassPerfInfo;
113 
114 /* The structures for logging registration */
115 typedef struct  {
116   char         *name;   /* The class name */
117   PetscClassId classid; /* The integer identifying this class */
118 } ClassRegInfo;
119 
120 typedef struct {
121   char         *name;   /* The name of this event */
122   PetscClassId classid; /* The class id for this event (should maybe give class ID instead) */
123 #if defined (PETSC_HAVE_MPE)
124   int          mpe_id_begin; /* MPE IDs that define the event */
125   int          mpe_id_end;
126 #endif
127 } EventRegInfo;
128 
129 typedef struct _n_EventRegLog *EventRegLog;
130 struct _n_EventRegLog {
131   int           numEvents; /* The number of registered events */
132   int           maxEvents; /* The maximum number of events */
133   EventRegInfo *eventInfo; /* The registration information for each event */
134 };
135 
136 typedef struct _n_EventPerfLog *EventPerfLog;
137 struct _n_EventPerfLog {
138   int            numEvents; /* The number of logging events */
139   int            maxEvents; /* The maximum number of events */
140   EventPerfInfo *eventInfo; /* The performance information for each event */
141 };
142 
143 /* The structure for logging class information */
144 typedef struct _n_ClassRegLog *ClassRegLog;
145 struct _n_ClassRegLog {
146   int           numClasses; /* The number of classes registered */
147   int           maxClasses; /* The maximum number of classes */
148   ClassRegInfo *classInfo;  /* The structure for class information (classids are monotonicly increasing) */
149 };
150 
151 typedef struct _n_ClassPerfLog *ClassPerfLog;
152 struct _n_ClassPerfLog {
153   int            numClasses; /* The number of logging classes */
154   int            maxClasses; /* The maximum number of classes */
155   ClassPerfInfo *classInfo;  /* The structure for class information (classids are monotonicly increasing) */
156 };
157 
158 /* The structures for logging in stages */
159 typedef struct _StageInfo {
160   char         *name;     /* The stage name */
161   PetscTruth    used;     /* The stage was pushed on this processor */
162   EventPerfInfo perfInfo; /* The stage performance information */
163   EventPerfLog  eventLog; /* The event information for this stage */
164   ClassPerfLog  classLog; /* The class information for this stage */
165 } StageInfo;
166 
167 struct _n_StageLog {
168   /* Size information */
169   int         numStages; /* The number of registered stages */
170   int         maxStages; /* The maximum number of stages */
171   /* Runtime information */
172   IntStack    stack;     /* The stack for active stages */
173   int         curStage;  /* The current stage (only used in macros so we don't call StackTop) */
174   /* Stage specific information */
175   StageInfo  *stageInfo; /* The information for each stage */
176   EventRegLog eventLog;  /* The registered events */
177   ClassRegLog classLog;  /* The registered classes */
178 };
179 
180 #if defined(PETSC_USE_LOG)  /* --- Logging is turned on --------------------------------*/
181 
182 /*
183    Flop counting:  We count each arithmetic operation (e.g., addition, multiplication) separately.
184 
185    For the complex numbers version, note that
186        1 complex addition = 2 flops
187        1 complex multiplication = 6 flops,
188    where we define 1 flop as that for a double precision scalar.  We roughly approximate
189    flop counting for complex numbers by multiplying the total flops by 4; this corresponds
190    to the assumption that we're counting mostly additions and multiplications -- and
191    roughly the same number of each.  More accurate counting could be done by distinguishing
192    among the various arithmetic operations.
193  */
194 
195 #if defined(PETSC_USE_COMPLEX)
196 #define PETSC_FLOPS_PER_OP 4.0
197 #else
198 #define PETSC_FLOPS_PER_OP 1.0
199 #endif
200 
201 #if defined(PETSC_USE_DEBUG)
202 #define PetscLogFlops(n) (petsc_tmp_flops = (PETSC_FLOPS_PER_OP*((PetscLogDouble)n)), ((petsc_tmp_flops < 0) ? PETSC_ERR_FLOP_COUNT : (_TotalFlops += petsc_tmp_flops,0)))
203 #define PetscLogFlopsNoError(n) (_TotalFlops += PETSC_FLOPS_PER_OP*((PetscLogDouble)n))
204 #else
205 #define PetscLogFlops(n) (_TotalFlops += PETSC_FLOPS_PER_OP*((PetscLogDouble)n),0)
206 #define PetscLogFlopsNoError(n) (_TotalFlops += PETSC_FLOPS_PER_OP*((PetscLogDouble)n))
207 #endif
208 
209 #if defined (PETSC_HAVE_MPE)
210 #include "mpe.h"
211 EXTERN PetscErrorCode PETSC_DLLEXPORT        PetscLogMPEBegin(void);
212 EXTERN PetscErrorCode PETSC_DLLEXPORT        PetscLogMPEDump(const char[]);
213 extern PetscTruth UseMPE;
214 #define PETSC_LOG_EVENT_MPE_BEGIN(e) \
215   ((UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
216    MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_begin,0,NULL) : 0)
217 
218 #define PETSC_LOG_EVENT_MPE_END(e) \
219   ((UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
220    MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_end,0,NULL) : 0)
221 
222 #else
223 #define PETSC_LOG_EVENT_MPE_BEGIN(e) 0
224 #define PETSC_LOG_EVENT_MPE_END(e)   0
225 #endif
226 
227 EXTERN PETSC_DLLEXPORT PetscErrorCode (*_PetscLogPLB)(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
228 EXTERN PETSC_DLLEXPORT PetscErrorCode (*_PetscLogPLE)(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
229 EXTERN PETSC_DLLEXPORT PetscErrorCode (*_PetscLogPHC)(PetscObject);
230 EXTERN PETSC_DLLEXPORT PetscErrorCode (*_PetscLogPHD)(PetscObject);
231 
232 #define PetscLogObjectParent(p,c) \
233   ((c && p) ? ((PetscObject)(c))->parent = (PetscObject)(p),((PetscObject)(c))->parentid = ((PetscObject)p)->id : 0, 0)
234 
235 #define PetscLogObjectParents(p,n,d)  0;{int _i; for (_i=0; _i<n; _i++) {ierr = PetscLogObjectParent(p,(d)[_i]);CHKERRQ(ierr);}}
236 #define PetscLogObjectCreate(h)      ((_PetscLogPHC) ? (*_PetscLogPHC)((PetscObject)h) : 0)
237 #define PetscLogObjectDestroy(h)     ((_PetscLogPHD) ? (*_PetscLogPHD)((PetscObject)h) : 0)
238 #define PetscLogObjectMemory(p,m)    (((PetscObject)(p))->mem += (m),0)
239 /* Initialization functions */
240 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogBegin(void);
241 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogAllBegin(void);
242 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogTraceBegin(FILE *);
243 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogActions(PetscTruth);
244 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogObjects(PetscTruth);
245 /* General functions */
246 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogGetRGBColor(const char*[]);
247 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogDestroy(void);
248 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogSet(PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
249                    PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject));
250 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogObjectState(PetscObject, const char[], ...)  PETSC_PRINTF_FORMAT_CHECK(2,3);
251 /* Output functions */
252 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogPrintSummary(MPI_Comm, const char[]);
253 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogPrintDetailed(MPI_Comm, const char[]);
254 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogDump(const char[]);
255 /* Counter functions */
256 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscGetFlops(PetscLogDouble *);
257 /* Stage functions */
258 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStageRegister(const char[],PetscLogStage*);
259 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStagePush(PetscLogStage);
260 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStagePop(void);
261 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStageSetActive(PetscLogStage, PetscTruth);
262 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStageGetActive(PetscLogStage, PetscTruth *);
263 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStageSetVisible(PetscLogStage, PetscTruth);
264 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStageGetVisible(PetscLogStage, PetscTruth *);
265 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogStageGetId(const char [], PetscLogStage *);
266 /* Event functions */
267 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogEventRegister(const char[], PetscClassId,PetscLogEvent*);
268 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogEventActivate(PetscLogEvent);
269 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogEventDeactivate(PetscLogEvent);
270 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogEventSetActiveAll(PetscLogEvent, PetscTruth);
271 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogEventActivateClass(PetscClassId);
272 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogEventDeactivateClass(PetscClassId);
273 
274 
275 /* Global counters */
276 extern PETSC_DLLEXPORT PetscLogDouble irecv_ct;
277 extern PETSC_DLLEXPORT PetscLogDouble isend_ct;
278 extern PETSC_DLLEXPORT PetscLogDouble recv_ct;
279 extern PETSC_DLLEXPORT PetscLogDouble send_ct;
280 extern PETSC_DLLEXPORT PetscLogDouble irecv_len;
281 extern PETSC_DLLEXPORT PetscLogDouble isend_len;
282 extern PETSC_DLLEXPORT PetscLogDouble recv_len;
283 extern PETSC_DLLEXPORT PetscLogDouble send_len;
284 extern PETSC_DLLEXPORT PetscLogDouble allreduce_ct;
285 extern PETSC_DLLEXPORT PetscLogDouble gather_ct;
286 extern PETSC_DLLEXPORT PetscLogDouble scatter_ct;
287 extern PETSC_DLLEXPORT PetscLogDouble wait_ct;
288 extern PETSC_DLLEXPORT PetscLogDouble wait_any_ct;
289 extern PETSC_DLLEXPORT PetscLogDouble wait_all_ct;
290 extern PETSC_DLLEXPORT PetscLogDouble sum_of_waits_ct;
291 
292 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \
293   (((_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active &&  _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
294     (PetscLogEventBegin((e),o1,o2,o3,o4) || MPI_Barrier(cm) || PetscLogEventEnd((e),o1,o2,o3,o4)) : 0 ) || \
295    PetscLogEventBegin((e)+1,o1,o2,o3,o4))
296 
297 #define PetscLogEventBegin(e,o1,o2,o3,o4) \
298   (((_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
299     (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
300   PETSC_LOG_EVENT_MPE_BEGIN(e))
301 
302 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4)
303 
304 #define PetscLogEventEnd(e,o1,o2,o3,o4) \
305   (((_PetscLogPLE && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
306     (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
307   PETSC_LOG_EVENT_MPE_END(e))
308 
309 /* Creation and destruction functions */
310 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogCreate(StageLog *);
311 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogDestroy(StageLog);
312 /* Registration functions */
313 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogRegister(StageLog, const char [], int *);
314 /* Runtime functions */
315 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogGetStageLog(StageLog *);
316 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogPush(StageLog, int);
317 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogPop(StageLog);
318 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetCurrent(StageLog, int *);
319 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogSetActive(StageLog, int, PetscTruth);
320 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetActive(StageLog, int, PetscTruth *);
321 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogSetVisible(StageLog, int, PetscTruth);
322 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetVisible(StageLog, int, PetscTruth *);
323 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetStage(StageLog, const char [], int *);
324 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetClassRegLog(StageLog, ClassRegLog *);
325 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetEventRegLog(StageLog, EventRegLog *);
326 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetClassPerfLog(StageLog, int, ClassPerfLog *);
327 EXTERN PetscErrorCode PETSC_DLLEXPORT StageLogGetEventPerfLog(StageLog, int, EventPerfLog *);
328 
329 EXTERN PetscErrorCode PETSC_DLLEXPORT EventRegLogGetEvent(EventRegLog, const char [], PetscLogEvent *);
330 
331 EXTERN PetscErrorCode PetscLogEventGetFlops(PetscLogEvent, PetscLogDouble*);
332 EXTERN PetscErrorCode PetscLogEventZeroFlops(PetscLogEvent);
333 
334 /*
335      These are used internally in the PETSc routines to keep a count of MPI messages and
336    their sizes.
337 
338      This does not work for MPI-Uni because our include/mpiuni/mpi.h file
339    uses macros to defined the MPI operations.
340 
341      It does not work correctly from HP-UX because it processes the
342    macros in a way that sometimes it double counts, hence
343    PETSC_HAVE_BROKEN_RECURSIVE_MACRO
344 
345      It does not work with Windows because winmpich lacks MPI_Type_size()
346 */
347 #if !defined(__MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO) && !defined (PETSC_HAVE_MPI_MISSING_TYPESIZE)
348 /*
349    Logging of MPI activities
350 */
351 PETSC_STATIC_INLINE PetscErrorCode TypeSize(PetscLogDouble *buff,PetscMPIInt count,MPI_Datatype type)
352 {
353   PetscMPIInt mysize; return  (MPI_Type_size(type,&mysize) || ((*buff += (PetscLogDouble) (count*mysize)),0));
354 }
355 
356 #define MPI_Irecv(buf,count,datatype,source,tag,comm,request) \
357  ((irecv_ct++,0) || TypeSize(&irecv_len,count,datatype) || MPI_Irecv(buf,count,datatype,source,tag,comm,request))
358 
359 #define MPI_Isend(buf,count,datatype,dest,tag,comm,request) \
360  ((isend_ct++,0) || TypeSize(&isend_len,count,datatype) || MPI_Isend(buf,count,datatype,dest,tag,comm,request))
361 
362 #define MPI_Startall_irecv(count,number,requests) \
363  ((irecv_ct += (PetscLogDouble)(number),0) || TypeSize(&irecv_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
364 
365 #define MPI_Startall_isend(count,number,requests) \
366  ((isend_ct += (PetscLogDouble)(number),0) || TypeSize(&isend_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
367 
368 #define MPI_Start_isend(count,requests) \
369  ((isend_ct++,0) || TypeSize(&isend_len,count,MPIU_SCALAR) || MPI_Start(requests))
370 
371 #define MPI_Recv(buf,count,datatype,source,tag,comm,status) \
372  ((recv_ct++,0) || TypeSize(&recv_len,count,datatype) || MPI_Recv(buf,count,datatype,source,tag,comm,status))
373 
374 #define MPI_Send(buf,count,datatype,dest,tag,comm) \
375  ((send_ct++,0) || TypeSize(&send_len,count,datatype) || MPI_Send(buf,count,datatype,dest,tag,comm))
376 
377 #define MPI_Wait(request,status) \
378  ((wait_ct++,sum_of_waits_ct++,0) || MPI_Wait(request,status))
379 
380 #define MPI_Waitany(a,b,c,d) \
381  ((wait_any_ct++,sum_of_waits_ct++,0) || MPI_Waitany(a,b,c,d))
382 
383 #define MPI_Waitall(count,array_of_requests,array_of_statuses) \
384  ((wait_all_ct++,sum_of_waits_ct += (PetscLogDouble) (count),0) || MPI_Waitall(count,array_of_requests,array_of_statuses))
385 
386 #define MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm) \
387  ((allreduce_ct++,0) || MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm))
388 
389 #define MPI_Allgather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm) \
390  ((gather_ct++,0) || MPI_Allgather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm))
391 
392 #define MPI_Allgatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,comm) \
393  ((gather_ct++,0) || MPI_Allgatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,comm))
394 
395 #define MPI_Gather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm) \
396  ((gather_ct++,0) || TypeSize(&send_len,sendcount,sendtype) || MPI_Gather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm))
397 
398 #define MPI_Gatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,root,comm) \
399  ((gather_ct++,0) || TypeSize(&send_len,sendcount,sendtype) || MPI_Gatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,root,comm))
400 
401 #define MPI_Scatter(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm) \
402   ((scatter_ct++,0) || TypeSize(&recv_len,recvcount,recvtype) || MPI_Scatter(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm))
403 
404 #define MPI_Scatterv(sendbuf,sendcount,displs,sendtype,recvbuf,recvcount,recvtype,root,comm) \
405   ((scatter_ct++,0) || TypeSize(&recv_len,recvcount,recvtype) || MPI_Scatterv(sendbuf,sendcount,displs,sendtype,recvbuf,recvcount,recvtype,root,comm))
406 
407 #else
408 
409 #define MPI_Startall_irecv(count,number,requests) \
410  (MPI_Startall(number,requests))
411 
412 #define MPI_Startall_isend(count,number,requests) \
413  (MPI_Startall(number,requests))
414 
415 #define MPI_Start_isend(count,requests) \
416  (MPI_Start(requests))
417 
418 #endif /* !__MPIUNI_H && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */
419 
420 #else  /* ---Logging is turned off --------------------------------------------*/
421 
422 #define PetscLogFlops(n) 0
423 #define PetscLogFlopsNoError(n)
424 
425 /*
426      With logging turned off, then MPE has to be turned off
427 */
428 #define PetscLogMPEBegin()         0
429 #define PetscLogMPEDump(a)         0
430 
431 #define PetscLogEventActivate(a)   0
432 #define PetscLogEventDeactivate(a) 0
433 
434 #define PetscLogEventActivateClass(a)   0
435 #define PetscLogEventDeactivateClass(a) 0
436 #define PetscLogEventSetActiveAll(a,b)  0
437 
438 #define _PetscLogPLB                        0
439 #define _PetscLogPLE                        0
440 #define _PetscLogPHC                        0
441 #define _PetscLogPHD                        0
442 #define PetscGetFlops(a)                (*(a) = 0.0,0)
443 #define PetscLogEventBegin(e,o1,o2,o3,o4)   0
444 #define PetscLogEventEnd(e,o1,o2,o3,o4)     0
445 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0
446 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm)   0
447 #define PetscLogObjectParent(p,c)           0
448 #define PetscLogObjectParents(p,n,c)        0
449 #define PetscLogObjectCreate(h)             0
450 #define PetscLogObjectDestroy(h)            0
451 #define PetscLogObjectMemory(p,m)           0
452 #define PetscLogDestroy()                   0
453 #define PetscLogStagePush(a)                0
454 #define PetscLogStagePop()                  0
455 #define PetscLogStageRegister(a,b)          0
456 #define PetscLogStagePrint(a,flg)           0
457 #define PetscLogPrintSummary(comm,file)     0
458 #define PetscLogPrintDetailed(comm,file)    0
459 #define PetscLogBegin()                     0
460 #define PetscLogTraceBegin(file)            0
461 #define PetscLogSet(lb,le)                  0
462 #define PetscLogAllBegin()                  0
463 #define PetscLogDump(c)                     0
464 #define PetscLogEventRegister(a,b,c)        0
465 #define PetscLogObjects(a)                  0
466 #define PetscLogActions(a)                  0
467 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscLogObjectState(PetscObject,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3);
468 
469 /* If PETSC_USE_LOG is NOT defined, these still need to be! */
470 #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests)
471 #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests)
472 #define MPI_Start_isend(count,requests) MPI_Start(requests)
473 
474 /* Creation and destruction functions */
475 #define StageLogCreate(stageLog)                     0
476 #define StageLogDestroy(stageLog)                    0
477 /* Registration functions */
478 #define StageLogRegister(stageLog, name, stage)      0
479 /* Runtime functions */
480 #define PetscLogGetStageLog(stageLog)                0
481 #define StageLogPush(stageLog, stage)                0
482 #define StageLogPop(stageLog)                        0
483 #define StageLogGetCurrent(stageLog, stage)          0
484 #define StageLogSetActive(stageLog, stage, active)   0
485 #define StageLogGetActive(stageLog, stage, active)   0
486 #define StageLogSetVisible(stageLog, stage, visible) 0
487 #define StageLogGetVisible(stageLog, stage, visible) 0
488 #define StageLogGetStage(stageLog, name, stage)      0
489 #define PetscLogStageGetId(a,b)                      (*(b)=0,0)
490 #define PetscLogStageSetActive(a,b)                  0
491 #define PetscLogStageGetActive(a,b)                  0
492 #define PetscLogStageGetVisible(a,b)                 0
493 #define PetscLogStageSetVisible(a,b)                 0
494 
495 #endif   /* PETSC_USE_LOG */
496 
497 /* Special support for C++ */
498 #include "petsclog.hh"
499 
500 #define PreLoadBegin(flag,name) \
501 {\
502   PetscTruth     PreLoading = flag;\
503   int            PreLoadMax,PreLoadIt;\
504   PetscLogStage  _stageNum;\
505   PetscErrorCode _3_ierr;	\
506   _3_ierr = PetscOptionsGetTruth(PETSC_NULL,"-preload",&PreLoading,PETSC_NULL);CHKERRQ(_3_ierr);\
507   PreLoadMax = (int)(PreLoading);\
508   PetscPreLoadingUsed = PreLoading ? PETSC_TRUE : PetscPreLoadingUsed;\
509   for (PreLoadIt=0; PreLoadIt<=PreLoadMax; PreLoadIt++) {\
510     PetscPreLoadingOn = PreLoading;\
511     _3_ierr = PetscBarrier(PETSC_NULL);CHKERRQ(_3_ierr);\
512     if (PreLoadIt>0) {\
513       _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
514     } else {\
515       _3_ierr = PetscLogStageRegister(name,&_stageNum);CHKERRQ(_3_ierr); \
516     }\
517     _3_ierr = PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\
518     _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
519 
520 #define PreLoadEnd() \
521     _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\
522     PreLoading = PETSC_FALSE;\
523   }\
524 }
525 
526 #define PreLoadStage(name) \
527   _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\
528   if (PreLoadIt>0) {\
529     _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
530   } else {\
531     _3_ierr = PetscLogStageRegister(name,&_stageNum);CHKERRQ(_3_ierr);	\
532   }\
533   _3_ierr = PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\
534   _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
535 
536 PETSC_EXTERN_CXX_END
537 #endif
538