xref: /petsc/include/petsclog.h (revision 8cc058d9cd56c1ccb3be12a47760ddfc446aaffc)
1 /*
2     Defines profile/logging in PETSc.
3 */
4 
5 #if !defined(__PetscLog_H)
6 #define __PetscLog_H
7 #include "petscsys.h"
8 
9 /*MC
10     PetscLogEvent - id used to identify PETSc or user events which timed portions (blocks of executable)
11      code.
12 
13     Level: intermediate
14 
15 .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStage
16 M*/
17 typedef int PetscLogEvent;
18 
19 /*MC
20     PetscLogStage - id used to identify user stages (phases, sections) of runs - for logging
21 
22     Level: intermediate
23 
24 .seealso: PetscLogStageRegister(), PetscLogStageBegin(), PetscLogStageEnd(), PetscLogEvent
25 M*/
26 typedef int PetscLogStage;
27 
28 #define PETSC_EVENT  1311311
29 PETSC_EXTERN PetscLogEvent PETSC_LARGEST_EVENT;
30 
31 /* Global flop counter */
32 PETSC_EXTERN PetscLogDouble petsc_TotalFlops;
33 PETSC_EXTERN PetscLogDouble petsc_tmp_flops;
34 
35 /* General logging of information; different from event logging */
36 PETSC_EXTERN PetscErrorCode PetscInfo_Private(const char[],void*,const char[],...);
37 #if defined(PETSC_USE_INFO)
38 #define PetscInfo(A,S)                       PetscInfo_Private(PETSC_FUNCTION_NAME,A,S)
39 #define PetscInfo1(A,S,a1)                   PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1)
40 #define PetscInfo2(A,S,a1,a2)                PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2)
41 #define PetscInfo3(A,S,a1,a2,a3)             PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3)
42 #define PetscInfo4(A,S,a1,a2,a3,a4)          PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3,a4)
43 #define PetscInfo5(A,S,a1,a2,a3,a4,a5)       PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3,a4,a5)
44 #define PetscInfo6(A,S,a1,a2,a3,a4,a5,a6)    PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3,a4,a5,a6)
45 #define PetscInfo7(A,S,a1,a2,a3,a4,a5,a6,a7) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3,a4,a5,a6,a7)
46 #else
47 #define PetscInfo(A,S)                       0
48 #define PetscInfo1(A,S,a1)                   0
49 #define PetscInfo2(A,S,a1,a2)                0
50 #define PetscInfo3(A,S,a1,a2,a3)             0
51 #define PetscInfo4(A,S,a1,a2,a3,a4)          0
52 #define PetscInfo5(A,S,a1,a2,a3,a4,a5)       0
53 #define PetscInfo6(A,S,a1,a2,a3,a4,a5,a6)    0
54 #define PetscInfo7(A,S,a1,a2,a3,a4,a5,a6,a7) 0
55 #endif
56 PETSC_EXTERN PetscErrorCode PetscInfoDeactivateClass(PetscClassId);
57 PETSC_EXTERN PetscErrorCode PetscInfoActivateClass(PetscClassId);
58 PETSC_EXTERN PetscBool PetscLogPrintInfo;  /* if true, indicates PetscInfo() is turned on */
59 
60 /* We must make the following structures available to access the event
61      activation flags in the PetscLogEventBegin/End() macros. These are not part of the PETSc public
62      API and are not intended to be used by other parts of PETSc or by users.
63 
64      The code that manipulates these structures is in src/sys/plog/utils.
65 */
66 typedef struct _n_PetscIntStack *PetscIntStack;
67 
68 /*
69     PetscClassRegInfo, PetscClassPerfInfo - Each class has two data structures associated with it. The first has
70        static information about it, the second collects statistics on how many objects of the class are created,
71        how much memory they use, etc.
72 
73     PetscClassRegLog, PetscClassPerfLog - arrays of the PetscClassRegInfo and PetscClassPerfInfo for all classes.
74 */
75 typedef struct  {
76   char           *name;   /* The class name */
77   PetscClassId   classid; /* The integer identifying this class */
78 } PetscClassRegInfo;
79 
80 typedef struct {
81   PetscClassId   id;           /* The integer identifying this class */
82   int            creations;    /* The number of objects of this class created */
83   int            destructions; /* The number of objects of this class destroyed */
84   PetscLogDouble mem;          /* The total memory allocated by objects of this class */
85   PetscLogDouble descMem;      /* The total memory allocated by descendents of these objects */
86 } PetscClassPerfInfo;
87 
88 typedef struct _n_PetscClassRegLog *PetscClassRegLog;
89 struct _n_PetscClassRegLog {
90   int               numClasses; /* The number of classes registered */
91   int               maxClasses; /* The maximum number of classes */
92   PetscClassRegInfo *classInfo; /* The structure for class information (classids are monotonicly increasing) */
93 };
94 
95 typedef struct _n_PetscClassPerfLog *PetscClassPerfLog;
96 struct _n_PetscClassPerfLog {
97   int                numClasses; /* The number of logging classes */
98   int                maxClasses; /* The maximum number of classes */
99   PetscClassPerfInfo *classInfo; /* The structure for class information (classids are monotonicly increasing) */
100 };
101 /* -----------------------------------------------------------------------------------------------------*/
102 /*
103     PetscEventRegInfo, PetscEventPerfInfo - Each event has two data structures associated with it. The first has
104        static information about it, the second collects statistics on how many times the event is used, how
105        much time it takes, etc.
106 
107     PetscEventRegLog, PetscEventPerfLog - an array of all PetscEventRegInfo and PetscEventPerfInfo for all events. There is one
108       of these for each stage.
109 
110 */
111 typedef struct {
112   char         *name;         /* The name of this event */
113   PetscClassId classid;       /* The class the event is associated with */
114 #if defined (PETSC_HAVE_MPE)
115   int          mpe_id_begin; /* MPE IDs that define the event */
116   int          mpe_id_end;
117 #endif
118 } PetscEventRegInfo;
119 
120 typedef struct {
121   int            id;            /* The integer identifying this event */
122   PetscBool      active;        /* The flag to activate logging */
123   PetscBool      visible;       /* The flag to print info in summary */
124   int            depth;         /* The nesting depth of the event call */
125   int            count;         /* The number of times this event was executed */
126   PetscLogDouble flops, flops2,flopsTmp; /* The flops and flops^2 used in this event */
127   PetscLogDouble time, time2, timeTmp;   /* The time and time^2 taken for this event */
128   PetscLogDouble numMessages;   /* The number of messages in this event */
129   PetscLogDouble messageLength; /* The total message lengths in this event */
130   PetscLogDouble numReductions; /* The number of reductions in this event */
131 } PetscEventPerfInfo;
132 
133 typedef struct _n_PetscEventRegLog *PetscEventRegLog;
134 struct _n_PetscEventRegLog {
135   int               numEvents;  /* The number of registered events */
136   int               maxEvents;  /* The maximum number of events */
137   PetscEventRegInfo *eventInfo; /* The registration information for each event */
138 };
139 
140 typedef struct _n_PetscEventPerfLog *PetscEventPerfLog;
141 struct _n_PetscEventPerfLog {
142   int                numEvents;  /* The number of logging events */
143   int                maxEvents;  /* The maximum number of events */
144   PetscEventPerfInfo *eventInfo; /* The performance information for each event */
145 };
146 /* ------------------------------------------------------------------------------------------------------------*/
147 /*
148    PetscStageInfo - Contains all the information about a particular stage.
149 
150    PetscStageLog - An array of PetscStageInfo for each registered stage. There is a single one of these in the code.
151 */
152 typedef struct _PetscStageInfo {
153   char               *name;     /* The stage name */
154   PetscBool          used;      /* The stage was pushed on this processor */
155   PetscEventPerfInfo perfInfo;  /* The stage performance information */
156   PetscEventPerfLog  eventLog;  /* The event information for this stage */
157   PetscClassPerfLog  classLog;  /* The class information for this stage */
158 } PetscStageInfo;
159 
160 typedef struct _n_PetscStageLog *PetscStageLog;
161 PETSC_EXTERN PetscStageLog petsc_stageLog;
162 struct _n_PetscStageLog {
163   int              numStages;   /* The number of registered stages */
164   int              maxStages;   /* The maximum number of stages */
165   PetscIntStack    stack;       /* The stack for active stages */
166   int              curStage;    /* The current stage (only used in macros so we don't call PetscIntStackTop) */
167   PetscStageInfo   *stageInfo;  /* The information for each stage */
168   PetscEventRegLog eventLog;    /* The registered events */
169   PetscClassRegLog classLog;    /* The registered classes */
170 };
171 
172 PETSC_EXTERN PetscErrorCode PetscLogGetStageLog(PetscStageLog*);
173 PETSC_EXTERN PetscErrorCode PetscStageLogGetCurrent(PetscStageLog,int*);
174 PETSC_EXTERN PetscErrorCode PetscStageLogGetEventPerfLog(PetscStageLog,int,PetscEventPerfLog*);
175 
176 
177 #if defined(PETSC_USE_LOG)  /* --- Logging is turned on --------------------------------*/
178 
179 /*
180    Flop counting:  We count each arithmetic operation (e.g., addition, multiplication) separately.
181 
182    For the complex numbers version, note that
183        1 complex addition = 2 flops
184        1 complex multiplication = 6 flops,
185    where we define 1 flop as that for a double precision scalar.  We roughly approximate
186    flop counting for complex numbers by multiplying the total flops by 4; this corresponds
187    to the assumption that we're counting mostly additions and multiplications -- and
188    roughly the same number of each.  More accurate counting could be done by distinguishing
189    among the various arithmetic operations.
190  */
191 
192 #if defined(PETSC_USE_COMPLEX)
193 #define PETSC_FLOPS_PER_OP 4.0
194 #else
195 #define PETSC_FLOPS_PER_OP 1.0
196 #endif
197 
198 #undef __FUNCT__
199 #define __FUNCT__ "PetscLogFlops"
200 PETSC_STATIC_INLINE PetscErrorCode PetscLogFlops(PetscLogDouble n)
201 {
202   PetscFunctionBegin;
203 #if defined(PETSC_USE_DEBUG)
204   if (n < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Cannot log negative flops");
205 #endif
206   petsc_TotalFlops += PETSC_FLOPS_PER_OP*n;
207   PetscFunctionReturn(0);
208 }
209 
210 #if defined (PETSC_HAVE_MPE)
211 #include "mpe.h"
212 PETSC_EXTERN PetscErrorCode PetscLogMPEBegin(void);
213 PETSC_EXTERN PetscErrorCode PetscLogMPEDump(const char[]);
214 PETSC_EXTERN PetscBool UseMPE;
215 #define PETSC_LOG_EVENT_MPE_BEGIN(e) \
216   ((UseMPE && petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? \
217    MPE_Log_event(petsc_stageLog->eventLog->eventInfo[e].mpe_id_begin,0,NULL) : 0)
218 
219 #define PETSC_LOG_EVENT_MPE_END(e) \
220   ((UseMPE && petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? \
221    MPE_Log_event(petsc_stageLog->eventLog->eventInfo[e].mpe_id_end,0,NULL) : 0)
222 
223 #else
224 #define PETSC_LOG_EVENT_MPE_BEGIN(e) 0
225 #define PETSC_LOG_EVENT_MPE_END(e)   0
226 #endif
227 
228 PETSC_EXTERN PetscErrorCode (*PetscLogPLB)(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
229 PETSC_EXTERN PetscErrorCode (*PetscLogPLE)(PetscLogEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
230 PETSC_EXTERN PetscErrorCode (*PetscLogPHC)(PetscObject);
231 PETSC_EXTERN PetscErrorCode (*PetscLogPHD)(PetscObject);
232 
233 #define PetscLogObjectParent(p,c) \
234   (c && p && (((PetscObject)(c))->parent = (PetscObject)(p),((PetscObject)(c))->parentid = ((PetscObject)p)->id,0))
235 
236 #define PetscLogObjectParents(p,n,d)  0;{int _i; for (_i=0; _i<n; _i++) {ierr = PetscLogObjectParent(p,(d)[_i]);CHKERRQ(ierr);}}
237 #define PetscLogObjectCreate(h)      ((PetscLogPHC) ? (*PetscLogPHC)((PetscObject)h) : 0)
238 #define PetscLogObjectDestroy(h)     ((PetscLogPHD) ? (*PetscLogPHD)((PetscObject)h) : 0)
239 #define PetscLogObjectMemory(p,m)    (((PetscObject)(p))->mem += (m),0)
240 /* Initialization functions */
241 PETSC_EXTERN PetscErrorCode PetscLogBegin(void);
242 PETSC_EXTERN PetscErrorCode PetscLogAllBegin(void);
243 PETSC_EXTERN PetscErrorCode PetscLogTraceBegin(FILE *);
244 PETSC_EXTERN PetscErrorCode PetscLogActions(PetscBool);
245 PETSC_EXTERN PetscErrorCode PetscLogObjects(PetscBool);
246 /* General functions */
247 PETSC_EXTERN PetscErrorCode PetscLogGetRGBColor(const char*[]);
248 PETSC_EXTERN PetscErrorCode PetscLogDestroy(void);
249 PETSC_EXTERN PetscErrorCode PetscLogSet(PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
250                                    PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject));
251 PETSC_EXTERN PetscErrorCode PetscLogObjectState(PetscObject, const char[], ...);
252 /* Output functions */
253 PETSC_EXTERN PetscErrorCode PetscLogView(PetscViewer);
254 PETSC_EXTERN PetscErrorCode PetscLogViewPython(PetscViewer);
255 PETSC_EXTERN PetscErrorCode PetscLogPrintDetailed(MPI_Comm, const char[]);
256 PETSC_EXTERN PetscErrorCode PetscLogDump(const char[]);
257 
258 PETSC_EXTERN PetscErrorCode PetscGetFlops(PetscLogDouble *);
259 
260 PETSC_EXTERN PetscErrorCode PetscLogStageRegister(const char[],PetscLogStage*);
261 PETSC_EXTERN PetscErrorCode PetscLogStagePush(PetscLogStage);
262 PETSC_EXTERN PetscErrorCode PetscLogStagePop(void);
263 PETSC_EXTERN PetscErrorCode PetscLogStageSetActive(PetscLogStage, PetscBool );
264 PETSC_EXTERN PetscErrorCode PetscLogStageGetActive(PetscLogStage, PetscBool  *);
265 PETSC_EXTERN PetscErrorCode PetscLogStageSetVisible(PetscLogStage, PetscBool );
266 PETSC_EXTERN PetscErrorCode PetscLogStageGetVisible(PetscLogStage, PetscBool  *);
267 PETSC_EXTERN PetscErrorCode PetscLogStageGetId(const char [], PetscLogStage *);
268 /* Event functions */
269 PETSC_EXTERN PetscErrorCode PetscLogEventRegister(const char[], PetscClassId,PetscLogEvent*);
270 PETSC_EXTERN PetscErrorCode PetscLogEventActivate(PetscLogEvent);
271 PETSC_EXTERN PetscErrorCode PetscLogEventDeactivate(PetscLogEvent);
272 PETSC_EXTERN PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent, PetscBool );
273 PETSC_EXTERN PetscErrorCode PetscLogEventActivateClass(PetscClassId);
274 PETSC_EXTERN PetscErrorCode PetscLogEventDeactivateClass(PetscClassId);
275 
276 
277 /* Global counters */
278 PETSC_EXTERN PetscLogDouble petsc_irecv_ct;
279 PETSC_EXTERN PetscLogDouble petsc_isend_ct;
280 PETSC_EXTERN PetscLogDouble petsc_recv_ct;
281 PETSC_EXTERN PetscLogDouble petsc_send_ct;
282 PETSC_EXTERN PetscLogDouble petsc_irecv_len;
283 PETSC_EXTERN PetscLogDouble petsc_isend_len;
284 PETSC_EXTERN PetscLogDouble petsc_recv_len;
285 PETSC_EXTERN PetscLogDouble petsc_send_len;
286 PETSC_EXTERN PetscLogDouble petsc_allreduce_ct;
287 PETSC_EXTERN PetscLogDouble petsc_gather_ct;
288 PETSC_EXTERN PetscLogDouble petsc_scatter_ct;
289 PETSC_EXTERN PetscLogDouble petsc_wait_ct;
290 PETSC_EXTERN PetscLogDouble petsc_wait_any_ct;
291 PETSC_EXTERN PetscLogDouble petsc_wait_all_ct;
292 PETSC_EXTERN PetscLogDouble petsc_sum_of_waits_ct;
293 
294 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \
295   (((PetscLogPLB && petsc_stageLog->stageInfo[petsc_stageLog->curStage].perfInfo.active &&  petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? \
296     (PetscLogEventBegin((e),o1,o2,o3,o4) || MPI_Barrier(cm) || PetscLogEventEnd((e),o1,o2,o3,o4)) : 0 ) || \
297    PetscLogEventBegin((e)+1,o1,o2,o3,o4))
298 
299 #define PetscLogEventBegin(e,o1,o2,o3,o4) \
300   (((PetscLogPLB && petsc_stageLog->stageInfo[petsc_stageLog->curStage].perfInfo.active && petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? \
301     (*PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
302   PETSC_LOG_EVENT_MPE_BEGIN(e))
303 
304 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4)
305 
306 #define PetscLogEventEnd(e,o1,o2,o3,o4) \
307   (((PetscLogPLE && petsc_stageLog->stageInfo[petsc_stageLog->curStage].perfInfo.active && petsc_stageLog->stageInfo[petsc_stageLog->curStage].eventLog->eventInfo[e].active) ? \
308     (*PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
309   PETSC_LOG_EVENT_MPE_END(e))
310 
311 PETSC_EXTERN PetscErrorCode PetscLogEventGetFlops(PetscLogEvent, PetscLogDouble*);
312 PETSC_EXTERN PetscErrorCode PetscLogEventZeroFlops(PetscLogEvent);
313 
314 /*
315      These are used internally in the PETSc routines to keep a count of MPI messages and
316    their sizes.
317 
318      This does not work for MPI-Uni because our include/mpiuni/mpi.h file
319    uses macros to defined the MPI operations.
320 
321      It does not work correctly from HP-UX because it processes the
322    macros in a way that sometimes it double counts, hence
323    PETSC_HAVE_BROKEN_RECURSIVE_MACRO
324 
325      It does not work with Windows because winmpich lacks MPI_Type_size()
326 */
327 #if !defined(__MPIUNI_H) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO) && !defined (PETSC_HAVE_MPI_MISSING_TYPESIZE)
328 /*
329    Logging of MPI activities
330 */
331 PETSC_STATIC_INLINE PetscErrorCode PetscMPITypeSize(PetscLogDouble *buff,PetscMPIInt count,MPI_Datatype type)
332 {
333   PetscMPIInt mysize; return  (MPI_Type_size(type,&mysize) || ((*buff += (PetscLogDouble) (count*mysize)),0));
334 }
335 
336 PETSC_STATIC_INLINE PetscErrorCode PetscMPITypeSizeComm(MPI_Comm comm, PetscLogDouble *buff,PetscMPIInt *counts,MPI_Datatype type)
337 {
338   PetscMPIInt mysize, commsize, p;
339   PetscErrorCode _myierr;
340 
341   _myierr = MPI_Comm_size(comm,&commsize);CHKERRQ(_myierr);
342   _myierr = MPI_Type_size(type,&mysize);CHKERRQ(_myierr);
343   for (p = 0; p < commsize; ++p) {
344     *buff += (PetscLogDouble) (counts[p]*mysize);
345   }
346   return 0;
347 }
348 
349 #define MPI_Irecv(buf,count,datatype,source,tag,comm,request) \
350  ((petsc_irecv_ct++,0) || PetscMPITypeSize(&petsc_irecv_len,count,datatype) || MPI_Irecv(buf,count,datatype,source,tag,comm,request))
351 
352 #define MPI_Isend(buf,count,datatype,dest,tag,comm,request) \
353  ((petsc_isend_ct++,0) || PetscMPITypeSize(&petsc_isend_len,count,datatype) || MPI_Isend(buf,count,datatype,dest,tag,comm,request))
354 
355 #define MPI_Startall_irecv(count,number,requests) \
356  ((petsc_irecv_ct += (PetscLogDouble)(number),0) || PetscMPITypeSize(&petsc_irecv_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
357 
358 #define MPI_Startall_isend(count,number,requests) \
359  ((petsc_isend_ct += (PetscLogDouble)(number),0) || PetscMPITypeSize(&petsc_isend_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
360 
361 #define MPI_Start_isend(count,requests) \
362  ((petsc_isend_ct++,0) || PetscMPITypeSize(&petsc_isend_len,count,MPIU_SCALAR) || MPI_Start(requests))
363 
364 #define MPI_Recv(buf,count,datatype,source,tag,comm,status) \
365  ((petsc_recv_ct++,0) || PetscMPITypeSize(&petsc_recv_len,count,datatype) || MPI_Recv(buf,count,datatype,source,tag,comm,status))
366 
367 #define MPI_Send(buf,count,datatype,dest,tag,comm) \
368  ((petsc_send_ct++,0) || PetscMPITypeSize(&petsc_send_len,count,datatype) || MPI_Send(buf,count,datatype,dest,tag,comm))
369 
370 #define MPI_Wait(request,status) \
371  ((petsc_wait_ct++,petsc_sum_of_waits_ct++,0) || MPI_Wait(request,status))
372 
373 #define MPI_Waitany(a,b,c,d) \
374  ((petsc_wait_any_ct++,petsc_sum_of_waits_ct++,0) || MPI_Waitany(a,b,c,d))
375 
376 #define MPI_Waitall(count,array_of_requests,array_of_statuses) \
377  ((petsc_wait_all_ct++,petsc_sum_of_waits_ct += (PetscLogDouble) (count),0) || MPI_Waitall(count,array_of_requests,array_of_statuses))
378 
379 #define MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm) \
380  ((petsc_allreduce_ct++,0) || MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm))
381 
382 #define MPI_Alltoall(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm) \
383  ((petsc_allreduce_ct++,0) || PetscMPITypeSize(&petsc_send_len,sendcount,sendtype) || MPI_Alltoall(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm))
384 
385 #define MPI_Alltoallv(sendbuf,sendcnts,sdispls,sendtype,recvbuf,recvcnts,rdispls,recvtype,comm) \
386  ((petsc_allreduce_ct++,0) || PetscMPITypeSizeComm(comm,&petsc_send_len,sendcnts,sendtype) || MPI_Alltoallv(sendbuf,sendcnts,sdispls,sendtype,recvbuf,recvcnts,rdispls,recvtype,comm))
387 
388 #define MPI_Allgather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm) \
389  ((petsc_gather_ct++,0) || MPI_Allgather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm))
390 
391 #define MPI_Allgatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,comm) \
392  ((petsc_gather_ct++,0) || MPI_Allgatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,comm))
393 
394 #define MPI_Gather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm) \
395  ((petsc_gather_ct++,0) || PetscMPITypeSize(&petsc_send_len,sendcount,sendtype) || MPI_Gather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm))
396 
397 #define MPI_Gatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,root,comm) \
398  ((petsc_gather_ct++,0) || PetscMPITypeSize(&petsc_send_len,sendcount,sendtype) || MPI_Gatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,root,comm))
399 
400 #define MPI_Scatter(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm) \
401  ((petsc_scatter_ct++,0) || PetscMPITypeSize(&petsc_recv_len,recvcount,recvtype) || MPI_Scatter(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm))
402 
403 #define MPI_Scatterv(sendbuf,sendcount,displs,sendtype,recvbuf,recvcount,recvtype,root,comm) \
404   ((petsc_scatter_ct++,0) || PetscMPITypeSize(&petsc_recv_len,recvcount,recvtype) || MPI_Scatterv(sendbuf,sendcount,displs,sendtype,recvbuf,recvcount,recvtype,root,comm))
405 
406 #else
407 
408 #define MPI_Startall_irecv(count,number,requests) \
409  (MPI_Startall(number,requests))
410 
411 #define MPI_Startall_isend(count,number,requests) \
412  (MPI_Startall(number,requests))
413 
414 #define MPI_Start_isend(count,requests) \
415  (MPI_Start(requests))
416 
417 #endif /* !__MPIUNI_H && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */
418 
419 #else  /* ---Logging is turned off --------------------------------------------*/
420 
421 #define PetscLogFlops(n) 0
422 
423 /*
424      With logging turned off, then MPE has to be turned off
425 */
426 #define PetscLogMPEBegin()         0
427 #define PetscLogMPEDump(a)         0
428 
429 #define PetscLogEventActivate(a)   0
430 #define PetscLogEventDeactivate(a) 0
431 
432 #define PetscLogEventActivateClass(a)   0
433 #define PetscLogEventDeactivateClass(a) 0
434 #define PetscLogEventSetActiveAll(a,b)  0
435 
436 #define PetscLogPLB                        0
437 #define PetscLogPLE                        0
438 #define PetscLogPHC                        0
439 #define PetscLogPHD                        0
440 #define PetscGetFlops(a)                (*(a) = 0.0,0)
441 #define PetscLogEventBegin(e,o1,o2,o3,o4)   0
442 #define PetscLogEventEnd(e,o1,o2,o3,o4)     0
443 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0
444 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm)   0
445 #define PetscLogObjectParent(p,c)           0
446 #define PetscLogObjectParents(p,n,c)        0
447 #define PetscLogObjectCreate(h)             0
448 #define PetscLogObjectDestroy(h)            0
449 #define PetscLogObjectMemory(p,m)           0
450 #define PetscLogDestroy()                   0
451 #define PetscLogStagePush(a)                0
452 #define PetscLogStagePop()                  0
453 #define PetscLogStageRegister(a,b)          0
454 #define PetscLogStagePrint(a,flg)           0
455 #define PetscLogView(viewer)                0
456 #define PetscLogViewPython(viewer)          0
457 #define PetscLogPrintDetailed(comm,file)    0
458 #define PetscLogBegin()                     0
459 #define PetscLogTraceBegin(file)            0
460 #define PetscLogSet(lb,le)                  0
461 #define PetscLogAllBegin()                  0
462 #define PetscLogDump(c)                     0
463 #define PetscLogEventRegister(a,b,c)        0
464 #define PetscLogObjects(a)                  0
465 #define PetscLogActions(a)                  0
466 PETSC_EXTERN PetscErrorCode PetscLogObjectState(PetscObject,const char[],...);
467 
468 /* If PETSC_USE_LOG is NOT defined, these still need to be! */
469 #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests)
470 #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests)
471 #define MPI_Start_isend(count,requests) MPI_Start(requests)
472 #define PetscLogStageGetId(a,b)                      (*(b)=0,0)
473 #define PetscLogStageSetActive(a,b)                  0
474 #define PetscLogStageGetActive(a,b)                  0
475 #define PetscLogStageGetVisible(a,b)                 0
476 #define PetscLogStageSetVisible(a,b)                 0
477 
478 #endif   /* PETSC_USE_LOG */
479 
480 PETSC_EXTERN PetscErrorCode PetscIntStackCreate(PetscIntStack *);
481 PETSC_EXTERN PetscErrorCode PetscIntStackDestroy(PetscIntStack);
482 PETSC_EXTERN PetscErrorCode PetscIntStackPush(PetscIntStack, int);
483 PETSC_EXTERN PetscErrorCode PetscIntStackPop(PetscIntStack, int *);
484 PETSC_EXTERN PetscErrorCode PetscIntStackTop(PetscIntStack, int *);
485 PETSC_EXTERN PetscErrorCode PetscIntStackEmpty(PetscIntStack, PetscBool  *);
486 
487 /* Special support for C++ */
488 #if defined(PETSC_CLANGUAGE_CXX) && defined(__cplusplus)
489 #include <petsclog.hh>
490 #endif
491 
492 #define PetscPreLoadBegin(flag,name) \
493 do {\
494   PetscBool      PetscPreLoading = flag;\
495   int            PetscPreLoadMax,PetscPreLoadIt;\
496   PetscLogStage  _stageNum;\
497   PetscErrorCode _3_ierr; \
498   _3_ierr = PetscOptionsGetBool(NULL,"-preload",&PetscPreLoading,NULL);CHKERRQ(_3_ierr);\
499   PetscPreLoadMax = (int)(PetscPreLoading);\
500   PetscPreLoadingUsed = PetscPreLoading ? PETSC_TRUE : PetscPreLoadingUsed;\
501   for (PetscPreLoadIt=0; PetscPreLoadIt<=PetscPreLoadMax; PetscPreLoadIt++) {\
502     PetscPreLoadingOn = PetscPreLoading;\
503     _3_ierr = PetscBarrier(NULL);CHKERRQ(_3_ierr);\
504     if (PetscPreLoadIt>0) {\
505       _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
506     } else {\
507       _3_ierr = PetscLogStageRegister(name,&_stageNum);CHKERRQ(_3_ierr); \
508     }\
509     _3_ierr = PetscLogStageSetActive(_stageNum,(PetscBool)(!PetscPreLoadMax || PetscPreLoadIt));\
510     _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
511 
512 #define PetscPreLoadEnd() \
513     _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\
514     PetscPreLoading = PETSC_FALSE;\
515   }\
516 } while (0)
517 
518 #define PetscPreLoadStage(name) do {                                         \
519     _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);                      \
520     if (PetscPreLoadIt>0) {                                                  \
521       _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);   \
522     } else {                                                            \
523       _3_ierr = PetscLogStageRegister(name,&_stageNum);CHKERRQ(_3_ierr); \
524     }                                                                   \
525     _3_ierr = PetscLogStageSetActive(_stageNum,(PetscBool)(!PetscPreLoadMax || PetscPreLoadIt)); \
526     _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);            \
527   } while (0)
528 
529 /* some vars for logging */
530 PETSC_EXTERN PetscBool PetscPreLoadingUsed;       /* true if we are or have done preloading */
531 PETSC_EXTERN PetscBool PetscPreLoadingOn;         /* true if we are currently in a preloading calculation */
532 
533 #endif
534