Actual source code: err.c
1: /*$Id: err.c,v 1.130 2001/09/07 15:24:29 bsmith Exp $*/
2: /*
3: Code that allows one to set the error handlers
4: */
5: #include petsc.h
6: #include petscsys.h
7: #include <stdarg.h>
8: #if defined(PETSC_HAVE_STDLIB_H)
9: #include <stdlib.h>
10: #endif
12: typedef struct _EH *EH;
13: struct _EH {
14: int cookie;
15: int (*handler)(int,const char*,const char*,const char *,int,int,const char*,void *);
16: void *ctx;
17: EH previous;
18: };
20: static EH eh = 0;
24: /*@C
25: PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
26: load the file where the error occured. Then calls the "previous" error handler.
28: Not Collective
30: Input Parameters:
31: + line - the line number of the error (indicated by __LINE__)
32: . func - the function where error is detected (indicated by __FUNCT__)
33: . file - the file in which the error was detected (indicated by __FILE__)
34: . dir - the directory of the file (indicated by __SDIR__)
35: . mess - an error text string, usually just printed to the screen
36: . n - the generic error number
37: . p - specific error number
38: - ctx - error handler context
40: Options Database Key:
41: . -on_error_emacs <machinename>
43: Level: developer
45: Notes:
46: You must put (server-start) in your .emacs file for the emacsclient software to work
48: Most users need not directly employ this routine and the other error
49: handlers, but can instead use the simplified interface SETERRQ, which has
50: the calling sequence
51: $ SETERRQ(number,p,mess)
53: Notes for experienced users:
54: Use PetscPushErrorHandler() to set the desired error handler. The
55: currently available PETSc error handlers include PetscTraceBackErrorHandler(),
56: PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler()
58: Concepts: emacs^going to on error
59: Concepts: error handler^going to line in emacs
61: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
62: PetscAbortErrorHandler()
63: @*/
64: int PetscEmacsClientErrorHandler(int line,const char *fun,const char* file,const char *dir,int n,int p,const char *mess,void *ctx)
65: {
66: int ierr;
67: char command[PETSC_MAX_PATH_LEN];
68: const char *pdir;
69: FILE *fp;
72: /* Note: don't check error codes since this an error handler :-) */
73: PetscGetPetscDir(&pdir);
74: sprintf(command,"emacsclient +%d %s/%s%s\n",line,pdir,dir,file);
75: PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp);
76: PetscFClose(MPI_COMM_WORLD,fp);
77: PetscPopErrorHandler(); /* remove this handler from the stack of handlers */
78: if (!eh) PetscTraceBackErrorHandler(line,fun,file,dir,n,p,mess,0);
79: else (*eh->handler)(line,fun,file,dir,n,p,mess,eh->ctx);
80: PetscFunctionReturn(ierr);
81: }
85: /*@C
86: PetscPushErrorHandler - Sets a routine to be called on detection of errors.
88: Not Collective
90: Input Parameters:
91: + handler - error handler routine
92: - ctx - optional handler context that contains information needed by the handler (for
93: example file pointers for error messages etc.)
95: Calling sequence of handler:
96: $ int handler(int line,char *func,char *file,char *dir,int n,int p,char *mess,void *ctx);
98: + func - the function where the error occured (indicated by __FUNCT__)
99: . line - the line number of the error (indicated by __LINE__)
100: . file - the file in which the error was detected (indicated by __FILE__)
101: . dir - the directory of the file (indicated by __SDIR__)
102: . n - the generic error number (see list defined in include/petscerror.h)
103: . p - the specific error number
104: . mess - an error text string, usually just printed to the screen
105: - ctx - the error handler context
107: Options Database Keys:
108: + -on_error_attach_debugger <noxterm,gdb or dbx>
109: - -on_error_abort
111: Level: intermediate
113: .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
115: @*/
116: int PetscPushErrorHandler(int (*handler)(int,const char *,const char*,const char*,int,int,const char*,void*),void *ctx)
117: {
118: EH neweh;
122: PetscNew(struct _EH,&neweh);
123: if (eh) {neweh->previous = eh;}
124: else {neweh->previous = 0;}
125: neweh->handler = handler;
126: neweh->ctx = ctx;
127: eh = neweh;
128: return(0);
129: }
133: /*@C
134: PetscPopErrorHandler - Removes the latest error handler that was
135: pushed with PetscPushErrorHandler().
137: Not Collective
139: Level: intermediate
141: Concepts: error handler^setting
143: .seealso: PetscPushErrorHandler()
144: @*/
145: int PetscPopErrorHandler(void)
146: {
147: EH tmp;
151: if (!eh) return(0);
152: tmp = eh;
153: eh = eh->previous;
154: PetscFree(tmp);
156: return(0);
157: }
158:
159: static char PetscErrorBaseMessage[1024];
160: static const char *PetscErrorStrings[] = {
161: /*55 */ "Out of memory",
162: "No support for this operation for this object type",
163: "",
164: /*58 */ "",
165: /*59 */ "Signal received",
166: /*60 */ "Nonconforming object sizes",
167: "Argument aliasing not permitted",
168: "Invalid argument",
169: /*63 */ "Argument out of range",
170: "Corrupt argument: see http://www.mcs.anl.gov/petsc/petsc-2/documentation/troubleshooting.html#Corrupt",
171: "Unable to open file",
172: "Read from file failed",
173: "Write to file failed",
174: "Invalid pointer",
175: /*69 */ "Arguments must have same type",
176: "Detected breakdown in Krylov method",
177: /*71 */ "Detected zero pivot in LU factorization",
178: /*72 */ "Floating point exception",
179: /*73 */ "Object is in wrong state",
180: "Corrupted Petsc object",
181: "Arguments are incompatible",
182: "Error in external library",
183: /*77 */ "Petsc has generated inconsistent data",
184: "Memory corruption",
185: "Unexpected data in file",
186: /*80 */ "Arguments must have same communicators",
187: /*81 */ "Detected zero pivot in Cholesky factorization",
188: " ",
189: " ",
190: " ",
191: /*85 */ "Null argument, when expecting valid pointer"};
195: /*@C
196: PetscErrorMessage - returns the text string associated with a PETSc error code.
198: Not Collective
200: Input Parameter:
201: . errnum - the error code
203: Output Parameter:
204: + text - the error message (PETSC_NULL if not desired)
205: - specific - the specific error message that was set with SETERRxxx() or PetscError(). (PETSC_NULL if not desired)
207: Level: developer
209: Concepts: error handler^messages
211: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
212: PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
213: @*/
214: int PetscErrorMessage(int errnum,const char *text[],char **specific)
215: {
217: if (text && errnum >= PETSC_ERR_MEM && errnum <= PETSC_ERR_MEM_MALLOC_0) {
218: *text = PetscErrorStrings[errnum-PETSC_ERR_MEM];
219: } else if (text) *text = 0;
221: if (specific) {
222: *specific = PetscErrorBaseMessage;
223: }
224: return(0);
225: }
229: /*@C
230: PetscError - Routine that is called when an error has been detected,
231: usually called through the macro SETERRQ().
233: Not Collective
235: Input Parameters:
236: + line - the line number of the error (indicated by __LINE__)
237: . func - the function where the error occured (indicated by __FUNCT__)
238: . dir - the directory of file (indicated by __SDIR__)
239: . file - the file in which the error was detected (indicated by __FILE__)
240: . mess - an error text string, usually just printed to the screen
241: . n - the generic error number
242: . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a
243: previously detected error
244: - mess - formatted message string - aka printf
246: Level: intermediate
248: Notes:
249: Most users need not directly use this routine and the error handlers, but
250: can instead use the simplified interface SETERRQ, which has the calling
251: sequence
252: $ SETERRQ(n,mess)
254: Experienced users can set the error handler with PetscPushErrorHandler().
256: Concepts: error^setting condition
258: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
259: @*/
260: int PetscError(int line,const char *func,const char* file,const char *dir,int n,int p,const char *mess,...)
261: {
262: va_list Argp;
263: int ierr;
264: char buf[2048],*lbuf = 0;
265: PetscTruth ismain,isunknown;
267: if (!func) func = "User provided function";
268: if (!file) file = "User file";
269: if (!dir) dir = " ";
272: /* Compose the message evaluating the print format */
273: if (mess) {
274: va_start(Argp,mess);
275: #if defined(PETSC_HAVE_VPRINTF_CHAR)
276: vsprintf(buf,mess,(char *)Argp);
277: #else
278: vsprintf(buf,mess,Argp);
279: #endif
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,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: int PetscIntView(int N,int idx[],PetscViewer viewer)
324: {
325: int j,i,n = N/20,p = N % 20,ierr;
326: PetscTruth isascii,issocket;
327: MPI_Comm comm;
330: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
333: PetscObjectGetComm((PetscObject)viewer,&comm);
335: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
336: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
337: if (isascii) {
338: for (i=0; i<n; i++) {
339: PetscViewerASCIISynchronizedPrintf(viewer,"%d:",20*i);
340: for (j=0; j<20; j++) {
341: PetscViewerASCIISynchronizedPrintf(viewer," %d",idx[i*20+j]);
342: }
343: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
344: }
345: if (p) {
346: PetscViewerASCIISynchronizedPrintf(viewer,"%d:",20*n);
347: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %d",idx[20*n+i]);}
348: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
349: }
350: PetscViewerFlush(viewer);
351: } else if (issocket) {
352: int *array,*sizes,rank,size,Ntotal,*displs;
354: MPI_Comm_rank(comm,&rank);
355: MPI_Comm_size(comm,&size);
357: if (size > 1) {
358: if (rank) {
359: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
360: MPI_Gatherv(idx,N,MPI_INT,0,0,0,MPI_INT,0,comm);
361: } else {
362: PetscMalloc(size*sizeof(int),&sizes);
363: MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
364: Ntotal = sizes[0];
365: PetscMalloc(size*sizeof(int),&displs);
366: displs[0] = 0;
367: for (i=1; i<size; i++) {
368: Ntotal += sizes[i];
369: displs[i] = displs[i-1] + sizes[i-1];
370: }
371: PetscMalloc(Ntotal*sizeof(int),&array);
372: MPI_Gatherv(idx,N,MPI_INT,array,sizes,displs,MPI_INT,0,comm);
373: PetscViewerSocketPutInt(viewer,Ntotal,array);
374: PetscFree(sizes);
375: PetscFree(displs);
376: PetscFree(array);
377: }
378: } else {
379: PetscViewerSocketPutInt(viewer,N,idx);
380: }
381: } else {
382: SETERRQ(1,"Cannot handle that PetscViewer");
383: }
384: return(0);
385: }
389: /*@C
390: PetscRealView - Prints an array of doubles; useful for debugging.
392: Collective on PetscViewer
394: Input Parameters:
395: + N - number of doubles in array
396: . idx - array of doubles
397: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
399: Level: intermediate
401: .seealso: PetscIntView()
402: @*/
403: int PetscRealView(int N,PetscReal idx[],PetscViewer viewer)
404: {
405: int j,i,n = N/5,p = N % 5,ierr;
406: PetscTruth isascii,issocket;
407: MPI_Comm comm;
410: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
413: PetscObjectGetComm((PetscObject)viewer,&comm);
415: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
416: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
417: if (isascii) {
418: for (i=0; i<n; i++) {
419: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);
420: for (j=0; j<5; j++) {
421: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);
422: }
423: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
424: }
425: if (p) {
426: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);
427: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);}
428: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
429: }
430: PetscViewerFlush(viewer);
431: } else if (issocket) {
432: int *sizes,rank,size,Ntotal,*displs;
433: PetscReal *array;
435: MPI_Comm_rank(comm,&rank);
436: MPI_Comm_size(comm,&size);
438: if (size > 1) {
439: if (rank) {
440: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
441: MPI_Gatherv(idx,N,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);
442: } else {
443: PetscMalloc(size*sizeof(int),&sizes);
444: MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
445: Ntotal = sizes[0];
446: PetscMalloc(size*sizeof(int),&displs);
447: displs[0] = 0;
448: for (i=1; i<size; i++) {
449: Ntotal += sizes[i];
450: displs[i] = displs[i-1] + sizes[i-1];
451: }
452: PetscMalloc(Ntotal*sizeof(PetscReal),&array);
453: MPI_Gatherv(idx,N,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);
454: PetscViewerSocketPutReal(viewer,Ntotal,1,array);
455: PetscFree(sizes);
456: PetscFree(displs);
457: PetscFree(array);
458: }
459: } else {
460: PetscViewerSocketPutReal(viewer,N,1,idx);
461: }
462: } else {
463: SETERRQ(1,"Cannot handle that PetscViewer");
464: }
465: return(0);
466: }
470: /*@C
471: PetscScalarView - Prints an array of scalars; useful for debugging.
473: Collective on PetscViewer
475: Input Parameters:
476: + N - number of scalars in array
477: . idx - array of scalars
478: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
480: Level: intermediate
482: .seealso: PetscIntView(), PetscRealView()
483: @*/
484: int PetscScalarView(int N,PetscScalar idx[],PetscViewer viewer)
485: {
486: int j,i,n = N/3,p = N % 3,ierr;
487: PetscTruth isascii,issocket;
488: MPI_Comm comm;
491: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
494: PetscObjectGetComm((PetscObject)viewer,&comm);
496: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
497: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
498: if (isascii) {
499: for (i=0; i<n; i++) {
500: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);
501: for (j=0; j<3; j++) {
502: #if defined (PETSC_USE_COMPLEX)
503: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
504: PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));
505: #else
506: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);
507: #endif
508: }
509: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
510: }
511: if (p) {
512: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);
513: for (i=0; i<p; i++) {
514: #if defined (PETSC_USE_COMPLEX)
515: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
516: PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));
517: #else
518: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);
519: #endif
520: }
521: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
522: }
523: PetscViewerFlush(viewer);
524: } else if (issocket) {
525: int *sizes,rank,size,Ntotal,*displs;
526: PetscScalar *array;
528: MPI_Comm_rank(comm,&rank);
529: MPI_Comm_size(comm,&size);
531: if (size > 1) {
532: if (rank) {
533: MPI_Gather(&N,1,MPI_INT,0,0,MPI_INT,0,comm);
534: MPI_Gatherv(idx,N,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);
535: } else {
536: PetscMalloc(size*sizeof(int),&sizes);
537: MPI_Gather(&N,1,MPI_INT,sizes,1,MPI_INT,0,comm);
538: Ntotal = sizes[0];
539: PetscMalloc(size*sizeof(int),&displs);
540: displs[0] = 0;
541: for (i=1; i<size; i++) {
542: Ntotal += sizes[i];
543: displs[i] = displs[i-1] + sizes[i-1];
544: }
545: PetscMalloc(Ntotal*sizeof(PetscScalar),&array);
546: MPI_Gatherv(idx,N,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);
547: PetscViewerSocketPutScalar(viewer,Ntotal,1,array);
548: PetscFree(sizes);
549: PetscFree(displs);
550: PetscFree(array);
551: }
552: } else {
553: PetscViewerSocketPutScalar(viewer,N,1,idx);
554: }
555: } else {
556: SETERRQ(1,"Cannot handle that PetscViewer");
557: }
558: return(0);
559: }