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: }