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