xref: /petsc/include/petsclog.h (revision 6a7c8fc2a6aac83ad1069891e131b23ca2c55a16)
1 /*
2     Defines profile/logging in PETSc.
3 */
4 
5 #if !defined(__PetscLog_H)
6 #define __PetscLog_H
7 #include "petsc.h"
8 PETSC_EXTERN_CXX_BEGIN
9 /*
10   Each PETSc object class has it's own cookie (internal integer in the
11   data structure used for error checking). These are all defined by an offset
12   from the lowest one, PETSC_COOKIE.
13 */
14 #define PETSC_COOKIE 1211211
15 extern PetscCookie PETSC_LARGEST_COOKIE;
16 #define PETSC_EVENT  1311311
17 extern PetscEvent PETSC_LARGEST_EVENT;
18 
19 /* Events for the Petsc standard library */
20 extern PetscEvent PETSC_Barrier;
21 
22 /* Global flop counter */
23 extern PetscLogDouble _TotalFlops;
24 
25 /* General logging of information; different from event logging */
26 EXTERN PetscErrorCode        PetscLogInfo_Private(void*,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3);
27 #if defined(PETSC_USE_DEBUG)
28 #define PetscLogInfo(A)      PetscLogInfo_Private A
29 #else
30 #define PetscLogInfo(A)      0
31 #endif
32 EXTERN PetscErrorCode        PetscLogInfoDeactivateClass(PetscCookie);
33 EXTERN PetscErrorCode        PetscLogInfoActivateClass(PetscCookie);
34 extern PetscTruth PetscLogPrintInfo;  /* if true, indicates PetscLogInfo() is turned on */
35 
36 #if defined(PETSC_USE_LOG)  /* --- Logging is turned on --------------------------------*/
37 
38 /*
39    Flop counting:  We count each arithmetic operation (e.g., addition, multiplication) separately.
40 
41    For the complex numbers version, note that
42        1 complex addition = 2 flops
43        1 complex multiplication = 6 flops,
44    where we define 1 flop as that for a double precision scalar.  We roughly approximate
45    flop counting for complex numbers by multiplying the total flops by 4; this corresponds
46    to the assumption that we're counting mostly additions and multiplications -- and
47    roughly the same number of each.  More accurate counting could be done by distinguishing
48    among the various arithmetic operations.
49  */
50 
51 #if defined(PETSC_USE_COMPLEX)
52 #define PetscLogFlops(n) (_TotalFlops += (4*n),0)
53 #else
54 #define PetscLogFlops(n) (_TotalFlops += (n),0)
55 #endif
56 
57 #if defined (PETSC_HAVE_MPE)
58 #include "mpe.h"
59 EXTERN PetscErrorCode        PetscLogMPEBegin(void);
60 EXTERN PetscErrorCode        PetscLogMPEDump(const char[]);
61 extern PetscTruth UseMPE;
62 #define PETSC_LOG_EVENT_MPE_BEGIN(e) \
63   ((UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ?
64    MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_begin,0,(char*)"") : 0)
65 
66 #define PETSC_LOG_EVENT_MPE_END(e) \
67   ((UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ?
68    MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_end,0,(char*)"") : 0)
69 
70 #else
71 #define PETSC_LOG_EVENT_MPE_BEGIN(e) 0
72 #define PETSC_LOG_EVENT_MPE_END(e)   0
73 #endif
74 
75 EXTERN PetscErrorCode (*_PetscLogPLB)(PetscEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
76 EXTERN PetscErrorCode (*_PetscLogPLE)(PetscEvent,int,PetscObject,PetscObject,PetscObject,PetscObject);
77 EXTERN PetscErrorCode (*_PetscLogPHC)(PetscObject);
78 EXTERN PetscErrorCode (*_PetscLogPHD)(PetscObject);
79 
80 #define PetscLogObjectParent(p,c) \
81   ((c && p) ? ((PetscObject)(c))->parent = (PetscObject)(p),((PetscObject)(c))->parentid = ((PetscObject)p)->id : 0, 0)
82 
83 #define PetscLogObjectParents(p,n,d)  0;{int _i; for (_i=0; _i<n; _i++) {ierr = PetscLogObjectParent(p,(d)[_i]);CHKERRQ(ierr);}}
84 #define PetscLogObjectCreate(h)      ((_PetscLogPHC) ? (*_PetscLogPHC)((PetscObject)h) : 0)
85 #define PetscLogObjectDestroy(h)     ((_PetscLogPHD) ? (*_PetscLogPHD)((PetscObject)h) : 0)
86 #define PetscLogObjectMemory(p,m)    (((PetscObject)(p))->mem += (m),0)
87 /* Initialization functions */
88 EXTERN PetscErrorCode PetscLogBegin(void);
89 EXTERN PetscErrorCode PetscLogAllBegin(void);
90 EXTERN PetscErrorCode PetscLogTraceBegin(FILE *);
91 EXTERN PetscErrorCode PetscLogActions(PetscTruth);
92 EXTERN PetscErrorCode PetscLogObjects(PetscTruth);
93 /* General functions */
94 EXTERN PetscErrorCode PetscLogGetRGBColor(const char*[]);
95 EXTERN PetscErrorCode PetscLogDestroy(void);
96 EXTERN PetscErrorCode PetscLogSet(PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject),
97                    PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject));
98 EXTERN PetscErrorCode PetscLogObjectState(PetscObject, const char[], ...)  PETSC_PRINTF_FORMAT_CHECK(2,3);
99 /* Output functions */
100 EXTERN PetscErrorCode PetscLogPrintSummary(MPI_Comm, const char[]);
101 EXTERN PetscErrorCode PetscLogDump(const char[]);
102 /* Counter functions */
103 EXTERN PetscErrorCode PetscGetFlops(PetscLogDouble *);
104 /* Stage functions */
105 EXTERN PetscErrorCode PetscLogStageRegister(int*, const char[]);
106 EXTERN PetscErrorCode PetscLogStagePush(int);
107 EXTERN PetscErrorCode PetscLogStagePop(void);
108 EXTERN PetscErrorCode PetscLogStageSetActive(int, PetscTruth);
109 EXTERN PetscErrorCode PetscLogStageGetActive(int, PetscTruth *);
110 EXTERN PetscErrorCode PetscLogStageSetVisible(int, PetscTruth);
111 EXTERN PetscErrorCode PetscLogStageGetVisible(int, PetscTruth *);
112 EXTERN PetscErrorCode PetscLogStageGetId(const char [], int *);
113 /* Event functions */
114 EXTERN PetscErrorCode PetscLogEventRegister(PetscEvent*, const char[], PetscCookie);
115 EXTERN PetscErrorCode PetscLogEventActivate(PetscEvent);
116 EXTERN PetscErrorCode PetscLogEventDeactivate(PetscEvent);
117 EXTERN PetscErrorCode PetscLogEventSetActiveAll(PetscEvent, PetscTruth);
118 EXTERN PetscErrorCode PetscLogEventActivateClass(PetscCookie);
119 EXTERN PetscErrorCode PetscLogEventDeactivateClass(PetscCookie);
120 /* Class functions */
121 EXTERN PetscErrorCode PetscLogClassRegister(PetscCookie*, 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_SIZE, PETSC_DUMMY_COUNT;
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   PetscCookie cookie; /* The integer identifying this class */
167 } ClassRegInfo;
168 
169 typedef struct _EventRegInfo {
170   char            *name;   /* The name of this event */
171   PetscCookie 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 typedef struct _EventRegLog *EventRegLog;
179 struct _EventRegLog {
180   int           numEvents; /* The number of registered events */
181   int           maxEvents; /* The maximum number of events */
182   EventRegInfo *eventInfo; /* The registration information for each event */
183 };
184 
185 typedef struct _EventPerfLog *EventPerfLog;
186 struct _EventPerfLog {
187   int            numEvents; /* The number of logging events */
188   int            maxEvents; /* The maximum number of events */
189   EventPerfInfo *eventInfo; /* The performance information for each event */
190 };
191 
192 /* The structure for logging class information */
193 typedef struct _ClassRegLog *ClassRegLog;
194 struct _ClassRegLog {
195   int           numClasses; /* The number of classes registered */
196   int           maxClasses; /* The maximum number of classes */
197   ClassRegInfo *classInfo;  /* The structure for class information (cookies are monotonicly increasing) */
198 };
199 
200 typedef struct _ClassPerfLog *ClassPerfLog;
201 struct _ClassPerfLog {
202   int            numClasses; /* The number of logging classes */
203   int            maxClasses; /* The maximum number of classes */
204   ClassPerfInfo *classInfo;  /* The structure for class information (cookies are monotonicly increasing) */
205 };
206 
207 /* The structures for logging in stages */
208 typedef struct _StageInfo {
209   char         *name;     /* The stage name */
210   PetscTruth    used;     /* The stage was pushed on this processor */
211   EventPerfInfo perfInfo; /* The stage performance information */
212   EventPerfLog  eventLog; /* The event information for this stage */
213   ClassPerfLog  classLog; /* The class information for this stage */
214 } StageInfo;
215 
216 struct _StageLog {
217   /* Size information */
218   int         numStages; /* The number of registered stages */
219   int         maxStages; /* The maximum number of stages */
220   /* Runtime information */
221   IntStack    stack;     /* The stack for active stages */
222   int         curStage;  /* The current stage (only used in macros so we don't call StackTop) */
223   /* Stage specific information */
224   StageInfo  *stageInfo; /* The information for each stage */
225   EventRegLog eventLog;  /* The registered events */
226   ClassRegLog classLog;  /* The registered classes */
227 };
228 
229 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \
230   (((_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active &&  _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
231     (PetscLogEventBegin((e),o1,o2,o3,o4) || MPI_Barrier(cm) || PetscLogEventEnd((e),o1,o2,o3,o4)) : 0 ) || \
232    PetscLogEventBegin((e)+1,o1,o2,o3,o4))
233 
234 #define PetscLogEventBegin(e,o1,o2,o3,o4) \
235   (((_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
236     (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
237   PETSC_LOG_EVENT_MPE_BEGIN(e))
238 
239 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4)
240 
241 #define PetscLogEventEnd(e,o1,o2,o3,o4) \
242   (((_PetscLogPLE && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
243     (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
244   PETSC_LOG_EVENT_MPE_END(e))
245 
246 /* Creation and destruction functions */
247 EXTERN PetscErrorCode StageLogCreate(StageLog *);
248 EXTERN PetscErrorCode StageLogDestroy(StageLog);
249 /* Registration functions */
250 EXTERN PetscErrorCode StageLogRegister(StageLog, const char [], int *);
251 /* Runtime functions */
252 EXTERN PetscErrorCode PetscLogGetStageLog(StageLog *);
253 EXTERN PetscErrorCode StageLogPush(StageLog, int);
254 EXTERN PetscErrorCode StageLogPop(StageLog);
255 EXTERN PetscErrorCode StageLogGetCurrent(StageLog, int *);
256 EXTERN PetscErrorCode StageLogSetActive(StageLog, int, PetscTruth);
257 EXTERN PetscErrorCode StageLogGetActive(StageLog, int, PetscTruth *);
258 EXTERN PetscErrorCode StageLogSetVisible(StageLog, int, PetscTruth);
259 EXTERN PetscErrorCode StageLogGetVisible(StageLog, int, PetscTruth *);
260 EXTERN PetscErrorCode StageLogGetStage(StageLog, const char [], int *);
261 EXTERN PetscErrorCode StageLogGetClassRegLog(StageLog, ClassRegLog *);
262 EXTERN PetscErrorCode StageLogGetEventRegLog(StageLog, EventRegLog *);
263 EXTERN PetscErrorCode StageLogGetClassPerfLog(StageLog, int, ClassPerfLog *);
264 EXTERN PetscErrorCode StageLogGetEventPerfLog(StageLog, int, EventPerfLog *);
265 
266 /*
267      This does not work for MPI-Uni because our include/mpiuni/mpi.h file
268    uses macros to defined the MPI operations.
269 
270      It does not work correctly from HP-UX because it processes the
271    macros in a way that sometimes it double counts, hence
272    PETSC_HAVE_BROKEN_RECURSIVE_MACRO
273 
274      It does not work with Windows because winmpich lacks MPI_Type_size()
275 */
276 #if !defined(_petsc_mpi_uni) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO) && !defined (PETSC_HAVE_MPI_MISSING_TYPESIZE)
277 /*
278    Logging of MPI activities
279 */
280 #define TypeSize(buff,count,type) \
281  (MPI_Type_size(type,&PETSC_DUMMY_SIZE) || (buff += (PetscLogDouble) ((count)*PETSC_DUMMY_SIZE),0))
282 
283 #define MPI_Irecv(buf,count,datatype,source,tag,comm,request) \
284  ((PETSC_DUMMY_COUNT = count,irecv_ct++,0) || TypeSize(irecv_len,PETSC_DUMMY_COUNT,datatype) || MPI_Irecv(buf,PETSC_DUMMY_COUNT,datatype,source,tag,comm,request))
285 
286 #define MPI_Isend(buf,count,datatype,dest,tag,comm,request) \
287  ((PETSC_DUMMY_COUNT = count,isend_ct++,0) || TypeSize(isend_len,PETSC_DUMMY_COUNT,datatype) || MPI_Isend(buf,PETSC_DUMMY_COUNT,datatype,dest,tag,comm,request))
288 
289 #define MPI_Startall_irecv(count,number,requests) \
290  ((irecv_ct += (PetscLogDouble)(number),0) || TypeSize(irecv_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
291 
292 #define MPI_Startall_isend(count,number,requests) \
293  ((isend_ct += (PetscLogDouble)(number),0) || TypeSize(isend_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
294 
295 #define MPI_Start_isend(count,requests) \
296  ((isend_ct++,0) || TypeSize(isend_len,count,MPIU_SCALAR) || MPI_Start(requests))
297 
298 #define MPI_Recv(buf,count,datatype,source,tag,comm,status) \
299  ((PETSC_DUMMY_COUNT = count,recv_ct++,0) || TypeSize(recv_len,PETSC_DUMMY_COUNT,datatype) || MPI_Recv(buf,PETSC_DUMMY_COUNT,datatype,source,tag,comm,status))
300 
301 #define MPI_Send(buf,count,datatype,dest,tag,comm) \
302  ((PETSC_DUMMY_COUNT = count,send_ct++,0) || TypeSize(send_len,PETSC_DUMMY_COUNT,datatype) || MPI_Send(buf,PETSC_DUMMY_COUNT,datatype,dest,tag,comm))
303 
304 #define MPI_Wait(request,status) \
305  ((wait_ct++,sum_of_waits_ct++,0) || MPI_Wait(request,status))
306 
307 #define MPI_Waitany(a,b,c,d) \
308  ((wait_any_ct++,sum_of_waits_ct++,0) || MPI_Waitany(a,b,c,d))
309 
310 #define MPI_Waitall(count,array_of_requests,array_of_statuses) \
311  ((PETSC_DUMMY_COUNT = count,wait_all_ct++,sum_of_waits_ct += (PetscLogDouble) (PETSC_DUMMY_COUNT),0) || MPI_Waitall(PETSC_DUMMY_COUNT,array_of_requests,array_of_statuses))
312 
313 #define MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm) \
314  ((allreduce_ct++,0) || MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm))
315 
316 #else
317 
318 #define MPI_Startall_irecv(count,number,requests) \
319  (MPI_Startall(number,requests))
320 
321 #define MPI_Startall_isend(count,number,requests) \
322  (MPI_Startall(number,requests))
323 
324 #define MPI_Start_isend(count,requests) \
325  (MPI_Start(requests))
326 
327 #endif /* !_petsc_mpi_uni && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */
328 
329 #else  /* ---Logging is turned off --------------------------------------------*/
330 
331 #define PetscLogFlops(n) 0
332 
333 /*
334      With logging turned off, then MPE has to be turned off
335 */
336 #define PetscLogMPEBegin()         0
337 #define PetscLogMPEDump(a)         0
338 
339 #define PetscLogEventActivate(a)   0
340 #define PetscLogEventDeactivate(a) 0
341 
342 #define PetscLogEventActivateClass(a)   0
343 #define PetscLogEventDeactivateClass(a) 0
344 
345 #define _PetscLogPLB                        0
346 #define _PetscLogPLE                        0
347 #define _PetscLogPHC                        0
348 #define _PetscLogPHD                        0
349 #define PetscGetFlops(a)                (*(a) = 0.0,0)
350 #define PetscLogEventBegin(e,o1,o2,o3,o4)   0
351 #define PetscLogEventEnd(e,o1,o2,o3,o4)     0
352 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0
353 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm)   0
354 #define PetscLogObjectParent(p,c)           0
355 #define PetscLogObjectParents(p,n,c)        0
356 #define PetscLogObjectCreate(h)             0
357 #define PetscLogObjectDestroy(h)            0
358 #define PetscLogObjectMemory(p,m)           0
359 #define PetscLogDestroy()                   0
360 #define PetscLogStagePush(a)                0
361 #define PetscLogStagePop()                  0
362 #define PetscLogStageRegister(a,b)          0
363 #define PetscLogStagePrint(a,flg)           0
364 #define PetscLogPrintSummary(comm,file)     0
365 #define PetscLogBegin()                     0
366 #define PetscLogTraceBegin(file)            0
367 #define PetscLogSet(lb,le)                  0
368 #define PetscLogAllBegin()                  0
369 #define PetscLogDump(c)                     0
370 #define PetscLogEventRegister(a,b,c)        0
371 #define PetscLogObjects(a)                  0
372 #define PetscLogActions(a)                  0
373 EXTERN PetscErrorCode PetscLogObjectState(PetscObject,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3);
374 
375 /* If PETSC_USE_LOG is NOT defined, these still need to be! */
376 #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests)
377 #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests)
378 #define MPI_Start_isend(count,requests) MPI_Start(requests)
379 
380 /* Creation and destruction functions */
381 #define StageLogCreate(stageLog)                     0
382 #define StageLogDestroy(stageLog)                    0
383 /* Registration functions */
384 #define StageLogRegister(stageLog, name, stage)      0
385 /* Runtime functions */
386 #define PetscLogGetStageLog(stageLog)                0
387 #define StageLogPush(stageLog, stage)                0
388 #define StageLogPop(stageLog)                        0
389 #define StageLogGetCurrent(stageLog, stage)          0
390 #define StageLogSetActive(stageLog, stage, active)   0
391 #define StageLogGetActive(stageLog, stage, active)   0
392 #define StageLogSetVisible(stageLog, stage, visible) 0
393 #define StageLogGetVisible(stageLog, stage, visible) 0
394 #define StageLogGetStage(stageLog, name, stage)      0
395 
396 #endif   /* PETSC_USE_LOG */
397 
398 extern PetscTruth PetscPreLoadingUsed;       /* true if we are or have done preloading */
399 extern PetscTruth PetscPreLoadingOn;         /* true if we are currently in a preloading calculation */
400 
401 #define PreLoadBegin(flag,name) \
402 {\
403   PetscTruth PreLoading = flag;\
404   int        PreLoadMax,PreLoadIt,_stageNum,_3_ierr;\
405   _3_ierr = PetscOptionsGetLogical(PETSC_NULL,"-preload",&PreLoading,PETSC_NULL);CHKERRQ(_3_ierr);\
406   PreLoadMax = (int)(PreLoading);\
407   PetscPreLoadingUsed = PreLoading ? PETSC_TRUE : PetscPreLoadingUsed;\
408   for (PreLoadIt=0; PreLoadIt<=PreLoadMax; PreLoadIt++) {\
409     PetscPreLoadingOn = PreLoading;\
410     _3_ierr = PetscBarrier(PETSC_NULL);CHKERRQ(_3_ierr);\
411     if (PreLoadIt>0) {\
412       _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
413     } else {\
414       _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\
415     }\
416     _3_ierr = PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\
417     _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
418 
419 #define PreLoadEnd() \
420     _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\
421     PreLoading = PETSC_FALSE;\
422   }\
423 }
424 
425 #define PreLoadStage(name) \
426   _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\
427   if (PreLoadIt>0) {\
428     _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
429   } else {\
430     _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\
431   }\
432   _3_ierr = PetscLogStageSetActive(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\
433   _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
434 
435 PETSC_EXTERN_CXX_END
436 #endif
437