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