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