xref: /petsc/src/sys/error/err.c (revision 8738c82190ebad3f707cdf672b6e3396bec82bba)
1 #define PETSC_DLL
2 /*
3       Code that allows one to set the error handlers
4 */
5 #include "petscsys.h"           /*I "petscsys.h" I*/
6 #include <stdarg.h>
7 #if defined(PETSC_HAVE_STDLIB_H)
8 #include <stdlib.h>
9 #endif
10 
11 typedef struct _EH *EH;
12 struct _EH {
13   int            classid;
14   PetscErrorCode (*handler)(MPI_Comm,int,const char*,const char*,const char *,PetscErrorCode,PetscErrorType,const char*,void *);
15   void           *ctx;
16   EH             previous;
17 };
18 
19 static EH eh = 0;
20 
21 #undef __FUNCT__
22 #define __FUNCT__ "PetscEmacsClientErrorHandler"
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.
26 
27    Not Collective
28 
29    Input Parameters:
30 +  comm - communicator over which error occured
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
39 
40    Options Database Key:
41 .   -on_error_emacs <machinename>
42 
43    Level: developer
44 
45    Notes:
46    You must put (server-start) in your .emacs file for the emacsclient software to work
47 
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(PETSC_COMM_SELF,number,p,mess)
52 
53    Notes for experienced users:
54    Use PetscPushErrorHandler() to set the desired error handler.
55 
56    Concepts: emacs^going to on error
57    Concepts: error handler^going to line in emacs
58 
59 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
60           PetscAbortErrorHandler()
61  @*/
62 PetscErrorCode PETSCSYS_DLLEXPORT PetscEmacsClientErrorHandler(MPI_Comm comm,int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
63 {
64   PetscErrorCode ierr;
65   char        command[PETSC_MAX_PATH_LEN];
66   const char  *pdir;
67   FILE        *fp;
68 
69   PetscFunctionBegin;
70   /* Note: don't check error codes since this an error handler :-) */
71   ierr = PetscGetPetscDir(&pdir);CHKERRQ(ierr);
72   sprintf(command,"emacsclient +%d %s/%s%s\n",line,pdir,dir,file);
73 #if defined(PETSC_HAVE_POPEN)
74   ierr = PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp);
75   ierr = PetscPClose(MPI_COMM_WORLD,fp);
76 #else
77   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
78 #endif
79   ierr = PetscPopErrorHandler(); /* remove this handler from the stack of handlers */
80   if (!eh)     ierr = PetscTraceBackErrorHandler(comm,line,fun,file,dir,n,p,mess,0);
81   else         ierr = (*eh->handler)(comm,line,fun,file,dir,n,p,mess,eh->ctx);
82   PetscFunctionReturn(ierr);
83 }
84 
85 #undef __FUNCT__
86 #define __FUNCT__ "PetscPushErrorHandler"
87 /*@C
88    PetscPushErrorHandler - Sets a routine to be called on detection of errors.
89 
90    Not Collective
91 
92    Input Parameters:
93 +  handler - error handler routine
94 -  ctx - optional handler context that contains information needed by the handler (for
95          example file pointers for error messages etc.)
96 
97    Calling sequence of handler:
98 $    int handler(MPI_Comm comm,int line,char *func,char *file,char *dir,PetscErrorCode n,int p,char *mess,void *ctx);
99 
100 +  comm - communicator over which error occured
101 .  func - the function where the error occured (indicated by __FUNCT__)
102 .  line - the line number of the error (indicated by __LINE__)
103 .  file - the file in which the error was detected (indicated by __FILE__)
104 .  dir - the directory of the file (indicated by __SDIR__)
105 .  n - the generic error number (see list defined in include/petscerror.h)
106 .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
107 .  mess - an error text string, usually just printed to the screen
108 -  ctx - the error handler context
109 
110    Options Database Keys:
111 +   -on_error_attach_debugger <noxterm,gdb or dbx>
112 -   -on_error_abort
113 
114    Level: intermediate
115 
116    Notes:
117    The currently available PETSc error handlers include PetscTraceBackErrorHandler(),
118    PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler(), PetscReturnErrorHandler().
119 
120    Fortran Notes: You can only push one error handler from Fortran before poping it.
121 
122 .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
123 
124 @*/
125 PetscErrorCode PETSCSYS_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm comm,int,const char *,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*),void *ctx)
126 {
127   EH             neweh;
128   PetscErrorCode ierr;
129 
130   PetscFunctionBegin;
131   ierr = PetscNew(struct _EH,&neweh);CHKERRQ(ierr);
132   if (eh) {neweh->previous = eh;}
133   else    {neweh->previous = 0;}
134   neweh->handler = handler;
135   neweh->ctx     = ctx;
136   eh             = neweh;
137   PetscFunctionReturn(0);
138 }
139 
140 #undef __FUNCT__
141 #define __FUNCT__ "PetscPopErrorHandler"
142 /*@
143    PetscPopErrorHandler - Removes the latest error handler that was
144    pushed with PetscPushErrorHandler().
145 
146    Not Collective
147 
148    Level: intermediate
149 
150    Concepts: error handler^setting
151 
152 .seealso: PetscPushErrorHandler()
153 @*/
154 PetscErrorCode PETSCSYS_DLLEXPORT PetscPopErrorHandler(void)
155 {
156   EH             tmp;
157   PetscErrorCode ierr;
158 
159   PetscFunctionBegin;
160   if (!eh) PetscFunctionReturn(0);
161   tmp  = eh;
162   eh   = eh->previous;
163   ierr = PetscFree(tmp);CHKERRQ(ierr);
164 
165   PetscFunctionReturn(0);
166 }
167 
168 #undef __FUNCT__
169 #define __FUNCT__ "PetscReturnErrorHandler"
170 /*@C
171   PetscReturnErrorHandler - Error handler that causes a return to the current
172   level.
173 
174    Not Collective
175 
176    Input Parameters:
177 +  comm - communicator over which error occurred
178 .  line - the line number of the error (indicated by __LINE__)
179 .  func - the function where error is detected (indicated by __FUNCT__)
180 .  file - the file in which the error was detected (indicated by __FILE__)
181 .  dir - the directory of the file (indicated by __SDIR__)
182 .  mess - an error text string, usually just printed to the screen
183 .  n - the generic error number
184 .  p - specific error number
185 -  ctx - error handler context
186 
187    Level: developer
188 
189    Notes:
190    Most users need not directly employ this routine and the other error
191    handlers, but can instead use the simplified interface SETERRQ, which has
192    the calling sequence
193 $     SETERRQ(comm,number,mess)
194 
195    Notes for experienced users:
196    This routine is good for catching errors such as zero pivots in preconditioners
197    or breakdown of iterative methods. It is not appropriate for memory violations
198    and similar errors.
199 
200    Use PetscPushErrorHandler() to set the desired error handler.  The
201    currently available PETSc error handlers include PetscTraceBackErrorHandler(),
202    PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscAbortErrorHandler()
203 
204    Concepts: error handler
205 
206 .seealso:  PetscPushErrorHandler(), PetscPopErrorHandler().
207  @*/
208 
209 PetscErrorCode PETSCSYS_DLLEXPORT PetscReturnErrorHandler(MPI_Comm comm,int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx)
210 {
211   PetscFunctionBegin;
212   PetscFunctionReturn(n);
213 }
214 
215 static char PetscErrorBaseMessage[1024];
216 /*
217        The numerical values for these are defined in include/petscerror.h; any changes
218    there must also be made here
219 */
220 static const char *PetscErrorStrings[] = {
221   /*55 */ "Out of memory",
222           "No support for this operation for this object type",
223           "No support for this operation on this system",
224   /*58 */ "Operation done in wrong order",
225   /*59 */ "Signal received",
226   /*60 */ "Nonconforming object sizes",
227           "Argument aliasing not permitted",
228           "Invalid argument",
229   /*63 */ "Argument out of range",
230           "Corrupt argument: see http://www.mcs.anl.gov/petsc/petsc-as/documentation/faq.html#valgrind",
231           "Unable to open file",
232           "Read from file failed",
233           "Write to file failed",
234           "Invalid pointer",
235   /*69 */ "Arguments must have same type",
236           "",
237   /*71 */ "Detected zero pivot in LU factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/faq.html#ZeroPivot",
238   /*72 */ "Floating point exception",
239   /*73 */ "Object is in wrong state",
240           "Corrupted Petsc object",
241           "Arguments are incompatible",
242           "Error in external library",
243   /*77 */ "Petsc has generated inconsistent data",
244           "Memory corruption",
245           "Unexpected data in file",
246   /*80 */ "Arguments must have same communicators",
247   /*81 */ "Detected zero pivot in Cholesky factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/faq.html#ZeroPivot",
248           "  ",
249           "  ",
250           "  ",
251   /*85 */ "Null argument, when expecting valid pointer",
252   /*86 */ "Unknown type. Check for miss-spelling or missing external package needed for type\n seehttp://www.mcs.anl.gov/petsc/petsc-as/documentation/installation.html#external",
253   /*87 */ "Not used",
254   /*88 */ "Error in system call",
255   /*89 */ "Object Type not set: see http://www.mcs.anl.gov/petsc/petsc-as/documentation/faq.html#objecttypenotset"};
256 
257 #undef __FUNCT__
258 #define __FUNCT__ "PetscErrorMessage"
259 /*@C
260    PetscErrorMessage - returns the text string associated with a PETSc error code.
261 
262    Not Collective
263 
264    Input Parameter:
265 .   errnum - the error code
266 
267    Output Parameter:
268 +  text - the error message (PETSC_NULL if not desired)
269 -  specific - the specific error message that was set with SETERRxxx() or PetscError().  (PETSC_NULL if not desired)
270 
271    Level: developer
272 
273    Concepts: error handler^messages
274 
275 .seealso:  PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
276           PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
277  @*/
278 PetscErrorCode PETSCSYS_DLLEXPORT PetscErrorMessage(int errnum,const char *text[],char **specific)
279 {
280   PetscFunctionBegin;
281   if (text && errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) {
282     *text = PetscErrorStrings[errnum-PETSC_ERR_MIN_VALUE-1];
283   } else if (text) *text = 0;
284 
285   if (specific) {
286     *specific = PetscErrorBaseMessage;
287   }
288   PetscFunctionReturn(0);
289 }
290 
291 #if defined(PETSC_USE_ERRORCHECKING)
292 PetscErrorCode PETSCSYS_DLLEXPORT PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX] = {0};
293 PetscInt       PETSCSYS_DLLEXPORT PetscErrorUncatchableCount                  = 0;
294 PetscErrorCode PETSCSYS_DLLEXPORT PetscExceptions[PETSC_EXCEPTIONS_MAX]       = {0};
295 PetscInt       PETSCSYS_DLLEXPORT PetscExceptionsCount                        = 0;
296 PetscErrorCode PETSCSYS_DLLEXPORT PetscExceptionTmp                           = 0;
297 PetscErrorCode PETSCSYS_DLLEXPORT PetscExceptionTmp1                          = 0;
298 
299 #undef __FUNCT__
300 #define __FUNCT__ "PetscErrorIsCatchable"
301 /*@C
302       PetscErrorIsCatchable - Returns if a PetscErrorCode can be caught with a PetscExceptionTry1() or
303            PetscExceptionPush()
304 
305   Input Parameters:
306 .   err - error code
307 
308   Level: advanced
309 
310    Notes:
311     PETSc must not be configured using the option --with-errorchecking=0 for this to work
312 
313 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop(), PetscErrorSetCatchable()
314 @*/
315 PetscTruth PETSCSYS_DLLEXPORT PetscErrorIsCatchable(PetscErrorCode err)
316 {
317   PetscInt i;
318   for (i=0; i<PetscErrorUncatchableCount; i++) {
319     if (err == PetscErrorUncatchable[i]) return PETSC_FALSE;
320   }
321   return PETSC_TRUE;
322 }
323 
324 #undef __FUNCT__
325 #define __FUNCT__ "PetscErrorSetCatchable"
326 /*@
327       PetscErrorSetCatchable - Sets if a PetscErrorCode can be caught with a PetscExceptionTry1()
328     PetscExceptionCaught() pair, or PetscExceptionPush(). By default all errors are catchable.
329 
330   Input Parameters:
331 +   err - error code
332 -   flg - PETSC_TRUE means allow to be caught, PETSC_FALSE means do not allow to be caught
333 
334   Level: advanced
335 
336    Notes:
337     PETSc must not be configured using the option --with-errorchecking=0 for this to work
338 
339 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop(), PetscErrorIsCatchable()
340 @*/
341 PetscErrorCode PETSCSYS_DLLEXPORT PetscErrorSetCatchable(PetscErrorCode err,PetscTruth flg)
342 {
343   PetscFunctionBegin;
344   if (!flg && PetscErrorIsCatchable(err)) {
345     /* add to list of uncatchable */
346     if (PetscErrorUncatchableCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Stack for PetscErrorUncatchable is overflowed, recompile \nsrc/sysd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX");
347     PetscErrorUncatchable[PetscErrorUncatchableCount++] = err;
348   } else if (flg && !PetscErrorIsCatchable(err)) {
349     /* remove from list of uncatchable */
350     PetscInt i;
351     for (i=0; i<PetscErrorUncatchableCount; i++) {
352       if (PetscErrorUncatchable[i] == err) break;
353     }
354     for (;i<PetscErrorUncatchableCount; i++) {
355       PetscErrorUncatchable[i] = PetscErrorUncatchable[i+1];
356     }
357     PetscErrorUncatchableCount--;
358   }
359   PetscFunctionReturn(0);
360 }
361 
362 #undef __FUNCT__
363 #define __FUNCT__ "PetscExceptionPush"
364 /*@
365       PetscExceptionPush - Adds the exception as one to be caught and passed up. If passed up
366         can be checked with PetscExceptionCaught() or PetscExceptionValue()
367 
368   Input Parameters:
369 .   err - the exception to catch
370 
371   Level: advanced
372 
373    Notes:
374     PETSc must not be configured using the option --with-errorchecking=0 for this to work
375 
376     Use PetscExceptionPop() to remove this as a value to be caught
377 
378     This is not usually needed in C/C++ rather use PetscExceptionTry1()
379 
380 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop()
381 @*/
382 PetscErrorCode PETSCSYS_DLLEXPORT PetscExceptionPush(PetscErrorCode err)
383 {
384   PetscFunctionBegin;
385   if (PetscExceptionsCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Stack for PetscExceptions is overflowed, recompile \nsrc/sysd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX");
386   if (PetscErrorIsCatchable(err)) PetscExceptions[PetscExceptionsCount++] = err;
387   PetscFunctionReturn(0);
388 }
389 
390 #undef __FUNCT__
391 #define __FUNCT__ "PetscExceptionPop"
392 /*@
393       PetscExceptionPop - Removes  the most recent exception asked to be caught with PetscExceptionPush()
394 
395   Input Parameters:
396 .   err - the exception that was pushed
397 
398   Level: advanced
399 
400    Notes:
401     PETSc must not be configured using the option --with-errorchecking=0 for this to work
402 
403     This is not usually needed in C/C++ rather use PetscExceptionTry1()
404 
405 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop()
406 @*/
407 PetscErrorCode PETSCSYS_DLLEXPORT PetscExceptionPop(PetscErrorCode err)
408 {
409   PetscFunctionBegin;
410   if (PetscExceptionsCount <= 0)SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Stack for PetscExceptions is empty");
411   if (PetscErrorIsCatchable(err)) PetscExceptionsCount--;
412   PetscFunctionReturn(0);
413 }
414 #endif
415 
416 #undef __FUNCT__
417 #define __FUNCT__ "PetscError"
418 /*@C
419    PetscError - Routine that is called when an error has been detected,
420    usually called through the macro SETERRQ(PETSC_COMM_SELF,).
421 
422    Not Collective
423 
424    Input Parameters:
425 +  comm - communicator over which error occurred.  ALL ranks of this communicator MUST call this routine
426 .  line - the line number of the error (indicated by __LINE__)
427 .  func - the function where the error occured (indicated by __FUNCT__)
428 .  dir - the directory of file (indicated by __SDIR__)
429 .  file - the file in which the error was detected (indicated by __FILE__)
430 .  mess - an error text string, usually just printed to the screen
431 .  n - the generic error number
432 .  p - PETSC_ERROR_INITIAL indicates the error was initially detected, PETSC_ERROR_REPEAT indicates this is a traceback from a previously detected error
433 -  mess - formatted message string - aka printf
434 
435   Level: intermediate
436 
437    Notes:
438    Most users need not directly use this routine and the error handlers, but
439    can instead use the simplified interface SETERRQ, which has the calling
440    sequence
441 $     SETERRQ(comm,n,mess)
442 
443    Experienced users can set the error handler with PetscPushErrorHandler().
444 
445    Concepts: error^setting condition
446 
447 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
448 @*/
449 PetscErrorCode PETSCSYS_DLLEXPORT PetscError(MPI_Comm comm,int line,const char *func,const char* file,const char *dir,PetscErrorCode n,PetscErrorType p,const char *mess,...)
450 {
451   va_list        Argp;
452   int            fullLength;
453   PetscErrorCode ierr;
454   char           buf[2048],*lbuf = 0;
455   PetscTruth     ismain,isunknown;
456 #if defined(PETSC_USE_ERRORCHECKING)
457   PetscInt       i;
458 #endif
459 
460   if (!func)  func = "User provided function";
461   if (!file)  file = "User file";
462   if (!dir)   dir = " ";
463 
464   PetscFunctionBegin;
465   /* Compose the message evaluating the print format */
466   if (mess) {
467     va_start(Argp,mess);
468     PetscVSNPrintf(buf,2048,mess,&fullLength,Argp);
469     va_end(Argp);
470     lbuf = buf;
471     if (p == 1) {
472       PetscStrncpy(PetscErrorBaseMessage,lbuf,1023);
473     }
474   }
475 
476 #if defined(PETSC_USE_ERRORCHECKING)
477   /* check if user is catching this exception */
478   for (i=0; i<PetscExceptionsCount; i++) {
479     if (n == PetscExceptions[i])  PetscFunctionReturn(n);
480   }
481 #endif
482 
483   if (!eh)     ierr = PetscTraceBackErrorHandler(comm,line,func,file,dir,n,p,lbuf,0);
484   else         ierr = (*eh->handler)(comm,line,func,file,dir,n,p,lbuf,eh->ctx);
485 
486   /*
487       If this is called from the main() routine we call MPI_Abort() instead of
488     return to allow the parallel program to be properly shutdown.
489 
490     Since this is in the error handler we don't check the errors below. Of course,
491     PetscStrncmp() does its own error checking which is problamatic
492   */
493   PetscStrncmp(func,"main",4,&ismain);
494   PetscStrncmp(func,"unknown",7,&isunknown);
495   if (ismain || isunknown) {
496     MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
497   }
498 #if defined(PETSC_CLANGUAGE_CXX) && !defined(PETSC_USE_EXTERN_CXX)
499   if (p == PETSC_ERROR_IN_CXX) {
500     const char *str;
501     if (eh->ctx) {
502       std::ostringstream *msg;
503       msg = (std::ostringstream*) eh->ctx;
504       str = msg->str().c_str();
505     } else {
506       str = "Error detected in C PETSc";
507     }
508     throw PETSc::Exception(str);
509   }
510 #endif
511   PetscFunctionReturn(ierr);
512 }
513 
514 /* -------------------------------------------------------------------------*/
515 
516 #undef __FUNCT__
517 #define __FUNCT__ "PetscIntView"
518 /*@C
519     PetscIntView - Prints an array of integers; useful for debugging.
520 
521     Collective on PetscViewer
522 
523     Input Parameters:
524 +   N - number of integers in array
525 .   idx - array of integers
526 -   viewer - location to print array,  PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
527 
528   Level: intermediate
529 
530     Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done
531 
532 .seealso: PetscRealView()
533 @*/
534 PetscErrorCode PETSCSYS_DLLEXPORT PetscIntView(PetscInt N,const PetscInt idx[],PetscViewer viewer)
535 {
536   PetscErrorCode ierr;
537   PetscInt       j,i,n = N/20,p = N % 20;
538   PetscTruth     iascii,isbinary;
539   MPI_Comm       comm;
540 
541   PetscFunctionBegin;
542   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
543   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3);
544   if (N) PetscValidIntPointer(idx,2);
545   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
546 
547   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
548   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
549   if (iascii) {
550     for (i=0; i<n; i++) {
551       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr);
552       for (j=0; j<20; j++) {
553         ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr);
554       }
555       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
556     }
557     if (p) {
558       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr);
559       for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);}
560       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
561     }
562     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
563   } else if (isbinary) {
564     PetscMPIInt rank,size,*sizes,Ntotal,*displs, NN = PetscMPIIntCast(N);
565     PetscInt    *array;
566     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
567     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
568 
569     if (size > 1) {
570       if (rank) {
571         ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr);
572         ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr);
573       } else {
574 	ierr      = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr);
575         ierr      = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr);
576         Ntotal    = sizes[0];
577 	ierr      = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr);
578         displs[0] = 0;
579         for (i=1; i<size; i++) {
580           Ntotal    += sizes[i];
581           displs[i] =  displs[i-1] + sizes[i-1];
582         }
583 	ierr = PetscMalloc(Ntotal*sizeof(PetscInt),&array);CHKERRQ(ierr);
584         ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr);
585         ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
586         ierr = PetscFree(sizes);CHKERRQ(ierr);
587         ierr = PetscFree(displs);CHKERRQ(ierr);
588         ierr = PetscFree(array);CHKERRQ(ierr);
589       }
590     } else {
591       ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
592     }
593   } else {
594     const char *tname;
595     ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr);
596     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
597   }
598   PetscFunctionReturn(0);
599 }
600 
601 #undef __FUNCT__
602 #define __FUNCT__ "PetscRealView"
603 /*@C
604     PetscRealView - Prints an array of doubles; useful for debugging.
605 
606     Collective on PetscViewer
607 
608     Input Parameters:
609 +   N - number of doubles in array
610 .   idx - array of doubles
611 -   viewer - location to print array,  PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
612 
613   Level: intermediate
614 
615     Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done
616 
617 .seealso: PetscIntView()
618 @*/
619 PetscErrorCode PETSCSYS_DLLEXPORT PetscRealView(PetscInt N,const PetscReal idx[],PetscViewer viewer)
620 {
621   PetscErrorCode ierr;
622   PetscInt       j,i,n = N/5,p = N % 5;
623   PetscTruth     iascii,isbinary;
624   MPI_Comm       comm;
625 
626   PetscFunctionBegin;
627   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
628   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3);
629   PetscValidScalarPointer(idx,2);
630   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
631 
632   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
633   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
634   if (iascii) {
635     for (i=0; i<n; i++) {
636       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr);
637       for (j=0; j<5; j++) {
638          ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr);
639       }
640       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
641     }
642     if (p) {
643       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr);
644       for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);}
645       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
646     }
647     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
648   } else if (isbinary) {
649     PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN = PetscMPIIntCast(N);
650     PetscReal   *array;
651 
652     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
653     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
654 
655     if (size > 1) {
656       if (rank) {
657         ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr);
658         ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);CHKERRQ(ierr);
659       } else {
660 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr);
661         ierr   = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr);
662         Ntotal = sizes[0];
663 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr);
664         displs[0] = 0;
665         for (i=1; i<size; i++) {
666           Ntotal    += sizes[i];
667           displs[i] =  displs[i-1] + sizes[i-1];
668         }
669 	ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr);
670         ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);CHKERRQ(ierr);
671         ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_REAL,PETSC_TRUE);CHKERRQ(ierr);
672         ierr = PetscFree(sizes);CHKERRQ(ierr);
673         ierr = PetscFree(displs);CHKERRQ(ierr);
674         ierr = PetscFree(array);CHKERRQ(ierr);
675       }
676     } else {
677       ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr);
678     }
679   } else {
680     const char *tname;
681     ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr);
682     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
683   }
684   PetscFunctionReturn(0);
685 }
686 
687 #undef __FUNCT__
688 #define __FUNCT__ "PetscScalarView"
689 /*@C
690     PetscScalarView - Prints an array of scalars; useful for debugging.
691 
692     Collective on PetscViewer
693 
694     Input Parameters:
695 +   N - number of scalars in array
696 .   idx - array of scalars
697 -   viewer - location to print array,  PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
698 
699   Level: intermediate
700 
701     Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done
702 
703 .seealso: PetscIntView(), PetscRealView()
704 @*/
705 PetscErrorCode PETSCSYS_DLLEXPORT PetscScalarView(PetscInt N,const PetscScalar idx[],PetscViewer viewer)
706 {
707   PetscErrorCode ierr;
708   PetscInt       j,i,n = N/3,p = N % 3;
709   PetscTruth     iascii,isbinary;
710   MPI_Comm       comm;
711 
712   PetscFunctionBegin;
713   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
714   PetscValidHeader(viewer,3);
715   PetscValidScalarPointer(idx,2);
716   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
717 
718   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
719   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
720   if (iascii) {
721     for (i=0; i<n; i++) {
722       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr);
723       for (j=0; j<3; j++) {
724 #if defined (PETSC_USE_COMPLEX)
725         ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
726                                  PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr);
727 #else
728         ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr);
729 #endif
730       }
731       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
732     }
733     if (p) {
734       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr);
735       for (i=0; i<p; i++) {
736 #if defined (PETSC_USE_COMPLEX)
737         ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
738                                  PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr);
739 #else
740         ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr);
741 #endif
742       }
743       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
744     }
745     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
746   } else if (isbinary) {
747     PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN = PetscMPIIntCast(N);
748     PetscScalar *array;
749 
750     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
751     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
752 
753     if (size > 1) {
754       if (rank) {
755         ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr);
756         ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr);
757       } else {
758 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr);
759         ierr   = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr);
760         Ntotal = sizes[0];
761 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr);
762         displs[0] = 0;
763         for (i=1; i<size; i++) {
764           Ntotal    += sizes[i];
765           displs[i] =  displs[i-1] + sizes[i-1];
766         }
767 	ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr);
768         ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr);
769         ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr);
770         ierr = PetscFree(sizes);CHKERRQ(ierr);
771         ierr = PetscFree(displs);CHKERRQ(ierr);
772         ierr = PetscFree(array);CHKERRQ(ierr);
773       }
774     } else {
775       ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
776     }
777   } else {
778     const char *tname;
779     ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr);
780     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
781   }
782   PetscFunctionReturn(0);
783 }
784 
785 
786 
787 
788