Actual source code: err.c
1: /*
2: Code that allows one to set the error handlers
3: */
4: #include petsc.h
5: #include petscsys.h
6: #include <stdarg.h>
7: #if defined(PETSC_HAVE_STDLIB_H)
8: #include <stdlib.h>
9: #endif
11: typedef struct _EH *EH;
12: struct _EH {
13: int cookie;
14: PetscErrorCode (*handler)(int,const char*,const char*,const char *,int,int,const char*,void *);
15: void *ctx;
16: EH previous;
17: };
19: static EH eh = 0;
23: /*@C
24: PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
25: load the file where the error occured. Then calls the "previous" error handler.
27: Not Collective
29: Input Parameters:
30: + line - the line number of the error (indicated by __LINE__)
31: . func - the function where error is detected (indicated by __FUNCT__)
32: . file - the file in which the error was detected (indicated by __FILE__)
33: . dir - the directory of the file (indicated by __SDIR__)
34: . mess - an error text string, usually just printed to the screen
35: . n - the generic error number
36: . p - specific error number
37: - ctx - error handler context
39: Options Database Key:
40: . -on_error_emacs <machinename>
42: Level: developer
44: Notes:
45: You must put (server-start) in your .emacs file for the emacsclient software to work
47: Most users need not directly employ this routine and the other error
48: handlers, but can instead use the simplified interface SETERRQ, which has
49: the calling sequence
50: $ SETERRQ(number,p,mess)
52: Notes for experienced users:
53: Use PetscPushErrorHandler() to set the desired error handler. The
54: currently available PETSc error handlers include PetscTraceBackErrorHandler(),
55: PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler()
57: Concepts: emacs^going to on error
58: Concepts: error handler^going to line in emacs
60: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
61: PetscAbortErrorHandler()
62: @*/
63: PetscErrorCode PetscEmacsClientErrorHandler(int line,const char *fun,const char* file,const char *dir,int n,int p,const char *mess,void *ctx)
64: {
66: char command[PETSC_MAX_PATH_LEN];
67: const char *pdir;
68: FILE *fp;
71: /* Note: don't check error codes since this an error handler :-) */
72: PetscGetPetscDir(&pdir);
73: sprintf(command,"emacsclient +%d %s/%s%s\n",line,pdir,dir,file);
74: PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp);
75: PetscFClose(MPI_COMM_WORLD,fp);
76: PetscPopErrorHandler(); /* remove this handler from the stack of handlers */
77: if (!eh) PetscTraceBackErrorHandler(line,fun,file,dir,n,p,mess,0);
78: else (*eh->handler)(line,fun,file,dir,n,p,mess,eh->ctx);
79: PetscFunctionReturn(ierr);
80: }
84: /*@C
85: PetscPushErrorHandler - Sets a routine to be called on detection of errors.
87: Not Collective
89: Input Parameters:
90: + handler - error handler routine
91: - ctx - optional handler context that contains information needed by the handler (for
92: example file pointers for error messages etc.)
94: Calling sequence of handler:
95: $ int handler(int line,char *func,char *file,char *dir,int n,int p,char *mess,void *ctx);
97: + func - the function where the error occured (indicated by __FUNCT__)
98: . line - the line number of the error (indicated by __LINE__)
99: . file - the file in which the error was detected (indicated by __FILE__)
100: . dir - the directory of the file (indicated by __SDIR__)
101: . n - the generic error number (see list defined in include/petscerror.h)
102: . p - the specific error number
103: . mess - an error text string, usually just printed to the screen
104: - ctx - the error handler context
106: Options Database Keys:
107: + -on_error_attach_debugger <noxterm,gdb or dbx>
108: - -on_error_abort
110: Level: intermediate
112: .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
114: @*/
115: PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char *,const char*,const char*,int,int,const char*,void*),void *ctx)
116: {
117: EH neweh;
121: PetscNew(struct _EH,&neweh);
122: if (eh) {neweh->previous = eh;}
123: else {neweh->previous = 0;}
124: neweh->handler = handler;
125: neweh->ctx = ctx;
126: eh = neweh;
127: return(0);
128: }
132: /*@C
133: PetscPopErrorHandler - Removes the latest error handler that was
134: pushed with PetscPushErrorHandler().
136: Not Collective
138: Level: intermediate
140: Concepts: error handler^setting
142: .seealso: PetscPushErrorHandler()
143: @*/
144: PetscErrorCode PetscPopErrorHandler(void)
145: {
146: EH tmp;
150: if (!eh) return(0);
151: tmp = eh;
152: eh = eh->previous;
153: PetscFree(tmp);
155: return(0);
156: }
157:
158: static char PetscErrorBaseMessage[1024];
159: /*
160: The numerical values for these are defined in include/petscerror.h; any changes
161: there must also be made here
162: */
163: static const char *PetscErrorStrings[] = {
164: /*55 */ "Out of memory",
165: "No support for this operation for this object type",
166: "No support for this operation on this system",
167: /*58 */ "Operation done in wrong order",
168: /*59 */ "Signal received",
169: /*60 */ "Nonconforming object sizes",
170: "Argument aliasing not permitted",
171: "Invalid argument",
172: /*63 */ "Argument out of range",
173: "Corrupt argument: see http://www.mcs.anl.gov/petsc/petsc-2/documentation/troubleshooting.html#Corrupt",
174: "Unable to open file",
175: "Read from file failed",
176: "Write to file failed",
177: "Invalid pointer",
178: /*69 */ "Arguments must have same type",
179: "",
180: /*71 */ "Detected zero pivot in LU factorization\nsee http://www.mcs.anl.gov/petsc/petsc-2/documentation/troubleshooting.html#ZeroPivot",
181: /*72 */ "Floating point exception",
182: /*73 */ "Object is in wrong state",
183: "Corrupted Petsc object",
184: "Arguments are incompatible",
185: "Error in external library",
186: /*77 */ "Petsc has generated inconsistent data",
187: "Memory corruption",
188: "Unexpected data in file",
189: /*80 */ "Arguments must have same communicators",
190: /*81 */ "Detected zero pivot in Cholesky factorization\nsee http://www.mcs.anl.gov/petsc/petsc-2/documentation/troubleshooting.html#ZeroPivot",
191: " ",
192: " ",
193: " ",
194: /*85 */ "Null argument, when expecting valid pointer",
195: /*86 */ "Unknown type. Check for miss-spelling or missing external package needed for type"};
199: /*@C
200: PetscErrorMessage - returns the text string associated with a PETSc error code.
202: Not Collective
204: Input Parameter:
205: . errnum - the error code
207: Output Parameter:
208: + text - the error message (PETSC_NULL if not desired)
209: - specific - the specific error message that was set with SETERRxxx() or PetscError(). (PETSC_NULL if not desired)
211: Level: developer
213: Concepts: error handler^messages
215: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
216: PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
217: @*/
218: PetscErrorCode PetscErrorMessage(int errnum,const char *text[],char **specific)
219: {
221: if (text && errnum >= PETSC_ERR_MEM && errnum <= PETSC_ERR_MEM_MALLOC_0) {
222: *text = PetscErrorStrings[errnum-PETSC_ERR_MEM];
223: } else if (text) *text = 0;
225: if (specific) {
226: *specific = PetscErrorBaseMessage;
227: }
228: return(0);
229: }
233: /*@C
234: PetscError - Routine that is called when an error has been detected,
235: usually called through the macro SETERRQ().
237: Not Collective
239: Input Parameters:
240: + line - the line number of the error (indicated by __LINE__)
241: . func - the function where the error occured (indicated by __FUNCT__)
242: . dir - the directory of file (indicated by __SDIR__)
243: . file - the file in which the error was detected (indicated by __FILE__)
244: . mess - an error text string, usually just printed to the screen
245: . n - the generic error number
246: . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a
247: previously detected error
248: - mess - formatted message string - aka printf
250: Level: intermediate
252: Notes:
253: Most users need not directly use this routine and the error handlers, but
254: can instead use the simplified interface SETERRQ, which has the calling
255: sequence
256: $ SETERRQ(n,mess)
258: Experienced users can set the error handler with PetscPushErrorHandler().
260: Concepts: error^setting condition
262: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
263: @*/
264: PetscErrorCode PetscError(int line,const char *func,const char* file,const char *dir,int n,int p,const char *mess,...)
265: {
266: va_list Argp;
268: char buf[2048],*lbuf = 0;
269: PetscTruth ismain,isunknown;
271: if (!func) func = "User provided function";
272: if (!file) file = "User file";
273: if (!dir) dir = " ";
276: /* Compose the message evaluating the print format */
277: if (mess) {
278: va_start(Argp,mess);
279: PetscVSNPrintf(buf,2048,mess,Argp);
280: va_end(Argp);
281: lbuf = buf;
282: if (p == 1) {
283: PetscStrncpy(PetscErrorBaseMessage,lbuf,1023);
284: }
285: }
287: if (!eh) PetscTraceBackErrorHandler(line,func,file,dir,n,p,lbuf,0);
288: else (*eh->handler)(line,func,file,dir,n,p,lbuf,eh->ctx);
290: /*
291: If this is called from the main() routine we call MPI_Abort() instead of
292: return to allow the parallel program to be properly shutdown.
294: Since this is in the error handler we don't check the errors below. Of course,
295: PetscStrncmp() does its own error checking which is problamatic
296: */
297: PetscStrncmp(func,"main",4,&ismain);
298: PetscStrncmp(func,"unknown",7,&isunknown);
299: if (ismain || isunknown) {
300: MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
301: }
302: PetscFunctionReturn(ierr);
303: }
305: /* -------------------------------------------------------------------------*/
309: /*@C
310: PetscIntView - Prints an array of integers; useful for debugging.
312: Collective on PetscViewer
314: Input Parameters:
315: + N - number of integers in array
316: . idx - array of integers
317: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
319: Level: intermediate
321: .seealso: PetscRealView()
322: @*/
323: PetscErrorCode PetscIntView(PetscInt N,PetscInt idx[],PetscViewer viewer)
324: {
326: PetscInt j,i,n = N/20,p = N % 20;
327: PetscTruth iascii,issocket;
328: MPI_Comm comm;
331: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
334: PetscObjectGetComm((PetscObject)viewer,&comm);
336: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
337: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
338: if (iascii) {
339: for (i=0; i<n; i++) {
340: PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);
341: for (j=0; j<20; j++) {
342: PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);
343: }
344: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
345: }
346: if (p) {
347: PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);
348: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);}
349: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
350: }
351: PetscViewerFlush(viewer);
352: } else if (issocket) {
353: PetscMPIInt rank,size,*sizes,Ntotal,*displs, NN = (PetscMPIInt)N;
354: PetscInt *array;
355: MPI_Comm_rank(comm,&rank);
356: MPI_Comm_size(comm,&size);
358: if (size > 1) {
359: if (rank) {
360: MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);
361: MPI_Gatherv(idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);
362: } else {
363: PetscMalloc(size*sizeof(PetscMPIInt),&sizes);
364: MPI_Gather(&NN,1,MPI_INT,sizes,1,MPIU_INT,0,comm);
365: Ntotal = sizes[0];
366: PetscMalloc(size*sizeof(PetscMPIInt),&displs);
367: displs[0] = 0;
368: for (i=1; i<size; i++) {
369: Ntotal += sizes[i];
370: displs[i] = displs[i-1] + sizes[i-1];
371: }
372: PetscMalloc(Ntotal*sizeof(PetscInt),&array);
373: MPI_Gatherv(idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);
374: PetscViewerSocketPutInt(viewer,Ntotal,array);
375: PetscFree(sizes);
376: PetscFree(displs);
377: PetscFree(array);
378: }
379: } else {
380: PetscViewerSocketPutInt(viewer,N,idx);
381: }
382: } else {
383: char *tname;
384: PetscObjectGetName((PetscObject)viewer,&tname);
385: SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
386: }
387: return(0);
388: }
392: /*@C
393: PetscRealView - Prints an array of doubles; useful for debugging.
395: Collective on PetscViewer
397: Input Parameters:
398: + N - number of doubles in array
399: . idx - array of doubles
400: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
402: Level: intermediate
404: .seealso: PetscIntView()
405: @*/
406: PetscErrorCode PetscRealView(PetscInt N,PetscReal idx[],PetscViewer viewer)
407: {
409: PetscInt j,i,n = N/5,p = N % 5;
410: PetscTruth iascii,issocket;
411: MPI_Comm comm;
414: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
417: PetscObjectGetComm((PetscObject)viewer,&comm);
419: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
420: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
421: if (iascii) {
422: for (i=0; i<n; i++) {
423: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);
424: for (j=0; j<5; j++) {
425: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);
426: }
427: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
428: }
429: if (p) {
430: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);
431: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);}
432: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
433: }
434: PetscViewerFlush(viewer);
435: } else if (issocket) {
436: PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN = (PetscMPIInt)N;
437: PetscReal *array;
439: MPI_Comm_rank(comm,&rank);
440: MPI_Comm_size(comm,&size);
442: if (size > 1) {
443: if (rank) {
444: MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);
445: MPI_Gatherv(idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);
446: } else {
447: PetscMalloc(size*sizeof(PetscMPIInt),&sizes);
448: MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);
449: Ntotal = sizes[0];
450: PetscMalloc(size*sizeof(PetscMPIInt),&displs);
451: displs[0] = 0;
452: for (i=1; i<size; i++) {
453: Ntotal += sizes[i];
454: displs[i] = displs[i-1] + sizes[i-1];
455: }
456: PetscMalloc(Ntotal*sizeof(PetscReal),&array);
457: MPI_Gatherv(idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);
458: PetscViewerSocketPutReal(viewer,Ntotal,1,array);
459: PetscFree(sizes);
460: PetscFree(displs);
461: PetscFree(array);
462: }
463: } else {
464: PetscViewerSocketPutReal(viewer,N,1,idx);
465: }
466: } else {
467: char *tname;
468: PetscObjectGetName((PetscObject)viewer,&tname);
469: SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
470: }
471: return(0);
472: }
476: /*@C
477: PetscScalarView - Prints an array of scalars; useful for debugging.
479: Collective on PetscViewer
481: Input Parameters:
482: + N - number of scalars in array
483: . idx - array of scalars
484: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
486: Level: intermediate
488: .seealso: PetscIntView(), PetscRealView()
489: @*/
490: PetscErrorCode PetscScalarView(PetscInt N,PetscScalar idx[],PetscViewer viewer)
491: {
493: PetscInt j,i,n = N/3,p = N % 3;
494: PetscTruth iascii,issocket;
495: MPI_Comm comm;
498: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
501: PetscObjectGetComm((PetscObject)viewer,&comm);
503: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
504: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
505: if (iascii) {
506: for (i=0; i<n; i++) {
507: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);
508: for (j=0; j<3; j++) {
509: #if defined (PETSC_USE_COMPLEX)
510: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
511: PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));
512: #else
513: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);
514: #endif
515: }
516: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
517: }
518: if (p) {
519: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);
520: for (i=0; i<p; i++) {
521: #if defined (PETSC_USE_COMPLEX)
522: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
523: PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));
524: #else
525: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);
526: #endif
527: }
528: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
529: }
530: PetscViewerFlush(viewer);
531: } else if (issocket) {
532: PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN = (PetscMPIInt)N;
533: PetscScalar *array;
535: MPI_Comm_rank(comm,&rank);
536: MPI_Comm_size(comm,&size);
538: if (size > 1) {
539: if (rank) {
540: MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);
541: MPI_Gatherv(idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);
542: } else {
543: PetscMalloc(size*sizeof(PetscMPIInt),&sizes);
544: MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);
545: Ntotal = sizes[0];
546: PetscMalloc(size*sizeof(PetscMPIInt),&displs);
547: displs[0] = 0;
548: for (i=1; i<size; i++) {
549: Ntotal += sizes[i];
550: displs[i] = displs[i-1] + sizes[i-1];
551: }
552: PetscMalloc(Ntotal*sizeof(PetscScalar),&array);
553: MPI_Gatherv(idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);
554: PetscViewerSocketPutScalar(viewer,Ntotal,1,array);
555: PetscFree(sizes);
556: PetscFree(displs);
557: PetscFree(array);
558: }
559: } else {
560: PetscViewerSocketPutScalar(viewer,N,1,idx);
561: }
562: } else {
563: char *tname;
564: PetscObjectGetName((PetscObject)viewer,&tname);
565: SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
566: }
567: return(0);
568: }