xref: /petsc/src/sys/error/err.c (revision e32f2f54e699d0aa6e733466c00da7e34666fe5e)
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,int,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 PETSC_DLLEXPORT PetscEmacsClientErrorHandler(MPI_Comm comm,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_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 - the specific error number
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 PETSC_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm comm,int,const char *,const char*,const char*,PetscErrorCode,int,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 PETSC_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 PETSC_DLLEXPORT PetscReturnErrorHandler(MPI_Comm comm,int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,int 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 PETSC_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 PETSC_DLLEXPORT PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX] = {0};
293 PetscInt       PETSC_DLLEXPORT PetscErrorUncatchableCount                  = 0;
294 PetscErrorCode PETSC_DLLEXPORT PetscExceptions[PETSC_EXCEPTIONS_MAX]       = {0};
295 PetscInt       PETSC_DLLEXPORT PetscExceptionsCount                        = 0;
296 PetscErrorCode PETSC_DLLEXPORT PetscExceptionTmp                           = 0;
297 PetscErrorCode PETSC_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 PETSC_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 PETSC_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 PETSC_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 PETSC_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 - 1 indicates the error was initially detected, 0 indicates this is a traceback from a
433    previously detected error
434 -  mess - formatted message string - aka printf
435 
436   Level: intermediate
437 
438    Notes:
439    Most users need not directly use this routine and the error handlers, but
440    can instead use the simplified interface SETERRQ, which has the calling
441    sequence
442 $     SETERRQ(comm,n,mess)
443 
444    Experienced users can set the error handler with PetscPushErrorHandler().
445 
446    Concepts: error^setting condition
447 
448 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
449 @*/
450 PetscErrorCode PETSC_DLLEXPORT PetscError(MPI_Comm comm,int line,const char *func,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,...)
451 {
452   va_list        Argp;
453   int            fullLength;
454   PetscErrorCode ierr;
455   char           buf[2048],*lbuf = 0;
456   PetscTruth     ismain,isunknown;
457 #if defined(PETSC_USE_ERRORCHECKING)
458   PetscInt       i;
459 #endif
460 
461   if (!func)  func = "User provided function";
462   if (!file)  file = "User file";
463   if (!dir)   dir = " ";
464 
465   PetscFunctionBegin;
466   /* Compose the message evaluating the print format */
467   if (mess) {
468     va_start(Argp,mess);
469     PetscVSNPrintf(buf,2048,mess,&fullLength,Argp);
470     va_end(Argp);
471     lbuf = buf;
472     if (p == 1) {
473       PetscStrncpy(PetscErrorBaseMessage,lbuf,1023);
474     }
475   }
476 
477 #if defined(PETSC_USE_ERRORCHECKING)
478   /* check if user is catching this exception */
479   for (i=0; i<PetscExceptionsCount; i++) {
480     if (n == PetscExceptions[i])  PetscFunctionReturn(n);
481   }
482 #endif
483 
484   if (!eh)     ierr = PetscTraceBackErrorHandler(comm,line,func,file,dir,n,p,lbuf,0);
485   else         ierr = (*eh->handler)(comm,line,func,file,dir,n,p,lbuf,eh->ctx);
486 
487   /*
488       If this is called from the main() routine we call MPI_Abort() instead of
489     return to allow the parallel program to be properly shutdown.
490 
491     Since this is in the error handler we don't check the errors below. Of course,
492     PetscStrncmp() does its own error checking which is problamatic
493   */
494   PetscStrncmp(func,"main",4,&ismain);
495   PetscStrncmp(func,"unknown",7,&isunknown);
496   if (ismain || isunknown) {
497     MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
498   }
499   PetscFunctionReturn(ierr);
500 }
501 
502 #if defined(PETSC_CLANGUAGE_CXX) && !defined(PETSC_USE_EXTERN_CXX)
503 #undef __FUNCT__
504 #define __FUNCT__ "PetscErrorCxx"
505 /*@C
506    PetscErrorCxx - Routine that is called when an error has been detected,
507    usually called through the macro SETERROR().
508 
509    Not Collective
510 
511    Input Parameters:
512 +  comm - communicator over which the error occurred
513 .  line - the line number of the error (indicated by __LINE__)
514 .  func - the function where the error occured (indicated by __FUNCT__)
515 .  dir - the directory of file (indicated by __SDIR__)
516 .  file - the file in which the error was detected (indicated by __FILE__)
517 .  n - the generic error number
518 .  p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a
519    previously detected error
520 
521   Level: intermediate
522 
523    Notes:
524    Most users need not directly use this routine and the error handlers, but
525    can instead use the simplified interface SETERRQ, which has the calling
526    sequence
527 $     SETERRQ(comm,n,mess)
528 
529    Experienced users can set the error handler with PetscPushErrorHandler().
530 
531    Concepts: error^setting condition
532 
533 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
534 @*/
535 void PETSC_DLLEXPORT PetscErrorCxx(MPI_Comm comm,int line,const char *func,const char* file,const char *dir,PetscErrorCode n,int p)
536 {
537   PetscTruth ismain, isunknown;
538 #if 0
539 #if defined(PETSC_USE_ERRORCHECKING)
540   PetscInt   i;
541 #endif
542 #endif
543 
544   if (!func) func = "User provided function";
545   if (!file) file = "User file";
546   if (!dir)  dir  = " ";
547 
548 #if 0
549 #if defined(PETSC_USE_ERRORCHECKING)
550   /* check if user is catching this exception */
551   for (i=0; i<PetscExceptionsCount; i++) {
552     if (n == PetscExceptions[i])  PetscFunctionReturn(n);
553   }
554 #endif
555 #endif
556 
557   std::ostringstream msg;
558 
559   PetscTraceBackErrorHandlerCxx(line, func, file, dir, n, p, msg);
560 
561   /*
562       If this is called from the main() routine we call MPI_Abort() instead of
563     return to allow the parallel program to be properly shutdown.
564 
565     Since this is in the error handler we don't check the errors below. Of course,
566     PetscStrncmp() does its own error checking which is problamatic
567   */
568   PetscStrncmp(func,"main",4,&ismain);
569   PetscStrncmp(func,"unknown",7,&isunknown);
570   if (ismain || isunknown) {
571     MPI_Abort(PETSC_COMM_WORLD, (int) n);
572   }
573   throw PETSc::Exception(msg.str().c_str());
574 }
575 #endif
576 
577 /* -------------------------------------------------------------------------*/
578 
579 #undef __FUNCT__
580 #define __FUNCT__ "PetscIntView"
581 /*@C
582     PetscIntView - Prints an array of integers; useful for debugging.
583 
584     Collective on PetscViewer
585 
586     Input Parameters:
587 +   N - number of integers in array
588 .   idx - array of integers
589 -   viewer - location to print array,  PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
590 
591   Level: intermediate
592 
593     Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done
594 
595 .seealso: PetscRealView()
596 @*/
597 PetscErrorCode PETSC_DLLEXPORT PetscIntView(PetscInt N,const PetscInt idx[],PetscViewer viewer)
598 {
599   PetscErrorCode ierr;
600   PetscInt       j,i,n = N/20,p = N % 20;
601   PetscTruth     iascii,isbinary;
602   MPI_Comm       comm;
603 
604   PetscFunctionBegin;
605   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
606   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3);
607   if (N) PetscValidIntPointer(idx,2);
608   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
609 
610   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
611   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
612   if (iascii) {
613     for (i=0; i<n; i++) {
614       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr);
615       for (j=0; j<20; j++) {
616         ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr);
617       }
618       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
619     }
620     if (p) {
621       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr);
622       for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);}
623       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
624     }
625     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
626   } else if (isbinary) {
627     PetscMPIInt rank,size,*sizes,Ntotal,*displs, NN = PetscMPIIntCast(N);
628     PetscInt    *array;
629     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
630     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
631 
632     if (size > 1) {
633       if (rank) {
634         ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr);
635         ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr);
636       } else {
637 	ierr      = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr);
638         ierr      = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr);
639         Ntotal    = sizes[0];
640 	ierr      = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr);
641         displs[0] = 0;
642         for (i=1; i<size; i++) {
643           Ntotal    += sizes[i];
644           displs[i] =  displs[i-1] + sizes[i-1];
645         }
646 	ierr = PetscMalloc(Ntotal*sizeof(PetscInt),&array);CHKERRQ(ierr);
647         ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr);
648         ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
649         ierr = PetscFree(sizes);CHKERRQ(ierr);
650         ierr = PetscFree(displs);CHKERRQ(ierr);
651         ierr = PetscFree(array);CHKERRQ(ierr);
652       }
653     } else {
654       ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
655     }
656   } else {
657     const char *tname;
658     ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr);
659     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
660   }
661   PetscFunctionReturn(0);
662 }
663 
664 #undef __FUNCT__
665 #define __FUNCT__ "PetscRealView"
666 /*@C
667     PetscRealView - Prints an array of doubles; useful for debugging.
668 
669     Collective on PetscViewer
670 
671     Input Parameters:
672 +   N - number of doubles in array
673 .   idx - array of doubles
674 -   viewer - location to print array,  PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
675 
676   Level: intermediate
677 
678     Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done
679 
680 .seealso: PetscIntView()
681 @*/
682 PetscErrorCode PETSC_DLLEXPORT PetscRealView(PetscInt N,const PetscReal idx[],PetscViewer viewer)
683 {
684   PetscErrorCode ierr;
685   PetscInt       j,i,n = N/5,p = N % 5;
686   PetscTruth     iascii,isbinary;
687   MPI_Comm       comm;
688 
689   PetscFunctionBegin;
690   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
691   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3);
692   PetscValidScalarPointer(idx,2);
693   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
694 
695   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
696   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
697   if (iascii) {
698     for (i=0; i<n; i++) {
699       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr);
700       for (j=0; j<5; j++) {
701          ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr);
702       }
703       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
704     }
705     if (p) {
706       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr);
707       for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);}
708       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
709     }
710     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
711   } else if (isbinary) {
712     PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN = PetscMPIIntCast(N);
713     PetscReal   *array;
714 
715     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
716     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
717 
718     if (size > 1) {
719       if (rank) {
720         ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr);
721         ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);CHKERRQ(ierr);
722       } else {
723 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr);
724         ierr   = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr);
725         Ntotal = sizes[0];
726 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr);
727         displs[0] = 0;
728         for (i=1; i<size; i++) {
729           Ntotal    += sizes[i];
730           displs[i] =  displs[i-1] + sizes[i-1];
731         }
732 	ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr);
733         ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);CHKERRQ(ierr);
734         ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_REAL,PETSC_TRUE);CHKERRQ(ierr);
735         ierr = PetscFree(sizes);CHKERRQ(ierr);
736         ierr = PetscFree(displs);CHKERRQ(ierr);
737         ierr = PetscFree(array);CHKERRQ(ierr);
738       }
739     } else {
740       ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr);
741     }
742   } else {
743     const char *tname;
744     ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr);
745     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
746   }
747   PetscFunctionReturn(0);
748 }
749 
750 #undef __FUNCT__
751 #define __FUNCT__ "PetscScalarView"
752 /*@C
753     PetscScalarView - Prints an array of scalars; useful for debugging.
754 
755     Collective on PetscViewer
756 
757     Input Parameters:
758 +   N - number of scalars in array
759 .   idx - array of scalars
760 -   viewer - location to print array,  PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
761 
762   Level: intermediate
763 
764     Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done
765 
766 .seealso: PetscIntView(), PetscRealView()
767 @*/
768 PetscErrorCode PETSC_DLLEXPORT PetscScalarView(PetscInt N,const PetscScalar idx[],PetscViewer viewer)
769 {
770   PetscErrorCode ierr;
771   PetscInt       j,i,n = N/3,p = N % 3;
772   PetscTruth     iascii,isbinary;
773   MPI_Comm       comm;
774 
775   PetscFunctionBegin;
776   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
777   PetscValidHeader(viewer,3);
778   PetscValidScalarPointer(idx,2);
779   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
780 
781   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
782   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
783   if (iascii) {
784     for (i=0; i<n; i++) {
785       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr);
786       for (j=0; j<3; j++) {
787 #if defined (PETSC_USE_COMPLEX)
788         ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
789                                  PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr);
790 #else
791         ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr);
792 #endif
793       }
794       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
795     }
796     if (p) {
797       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr);
798       for (i=0; i<p; i++) {
799 #if defined (PETSC_USE_COMPLEX)
800         ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
801                                  PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr);
802 #else
803         ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr);
804 #endif
805       }
806       ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr);
807     }
808     ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
809   } else if (isbinary) {
810     PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN = PetscMPIIntCast(N);
811     PetscScalar *array;
812 
813     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
814     ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
815 
816     if (size > 1) {
817       if (rank) {
818         ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr);
819         ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr);
820       } else {
821 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr);
822         ierr   = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr);
823         Ntotal = sizes[0];
824 	ierr   = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr);
825         displs[0] = 0;
826         for (i=1; i<size; i++) {
827           Ntotal    += sizes[i];
828           displs[i] =  displs[i-1] + sizes[i-1];
829         }
830 	ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr);
831         ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr);
832         ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr);
833         ierr = PetscFree(sizes);CHKERRQ(ierr);
834         ierr = PetscFree(displs);CHKERRQ(ierr);
835         ierr = PetscFree(array);CHKERRQ(ierr);
836       }
837     } else {
838       ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
839     }
840   } else {
841     const char *tname;
842     ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr);
843     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
844   }
845   PetscFunctionReturn(0);
846 }
847 
848 
849 
850 
851