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 char *color; /* The color of this class */ 157 int cookie; /* The integer identifying this class */ 158 } ClassRegInfo; 159 160 typedef struct _EventRegInfo { 161 char *name; /* The name of this event */ 162 char *color; /* The color of this event */ 163 int cookie; /* The class id for this event (should maybe give class ID instead) */ 164 } EventRegInfo; 165 166 /* The structure for logging events */ 167 typedef int PetscEvent; 168 169 typedef struct _EventRegLog *EventRegLog; 170 struct _EventRegLog { 171 int numEvents; /* The number of registered events */ 172 int maxEvents; /* The maximum number of events */ 173 EventRegInfo *eventInfo; /* The registration information for each event */ 174 }; 175 176 typedef struct _EventPerfLog *EventPerfLog; 177 struct _EventPerfLog { 178 int numEvents; /* The number of logging events */ 179 int maxEvents; /* The maximum number of events */ 180 PerfInfo *eventInfo; /* The performance information for each event */ 181 }; 182 183 /* The structure for logging class information */ 184 typedef struct _ClassRegLog *ClassRegLog; 185 struct _ClassRegLog { 186 int numClasses; /* The number of classes registered */ 187 int maxClasses; /* The maximum number of classes */ 188 ClassRegInfo *classInfo; /* The structure for class information (cookies are monotonicly increasing) */ 189 }; 190 191 typedef struct _ClassPerfLog *ClassPerfLog; 192 struct _ClassPerfLog { 193 int numClasses; /* The number of logging classes */ 194 int maxClasses; /* The maximum number of classes */ 195 ClassPerfInfo *classInfo; /* The structure for class information (cookies are monotonicly increasing) */ 196 }; 197 198 /* The structures for logging in stages */ 199 typedef struct _StageInfo { 200 char *name; /* The stage name */ 201 char *color; /* The color of this stage */ 202 PerfInfo perfInfo; /* The stage performance information */ 203 EventPerfLog eventLog; /* The event information for this stage */ 204 ClassPerfLog classLog; /* The class information for this stage */ 205 } StageInfo; 206 207 struct _StageLog { 208 /* Size information */ 209 int numStages; /* The number of registered stages */ 210 int maxStages; /* The maximum number of stages */ 211 /* Runtime information */ 212 IntStack stack; /* The stack for active stages */ 213 int curStage; /* The current stage (only used in macros so we don't call StackTop) */ 214 /* Stage specific information */ 215 StageInfo *stageInfo; /* The information for each stage */ 216 EventRegLog eventLog; /* The registered events */ 217 ClassRegLog classLog; /* The registered classes */ 218 }; 219 220 #if defined(PETSC_HAVE_MPE) 221 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \ 222 0; { int _1_ierr; \ 223 if (_PetscLogPLB && _stageLog->eventLog[_stageLog->curStage]->eventInfo[e].active) { \ 224 _1_ierr = PetscLogEventBegin((e),o1,o2,o3,o4);CHKERRQ(_1_ierr); \ 225 if (UseMPE && PetscLogEventMPEFlags[(e)]) \ 226 MPE_Log_event(MPEBEGIN+2*(e),0,""); \ 227 _1_ierr = MPI_Barrier(cm);CHKERRQ(_1_ierr); \ 228 _1_ierr = PetscLogEventEnd((e),o1,o2,o3,o4);CHKERRQ(_1_ierr); \ 229 if (UseMPE && PetscLogEventMPEFlags[(e)]) \ 230 MPE_Log_event(MPEBEGIN+2*((e)+1),0,""); \ 231 } \ 232 _1_ierr = PetscLogEventBegin(e+1,o1,o2,o3,o4);CHKERRQ(_1_ierr); \ 233 if (UseMPE && PetscLogEventMPEFlags[(e)+1]) \ 234 MPE_Log_event(MPEBEGIN+2*((e)+1),0,""); \ 235 } 236 #define PetscLogEventBegin(e,o1,o2,o3,o4) \ 237 0; { \ 238 if (_PetscLogPLB && _stageLog->eventLog[_stageLog->curStage]->eventInfo[e].active) {\ 239 (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 240 if (UseMPE && PetscLogEventMPEFlags[(e)])\ 241 MPE_Log_event(MPEBEGIN+2*(e),0,"");\ 242 } 243 #else 244 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) \ 245 0; { int _2_ierr;\ 246 if (_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) { \ 247 _2_ierr = PetscLogEventBegin((e),o1,o2,o3,o4);CHKERRQ(_2_ierr); \ 248 _2_ierr = MPI_Barrier(cm);CHKERRQ(_2_ierr); \ 249 _2_ierr = PetscLogEventEnd((e),o1,o2,o3,o4);CHKERRQ(_2_ierr); \ 250 } \ 251 _2_ierr = PetscLogEventBegin((e)+1,o1,o2,o3,o4);CHKERRQ(_2_ierr); \ 252 } 253 #define PetscLogEventBegin(e,o1,o2,o3,o4) \ 254 0; { \ 255 if (_PetscLogPLB && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {\ 256 (*_PetscLogPLB)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 257 } 258 #endif 259 260 #if defined(PETSC_HAVE_MPE) 261 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4) 262 #define PetscLogEventEnd(e,o1,o2,o3,o4) \ 263 0; { \ 264 if (_PetscLogPLE && _stageLog->eventLog[_stageLog->curStage]->eventInfo[e].active) {\ 265 (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 266 if (UseMPE && PetscLogEventMPEFlags[(e)])\ 267 MPE_Log_event(MPEBEGIN+2*(e)+1,0,"");\ 268 } 269 #else 270 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) PetscLogEventEnd(e+1,o1,o2,o3,o4) 271 #define PetscLogEventEnd(e,o1,o2,o3,o4) \ 272 0; { \ 273 if (_PetscLogPLE && _stageLog->stageInfo[_stageLog->curStage].eventLog->eventInfo[e].active) {\ 274 (*_PetscLogPLE)((e),0,(PetscObject)(o1),(PetscObject)(o2),(PetscObject)(o3),(PetscObject)(o4));}\ 275 } 276 #endif 277 278 /* 279 This does not work for MPI-Uni because our src/mpiuni/mpi.h file 280 uses macros to defined the MPI operations. 281 282 It does not work correctly from HP-UX because it processes the 283 macros in a way that sometimes it double counts, hence 284 PETSC_HAVE_BROKEN_RECURSIVE_MACRO 285 286 It does not work with Windows NT because winmpich lacks MPI_Type_size() 287 */ 288 #if !defined(PETSC_HAVE_MPI_UNI) && !defined(PETSC_HAVE_BROKEN_RECURSIVE_MACRO) && !defined (PETSC_HAVE_MPI_MISSING_TYPESIZE) 289 /* 290 Logging of MPI activities 291 */ 292 293 #define TypeSize(buff,count,type) \ 294 (\ 295 MPI_Type_size(type,&PETSC_DUMMY_SIZE),buff += ((PetscLogDouble) ((count)*PETSC_DUMMY_SIZE)) \ 296 ) 297 298 #define MPI_Irecv(buf,count, datatype,source,tag,comm,request) \ 299 (\ 300 PETSC_DUMMY = MPI_Irecv(buf,count, datatype,source,tag,comm,request), \ 301 irecv_ct++,TypeSize(irecv_len,count,datatype),PETSC_DUMMY \ 302 ) 303 304 #define MPI_Isend(buf,count, datatype,dest,tag,comm,request) \ 305 (\ 306 PETSC_DUMMY = MPI_Isend(buf,count, datatype,dest,tag,comm,request), \ 307 isend_ct++, TypeSize(isend_len,count,datatype),PETSC_DUMMY \ 308 ) 309 310 #define MPI_Startall_irecv(count,number,requests) \ 311 (\ 312 PETSC_DUMMY = MPI_Startall(number,requests), \ 313 irecv_ct += (PetscLogDouble)(number),irecv_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY \ 314 ) 315 316 #define MPI_Startall_isend(count,number,requests) \ 317 (\ 318 PETSC_DUMMY = MPI_Startall(number,requests), \ 319 isend_ct += (PetscLogDouble)(number),isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY \ 320 ) 321 322 #define MPI_Start_isend(count, requests)\ 323 (\ 324 PETSC_DUMMY = MPI_Start(requests),\ 325 isend_ct++,isend_len += ((PetscLogDouble) ((count)*sizeof(PetscScalar))),PETSC_DUMMY\ 326 ) 327 328 #define MPI_Recv(buf,count, datatype,source,tag,comm,status) \ 329 (\ 330 PETSC_DUMMY = MPI_Recv(buf,count, datatype,source,tag,comm,status), \ 331 recv_ct++,TypeSize(recv_len,count,datatype),PETSC_DUMMY \ 332 ) 333 334 #define MPI_Send(buf,count, datatype,dest,tag,comm) \ 335 (\ 336 PETSC_DUMMY = MPI_Send(buf,count, datatype,dest,tag,comm), \ 337 send_ct++, TypeSize(send_len,count,datatype),PETSC_DUMMY \ 338 ) 339 340 #define MPI_Wait(request,status) \ 341 (\ 342 wait_ct++,sum_of_waits_ct++, \ 343 MPI_Wait(request,status) \ 344 ) 345 346 #define MPI_Waitany(a,b,c,d) \ 347 (\ 348 wait_any_ct++,sum_of_waits_ct++,\ 349 MPI_Waitany(a,b,c,d) \ 350 ) 351 352 #define MPI_Waitall(count,array_of_requests,array_of_statuses) \ 353 (\ 354 wait_all_ct++,sum_of_waits_ct += (PetscLogDouble) (count), \ 355 MPI_Waitall(count,array_of_requests,array_of_statuses) \ 356 ) 357 358 #define MPI_Allreduce(sendbuf, recvbuf,count,datatype,op,comm) \ 359 (\ 360 allreduce_ct++,MPI_Allreduce(sendbuf,recvbuf,count,datatype,op,comm)\ 361 ) 362 363 #else 364 365 #define MPI_Startall_irecv(count,number,requests) \ 366 (\ 367 MPI_Startall(number,requests) \ 368 ) 369 370 #define MPI_Startall_isend(count,number,requests) \ 371 (\ 372 MPI_Startall(number,requests) \ 373 ) 374 375 #define MPI_Start_isend(count, requests) \ 376 (\ 377 MPI_Start(requests) \ 378 ) 379 380 #endif /* !PETSC_HAVE_MPI_UNI && ! PETSC_HAVE_BROKEN_RECURSIVE_MACRO */ 381 382 #else /* ---Logging is turned off --------------------------------------------*/ 383 384 #define PetscLogFlops(n) 0 385 386 /* 387 With logging turned off, then MPE has to be turned off 388 */ 389 #define MPEBEGIN 1000 390 #define PetscLogMPEBegin() 0 391 #define PetscLogMPEDump(a) 0 392 #define PetscLogEventMPEActivate(a) 0 393 #define PetscLogEventMPEDeactivate(a) 0 394 395 #define PetscLogEventActivate(a) 0 396 #define PetscLogEventDeactivate(a) 0 397 398 #define PetscLogEventActivateClass(a) 0 399 #define PetscLogEventDeactivateClass(a) 0 400 401 #define _PetscLogPLB 0 402 #define _PetscLogPLE 0 403 #define _PetscLogPHC 0 404 #define _PetscLogPHD 0 405 #define PetscGetFlops(a) (*(a) = 0.0,0) 406 #define PetscLogEventBegin(e,o1,o2,o3,o4) 0 407 #define PetscLogEventEnd(e,o1,o2,o3,o4) 0 408 #define PetscLogEventBarrierBegin(e,o1,o2,o3,o4,cm) 0 409 #define PetscLogEventBarrierEnd(e,o1,o2,o3,o4,cm) 0 410 #define PetscLogObjectParent(p,c) 411 #define PetscLogObjectParents(p,n,c) 412 #define PetscLogObjectCreate(h) 413 #define PetscLogObjectDestroy(h) 414 #define PetscLogObjectMemory(p,m) 415 #define PetscLogDestroy() 0 416 #define PetscLogStagePush(a) 0 417 #define PetscLogStagePop() 0 418 #define PetscLogStageRegister(a,b) 0 419 #define PetscLogStagePrint(a,flg) 0 420 #define PetscLogPrintSummary(comm,file) 0 421 #define PetscLogBegin() 0 422 #define PetscLogTraceBegin(file) 0 423 #define PetscLogSet(lb,le) 0 424 #define PetscLogAllBegin() 0 425 #define PetscLogDump(c) 0 426 #define PetscLogEventRegister(a,b,c,d) 0 427 EXTERN int PetscLogObjectState(PetscObject,const char[],...) PETSC_PRINTF_FORMAT_CHECK(2,3); 428 429 /* If PETSC_USE_LOG is NOT defined, these still need to be! */ 430 #define MPI_Startall_irecv(count,number,requests) MPI_Startall(number,requests) 431 432 #define MPI_Startall_isend(count,number,requests) MPI_Startall(number,requests) 433 434 #define MPI_Start_isend(count,requests) MPI_Start(requests) 435 436 #endif /* PETSC_USE_LOG */ 437 438 extern PetscTruth PetscPreLoadingUsed; /* true if we are or have done preloading */ 439 extern PetscTruth PetscPreLoadingOn; /* true if we are currently in a preloading calculation */ 440 441 #define PreLoadBegin(flag,name) {PetscTruth PreLoading = flag; \ 442 int PreLoadMax,PreLoadIt,_stageNum,_3_ierr;\ 443 _3_ierr = PetscOptionsGetLogical(PETSC_NULL,"-preload",&PreLoading,PETSC_NULL);CHKERRQ(_3_ierr);\ 444 PreLoadMax = (int)(PreLoading);PetscPreLoadingUsed = PreLoading ? PETSC_TRUE : PetscPreLoadingUsed;\ 445 for (PreLoadIt=0; PreLoadIt<=PreLoadMax; PreLoadIt++) {\ 446 PetscPreLoadingOn = PreLoading;\ 447 _3_ierr = PetscBarrier(PETSC_NULL);CHKERRQ(_3_ierr);\ 448 if (PreLoadIt>0) {\ 449 _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\ 450 } else {\ 451 _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\ 452 _3_ierr = PetscLogStageSetVisible(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\ 453 }\ 454 _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr); 455 456 #define PreLoadEnd() _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);PreLoading = PETSC_FALSE;}} 457 458 #define PreLoadStage(name) _3_ierr = PetscLogStagePop();CHKERRQ(_3_ierr);\ 459 if (PreLoadIt>0) {\ 460 _3_ierr = PetscLogStageGetId(name,&_stageNum);CHKERRQ(_3_ierr);\ 461 } else {\ 462 _3_ierr = PetscLogStageRegister(&_stageNum,name);CHKERRQ(_3_ierr);\ 463 _3_ierr = PetscLogStageSetVisible(_stageNum,(PetscTruth)(!PreLoadMax || PreLoadIt));\ 464 }\ 465 _3_ierr = PetscLogStagePush(_stageNum);CHKERRQ(_3_ierr); 466 #endif 467