Actual source code: petsclog.h
1: /*
2: Defines profile/logging in PETSc.
3: */
7: #include petscsys.h
10: /*MC
11: PetscLogEvent - id used to identify PETSc or user events which timed portions (blocks of executable)
12: code.
14: Level: intermediate
16: .seealso: PetscLogEventRegister(), PetscLogEventBegin(), PetscLogEventEnd(), PetscLogStage
17: M*/
18: typedef int PetscLogEvent;
20: /*MC
21: PetscLogStage - id used to identify user stages (phases, sections) of runs - for logging
23: Level: intermediate
25: .seealso: PetscLogStageRegister(), PetscLogStageBegin(), PetscLogStageEnd(), PetscLogEvent
26: M*/
27: typedef int PetscLogStage;
29: #define PETSC_EVENT 1311311
32: /* Global flop counter */
36: /* General logging of information; different from event logging */
38: #if defined(PETSC_USE_INFO)
39: #define PetscInfo(A,S) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S)
40: #define PetscInfo1(A,S,a1) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1)
41: #define PetscInfo2(A,S,a1,a2) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2)
42: #define PetscInfo3(A,S,a1,a2,a3) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3)
43: #define PetscInfo4(A,S,a1,a2,a3,a4) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3,a4)
44: #define PetscInfo5(A,S,a1,a2,a3,a4,a5) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3,a4,a5)
45: #define PetscInfo6(A,S,a1,a2,a3,a4,a5,a6) PetscInfo_Private(PETSC_FUNCTION_NAME,A,S,a1,a2,a3,a4,a5,a6)
46: #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)
47: #else
48: #define PetscInfo(A,S) 0
49: #define PetscInfo1(A,S,a1) 0
50: #define PetscInfo2(A,S,a1,a2) 0
51: #define PetscInfo3(A,S,a1,a2,a3) 0
52: #define PetscInfo4(A,S,a1,a2,a3,a4) 0
53: #define PetscInfo5(A,S,a1,a2,a3,a4,a5) 0
54: #define PetscInfo6(A,S,a1,a2,a3,a4,a5,a6) 0
55: #define PetscInfo7(A,S,a1,a2,a3,a4,a5,a6,a7) 0
56: #endif
61: /* We must make the following structures available to access the event
62: activation flags in the PetscLogEventBegin/End() macros. These are not part of the PETSc public
63: API and are not intended to be used by other parts of PETSc or by users.
64:
65: The code that manipulates these structures is in src/sys/plog/utils.
66: */
67: typedef struct _n_PetscIntStack *PetscIntStack;
69: /*
70: PetscClassRegInfo, PetscClassPerfInfo - Each class has two data structures associated with it. The first has
71: static information about it, the second collects statistics on how many objects of the class are created,
72: how much memory they use, etc.
74: PetscClassRegLog, PetscClassPerfLog - arrays of the PetscClassRegInfo and PetscClassPerfInfo for all classes.
75: */
76: typedef struct {
77: char *name; /* The class name */
78: PetscClassId classid; /* The integer identifying this class */
79: } PetscClassRegInfo;
81: typedef struct {
82: PetscClassId id; /* The integer identifying this class */
83: int creations; /* The number of objects of this class created */
84: int destructions; /* The number of objects of this class destroyed */
85: PetscLogDouble mem; /* The total memory allocated by objects of this class */
86: PetscLogDouble descMem; /* The total memory allocated by descendents of these objects */
87: } PetscClassPerfInfo;
89: typedef struct _n_PetscClassRegLog *PetscClassRegLog;
90: struct _n_PetscClassRegLog {
91: int numClasses; /* The number of classes registered */
92: int maxClasses; /* The maximum number of classes */
93: PetscClassRegInfo *classInfo; /* The structure for class information (classids are monotonicly increasing) */
94: };
96: typedef struct _n_PetscClassPerfLog *PetscClassPerfLog;
97: struct _n_PetscClassPerfLog {
98: int numClasses; /* The number of logging classes */
99: int maxClasses; /* The maximum number of classes */
100: PetscClassPerfInfo *classInfo; /* The structure for class information (classids are monotonicly increasing) */
101: };
102: /* -----------------------------------------------------------------------------------------------------*/
103: /*
104: PetscEventRegInfo, PetscEventPerfInfo - Each event has two data structures associated with it. The first has
105: static information about it, the second collects statistics on how many times the event is used, how
106: much time it takes, etc.
108: PetscEventRegLog, PetscEventPerfLog - an array of all PetscEventRegInfo and PetscEventPerfInfo for all events. There is one
109: of these for each stage.
111: */
112: typedef struct {
113: char *name; /* The name of this event */
114: PetscClassId classid; /* The class the event is associated with */
115: #if defined (PETSC_HAVE_MPE)
116: int mpe_id_begin; /* MPE IDs that define the event */
117: int mpe_id_end;
118: #endif
119: } PetscEventRegInfo;
121: typedef struct {
122: int id; /* The integer identifying this event */
123: PetscBool active; /* The flag to activate logging */
124: PetscBool visible; /* The flag to print info in summary */
125: int depth; /* The nesting depth of the event call */
126: int count; /* The number of times this event was executed */
127: PetscLogDouble flops; /* The flops used in this event */
128: PetscLogDouble time; /* The time taken for this event */
129: PetscLogDouble numMessages; /* The number of messages in this event */
130: PetscLogDouble messageLength; /* The total message lengths in this event */
131: PetscLogDouble numReductions; /* The number of reductions in this event */
132: } PetscEventPerfInfo;
134: typedef struct _n_PetscEventRegLog *PetscEventRegLog;
135: struct _n_PetscEventRegLog {
136: int numEvents; /* The number of registered events */
137: int maxEvents; /* The maximum number of events */
138: PetscEventRegInfo *eventInfo; /* The registration information for each event */
139: };
141: typedef struct _n_PetscEventPerfLog *PetscEventPerfLog;
142: struct _n_PetscEventPerfLog {
143: int numEvents; /* The number of logging events */
144: int maxEvents; /* The maximum number of events */
145: PetscEventPerfInfo *eventInfo; /* The performance information for each event */
146: };
147: /* ------------------------------------------------------------------------------------------------------------*/
148: /*
149: PetscStageInfo - Contains all the information about a particular stage.
151: PetscStageLog - An array of PetscStageInfo for each registered stage. There is a single one of these in the code.
152: */
153: typedef struct _PetscStageInfo {
154: char *name; /* The stage name */
155: PetscBool used; /* The stage was pushed on this processor */
156: PetscEventPerfInfo perfInfo; /* The stage performance information */
157: PetscEventPerfLog eventLog; /* The event information for this stage */
158: PetscClassPerfLog classLog; /* The class information for this stage */
159: } PetscStageInfo;
161: typedef struct _n_PetscStageLog *PetscStageLog;
163: struct _n_PetscStageLog {
164: int numStages; /* The number of registered stages */
165: int maxStages; /* The maximum number of stages */
166: PetscIntStack stack; /* The stack for active stages */
167: int curStage; /* The current stage (only used in macros so we don't call PetscIntStackTop) */
168: PetscStageInfo *stageInfo; /* The information for each stage */
169: PetscEventRegLog eventLog; /* The registered events */
170: PetscClassRegLog classLog; /* The registered classes */
171: };
173: #if defined(PETSC_USE_LOG) /* --- Logging is turned on --------------------------------*/
175: /*
176: Flop counting: We count each arithmetic operation (e.g., addition, multiplication) separately.
178: For the complex numbers version, note that
179: 1 complex addition = 2 flops
180: 1 complex multiplication = 6 flops,
181: where we define 1 flop as that for a double precision scalar. We roughly approximate
182: flop counting for complex numbers by multiplying the total flops by 4; this corresponds
183: to the assumption that we're counting mostly additions and multiplications -- and
184: roughly the same number of each. More accurate counting could be done by distinguishing
185: among the various arithmetic operations.
186: */
188: #if defined(PETSC_USE_COMPLEX)
189: #define PETSC_FLOPS_PER_OP 4.0
190: #else
191: #define PETSC_FLOPS_PER_OP 1.0
192: #endif
194: #if defined(PETSC_USE_DEBUG)
195: #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)))
196: #define PetscLogFlopsNoError(n) (_TotalFlops += PETSC_FLOPS_PER_OP*((PetscLogDouble)n))
197: #else
198: #define PetscLogFlops(n) (_TotalFlops += PETSC_FLOPS_PER_OP*((PetscLogDouble)n),0)
199: #define PetscLogFlopsNoError(n) (_TotalFlops += PETSC_FLOPS_PER_OP*((PetscLogDouble)n))
200: #endif
202: #if defined (PETSC_HAVE_MPE)
203: #include "mpe.h"
207: #define PETSC_LOG_EVENT_MPE_BEGIN(e) \
208: ((UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
209: MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_begin,0,NULL) : 0)
211: #define PETSC_LOG_EVENT_MPE_END(e) \
212: ((UseMPE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
213: MPE_Log_event(_stageLog->eventLog->eventInfo[e].mpe_id_end,0,NULL) : 0)
215: #else
216: #define PETSC_LOG_EVENT_MPE_BEGIN(e) 0
217: #define PETSC_LOG_EVENT_MPE_END(e) 0
218: #endif
225: #define PetscLogObjectParent(p,c) \
226: (c && p && (((PetscObject)(c))->parent = (PetscObject)(p),((PetscObject)(c))->parentid = ((PetscObject)p)->id,0))
228: #define PetscLogObjectParents(p,n,d) 0;{int _i; for (_i=0; _i<n; _i++) {PetscLogObjectParent(p,(d)[_i]);}}
229: #define PetscLogObjectCreate(h) ((_PetscLogPHC) ? (*_PetscLogPHC)((PetscObject)h) : 0)
230: #define PetscLogObjectDestroy(h) ((_PetscLogPHD) ? (*_PetscLogPHD)((PetscObject)h) : 0)
231: #define PetscLogObjectMemory(p,m) (((PetscObject)(p))->mem += (m),0)
232: /* Initialization functions */
238: /* General functions */
242: PetscErrorCode (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject));
244: /* Output functions */
260: /* Event functions */
269: /* Global counters */
286: #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \
287: (((_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
288: (PetscLogEventBegin((e),o1,o2,o3,o4) || MPI_Barrier(cm) || PetscLogEventEnd((e),o1,o2,o3,o4)) : 0 ) || \
289: PetscLogEventBegin((e)+1,o1,o2,o3,o4))
291: #define PetscLogEventBegin(e,o1,o2,o3,o4) \
292: (((_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
293: (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
294: PETSC_LOG_EVENT_MPE_BEGIN(e))
296: #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4)
298: #define PetscLogEventEnd(e,o1,o2,o3,o4) \
299: (((_PetscLogPLE && _stageLog->stageInfo[_stageLog->curStage].perfInfo.active && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) ? \
300: (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4)) : 0 ) || \
301: PETSC_LOG_EVENT_MPE_END(e))
306: /*
307: These are used internally in the PETSc routines to keep a count of MPI messages and
308: their sizes.
310: This does not work for MPI-Uni because our include/mpiuni/mpi.h file
311: uses macros to defined the MPI operations.
313: It does not work correctly from HP-UX because it processes the
314: macros in a way that sometimes it double counts, hence
315: PETSC_HAVE_BROKEN_RECURSIVE_MACRO
317: It does not work with Windows because winmpich lacks MPI_Type_size()
318: */
320: /*
321: Logging of MPI activities
322: */
323: PETSC_STATIC_INLINE PetscErrorCode PetscMPITypeSize(PetscLogDouble *buff,PetscMPIInt count,MPI_Datatype type)
324: {
325: PetscMPIInt mysize; return (MPI_Type_size(type,&mysize) || ((*buff += (PetscLogDouble) (count*mysize)),0));
326: }
328: PETSC_STATIC_INLINE PetscErrorCode PetscMPITypeSizeComm(MPI_Comm comm, PetscLogDouble *buff,PetscMPIInt *counts,MPI_Datatype type)
329: {
330: PetscMPIInt mysize, commsize, p;
331: PetscErrorCode _myierr;
333: _myMPI_Comm_size(comm,&commsize);CHKERRQ(_myierr);
334: _myMPI_Type_size(type,&mysize);CHKERRQ(_myierr);
335: for(p = 0; p < commsize; ++p) {
336: *buff += (PetscLogDouble) (counts[p]*mysize);
337: }
338: return 0;
339: }
341: #define MPI_Irecv(buf,count,datatype,source,tag,comm,request) \
342: ((petsc_irecv_ct++,0) || PetscMPITypeSize(&petsc_irecv_len,count,datatype) || MPI_Irecv(buf,count,datatype,source,tag,comm,request))
344: #define MPI_Isend(buf,count,datatype,dest,tag,comm,request) \
345: ((petsc_isend_ct++,0) || PetscMPITypeSize(&petsc_isend_len,count,datatype) || MPI_Isend(buf,count,datatype,dest,tag,comm,request))
347: #define MPI_Startall_irecv(count,number,requests) \
348: ((petsc_irecv_ct += (PetscLogDouble)(number),0) || PetscMPITypeSize(&petsc_irecv_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
350: #define MPI_Startall_isend(count,number,requests) \
351: ((petsc_isend_ct += (PetscLogDouble)(number),0) || PetscMPITypeSize(&petsc_isend_len,count,MPIU_SCALAR) || MPI_Startall(number,requests))
353: #define MPI_Start_isend(count,requests) \
354: ((petsc_isend_ct++,0) || PetscMPITypeSize(&petsc_isend_len,count,MPIU_SCALAR) || MPI_Start(requests))
356: #define MPI_Recv(buf,count,datatype,source,tag,comm,status) \
357: ((petsc_recv_ct++,0) || PetscMPITypeSize(&petsc_recv_len,count,datatype) || MPI_Recv(buf,count,datatype,source,tag,comm,status))
359: #define MPI_Send(buf,count,datatype,dest,tag,comm) \
360: ((petsc_send_ct++,0) || PetscMPITypeSize(&petsc_send_len,count,datatype) || MPI_Send(buf,count,datatype,dest,tag,comm))
362: #define MPI_Wait(request,status) \
363: ((petsc_wait_ct++,petsc_sum_of_waits_ct++,0) || MPI_Wait(request,status))
364:
365: #define MPI_Waitany(a,b,c,d) \
366: ((petsc_wait_any_ct++,petsc_sum_of_waits_ct++,0) || MPI_Waitany(a,b,c,d))
368: #define MPI_Waitall(count,array_of_requests,array_of_statuses) \
369: ((petsc_wait_all_ct++,petsc_sum_of_waits_ct += (PetscLogDouble) (count),0) || MPI_Waitall(count,array_of_requests,array_of_statuses))
371: #define MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm) \
372: ((petsc_allreduce_ct++,0) || MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm))
374: #define MPI_Alltoall(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm) \
375: ((petsc_allreduce_ct++,0) || PetscMPITypeSize(&petsc_send_len,sendcount,sendtype) || MPI_Alltoall(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm))
377: #define MPI_Alltoallv(sendbuf,sendcnts,sdispls,sendtype,recvbuf,recvcnts,rdispls,recvtype,comm) \
378: ((petsc_allreduce_ct++,0) || PetscMPITypeSizeComm(comm,&petsc_send_len,sendcnts,sendtype) || MPI_Alltoallv(sendbuf,sendcnts,sdispls,sendtype,recvbuf,recvcnts,rdispls,recvtype,comm))
380: #define MPI_Allgather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm) \
381: ((petsc_gather_ct++,0) || MPI_Allgather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,comm))
383: #define MPI_Allgatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,comm) \
384: ((petsc_gather_ct++,0) || MPI_Allgatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,comm))
386: #define MPI_Gather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm) \
387: ((petsc_gather_ct++,0) || PetscMPITypeSize(&petsc_send_len,sendcount,sendtype) || MPI_Gather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm))
389: #define MPI_Gatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,root,comm) \
390: ((petsc_gather_ct++,0) || PetscMPITypeSize(&petsc_send_len,sendcount,sendtype) || MPI_Gatherv(sendbuf,sendcount,sendtype,recvbuf,recvcount,displs,recvtype,root,comm))
392: #define MPI_Scatter(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm) \
393: ((petsc_scatter_ct++,0) || PetscMPITypeSize(&petsc_recv_len,recvcount,recvtype) || MPI_Scatter(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm))
395: #define MPI_Scatterv(sendbuf,sendcount,displs,sendtype,recvbuf,recvcount,recvtype,root,comm) \
396: ((petsc_scatter_ct++,0) || PetscMPITypeSize(&petsc_recv_len,recvcount,recvtype) || MPI_Scatterv(sendbuf,sendcount,displs,sendtype,recvbuf,recvcount,recvtype,root,comm))
398: #else
400: #define MPI_Startall_irecv(count,number,requests) \
401: (MPI_Startall(number,requests))
403: #define MPI_Startall_isend(count,number,requests) \
404: (MPI_Startall(number,requests))
406: #define MPI_Start_isend(count,requests) \
407: (MPI_Start(requests))
409: #endif /* !__MPIUNI_H && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */
411: #else /* ---Logging is turned off --------------------------------------------*/
413: #define PetscLogFlops(n) 0
414: #define PetscLogFlopsNoError(n)
416: /*
417: With logging turned off, then MPE has to be turned off
418: */
419: #define PetscLogMPEBegin() 0
420: #define PetscLogMPEDump(a) 0
422: #define PetscLogEventActivate(a) 0
423: #define PetscLogEventDeactivate(a) 0
425: #define PetscLogEventActivateClass(a) 0
426: #define PetscLogEventDeactivateClass(a) 0
427: #define PetscLogEventSetActiveAll(a,b) 0
429: #define _PetscLogPLB 0
430: #define _PetscLogPLE 0
431: #define _PetscLogPHC 0
432: #define _PetscLogPHD 0
433: #define PetscGetFlops(a) (*(a) = 0.0,0)
434: #define PetscLogEventBegin(e,o1,o2,o3,o4) 0
435: #define PetscLogEventEnd(e,o1,o2,o3,o4) 0
436: #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0
437: #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) 0
438: #define PetscLogObjectParent(p,c) 0
439: #define PetscLogObjectParents(p,n,c) 0
440: #define PetscLogObjectCreate(h) 0
441: #define PetscLogObjectDestroy(h) 0
442: #define PetscLogObjectMemory(p,m) 0
443: #define PetscLogDestroy() 0
444: #define PetscLogStagePush(a) 0
445: #define PetscLogStagePop() 0
446: #define PetscLogStageRegister(a,b) 0
447: #define PetscLogStagePrint(a,flg) 0
448: #define PetscLogView(viewer) 0
449: #define PetscLogViewPython(viewer) 0
450: #define PetscLogPrintDetailed(comm,file) 0
451: #define PetscLogBegin() 0
452: #define PetscLogTraceBegin(file) 0
453: #define PetscLogSet(lb,le) 0
454: #define PetscLogAllBegin() 0
455: #define PetscLogDump(c) 0
456: #define PetscLogEventRegister(a,b,c) 0
457: #define PetscLogObjects(a) 0
458: #define PetscLogActions(a) 0
461: /* If PETSC_USE_LOG is NOT defined, these still need to be! */
462: #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests)
463: #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests)
464: #define MPI_Start_isend(count,requests) MPI_Start(requests)
465: #define PetscLogStageGetId(a,b) (*(b)=0,0)
466: #define PetscLogStageSetActive(a,b) 0
467: #define PetscLogStageGetActive(a,b) 0
468: #define PetscLogStageGetVisible(a,b) 0
469: #define PetscLogStageSetVisible(a,b) 0
471: #endif /* PETSC_USE_LOG */
482: /*@C
483: PetscLogGetStageLog - This function returns the default stage logging object.
485: Not collective
487: Output Parameter:
488: . stageLog - The default PetscStageLog
490: Level: developer
492: Developer Notes: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
494: .keywords: log, stage
495: .seealso: PetscStageLogCreate()
496: @*/
497: PETSC_STATIC_INLINE PetscErrorCode PetscLogGetStageLog(PetscStageLog *stageLog)
498: {
501: if (!_stageLog) {
502: fprintf(stderr, "PETSC ERROR: Logging has not been enabled.\nYou might have forgotten to call PetscInitialize().\n");
503: MPI_Abort(MPI_COMM_WORLD, PETSC_ERR_SUP);
504: }
505: *stageLog = _stageLog;
506: return(0);
507: }
511: /*@C
512: PetscStageLogGetCurrent - This function returns the stage from the top of the stack.
514: Not Collective
516: Input Parameter:
517: . stageLog - The PetscStageLog
519: Output Parameter:
520: . stage - The current stage
522: Notes:
523: If no stage is currently active, stage is set to -1.
525: Level: developer
527: Developer Notes: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
529: .keywords: log, stage
530: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
531: @*/
532: PETSC_STATIC_INLINE PetscErrorCode PetscStageLogGetCurrent(PetscStageLog stageLog, int *stage)
533: {
534: PetscBool empty;
538: PetscIntStackEmpty(stageLog->stack, &empty);
539: if (empty) {
540: *stage = -1;
541: } else {
542: PetscIntStackTop(stageLog->stack, stage);
543: }
544: #ifdef PETSC_USE_DEBUG
545: if (*stage != stageLog->curStage) {
546: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Inconsistency in stage log: stage %d should be %d", *stage, stageLog->curStage);
547: }
548: #endif
549: return(0);
550: }
554: /*@C
555: PetscStageLogGetEventPerfLog - This function returns the PetscEventPerfLog for the given stage.
557: Not Collective
559: Input Parameters:
560: + stageLog - The PetscStageLog
561: - stage - The stage
563: Output Parameter:
564: . eventLog - The PetscEventPerfLog
566: Level: developer
568: Developer Notes: Inline since called for EACH PetscEventLogBeginDefault() and PetscEventLogEndDefault()
570: .keywords: log, stage
571: .seealso: PetscStageLogPush(), PetscStageLogPop(), PetscLogGetStageLog()
572: @*/
573: PETSC_STATIC_INLINE PetscErrorCode PetscStageLogGetEventPerfLog(PetscStageLog stageLog, int stage, PetscEventPerfLog *eventLog)
574: {
577: if ((stage < 0) || (stage >= stageLog->numStages)) {
578: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Invalid stage %d should be in [0,%d)", stage, stageLog->numStages);
579: }
580: *eventLog = stageLog->stageInfo[stage].eventLog;
581: return(0);
582: }
584: /* Special support for C++ */
585: #include petsclog.hh
587: #define PetscPreLoadBegin(flag,name) \
588: do {\
589: PetscBool PetscPreLoading = flag;\
590: int PetscPreLoadMax,PetscPreLoadIt;\
591: PetscLogStage _stageNum;\
592: PetscErrorCode _3_ierr; \
593: _3_PetscOptionsGetBool(PETSC_NULL,"-preload",&PetscPreLoading,PETSC_NULL);CHKERRQ(_3_ierr);\
594: PetscPreLoadMax = (int)(PetscPreLoading);\
595: PetscPreLoadingUsed = PetscPreLoading ? PETSC_TRUE : PetscPreLoadingUsed;\
596: for (PetscPreLoadIt=0; PetscPreLoadIt<=PetscPreLoadMax; PetscPreLoadIt++) {\
597: PetscPreLoadingOn = PetscPreLoading;\
598: _3_PetscBarrier(PETSC_NULL);CHKERRQ(_3_ierr);\
599: if (PetscPreLoadIt>0) {\
600: _3_PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\
601: } else {\
602: _3_PetscLogStageRegister(name,&_stageNum);CHKERRQ(_3_ierr); \
603: }\
604: _3_PetscLogStageSetActive(_stageNum,(PetscBool)(!PetscPreLoadMax || PetscPreLoadIt));\
605: _3_PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr);
607: #define PetscPreLoadEnd() \
608: _3_PetscLogStagePop();CHKERRQ(_3_ierr);\
609: PetscPreLoading = PETSC_FALSE;\
610: }\
611: } while (0)
613: #define PetscPreLoadStage(name) do { \
614: _3_PetscLogStagePop();CHKERRQ(_3_ierr); \
615: if (PetscPreLoadIt>0) { \
616: _3_PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr); \
617: } else { \
618: _3_PetscLogStageRegister(name,&_stageNum);CHKERRQ(_3_ierr); \
619: } \
620: _3_PetscLogStageSetActive(_stageNum,(PetscBool)(!PetscPreLoadMax || PetscPreLoadIt)); \
621: _3_PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr); \
622: } while (0)
625: #endif