1 /* $Id: petsclog.h,v 1.155 2001/09/06 14:51:20 bsmith Exp $ */ 2 3 /* 4 Defines profile/logging in PETSc. 5 */ 6 7 #if !defined(__PetscLog_H) 8 #define __PetscLog_H 9 #include "petsc.h" 10 11 /* 12 Each PETSc object class has it's own cookie (internal integer in the 13 data structure used for error checking). These are all defined by an offset 14 from the lowest one, PETSC_COOKIE. 15 */ 16 #define PETSC_COOKIE 1211211 17 extern int PETSC_LARGEST_COOKIE; 18 #define PETSC_EVENT 1311311 19 extern int PETSC_LARGEST_EVENT; 20 21 /* Events for the Petsc standard library */ 22 extern int PETSC_Barrier; 23 24 /* Global flop counter */ 25 extern PetscLogDouble _TotalFlops; 26 27 /* General logging of information; different from event logging */ 28 EXTERN int PetscLogInfo(void*,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3); 29 EXTERN int PetscLogInfoDeactivateClass(int); 30 EXTERN int PetscLogInfoActivateClass(int); 31 extern PetscTruth PetscLogPrintInfo; /* if true, indicates PetscLogInfo() is turned on */ 32 33 #if defined(PETSC_USE_LOG) /* --- Logging is turned on --------------------------------*/ 34 35 /* 36 Flop counting: We count each arithmetic operation (e.g., addition, multiplication) separately. 37 38 For the complex numbers version, note that 39 1 complex addition = 2 flops 40 1 complex multiplication = 6 flops, 41 where we define 1 flop as that for a double precision scalar. We roughly approximate 42 flop counting for complex numbers by multiplying the total flops by 4; this corresponds 43 to the assumption that we're counting mostly additions and multiplications -- and 44 roughly the same number of each. More accurate counting could be done by distinguishing 45 among the various arithmetic operations. 46 */ 47 48 #if defined(PETSC_USE_COMPLEX) 49 #define PetscLogFlops(n) (_TotalFlops += (4*n),0) 50 #else 51 #define PetscLogFlops(n) (_TotalFlops += (n),0) 52 #endif 53 54 #if defined (PETSC_HAVE_MPE) 55 #include "mpe.h" 56 #define MPEBEGIN 1000 57 EXTERN int PetscLogMPEBegin(void); 58 EXTERN int PetscLogMPEDump(const char[]); 59 extern PetscTruth UseMPE; 60 extern int PetscLogEventMPEFlags[]; 61 EXTERN int PetscLogEventMPEActivate(int); 62 EXTERN int PetscLogEventMPEDeactivate(int); 63 #else 64 #define PetscLogEventMPEActivate(a) 0 65 #define PetscLogEventMPEDeactivate(a) 0 66 #endif 67 68 EXTERN int (*_PetscLogPLB)(int,int,PetscObject,PetscObject,PetscObject,PetscObject); 69 EXTERN int (*_PetscLogPLE)(int,int,PetscObject,PetscObject,PetscObject,PetscObject); 70 EXTERN int (*_PetscLogPHC)(PetscObject); 71 EXTERN int (*_PetscLogPHD)(PetscObject); 72 73 #define PetscLogObjectParent(p,c) if (c) {PetscValidHeader((PetscObject)(c)); \ 74 PetscValidHeader((PetscObject)(p));\ 75 ((PetscObject)(c))->parent = (PetscObject)(p);\ 76 ((PetscObject)(c))->parentid = ((PetscObject)p)->id;} 77 #define PetscLogObjectParents(p,n,d) {int _i; for (_i=0; _i<n; _i++) \ 78 PetscLogObjectParent(p,(d)[_i]);} 79 #define PetscLogObjectCreate(h) {if (_PetscLogPHC) (*_PetscLogPHC)((PetscObject)h);} 80 #define PetscLogObjectDestroy(h) {if (_PetscLogPHD) (*_PetscLogPHD)((PetscObject)h);} 81 #define PetscLogObjectMemory(p,m) {PetscValidHeader((PetscObject)p);\ 82 ((PetscObject)(p))->mem += (m);} 83 /* Initialization functions */ 84 EXTERN int PetscLogBegin(void); 85 EXTERN int PetscLogAllBegin(void); 86 EXTERN int PetscLogTraceBegin(FILE *); 87 /* General functions */ 88 EXTERN int PetscLogDestroy(void); 89 EXTERN int PetscLogSet(int (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject), 90 int (*)(int, int, PetscObject, PetscObject, PetscObject, PetscObject)); 91 EXTERN int PetscLogObjectState(PetscObject, const char[], ...) PETSC_PRINTF_FORMAT_CHECK(2,3); 92 /* Output functions */ 93 EXTERN int PetscLogPrintSummary(MPI_Comm, const char[]); 94 EXTERN int PetscLogDump(const char[]); 95 /* Counter functions */ 96 EXTERN int PetscGetFlops(PetscLogDouble *); 97 /* Stage functions */ 98 EXTERN int PetscLogStageRegister(int *, const char[]); 99 EXTERN int PetscLogStagePush(int); 100 EXTERN int PetscLogStagePop(void); 101 EXTERN int PetscLogStageSetVisible(int, PetscTruth); 102 EXTERN int PetscLogStageGetVisible(int, PetscTruth *); 103 EXTERN int PetscLogStageGetId(const char [], int *); 104 /* Event functions */ 105 EXTERN int PetscLogEventRegister(int *, const char[], const char[], int); 106 EXTERN int PetscLogEventActivate(int); 107 EXTERN int PetscLogEventDeactivate(int); 108 EXTERN int PetscLogEventActivateClass(int); 109 EXTERN int PetscLogEventDeactivateClass(int); 110 /* Class functions */ 111 EXTERN int PetscLogClassRegister(int *, const char []); 112 113 /* Global counters */ 114 extern PetscLogDouble irecv_ct, isend_ct, recv_ct, send_ct; 115 extern PetscLogDouble irecv_len, isend_len, recv_len, send_len; 116 extern PetscLogDouble allreduce_ct; 117 extern PetscLogDouble wait_ct, wait_any_ct, wait_all_ct, sum_of_waits_ct; 118 extern int PETSC_DUMMY, PETSC_DUMMY_SIZE; 119 120 /* We must make these structures available if we are to access the event 121 activation flags in the PetscLogEventBegin/End() macros. If we forced a 122 function call each time, we could leave these structures in plog.h 123 */ 124 /* Default log */ 125 typedef struct _StageLog *StageLog; 126 extern StageLog _stageLog; 127 128 /* A simple stack (should replace) */ 129 typedef struct _IntStack *IntStack; 130 131 /* The structures for logging performance */ 132 typedef struct _PerfInfo { 133 int id; /* The integer identifying this section */ 134 PetscTruth active; /* The flag to activate logging */ 135 PetscTruth visible; /* The flag to print info in summary */ 136 int depth; /* The nesting depth of the event call */ 137 int count; /* The number of times this section was executed */ 138 PetscLogDouble flops; /* The flops used in this section */ 139 PetscLogDouble time; /* The time taken for this section */ 140 PetscLogDouble numMessages; /* The number of messages in this section */ 141 PetscLogDouble messageLength; /* The total message lengths in this section */ 142 PetscLogDouble numReductions; /* The number of reductions in this section */ 143 } PerfInfo; 144 145 typedef struct _ClassPerfInfo { 146 int id; /* The integer identifying this class */ 147 int creations; /* The number of objects of this class created */ 148 int destructions; /* The number of objects of this class destroyed */ 149 PetscLogDouble mem; /* The total memory allocated by objects of this class */ 150 PetscLogDouble descMem; /* The total memory allocated by descendents of these objects */ 151 } ClassPerfInfo; 152 153 /* The structures for logging registration */ 154 typedef struct _ClassRegInfo { 155 char *name; /* The class name */ 156 int cookie; /* The integer identifying this class */ 157 } ClassRegInfo; 158 159 typedef struct _EventRegInfo { 160 char *name; /* The name of this event */ 161 int cookie; /* The class id for this event (should maybe give class ID instead) */ 162 } EventRegInfo; 163 164 /* The structure for logging events */ 165 typedef int PetscEvent; 166 167 typedef struct _EventRegLog *EventRegLog; 168 struct _EventRegLog { 169 int numEvents; /* The number of registered events */ 170 int maxEvents; /* The maximum number of events */ 171 EventRegInfo *eventInfo; /* The registration information for each event */ 172 }; 173 174 typedef struct _EventPerfLog *EventPerfLog; 175 struct _EventPerfLog { 176 int numEvents; /* The number of logging events */ 177 int maxEvents; /* The maximum number of events */ 178 PerfInfo *eventInfo; /* The performance information for each event */ 179 }; 180 181 /* The structure for logging class information */ 182 typedef struct _ClassRegLog *ClassRegLog; 183 struct _ClassRegLog { 184 int numClasses; /* The number of classes registered */ 185 int maxClasses; /* The maximum number of classes */ 186 ClassRegInfo *classInfo; /* The structure for class information (cookies are monotonicly increasing) */ 187 }; 188 189 typedef struct _ClassPerfLog *ClassPerfLog; 190 struct _ClassPerfLog { 191 int numClasses; /* The number of logging classes */ 192 int maxClasses; /* The maximum number of classes */ 193 ClassPerfInfo *classInfo; /* The structure for class information (cookies are monotonicly increasing) */ 194 }; 195 196 /* The structures for logging in stages */ 197 typedef struct _StageInfo { 198 char *name; /* The stage name */ 199 PerfInfo perfInfo; /* The stage performance information */ 200 EventPerfLog eventLog; /* The event information for this stage */ 201 ClassPerfLog classLog; /* The class information for this stage */ 202 } StageInfo; 203 204 struct _StageLog { 205 /* Size information */ 206 int numStages; /* The number of registered stages */ 207 int maxStages; /* The maximum number of stages */ 208 /* Runtime information */ 209 IntStack stack; /* The stack for active stages */ 210 int curStage; /* The current stage (only used in macros so we don't call StackTop) */ 211 /* Stage specific information */ 212 StageInfo *stageInfo; /* The information for each stage */ 213 EventRegLog eventLog; /* The registered events */ 214 ClassRegLog classLog; /* The registered classes */ 215 }; 216 217 #if defined(PETSC_HAVE_MPE) 218 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \ 219 0; { int _1_ierr; \ 220 if (_PetscLogPLB && _stageLog->eventLog[_stageLog->curStage]->eventInfo[e].active) { \ 221 _1_ierr = PetscLogEventBegin((e),o1,o2,o3,o4);CHKERRQ(_1_ierr); \ 222 if (UseMPE && PetscLogEventMPEFlags[(e)]) \ 223 MPE_Log_event(MPEBEGIN+2*(e),0,""); \ 224 _1_ierr = MPI_Barrier(cm);CHKERRQ(_1_ierr); \ 225 _1_ierr = PetscLogEventEnd((e),o1,o2,o3,o4);CHKERRQ(_1_ierr); \ 226 if (UseMPE && PetscLogEventMPEFlags[(e)]) \ 227 MPE_Log_event(MPEBEGIN+2*((e)+1),0,""); \ 228 } \ 229 _1_ierr = PetscLogEventBegin(e+1,o1,o2,o3,o4);CHKERRQ(_1_ierr); \ 230 if (UseMPE && PetscLogEventMPEFlags[(e)+1]) \ 231 MPE_Log_event(MPEBEGIN+2*((e)+1),0,""); \ 232 } 233 #define PetscLogEventBegin(e,o1,o2,o3,o4) \ 234 0; { \ 235 if (_PetscLogPLB && _stageLog->eventLog[_stageLog->curStage]->eventInfo[e].active) {\ 236 (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 237 if (UseMPE && PetscLogEventMPEFlags[(e)])\ 238 MPE_Log_event(MPEBEGIN+2*(e),0,"");\ 239 } 240 #else 241 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \ 242 0; { int _2_ierr;\ 243 if (_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) { \ 244 _2_ierr = PetscLogEventBegin((e),o1,o2,o3,o4);CHKERRQ(_2_ierr); \ 245 _2_ierr = MPI_Barrier(cm);CHKERRQ(_2_ierr); \ 246 _2_ierr = PetscLogEventEnd((e),o1,o2,o3,o4);CHKERRQ(_2_ierr); \ 247 } \ 248 _2_ierr = PetscLogEventBegin((e)+1,o1,o2,o3,o4);CHKERRQ(_2_ierr); \ 249 } 250 #define PetscLogEventBegin(e,o1,o2,o3,o4) \ 251 0; { \ 252 if (_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {\ 253 (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 254 } 255 #endif 256 257 #if defined(PETSC_HAVE_MPE) 258 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4) 259 #define PetscLogEventEnd(e,o1,o2,o3,o4) \ 260 0; { \ 261 if (_PetscLogPLE && _stageLog->eventLog[_stageLog->curStage]->eventInfo[e].active) {\ 262 (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 263 if (UseMPE && PetscLogEventMPEFlags[(e)])\ 264 MPE_Log_event(MPEBEGIN+2*(e)+1,0,"");\ 265 } 266 #else 267 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4) 268 #define PetscLogEventEnd(e,o1,o2,o3,o4) \ 269 0; { \ 270 if (_PetscLogPLE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {\ 271 (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 272 } 273 #endif 274 275 /* 276 This does not work for MPI-Uni because our src/mpiuni/mpi.h file 277 uses macros to defined the MPI operations. 278 279 It does not work correctly from HP-UX because it processes the 280 macros in a way that sometimes it double counts, hence 281 PETSC_HAVE_BROKEN_RECURSIVE_MACRO 282 283 It does not work with Windows NT because winmpich lacks MPI_Type_size() 284 */ 285 #if !defined(PETSC_HAVE_MPI_UNI) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO) && !defined (PETSC_HAVE_MPI_MISSING_TYPESIZE) 286 /* 287 Logging of MPI activities 288 */ 289 290 #define TypeSize(buff,count,type) \ 291 (\ 292 MPI_Type_size(type,&PETSC_DUMMY_SIZE),buff += ((PetscLogDouble) ((count)*PETSC_DUMMY_SIZE)) \ 293 ) 294 295 #define MPI_Irecv(buf,count, datatype,source,tag,comm,request) \ 296 (\ 297 PETSC_DUMMY = MPI_Irecv(buf,count, datatype,source,tag,comm,request), \ 298 irecv_ct++,TypeSize(irecv_len,count,datatype),PETSC_DUMMY \ 299 ) 300 301 #define MPI_Isend(buf,count, datatype,dest,tag,comm,request) \ 302 (\ 303 PETSC_DUMMY = MPI_Isend(buf,count, datatype,dest,tag,comm,request), \ 304 isend_ct++, TypeSize(isend_len,count,datatype),PETSC_DUMMY \ 305 ) 306 307 #define MPI_Startall_irecv(count,number,requests) \ 308 (\ 309 PETSC_DUMMY = MPI_Startall(number,requests), \ 310 irecv_ct += (PetscLogDouble)(number),irecv_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY \ 311 ) 312 313 #define MPI_Startall_isend(count,number,requests) \ 314 (\ 315 PETSC_DUMMY = MPI_Startall(number,requests), \ 316 isend_ct += (PetscLogDouble)(number),isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY \ 317 ) 318 319 #define MPI_Start_isend(count, requests)\ 320 (\ 321 PETSC_DUMMY = MPI_Start(requests),\ 322 isend_ct++,isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY\ 323 ) 324 325 #define MPI_Recv(buf,count, datatype,source,tag,comm,status) \ 326 (\ 327 PETSC_DUMMY = MPI_Recv(buf,count, datatype,source,tag,comm,status), \ 328 recv_ct++,TypeSize(recv_len,count,datatype),PETSC_DUMMY \ 329 ) 330 331 #define MPI_Send(buf,count, datatype,dest,tag,comm) \ 332 (\ 333 PETSC_DUMMY = MPI_Send(buf,count, datatype,dest,tag,comm), \ 334 send_ct++, TypeSize(send_len,count,datatype),PETSC_DUMMY \ 335 ) 336 337 #define MPI_Wait(request,status) \ 338 (\ 339 wait_ct++,sum_of_waits_ct++, \ 340 MPI_Wait(request,status) \ 341 ) 342 343 #define MPI_Waitany(a,b,c,d) \ 344 (\ 345 wait_any_ct++,sum_of_waits_ct++,\ 346 MPI_Waitany(a,b,c,d) \ 347 ) 348 349 #define MPI_Waitall(count,array_of_requests,array_of_statuses) \ 350 (\ 351 wait_all_ct++,sum_of_waits_ct += (PetscLogDouble) (count), \ 352 MPI_Waitall(count,array_of_requests,array_of_statuses) \ 353 ) 354 355 #define MPI_Allreduce(sendbuf, recvbuf,count,datatype,op,comm) \ 356 (\ 357 allreduce_ct++,MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm)\ 358 ) 359 360 #else 361 362 #define MPI_Startall_irecv(count,number,requests) \ 363 (\ 364 MPI_Startall(number,requests) \ 365 ) 366 367 #define MPI_Startall_isend(count,number,requests) \ 368 (\ 369 MPI_Startall(number,requests) \ 370 ) 371 372 #define MPI_Start_isend(count, requests) \ 373 (\ 374 MPI_Start(requests) \ 375 ) 376 377 #endif /* !PETSC_HAVE_MPI_UNI && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */ 378 379 #else /* ---Logging is turned off --------------------------------------------*/ 380 381 #define PetscLogFlops(n) 0 382 383 /* 384 With logging turned off, then MPE has to be turned off 385 */ 386 #define MPEBEGIN 1000 387 #define PetscLogMPEBegin() 0 388 #define PetscLogMPEDump(a) 0 389 #define PetscLogEventMPEActivate(a) 0 390 #define PetscLogEventMPEDeactivate(a) 0 391 392 #define PetscLogEventActivate(a) 0 393 #define PetscLogEventDeactivate(a) 0 394 395 #define PetscLogEventActivateClass(a) 0 396 #define PetscLogEventDeactivateClass(a) 0 397 398 #define _PetscLogPLB 0 399 #define _PetscLogPLE 0 400 #define _PetscLogPHC 0 401 #define _PetscLogPHD 0 402 #define PetscGetFlops(a) (*(a) = 0.0,0) 403 #define PetscLogEventBegin(e,o1,o2,o3,o4) 0 404 #define PetscLogEventEnd(e,o1,o2,o3,o4) 0 405 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0 406 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) 0 407 #define PetscLogObjectParent(p,c) 408 #define PetscLogObjectParents(p,n,c) 409 #define PetscLogObjectCreate(h) 410 #define PetscLogObjectDestroy(h) 411 #define PetscLogObjectMemory(p,m) 412 #define PetscLogDestroy() 0 413 #define PetscLogStagePush(a) 0 414 #define PetscLogStagePop() 0 415 #define PetscLogStageRegister(a,b) 0 416 #define PetscLogStagePrint(a,flg) 0 417 #define PetscLogPrintSummary(comm,file) 0 418 #define PetscLogBegin() 0 419 #define PetscLogTraceBegin(file) 0 420 #define PetscLogSet(lb,le) 0 421 #define PetscLogAllBegin() 0 422 #define PetscLogDump(c) 0 423 #define PetscLogEventRegister(a,b,c,d) 0 424 EXTERN int PetscLogObjectState(PetscObject,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3); 425 426 /* If PETSC_USE_LOG is NOT defined, these still need to be! */ 427 #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests) 428 429 #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests) 430 431 #define MPI_Start_isend(count,requests) MPI_Start(requests) 432 433 #endif /* PETSC_USE_LOG */ 434 435 extern PetscTruth PetscPreLoadingUsed; /* true if we are or have done preloading */ 436 extern PetscTruth PetscPreLoadingOn; /* true if we are currently in a preloading calculation */ 437 438 #define PreLoadBegin(flag,name) {PetscTruth PreLoading = flag; \ 439 int PreLoadMax,PreLoadIt,_stageNum,_3_ierr;\ 440 _3_ierr = PetscOptionsGetLogical(PETSC_NULL,"-preload",&PreLoading,PETSC_NULL);CHKERRQ(_3_ierr);\ 441 PreLoadMax = (int)(PreLoading);PetscPreLoadingUsed = PreLoading ? PETSC_TRUE : PetscPreLoadingUsed;\ 442 for (PreLoadIt=0; PreLoadIt<=PreLoadMax; PreLoadIt++) {\ 443 PetscPreLoadingOn = PreLoading;\ 444 _3_ierr = PetscBarrier(PETSC_NULL);CHKERRQ(_3_ierr);\ 445 if (PreLoadIt>0) {\ 446 _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\ 447 } else {\ 448 _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\ 449 _3_ierr = PetscLogStageSetVisible(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\ 450 }\ 451 _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr); 452 453 #define PreLoadEnd() _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);PreLoading = PETSC_FALSE;}} 454 455 #define PreLoadStage(name) _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\ 456 if (PreLoadIt>0) {\ 457 _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\ 458 } else {\ 459 _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\ 460 _3_ierr = PetscLogStageSetVisible(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\ 461 }\ 462 _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr); 463 #endif 464