1 /* 2 Contains all error handling code for PETSc. 3 */ 4 #if !defined(__PETSCERROR_H) 5 #define __PETSCERROR_H 6 #include "petsc.h" 7 PETSC_EXTERN_CXX_BEGIN 8 9 #if defined(PETSC_HAVE_AMS) 10 #include "ams.h" 11 #endif 12 13 /* 14 Defines the directory where the compiled source is located; used 15 in printing error messages. Each makefile has an entry 16 LOCDIR = thedirectory 17 and bmake/common_variables includes in CCPPFLAGS -D__SDIR__='"${LOCDIR}"' 18 which is a flag passed to the C/C++ compilers. 19 */ 20 #if !defined(__SDIR__) 21 #define __SDIR__ "unknowndirectory/" 22 #endif 23 24 /* 25 Defines the function where the compiled source is located; used 26 in printing error messages. 27 */ 28 #if !defined(__FUNCT__) 29 #define __FUNCT__ "User provided function" 30 #endif 31 32 /* 33 These are the generic error codes. These error codes are used 34 many different places in the PETSc source code. The string versions are 35 at src/sys/src/error/err.c any changes here must also be made there 36 37 */ 38 #define PETSC_ERR_MEM 55 /* unable to allocate requested memory */ 39 #define PETSC_ERR_MEM_MALLOC_0 85 /* cannot malloc zero size */ 40 #define PETSC_ERR_SUP 56 /* no support for requested operation */ 41 #define PETSC_ERR_SUP_SYS 57 /* no support for requested operation on this computer system */ 42 #define PETSC_ERR_ORDER 58 /* operation done in wrong order */ 43 #define PETSC_ERR_SIG 59 /* signal received */ 44 #define PETSC_ERR_FP 72 /* floating point exception */ 45 #define PETSC_ERR_COR 74 /* corrupted PETSc object */ 46 #define PETSC_ERR_LIB 76 /* error in library called by PETSc */ 47 #define PETSC_ERR_PLIB 77 /* PETSc library generated inconsistent data */ 48 #define PETSC_ERR_MEMC 78 /* memory corruption */ 49 #define PETSC_ERR_CONV_FAILED 82 /* iterative method (KSP or SNES) failed */ 50 51 #define PETSC_ERR_ARG_SIZ 60 /* nonconforming object sizes used in operation */ 52 #define PETSC_ERR_ARG_IDN 61 /* two arguments not allowed to be the same */ 53 #define PETSC_ERR_ARG_WRONG 62 /* wrong argument (but object probably ok) */ 54 #define PETSC_ERR_ARG_CORRUPT 64 /* null or corrupted PETSc object as argument */ 55 #define PETSC_ERR_ARG_OUTOFRANGE 63 /* input argument, out of range */ 56 #define PETSC_ERR_ARG_BADPTR 68 /* invalid pointer argument */ 57 #define PETSC_ERR_ARG_NOTSAMETYPE 69 /* two args must be same object type */ 58 #define PETSC_ERR_ARG_NOTSAMECOMM 80 /* two args must be same communicators */ 59 #define PETSC_ERR_ARG_WRONGSTATE 73 /* object in argument is in wrong state, e.g. unassembled mat */ 60 #define PETSC_ERR_ARG_INCOMP 75 /* two arguments are incompatible */ 61 #define PETSC_ERR_ARG_NULL 85 /* argument is null that should not be */ 62 #define PETSC_ERR_ARG_UNKNOWN_TYPE 86 /* type name doesn't match any registered type */ 63 64 #define PETSC_ERR_FILE_OPEN 65 /* unable to open file */ 65 #define PETSC_ERR_FILE_READ 66 /* unable to read from file */ 66 #define PETSC_ERR_FILE_WRITE 67 /* unable to write to file */ 67 #define PETSC_ERR_FILE_UNEXPECTED 79 /* unexpected data in file */ 68 69 #define PETSC_ERR_MAT_LU_ZRPVT 71 /* detected a zero pivot during LU factorization */ 70 #define PETSC_ERR_MAT_CH_ZRPVT 81 /* detected a zero pivot during Cholesky factorization */ 71 72 #if defined(PETSC_USE_DEBUG) 73 74 /*MC 75 SETERRQ - Macro that is called when an error has been detected, 76 77 Not Collective 78 79 Synopsis: 80 void SETERRQ(int errorcode,char *message) 81 82 83 Input Parameters: 84 + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h 85 - message - error message 86 87 Level: beginner 88 89 Notes: 90 Once the error handler is called the calling function is then returned from with the given error code. 91 92 See SETERRQ1(), SETERRQ2(), SETERRQ3() for versions that take arguments 93 94 95 Experienced users can set the error handler with PetscPushErrorHandler(). 96 97 Concepts: error^setting condition 98 99 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3() 100 M*/ 101 #define SETERRQ(n,s) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);} 102 103 /*MC 104 SETERRQ1 - Macro that is called when an error has been detected, 105 106 Not Collective 107 108 Synopsis: 109 void SETERRQ1(int errorcode,char *formatmessage,arg) 110 111 112 Input Parameters: 113 + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h 114 . message - error message in the printf format 115 - arg - argument (for example an integer, string or double) 116 117 Level: beginner 118 119 Notes: 120 Once the error handler is called the calling function is then returned from with the given error code. 121 122 Experienced users can set the error handler with PetscPushErrorHandler(). 123 124 Concepts: error^setting condition 125 126 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ(), SETERRQ2(), SETERRQ3() 127 M*/ 128 #define SETERRQ1(n,s,a1) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1);} 129 130 /*MC 131 SETERRQ2 - Macro that is called when an error has been detected, 132 133 Not Collective 134 135 Synopsis: 136 void SETERRQ2(int errorcode,char *formatmessage,arg1,arg2) 137 138 139 Input Parameters: 140 + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h 141 . message - error message in the printf format 142 . arg1 - argument (for example an integer, string or double) 143 - arg2 - argument (for example an integer, string or double) 144 145 Level: beginner 146 147 Notes: 148 Once the error handler is called the calling function is then returned from with the given error code. 149 150 Experienced users can set the error handler with PetscPushErrorHandler(). 151 152 Concepts: error^setting condition 153 154 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3() 155 M*/ 156 #define SETERRQ2(n,s,a1,a2) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2);} 157 158 /*MC 159 SETERRQ3 - Macro that is called when an error has been detected, 160 161 Not Collective 162 163 Synopsis: 164 void SETERRQ3(int errorcode,char *formatmessage,arg1,arg2,arg3) 165 166 167 Input Parameters: 168 + errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h 169 . message - error message in the printf format 170 . arg1 - argument (for example an integer, string or double) 171 . arg2 - argument (for example an integer, string or double) 172 - arg3 - argument (for example an integer, string or double) 173 174 Level: beginner 175 176 Notes: 177 Once the error handler is called the calling function is then returned from with the given error code. 178 179 Experienced users can set the error handler with PetscPushErrorHandler(). 180 181 Concepts: error^setting condition 182 183 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ2() 184 M*/ 185 #define SETERRQ3(n,s,a1,a2,a3) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3);} 186 187 #define SETERRQ4(n,s,a1,a2,a3,a4) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4);} 188 #define SETERRQ5(n,s,a1,a2,a3,a4,a5) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5);} 189 #define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5,a6);} 190 #define SETERRQ7(n,s,a1,a2,a3,a4,a5,a6,a7) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5,a6,a7);} 191 #define SETERRABORT(comm,n,s) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);MPI_Abort(comm,n);} 192 193 /*MC 194 CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns 195 196 Not Collective 197 198 Synopsis: 199 void CHKERRQ(int errorcode) 200 201 202 Input Parameters: 203 . errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h 204 205 Level: beginner 206 207 Notes: 208 Once the error handler is called the calling function is then returned from with the given error code. 209 210 Experienced users can set the error handler with PetscPushErrorHandler(). 211 212 Concepts: error^setting condition 213 214 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ2() 215 M*/ 216 #define CHKERRQ(n) if (n) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");} 217 218 #define CHKERRABORT(comm,n) if (n) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");MPI_Abort(comm,n);} 219 #define CHKERRCONTINUE(n) if (n) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");} 220 221 /*MC 222 CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected 223 224 Not Collective 225 226 Synopsis: 227 CHKMEMQ; 228 229 Level: beginner 230 231 Notes: 232 Must run with the option -trdebug to enable this option 233 234 Once the error handler is called the calling function is then returned from with the given error code. 235 236 By defaults prints location where memory that is corrupted was allocated. 237 238 Concepts: memory corruption 239 240 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ2(), 241 PetscTrValid() 242 M*/ 243 #define CHKMEMQ {int _7_ierr = PetscTrValid(__LINE__,__FUNCT__,__FILE__,__SDIR__);CHKERRQ(_7_ierr);} 244 245 #if !defined(PETSC_SKIP_UNDERSCORE_CHKERR) 246 extern PetscErrorCode __gierr; 247 #define _ __gierr = 248 #define ___ CHKERRQ(__gierr); 249 #endif 250 251 #else 252 #define SETERRQ(n,s) ; 253 #define SETERRQ1(n,s,a1) ; 254 #define SETERRQ2(n,s,a1,a2) ; 255 #define SETERRQ3(n,s,a1,a2,a3) ; 256 #define SETERRQ4(n,s,a1,a2,a3,a4) ; 257 #define SETERRABORT(comm,n,s) ; 258 259 #define CHKERRQ(n) ; 260 #define CHKERRABORT(comm,n) ; 261 #define CHKERRCONTINUE(n) ; 262 263 #define CHKMEMQ ; 264 265 #if !defined(PETSC_SKIP_UNDERSCORE_CHKERR) 266 #define _ 267 #define ___ 268 #endif 269 270 #endif 271 272 EXTERN PetscErrorCode PetscErrorMessage(int,const char*[],char **); 273 EXTERN PetscErrorCode PetscTraceBackErrorHandler(int,const char*,const char*,const char*,int,int,const char*,void*); 274 EXTERN PetscErrorCode PetscIgnoreErrorHandler(int,const char*,const char*,const char*,int,int,const char*,void*); 275 EXTERN PetscErrorCode PetscEmacsClientErrorHandler(int,const char*,const char*,const char*,int,int,const char*,void*); 276 EXTERN PetscErrorCode PetscStopErrorHandler(int,const char*,const char*,const char*,int,int,const char*,void*); 277 EXTERN PetscErrorCode PetscAbortErrorHandler(int,const char*,const char*,const char*,int,int,const char*,void*); 278 EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(int,const char*,const char*,const char*,int,int,const char*,void*); 279 EXTERN PetscErrorCode PetscError(int,const char*,const char*,const char*,int,int,const char*,...) PETSC_PRINTF_FORMAT_CHECK(7,8); 280 EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char*,const char*,const char*,int,int,const char*,void*),void*); 281 EXTERN PetscErrorCode PetscPopErrorHandler(void); 282 EXTERN PetscErrorCode PetscDefaultSignalHandler(int,void*); 283 EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*); 284 EXTERN PetscErrorCode PetscPopSignalHandler(void); 285 286 typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap; 287 EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap); 288 289 /* 290 Allows the code to build a stack frame as it runs 291 */ 292 #if defined(PETSC_USE_STACK) 293 294 #define PETSCSTACKSIZE 15 295 296 typedef struct { 297 const char *function[PETSCSTACKSIZE]; 298 const char *file[PETSCSTACKSIZE]; 299 const char *directory[PETSCSTACKSIZE]; 300 int line[PETSCSTACKSIZE]; 301 int currentsize; 302 } PetscStack; 303 304 extern PetscStack *petscstack; 305 EXTERN PetscErrorCode PetscStackCopy(PetscStack*,PetscStack*); 306 EXTERN PetscErrorCode PetscStackPrint(PetscStack*,FILE* fp); 307 308 #define PetscStackActive (petscstack != 0) 309 310 #if !defined(PETSC_HAVE_AMS) 311 312 /*MC 313 PetscFunctionBegin - First executable line of each PETSc function 314 used for error handling. 315 316 Synopsis: 317 void PetscFunctionBegin; 318 319 Usage: 320 .vb 321 int something; 322 323 PetscFunctionBegin; 324 .ve 325 326 Notes: 327 Not available in Fortran 328 329 Level: developer 330 331 .seealso: PetscFunctionReturn() 332 333 .keywords: traceback, error handling 334 M*/ 335 #define PetscFunctionBegin \ 336 {\ 337 if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) { \ 338 petscstack->function[petscstack->currentsize] = __FUNCT__; \ 339 petscstack->file[petscstack->currentsize] = __FILE__; \ 340 petscstack->directory[petscstack->currentsize] = __SDIR__; \ 341 petscstack->line[petscstack->currentsize] = __LINE__; \ 342 petscstack->currentsize++; \ 343 }} 344 345 #define PetscStackPush(n) \ 346 {if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) { \ 347 petscstack->function[petscstack->currentsize] = n; \ 348 petscstack->file[petscstack->currentsize] = "unknown"; \ 349 petscstack->directory[petscstack->currentsize] = "unknown"; \ 350 petscstack->line[petscstack->currentsize] = 0; \ 351 petscstack->currentsize++; \ 352 }} 353 354 #define PetscStackPop \ 355 {if (petscstack && petscstack->currentsize > 0) { \ 356 petscstack->currentsize--; \ 357 petscstack->function[petscstack->currentsize] = 0; \ 358 petscstack->file[petscstack->currentsize] = 0; \ 359 petscstack->directory[petscstack->currentsize] = 0; \ 360 petscstack->line[petscstack->currentsize] = 0; \ 361 }}; 362 363 /*MC 364 PetscFunctionReturn - Last executable line of each PETSc function 365 used for error handling. Replaces return() 366 367 Synopsis: 368 void PetscFunctionReturn(0); 369 370 Usage: 371 .vb 372 .... 373 PetscFunctionReturn(0); 374 } 375 .ve 376 377 Notes: 378 Not available in Fortran 379 380 Level: developer 381 382 .seealso: PetscFunctionBegin() 383 384 .keywords: traceback, error handling 385 M*/ 386 #define PetscFunctionReturn(a) \ 387 {\ 388 PetscStackPop; \ 389 return(a);} 390 391 #define PetscFunctionReturnVoid() \ 392 {\ 393 PetscStackPop; \ 394 return;} 395 396 #else 397 398 /* 399 Duplicate Code for when the ALICE Memory Snooper (AMS) 400 is being used. When PETSC_HAVE_AMS is defined. 401 402 stack_mem is the AMS memory that contains fields for the 403 number of stack frames and names of the stack frames 404 */ 405 406 extern AMS_Memory stack_mem; 407 extern int stack_err; 408 409 #define PetscFunctionBegin \ 410 {\ 411 if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) { \ 412 if (!(stack_mem < 0)) stack_err = AMS_Memory_take_access(stack_mem);\ 413 petscstack->function[petscstack->currentsize] = __FUNCT__; \ 414 petscstack->file[petscstack->currentsize] = __FILE__; \ 415 petscstack->directory[petscstack->currentsize] = __SDIR__; \ 416 petscstack->line[petscstack->currentsize] = __LINE__; \ 417 petscstack->currentsize++; \ 418 if (!(stack_mem < 0)) stack_err = AMS_Memory_grant_access(stack_mem);\ 419 }} 420 421 #define PetscStackPush(n) \ 422 {if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) { \ 423 if (!(stack_mem < 0)) stack_err = AMS_Memory_take_access(stack_mem);\ 424 petscstack->function[petscstack->currentsize] = n; \ 425 petscstack->file[petscstack->currentsize] = "unknown"; \ 426 petscstack->directory[petscstack->currentsize] = "unknown"; \ 427 petscstack->line[petscstack->currentsize] = 0; \ 428 petscstack->currentsize++; \ 429 if (!(stack_mem < 0)) stack_err = AMS_Memory_grant_access(stack_mem);\ 430 }} 431 432 #define PetscStackPop \ 433 {if (petscstack && petscstack->currentsize > 0) { \ 434 if (!(stack_mem < 0)) stack_err = AMS_Memory_take_access(stack_mem);\ 435 petscstack->currentsize--; \ 436 petscstack->function[petscstack->currentsize] = 0; \ 437 petscstack->file[petscstack->currentsize] = 0; \ 438 petscstack->directory[petscstack->currentsize] = 0; \ 439 petscstack->line[petscstack->currentsize] = 0; \ 440 if (!(stack_mem < 0)) stack_err = AMS_Memory_grant_access(stack_mem);\ 441 }}; 442 443 #define PetscFunctionReturn(a) \ 444 {\ 445 PetscStackPop; \ 446 return(a);} 447 448 #define PetscFunctionReturnVoid() \ 449 {\ 450 PetscStackPop; \ 451 return;} 452 453 454 #endif 455 456 #else 457 458 #define PetscFunctionBegin 459 #define PetscFunctionReturn(a) return(a) 460 #define PetscFunctionReturnVoid() return() 461 #define PetscStackPop 462 #define PetscStackPush(f) 463 #define PetscStackActive 0 464 465 #endif 466 467 EXTERN PetscErrorCode PetscStackCreate(void); 468 EXTERN PetscErrorCode PetscStackView(PetscViewer); 469 EXTERN PetscErrorCode PetscStackDestroy(void); 470 EXTERN PetscErrorCode PetscStackPublish(void); 471 EXTERN PetscErrorCode PetscStackDepublish(void); 472 473 474 PETSC_EXTERN_CXX_END 475 #endif 476