Actual source code: petscerror.h

petsc-3.3-p7 2013-05-11
  1: /*
  2:     Contains all error handling interfaces for PETSc.
  3: */

  7: #if defined(PETSC_HAVE_STRING_H)
  8: #include <string.h> /* for strcmp */
  9: #endif


 12: /*
 13:    Defines the directory where the compiled source is located; used
 14:    in printing error messages. Each makefile has an entry 
 15:    LOCDIR          =  thedirectory
 16:    and bmake/common_variables includes in CCPPFLAGS -D__SDIR__=${LOCDIR}
 17:    which is a flag passed to the C/C++ compilers. This declaration below
 18:    is only needed if some code is compiled without the -D__SDIR__
 19: */
 22: #endif

 24: /*
 25:    Defines the function where the compiled source is located; used 
 26:    in printing error messages. This is defined here in case the user
 27:    does not declare it.
 28: */
 31: #endif

 33: /* 
 34:      These are the generic error codes. These error codes are used
 35:      many different places in the PETSc source code. The string versions are
 36:      at src/sys/error/err.c any changes here must also be made there
 37:      These are also define in include/finclude/petscerror.h any CHANGES here
 38:      must be also made there.

 40: */
 41: #define PETSC_ERR_MIN_VALUE        54   /* should always be one less then the smallest value */

 43: #define PETSC_ERR_MEM              55   /* unable to allocate requested memory */
 44: #define PETSC_ERR_SUP              56   /* no support for requested operation */
 45: #define PETSC_ERR_SUP_SYS          57   /* no support for requested operation on this computer system */
 46: #define PETSC_ERR_ORDER            58   /* operation done in wrong order */
 47: #define PETSC_ERR_SIG              59   /* signal received */
 48: #define PETSC_ERR_FP               72   /* floating point exception */
 49: #define PETSC_ERR_COR              74   /* corrupted PETSc object */
 50: #define PETSC_ERR_LIB              76   /* error in library called by PETSc */
 51: #define PETSC_ERR_PLIB             77   /* PETSc library generated inconsistent data */
 52: #define PETSC_ERR_MEMC             78   /* memory corruption */
 53: #define PETSC_ERR_CONV_FAILED      82   /* iterative method (KSP or SNES) failed */
 54: #define PETSC_ERR_USER             83   /* user has not provided needed function */
 55: #define PETSC_ERR_SYS              88   /* error in system call */

 57: #define PETSC_ERR_ARG_SIZ          60   /* nonconforming object sizes used in operation */
 58: #define PETSC_ERR_ARG_IDN          61   /* two arguments not allowed to be the same */
 59: #define PETSC_ERR_ARG_WRONG        62   /* wrong argument (but object probably ok) */
 60: #define PETSC_ERR_ARG_CORRUPT      64   /* null or corrupted PETSc object as argument */
 61: #define PETSC_ERR_ARG_OUTOFRANGE   63   /* input argument, out of range */
 62: #define PETSC_ERR_ARG_BADPTR       68   /* invalid pointer argument */
 63: #define PETSC_ERR_ARG_NOTSAMETYPE  69   /* two args must be same object type */
 64: #define PETSC_ERR_ARG_NOTSAMECOMM  80   /* two args must be same communicators */
 65: #define PETSC_ERR_ARG_WRONGSTATE   73   /* object in argument is in wrong state, e.g. unassembled mat */
 66: #define PETSC_ERR_ARG_TYPENOTSET   89   /* the type of the object has not yet been set */
 67: #define PETSC_ERR_ARG_INCOMP       75   /* two arguments are incompatible */
 68: #define PETSC_ERR_ARG_NULL         85   /* argument is null that should not be */
 69: #define PETSC_ERR_ARG_UNKNOWN_TYPE 86   /* type name doesn't match any registered type */

 71: #define PETSC_ERR_FILE_OPEN        65   /* unable to open file */
 72: #define PETSC_ERR_FILE_READ        66   /* unable to read from file */
 73: #define PETSC_ERR_FILE_WRITE       67   /* unable to write to file */
 74: #define PETSC_ERR_FILE_UNEXPECTED  79   /* unexpected data in file */

 76: #define PETSC_ERR_MAT_LU_ZRPVT     71   /* detected a zero pivot during LU factorization */
 77: #define PETSC_ERR_MAT_CH_ZRPVT     81   /* detected a zero pivot during Cholesky factorization */

 79: #define PETSC_ERR_INT_OVERFLOW     84   /* should always be one less then the smallest value */

 81: #define PETSC_ERR_FLOP_COUNT       90
 82: #define PETSC_ERR_NOT_CONVERGED    91  /* solver did not converge */
 83: #define PETSC_ERR_MAX_VALUE        92  /* this is always the one more than the largest error code */

 85: #define PetscStringizeArg(a) #a
 86: #define PetscStringize(a) PetscStringizeArg(a)

 89: #if defined(PETSC_USE_ERRORCHECKING)

 91: /*MC
 92:    SETERRQ - Macro that is called when an error has been detected, 

 94:    Synopsis:
 95:    PetscErrorCode SETERRQ(MPI_Comm comm,PetscErrorCode errorcode,char *message)

 97:    Not Collective

 99:    Input Parameters:
100: +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
101: -  message - error message

103:   Level: beginner

105:    Notes:
106:     Once the error handler is called the calling function is then returned from with the given error code.

108:     See SETERRQ1(), SETERRQ2(), SETERRQ3() for versions that take arguments

110:     In Fortran MPI_Abort() is always called

112:     Experienced users can set the error handler with PetscPushErrorHandler().

114:    Concepts: error^setting condition

116: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3()
117: M*/
118: #define SETERRQ(comm,n,s)              return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s)

120: /*MC
121:    SETERRQ1 - Macro that is called when an error has been detected, 

123:    Synopsis:
124:    PetscErrorCode SETERRQ1(MPI_Comm comm,PetscErrorCode errorcode,char *formatmessage,arg)

126:    Not Collective

128:    Input Parameters:
129: +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
130: .  message - error message in the printf format
131: -  arg - argument (for example an integer, string or double)

133:   Level: beginner

135:    Notes:
136:     Once the error handler is called the calling function is then returned from with the given error code.

138:    Experienced users can set the error handler with PetscPushErrorHandler().

140:    Concepts: error^setting condition

142: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ(), SETERRQ2(), SETERRQ3()
143: M*/
144: #define SETERRQ1(comm,n,s,a1)          return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1)

146: /*MC
147:    SETERRQ2 - Macro that is called when an error has been detected, 

149:    Synopsis:
150:    PetscErrorCode SETERRQ2(PetscErrorCode errorcode,char *formatmessage,arg1,arg2)

152:    Not Collective

154:    Input Parameters:
155: +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
156: .  message - error message in the printf format
157: .  arg1 - argument (for example an integer, string or double)
158: -  arg2 - argument (for example an integer, string or double)

160:   Level: beginner

162:    Notes:
163:     Once the error handler is called the calling function is then returned from with the given error code.

165:    Experienced users can set the error handler with PetscPushErrorHandler().

167:    Concepts: error^setting condition

169: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ3()
170: M*/
171: #define SETERRQ2(comm,n,s,a1,a2)       return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1,a2)

173: /*MC
174:    SETERRQ3 - Macro that is called when an error has been detected, 

176:    Synopsis:
177:    PetscErrorCode SETERRQ3(PetscErrorCode errorcode,char *formatmessage,arg1,arg2,arg3)

179:    Not Collective

181:    Input Parameters:
182: +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
183: .  message - error message in the printf format
184: .  arg1 - argument (for example an integer, string or double)
185: .  arg2 - argument (for example an integer, string or double)
186: -  arg3 - argument (for example an integer, string or double)

188:   Level: beginner

190:    Notes:
191:     Once the error handler is called the calling function is then returned from with the given error code.

193:     There are also versions for 4, 5, 6 and 7 arguments.

195:    Experienced users can set the error handler with PetscPushErrorHandler().

197:    Concepts: error^setting condition

199: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
200: M*/
201: #define SETERRQ3(comm,n,s,a1,a2,a3)    return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1,a2,a3)

203: #define SETERRQ4(comm,n,s,a1,a2,a3,a4) return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1,a2,a3,a4)
204: #define SETERRQ5(comm,n,s,a1,a2,a3,a4,a5)       return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1,a2,a3,a4,a5)
205: #define SETERRQ6(comm,n,s,a1,a2,a3,a4,a5,a6)    return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1,a2,a3,a4,a5,a6)
206: #define SETERRQ7(comm,n,s,a1,a2,a3,a4,a5,a6,a7) return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1,a2,a3,a4,a5,a6,a7)
207: #define SETERRQ8(comm,n,s,a1,a2,a3,a4,a5,a6,a7,a8) return PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s,a1,a2,a3,a4,a5,a6,a7,a8)
208: #define SETERRABORT(comm,n,s)     do {PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_INITIAL,s);MPI_Abort(comm,n);} while (0)

210: /*MC
211:    CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns

213:    Synopsis:
214:    PetscErrorCode CHKERRQ(PetscErrorCode errorcode)

216:    Not Collective

218:    Input Parameters:
219: .  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h

221:   Level: beginner

223:    Notes:
224:     Once the error handler is called the calling function is then returned from with the given error code.

226:     Experienced users can set the error handler with PetscPushErrorHandler().

228:     CHKERRQ(n) is fundamentally a macro replacement for
229:          if (n) return(PetscError(...,n,...));

231:     Although typical usage resembles "void CHKERRQ(PetscErrorCode)" as described above, for certain uses it is
232:     highly inappropriate to use it in this manner as it invokes return(PetscErrorCode). In particular,
233:     it cannot be used in functions which return(void) or any other datatype.  In these types of functions,
234:     you can use CHKERRV() which returns without an error code (bad idea since the error is ignored or
235:          if (n) {PetscError(....); return(YourReturnType);} 
236:     where you may pass back a PETSC_NULL to indicate an error. You can also call CHKERRABORT(comm,n) to have
237:     MPI_Abort() returned immediately.

239:     In Fortran MPI_Abort() is always called

241:    Concepts: error^setting condition

243: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ2()
244: M*/
245: #define CHKERRQ(n)             do {if (PetscUnlikely(n)) return PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_REPEAT," ");} while (0)

247: #define CHKERRV(n)             do {if (PetscUnlikely(n)) {n = PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_REPEAT," ");return;}} while(0)
248: #define CHKERRABORT(comm,n)    do {if (PetscUnlikely(n)) {PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_REPEAT," ");MPI_Abort(comm,n);}} while (0)
249: #define CHKERRCONTINUE(n)      do {if (PetscUnlikely(n)) {PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_REPEAT," ");}} while (0)

251: #ifdef PETSC_CLANGUAGE_CXX

253: /*MC
254:    CHKERRXX - Checks error code, if non-zero it calls the C++ error handler which throws an exception

256:    Synopsis:
257:    void CHKERRXX(PetscErrorCode errorcode)

259:    Not Collective

261:    Input Parameters:
262: .  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h

264:   Level: beginner

266:    Notes:
267:     Once the error handler throws a ??? exception.

269:     You can use CHKERRV() which returns without an error code (bad idea since the error is ignored)
270:     or CHKERRABORT(comm,n) to have MPI_Abort() returned immediately.

272:    Concepts: error^setting condition

274: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKERRQ(), CHKMEMQ
275: M*/
276: #define CHKERRXX(n)            do {if (PetscUnlikely(n)) {PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__,n,PETSC_ERROR_IN_CXX,0);}} while(0)

278: #endif

280: /*MC
281:    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected

283:    Synopsis:
284:    CHKMEMQ;

286:    Not Collective

288:   Level: beginner

290:    Notes:
291:     Must run with the option -malloc_debug to enable this option

293:     Once the error handler is called the calling function is then returned from with the given error code.

295:     By defaults prints location where memory that is corrupted was allocated.

297:     Use CHKMEMA for functions that return void

299:    Concepts: memory corruption

301: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(), 
302:           PetscMallocValidate()
303: M*/
304: #define CHKMEMQ do {PetscErrorCode _7_PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__);CHKERRQ(_7_ierr);} while(0)

306: #define CHKMEMA PetscMallocValidate(__LINE__,PETSC_FUNCTION_NAME,__FILE__,__SDIR__)

308: #else /* PETSC_USE_ERRORCHECKING */

310: /* 
311:     These are defined to be empty for when error checking is turned off, with ./configure --with-errorchecking=0
312: */

314: #define SETERRQ(c,n,s) 
315: #define SETERRQ1(c,n,s,a1) 
316: #define SETERRQ2(c,n,s,a1,a2) 
317: #define SETERRQ3(c,n,s,a1,a2,a3) 
318: #define SETERRQ4(c,n,s,a1,a2,a3,a4) 
319: #define SETERRQ5(c,n,s,a1,a2,a3,a4,a5) 
320: #define SETERRQ6(c,n,s,a1,a2,a3,a4,a5,a6) 
321: #define SETERRQ7(c,n,s,a1,a2,a3,a4,a5,a6,a7) 
322: #define SETERRQ8(c,n,s,a1,a2,a3,a4,a5,a6,a7,a8) 
323: #define SETERRABORT(comm,n,s) 

325: #define CHKERRQ(n)     ;
326: #define CHKERRABORT(comm,n) ;
327: #define CHKERRCONTINUE(n) ;
328: #define CHKMEMQ        ;

330: #ifdef PETSC_CLANGUAGE_CXX
331: #define CHKERRXX(n) ;
332: #endif

334: #endif /* PETSC_USE_ERRORCHECKING */

336: /*E
337:   PetscErrorType - passed to the PETSc error handling routines indicating if this is the first or a later call to the error handlers

339:   Level: advanced

341:   PETSC_ERROR_IN_CXX indicates the error was detected in C++ and an exception should be generated

343:   Developer Notes: This is currently used to decide when to print the detailed information about the run in PetscTraceBackErrorHandling()

345: .seealso: PetscError(), SETERRXX()
346: E*/
347: typedef enum {PETSC_ERROR_INITIAL=0,PETSC_ERROR_REPEAT=1,PETSC_ERROR_IN_CXX = 2} PetscErrorType;

349: PETSC_EXTERN PetscErrorCode PetscErrorPrintfInitialize(void);
350: PETSC_EXTERN PetscErrorCode PetscErrorMessage(int,const char*[],char **);
351: PETSC_EXTERN PetscErrorCode PetscTraceBackErrorHandler(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
352: PETSC_EXTERN PetscErrorCode PetscIgnoreErrorHandler(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
353: PETSC_EXTERN PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
354: PETSC_EXTERN PetscErrorCode PetscMPIAbortErrorHandler(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
355: PETSC_EXTERN PetscErrorCode PetscAbortErrorHandler(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
356: PETSC_EXTERN PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
357: PETSC_EXTERN PetscErrorCode PetscReturnErrorHandler(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*);
358: PETSC_EXTERN PetscErrorCode PetscError(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,...);
359: PETSC_EXTERN PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm,int,const char*,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*),void*);
360: PETSC_EXTERN PetscErrorCode PetscPopErrorHandler(void);
361: PETSC_EXTERN PetscErrorCode PetscDefaultSignalHandler(int,void*);
362: PETSC_EXTERN PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
363: PETSC_EXTERN PetscErrorCode PetscPopSignalHandler(void);

365: typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
366: PETSC_EXTERN PetscErrorCode PetscSetFPTrap(PetscFPTrap);
367: PETSC_EXTERN PetscErrorCode PetscFPTrapPush(PetscFPTrap);
368: PETSC_EXTERN PetscErrorCode PetscFPTrapPop(void);

370: /*  Linux functions CPU_SET and others don't work if sched.h is not included before
371:     including pthread.h. Also, these functions are active only if either _GNU_SOURCE
372:     or __USE_GNU is not set (see /usr/include/sched.h and /usr/include/features.h), hence
373:     set these first.
374: */
375: #if defined(PETSC_HAVE_PTHREADCLASSES)
376: #if defined(PETSC_HAVE_SCHED_H)
377: #ifndef _GNU_SOURCE
378: #define _GNU_SOURCE
379: #endif
380: #include <sched.h>
381: #endif
382: #include <pthread.h>
383: #endif

385: /*
386:       Allows the code to build a stack frame as it runs
387: */
388: #if defined(PETSC_USE_DEBUG)

390: #define PETSCSTACKSIZE 64

392: typedef struct  {
393:   const char *function[PETSCSTACKSIZE];
394:   const char *file[PETSCSTACKSIZE];
395:   const char *directory[PETSCSTACKSIZE];
396:         int  line[PETSCSTACKSIZE];
397:         int  currentsize;
398: } PetscStack;

400: #if defined(PETSC_HAVE_PTHREADCLASSES)
401: #if defined(PETSC_PTHREAD_LOCAL)
402: PETSC_EXTERN PETSC_PTHREAD_LOCAL PetscStack *petscstack;
403: #else
404: PETSC_EXTERN pthread_key_t petscstack_key;
405: PETSC_EXTERN PetscStack *petscstack;
406: #endif
407: #else
408: PETSC_EXTERN PetscStack *petscstack;
409: #endif

411: PETSC_EXTERN PetscErrorCode PetscStackCopy(PetscStack*,PetscStack*);
412: PETSC_EXTERN PetscErrorCode PetscStackPrint(PetscStack*,FILE* fp);

414: #define PetscStackActive (petscstack != 0)

416: #if defined(PETSC_HAVE_PTHREADCLASSES) && !defined(PETSC_PTHREAD_LOCAL)
417: /* Get the value associated with name_key */
418: #define PetscThreadLocalGetValue(name,type) ( (type)pthread_getspecific(name##_key))
419: /* Set the value for name_key */
420: #define PetscThreadLocalSetValue(name,value) ( pthread_setspecific(name##_key,(void*)value) )
421: /* Create name_key */
422: #define PetscThreadLocalRegister(name) ( pthread_key_create(&name##_key,NULL) )
423: /* Destroy name_key */
424: #define PetscThreadLocalDestroy(name) ( pthread_key_delete(name##_key) )
425: #else
426: #define PetscThreadLocalGetValue(name,type) ( (type)name )
427: #define PetscThreadLocalSetValue(name,value)
428: #define PetscThreadLocalRegister(name)
429: #define PetscThreadLocalDestroy(name)
430: #endif

432: /*MC
434:         used for error handling.

436:    Synopsis:

439:    Not Collective

441:    Usage:
442: .vb
443:      int something;

446: .ve

448:    Notes:
449:      Not available in Fortran

451:    Level: developer

453: .seealso: PetscFunctionReturn()

455: .keywords: traceback, error handling
456: M*/
458:   do {                                                                        \
459:     petscstack = PetscThreadLocalGetValue(petscstack,PetscStack*);        \
460:     if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) {        \
461:       petscstack->function[petscstack->currentsize]  = PETSC_FUNCTION_NAME; \
462:       petscstack->file[petscstack->currentsize]      = __FILE__;        \
463:       petscstack->directory[petscstack->currentsize] = __SDIR__;        \
464:       petscstack->line[petscstack->currentsize]      = __LINE__;        \
465:       petscstack->currentsize++;                                        \
466:     }                                                                   \
468:   } while (0)

471:     if (strcmp(PETSC_FUNCTION_NAME,__FUNCT__) && strcmp(__FUNCT__,"User provided function")) { \
472:       (*PetscErrorPrintf)("%s%s:%d: __FUNCT__=\"%s\" does not agree with %s=\"%s\"\n",__SDIR__,__FILE__,__LINE__,__FUNCT__,PetscStringize(PETSC_FUNCTION_NAME),PETSC_FUNCTION_NAME); \
473:     }                                                                   \
474:   } while (0)

476: #define PetscStackPush(n) \
477:   do {                                                                        \
478:     petscstack = PetscThreadLocalGetValue(petscstack,PetscStack*);        \
479:     if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) {        \
480:       petscstack->function[petscstack->currentsize]  = n;                \
481:       petscstack->file[petscstack->currentsize]      = "unknown";        \
482:       petscstack->directory[petscstack->currentsize] = "unknown";        \
483:       petscstack->line[petscstack->currentsize]      = 0;                \
484:       petscstack->currentsize++;                                        \
485:     } CHKMEMQ;} while (0)

487: #define PetscStackPop \
488:   do {CHKMEMQ;petscstack = PetscThreadLocalGetValue(petscstack,PetscStack*); \
489:     if (petscstack && petscstack->currentsize > 0) {                        \
490:       petscstack->currentsize--;                                        \
491:       petscstack->function[petscstack->currentsize]  = 0;                \
492:       petscstack->file[petscstack->currentsize]      = 0;                \
493:       petscstack->directory[petscstack->currentsize] = 0;                \
494:       petscstack->line[petscstack->currentsize]      = 0;                \
495:     }} while (0)

497: /*MC
498:    PetscFunctionReturn - Last executable line of each PETSc function
499:         used for error handling. Replaces return()

501:    Synopsis:
502:    void return(0);

504:    Not Collective

506:    Usage:
507: .vb
508:     ....
509:      return(0);
510:    }
511: .ve

513:    Notes:
514:      Not available in Fortran

516:    Level: developer


520: .keywords: traceback, error handling
521: M*/
522: #define PetscFunctionReturn(a) \
523:   do {                                                                        \
524:     petscstack = PetscThreadLocalGetValue(petscstack,PetscStack*);        \
525:     if (petscstack && petscstack->currentsize > 0) {                        \
526:       petscstack->currentsize--;                                        \
527:       petscstack->function[petscstack->currentsize]  = 0;                \
528:       petscstack->file[petscstack->currentsize]      = 0;                \
529:       petscstack->directory[petscstack->currentsize] = 0;                \
530:       petscstack->line[petscstack->currentsize]      = 0;                \
531:     }                                                                        \
532:     return(a);} while (0)

534: #define PetscFunctionReturnVoid() \
535:   do {                                                        \
536:     petscstack = PetscThreadLocalGetValue(petscstack,PetscStack*);        \
537:     if (petscstack && petscstack->currentsize > 0) {                        \
538:       petscstack->currentsize--;                                        \
539:       petscstack->function[petscstack->currentsize]  = 0;                \
540:       petscstack->file[petscstack->currentsize]      = 0;                \
541:       petscstack->directory[petscstack->currentsize] = 0;                \
542:       petscstack->line[petscstack->currentsize]      = 0;                \
543:     }                                                                        \
544:     return;} while (0)
545: #else

548: #define PetscFunctionReturn(a)  return(a)
549: #define PetscFunctionReturnVoid() return
550: #define PetscStackPop     CHKMEMQ
551: #define PetscStackPush(f) CHKMEMQ
552: #define PetscStackActive        0

554: #endif

556: /*
557:     PetscStackCall - Calls an external library routine or user function after pushing the name of the routine on the stack.

559:    Input Parameters:
560: +   name - string that gives the name of the function being called
561: -   routine - actual call to the routine

563:    Developer Note: this is so that when a user or external library routine results in a crash or corrupts memory, they get blamed instead of PETSc.

565: */
566: #define PetscStackCall(name,routine) PetscStackPush(name);routine;PetscStackPop;

568: PETSC_EXTERN PetscErrorCode PetscStackCreate(void);
569: PETSC_EXTERN PetscErrorCode PetscStackView(PetscViewer);
570: PETSC_EXTERN PetscErrorCode PetscStackDestroy(void);
571: PETSC_EXTERN PetscErrorCode PetscStackPublish(void);
572: PETSC_EXTERN PetscErrorCode PetscStackDepublish(void);

574: #endif