xref: /petsc/src/sys/error/err.c (revision 811af0c4b09a35de4306c442f88bd09fdc09897d)
17d0a6c19SBarry Smith 
2e5c89e4eSSatish Balay /*
3e5c89e4eSSatish Balay       Code that allows one to set the error handlers
4e5c89e4eSSatish Balay */
5af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/
6665c2dedSJed Brown #include <petscviewer.h>
7e5c89e4eSSatish Balay 
8e5c89e4eSSatish Balay typedef struct _EH *EH;
9e5c89e4eSSatish Balay struct _EH {
10efca3c55SSatish Balay   PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *);
11e5c89e4eSSatish Balay   void *ctx;
12e5c89e4eSSatish Balay   EH    previous;
13e5c89e4eSSatish Balay };
14e5c89e4eSSatish Balay 
1502c9f0b5SLisandro Dalcin static EH eh = NULL;
16e5c89e4eSSatish Balay 
17e5c89e4eSSatish Balay /*@C
18e5c89e4eSSatish Balay    PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
19a5b23f4aSJose E. Roman     load the file where the error occurred. Then calls the "previous" error handler.
20e5c89e4eSSatish Balay 
21e5c89e4eSSatish Balay    Not Collective
22e5c89e4eSSatish Balay 
23e5c89e4eSSatish Balay    Input Parameters:
24a5b23f4aSJose E. Roman +  comm - communicator over which error occurred
25e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
26e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
27e5c89e4eSSatish Balay .  mess - an error text string, usually just printed to the screen
28e5c89e4eSSatish Balay .  n - the generic error number
29e5c89e4eSSatish Balay .  p - specific error number
30e5c89e4eSSatish Balay -  ctx - error handler context
31e5c89e4eSSatish Balay 
32e5c89e4eSSatish Balay    Options Database Key:
3310699b91SBarry Smith .   -on_error_emacs <machinename> - will contact machinename to open the Emacs client there
34e5c89e4eSSatish Balay 
35e5c89e4eSSatish Balay    Level: developer
36e5c89e4eSSatish Balay 
37*811af0c4SBarry Smith    Note:
38e5c89e4eSSatish Balay    You must put (server-start) in your .emacs file for the emacsclient software to work
39e5c89e4eSSatish Balay 
40cc12936aSPatrick Sanan    Developer Note:
41*811af0c4SBarry Smith    Since this is an error handler it cannot call `PetscCall()`; thus we just return if an error is detected.
42*811af0c4SBarry Smith    But some of the functions it calls do perform error checking that may not be appropriate in a error handler call.
433bf036e2SBarry Smith 
44db781477SPatrick Sanan .seealso: `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`,
45db781477SPatrick Sanan           `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscReturnErrorHandler()`
46e5c89e4eSSatish Balay  @*/
479371c9d4SSatish Balay PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx) {
48e5c89e4eSSatish Balay   PetscErrorCode ierr;
49e5c89e4eSSatish Balay   char           command[PETSC_MAX_PATH_LEN];
50e5c89e4eSSatish Balay   const char    *pdir;
51e5c89e4eSSatish Balay   FILE          *fp;
52e5c89e4eSSatish Balay 
539371c9d4SSatish Balay   ierr = PetscGetPetscDir(&pdir);
5411cc89d2SBarry Smith   if (ierr) return ierr;
55efca3c55SSatish Balay   sprintf(command, "cd %s; emacsclient --no-wait +%d %s\n", pdir, line, file);
56e5c89e4eSSatish Balay #if defined(PETSC_HAVE_POPEN)
579371c9d4SSatish Balay   ierr = PetscPOpen(MPI_COMM_WORLD, (char *)ctx, command, "r", &fp);
5811cc89d2SBarry Smith   if (ierr) return ierr;
599371c9d4SSatish Balay   ierr = PetscPClose(MPI_COMM_WORLD, fp);
6011cc89d2SBarry Smith   if (ierr) return ierr;
61e5c89e4eSSatish Balay #else
62e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine");
63e5c89e4eSSatish Balay #endif
649371c9d4SSatish Balay   ierr = PetscPopErrorHandler();
6511cc89d2SBarry Smith   if (ierr) return ierr; /* remove this handler from the stack of handlers */
663bf036e2SBarry Smith   if (!eh) {
679371c9d4SSatish Balay     ierr = PetscTraceBackErrorHandler(comm, line, fun, file, n, p, mess, NULL);
6811cc89d2SBarry Smith     if (ierr) return ierr;
693bf036e2SBarry Smith   } else {
709371c9d4SSatish Balay     ierr = (*eh->handler)(comm, line, fun, file, n, p, mess, eh->ctx);
7111cc89d2SBarry Smith     if (ierr) return ierr;
723bf036e2SBarry Smith   }
7311cc89d2SBarry Smith   return 0;
74e5c89e4eSSatish Balay }
75e5c89e4eSSatish Balay 
76e5c89e4eSSatish Balay /*@C
77e5c89e4eSSatish Balay    PetscPushErrorHandler - Sets a routine to be called on detection of errors.
78e5c89e4eSSatish Balay 
79e5c89e4eSSatish Balay    Not Collective
80e5c89e4eSSatish Balay 
81e5c89e4eSSatish Balay    Input Parameters:
82e5c89e4eSSatish Balay +  handler - error handler routine
83e5c89e4eSSatish Balay -  ctx - optional handler context that contains information needed by the handler (for
84e5c89e4eSSatish Balay          example file pointers for error messages etc.)
85e5c89e4eSSatish Balay 
86e5c89e4eSSatish Balay    Calling sequence of handler:
87efca3c55SSatish Balay $    int handler(MPI_Comm comm,int line,char *func,char *file,PetscErrorCode n,int p,char *mess,void *ctx);
88e5c89e4eSSatish Balay 
89a5b23f4aSJose E. Roman +  comm - communicator over which error occurred
90e5c89e4eSSatish Balay .  line - the line number of the error (indicated by __LINE__)
91e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
92e5c89e4eSSatish Balay .  n - the generic error number (see list defined in include/petscerror.h)
93668f157eSBarry Smith .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
94e5c89e4eSSatish Balay .  mess - an error text string, usually just printed to the screen
95e5c89e4eSSatish Balay -  ctx - the error handler context
96e5c89e4eSSatish Balay 
97e5c89e4eSSatish Balay    Options Database Keys:
9810699b91SBarry Smith +   -on_error_attach_debugger <noxterm,gdb or dbx> - starts up the debugger if an error occurs
9910699b91SBarry Smith -   -on_error_abort - aborts the program if an error occurs
100e5c89e4eSSatish Balay 
101e5c89e4eSSatish Balay    Level: intermediate
102e5c89e4eSSatish Balay 
103*811af0c4SBarry Smith    Note:
104*811af0c4SBarry Smith    The currently available PETSc error handlers include `PetscTraceBackErrorHandler()`,
105*811af0c4SBarry Smith    `PetscAttachDebuggerErrorHandler()`, `PetscAbortErrorHandler()`, and `PetscMPIAbortErrorHandler()`, `PetscReturnErrorHandler()`.
106e93bc3c1Svictor 
107*811af0c4SBarry Smith    Fortran Note:
10895452b02SPatrick Sanan     You can only push one error handler from Fortran before poping it.
1097850c7c0SBarry Smith 
110db781477SPatrick Sanan .seealso: `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscAbortErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscPushSignalHandler()`
111e5c89e4eSSatish Balay @*/
1129371c9d4SSatish Balay PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *ctx) {
113e5c89e4eSSatish Balay   EH neweh;
114e5c89e4eSSatish Balay 
115e5c89e4eSSatish Balay   PetscFunctionBegin;
1169566063dSJacob Faibussowitsch   PetscCall(PetscNew(&neweh));
117a297a907SKarl Rupp   if (eh) neweh->previous = eh;
11802c9f0b5SLisandro Dalcin   else neweh->previous = NULL;
119e5c89e4eSSatish Balay   neweh->handler = handler;
120e5c89e4eSSatish Balay   neweh->ctx     = ctx;
121e5c89e4eSSatish Balay   eh             = neweh;
122e5c89e4eSSatish Balay   PetscFunctionReturn(0);
123e5c89e4eSSatish Balay }
124e5c89e4eSSatish Balay 
125e30d2299SSatish Balay /*@
126e5c89e4eSSatish Balay    PetscPopErrorHandler - Removes the latest error handler that was
127*811af0c4SBarry Smith    pushed with `PetscPushErrorHandler()`.
128e5c89e4eSSatish Balay 
129e5c89e4eSSatish Balay    Not Collective
130e5c89e4eSSatish Balay 
131e5c89e4eSSatish Balay    Level: intermediate
132e5c89e4eSSatish Balay 
133db781477SPatrick Sanan .seealso: `PetscPushErrorHandler()`
134e5c89e4eSSatish Balay @*/
1359371c9d4SSatish Balay PetscErrorCode PetscPopErrorHandler(void) {
136e5c89e4eSSatish Balay   EH tmp;
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay   PetscFunctionBegin;
139e5c89e4eSSatish Balay   if (!eh) PetscFunctionReturn(0);
140e5c89e4eSSatish Balay   tmp = eh;
141e5c89e4eSSatish Balay   eh  = eh->previous;
1429566063dSJacob Faibussowitsch   PetscCall(PetscFree(tmp));
143e5c89e4eSSatish Balay   PetscFunctionReturn(0);
144e5c89e4eSSatish Balay }
145e5c89e4eSSatish Balay 
146e93bc3c1Svictor /*@C
14745b666d6SBarry Smith   PetscReturnErrorHandler - Error handler that causes a return without printing an error message.
148e93bc3c1Svictor 
149e93bc3c1Svictor    Not Collective
150e93bc3c1Svictor 
151e93bc3c1Svictor    Input Parameters:
152e32f2f54SBarry Smith +  comm - communicator over which error occurred
153e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
154e93bc3c1Svictor .  file - the file in which the error was detected (indicated by __FILE__)
155e93bc3c1Svictor .  mess - an error text string, usually just printed to the screen
156e93bc3c1Svictor .  n - the generic error number
157e93bc3c1Svictor .  p - specific error number
158e93bc3c1Svictor -  ctx - error handler context
159e93bc3c1Svictor 
160e93bc3c1Svictor    Level: developer
161e93bc3c1Svictor 
162e93bc3c1Svictor    Notes:
163e93bc3c1Svictor    Most users need not directly employ this routine and the other error
164*811af0c4SBarry Smith    handlers, but can instead use the simplified interface `SETERRQ()`, which has
165e93bc3c1Svictor    the calling sequence
166e32f2f54SBarry Smith $     SETERRQ(comm,number,mess)
167e93bc3c1Svictor 
168*811af0c4SBarry Smith    `PetscIgnoreErrorHandler()` does the same thing as this function, but is deprecated, you should use this function.
169e93bc3c1Svictor 
170*811af0c4SBarry Smith    Use `PetscPushErrorHandler()` to set the desired error handler.
171e93bc3c1Svictor 
172db781477SPatrick Sanan .seealso: `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscError()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscTraceBackErrorHandler()`,
173db781477SPatrick Sanan           `PetscAttachDebuggerErrorHandler()`, `PetscEmacsClientErrorHandler()`
174e93bc3c1Svictor  @*/
1759371c9d4SSatish Balay PetscErrorCode PetscReturnErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx) {
176362febeeSStefano Zampini   return n;
177e93bc3c1Svictor }
178e93bc3c1Svictor 
179e5c89e4eSSatish Balay static char        PetscErrorBaseMessage[1024];
180e5c89e4eSSatish Balay /*
181e5c89e4eSSatish Balay        The numerical values for these are defined in include/petscerror.h; any changes
182e5c89e4eSSatish Balay    there must also be made here
183e5c89e4eSSatish Balay */
184e5c89e4eSSatish Balay static const char *PetscErrorStrings[] = {
185e5c89e4eSSatish Balay   /*55 */ "Out of memory",
186e5c89e4eSSatish Balay   "No support for this operation for this object type",
187e5c89e4eSSatish Balay   "No support for this operation on this system",
188e5c89e4eSSatish Balay   /*58 */ "Operation done in wrong order",
189e5c89e4eSSatish Balay   /*59 */ "Signal received",
190e5c89e4eSSatish Balay   /*60 */ "Nonconforming object sizes",
191e5c89e4eSSatish Balay   "Argument aliasing not permitted",
192e5c89e4eSSatish Balay   "Invalid argument",
193e5c89e4eSSatish Balay   /*63 */ "Argument out of range",
194a17b96a8SKyle Gerard Felker   "Corrupt argument: https://petsc.org/release/faq/#valgrind",
195e5c89e4eSSatish Balay   "Unable to open file",
196e5c89e4eSSatish Balay   "Read from file failed",
197e5c89e4eSSatish Balay   "Write to file failed",
198e5c89e4eSSatish Balay   "Invalid pointer",
199e5c89e4eSSatish Balay   /*69 */ "Arguments must have same type",
200a8b45ee7SBarry Smith   /*70 */ "Attempt to use a pointer that does not point to a valid accessible location",
201a17b96a8SKyle Gerard Felker   /*71 */ "Zero pivot in LU factorization: https://petsc.org/release/faq/#zeropivot",
202e5c89e4eSSatish Balay   /*72 */ "Floating point exception",
203e5c89e4eSSatish Balay   /*73 */ "Object is in wrong state",
204e5c89e4eSSatish Balay   "Corrupted Petsc object",
205e5c89e4eSSatish Balay   "Arguments are incompatible",
206e5c89e4eSSatish Balay   "Error in external library",
207e5c89e4eSSatish Balay   /*77 */ "Petsc has generated inconsistent data",
208a17b96a8SKyle Gerard Felker   "Memory corruption: https://petsc.org/release/faq/#valgrind",
209e5c89e4eSSatish Balay   "Unexpected data in file",
210e5c89e4eSSatish Balay   /*80 */ "Arguments must have same communicators",
211a17b96a8SKyle Gerard Felker   /*81 */ "Zero pivot in Cholesky factorization: https://petsc.org/release/faq/#zeropivot",
212e5c89e4eSSatish Balay   "",
213e5c89e4eSSatish Balay   "",
214a17b96a8SKyle Gerard Felker   "Overflow in integer operation: https://petsc.org/release/faq/#64-bit-indices",
215e5c89e4eSSatish Balay   /*85 */ "Null argument, when expecting valid pointer",
216a17b96a8SKyle Gerard Felker   /*86 */ "Unknown type. Check for miss-spelling or missing package: https://petsc.org/release/install/install/#external-packages",
2173d96e996SBarry Smith   /*87 */ "MPI library at runtime is not compatible with MPI used at compile time",
2188cda6cd7SBarry Smith   /*88 */ "Error in system call",
219a17b96a8SKyle Gerard Felker   /*89 */ "Object Type not set: https://petsc.org/release/faq/#object-type-not-set",
22073260a9bSLisandro Dalcin   /*90 */ "",
22173260a9bSLisandro Dalcin   /*   */ "",
222a17b96a8SKyle Gerard Felker   /*92 */ "See https://petsc.org/release/overview/linear_solve_table/ for possible LU and Cholesky solvers",
223f560318cSPatrick Sanan   /*93 */ "You cannot overwrite this option since that will conflict with other previously set options",
224691b26d3SBarry Smith   /*94 */ "Example/application run with number of MPI ranks it does not support",
225691b26d3SBarry Smith   /*95 */ "Missing or incorrect user input",
226e57d7714SBarry Smith   /*96 */ "GPU resources unavailable",
227764761abSStefano Zampini   /*97 */ "GPU error",
2289371c9d4SSatish Balay   /*98 */ "General MPI error"};
229e5c89e4eSSatish Balay 
230e5c89e4eSSatish Balay /*@C
231e5c89e4eSSatish Balay    PetscErrorMessage - returns the text string associated with a PETSc error code.
232e5c89e4eSSatish Balay 
233e5c89e4eSSatish Balay    Not Collective
234e5c89e4eSSatish Balay 
235e5c89e4eSSatish Balay    Input Parameter:
236e5c89e4eSSatish Balay .   errnum - the error code
237e5c89e4eSSatish Balay 
238d8d19677SJose E. Roman    Output Parameters:
2390298fd71SBarry Smith +  text - the error message (NULL if not desired)
240*811af0c4SBarry Smith -  specific - the specific error message that was set with `SETERRQ()` or `PetscError()`.  (NULL if not desired)
241e5c89e4eSSatish Balay 
242e5c89e4eSSatish Balay    Level: developer
243e5c89e4eSSatish Balay 
244db781477SPatrick Sanan .seealso: `PetscPushErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscCall()`
245db781477SPatrick Sanan           `PetscAbortErrorHandler()`, `PetscTraceBackErrorHandler()`
246e5c89e4eSSatish Balay  @*/
2479371c9d4SSatish Balay PetscErrorCode PetscErrorMessage(int errnum, const char *text[], char **specific) {
248c35ec7c7SPierre Jolivet   size_t len;
249c35ec7c7SPierre Jolivet 
250e5c89e4eSSatish Balay   PetscFunctionBegin;
251c35ec7c7SPierre Jolivet   if (text && errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) {
252c35ec7c7SPierre Jolivet     *text = PetscErrorStrings[errnum - PETSC_ERR_MIN_VALUE - 1];
253c35ec7c7SPierre Jolivet     PetscCall(PetscStrlen(*text, &len));
254c35ec7c7SPierre Jolivet     if (!len) *text = NULL;
2559371c9d4SSatish Balay   } else if (text) *text = NULL;
256e5c89e4eSSatish Balay 
257a297a907SKarl Rupp   if (specific) *specific = PetscErrorBaseMessage;
258e5c89e4eSSatish Balay   PetscFunctionReturn(0);
259e5c89e4eSSatish Balay }
260e5c89e4eSSatish Balay 
261984a1229SMatthew G. Knepley #if defined(PETSC_CLANGUAGE_CXX)
262984a1229SMatthew G. Knepley /* C++ exceptions are formally not allowed to propagate through extern "C" code. In practice, far too much software
263984a1229SMatthew G. Knepley  * would be broken if implementations did not handle it it some common cases. However, keep in mind
264984a1229SMatthew G. Knepley  *
265984a1229SMatthew G. Knepley  *   Rule 62. Don't allow exceptions to propagate across module boundaries
266984a1229SMatthew G. Knepley  *
267984a1229SMatthew G. Knepley  * in "C++ Coding Standards" by Sutter and Alexandrescu. (This accounts for part of the ongoing C++ binary interface
268984a1229SMatthew G. Knepley  * instability.) Having PETSc raise errors as C++ exceptions was probably misguided and should eventually be removed.
269984a1229SMatthew G. Knepley  *
270984a1229SMatthew G. Knepley  * Here is the problem: You have a C++ function call a PETSc function, and you would like to maintain the error message
271984a1229SMatthew G. Knepley  * and stack information from the PETSc error. You could make everyone write exactly this code in their C++, but that
272984a1229SMatthew G. Knepley  * seems crazy to me.
273984a1229SMatthew G. Knepley  */
274984a1229SMatthew G. Knepley #include <sstream>
2754c94c282SMatthew G. Knepley #include <stdexcept>
2769371c9d4SSatish Balay static void PetscCxxErrorThrow() {
277984a1229SMatthew G. Knepley   const char *str;
278984a1229SMatthew G. Knepley   if (eh && eh->ctx) {
279984a1229SMatthew G. Knepley     std::ostringstream *msg;
280984a1229SMatthew G. Knepley     msg = (std::ostringstream *)eh->ctx;
281984a1229SMatthew G. Knepley     str = msg->str().c_str();
282984a1229SMatthew G. Knepley   } else str = "Error detected in C PETSc";
283984a1229SMatthew G. Knepley 
284984a1229SMatthew G. Knepley   throw std::runtime_error(str);
285984a1229SMatthew G. Knepley }
286984a1229SMatthew G. Knepley #endif
287984a1229SMatthew G. Knepley 
288e5c89e4eSSatish Balay /*@C
28945b666d6SBarry Smith    PetscError - Routine that is called when an error has been detected, usually called through the macro SETERRQ(PETSC_COMM_SELF,).
290e5c89e4eSSatish Balay 
291*811af0c4SBarry Smith   Collective
292e5c89e4eSSatish Balay 
293e5c89e4eSSatish Balay    Input Parameters:
294e32f2f54SBarry Smith +  comm - communicator over which error occurred.  ALL ranks of this communicator MUST call this routine
295e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
2963de71b31SHong Zhang .  func - the function name in which the error was detected
297e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
298e5c89e4eSSatish Balay .  n - the generic error number
299*811af0c4SBarry Smith .  p - `PETSC_ERROR_INITIAL` indicates the error was initially detected, `PETSC_ERROR_REPEAT` indicates this is a traceback from a previously detected error
300e5c89e4eSSatish Balay -  mess - formatted message string - aka printf
301e5c89e4eSSatish Balay 
302*811af0c4SBarry Smith   Options Database Keys:
30345b666d6SBarry Smith +  -error_output_stdout - output the error messages to stdout instead of the default stderr
30445b666d6SBarry Smith -  -error_output_none - do not output the error messages
30545b666d6SBarry Smith 
306e5c89e4eSSatish Balay   Level: intermediate
307e5c89e4eSSatish Balay 
308e5c89e4eSSatish Balay    Notes:
30945b666d6SBarry Smith    PETSc error handling is done with error return codes. A non-zero return indicates an error was detected. Errors are generally not something that the code
31045b666d6SBarry Smith    can recover from. Note that numerical errors (potential divide by zero, for example) are not managed by the error return codes; they are managed via, for example,
311*811af0c4SBarry Smith    `KSPGetConvergedReason()` that indicates if the solve was successful or not. The option -ksp_error_if_not_converged, for example, turns numerical failures into
312*811af0c4SBarry Smith    hard errors managed via `PetscError()`.
31345b666d6SBarry Smith 
31445b666d6SBarry Smith    PETSc provides a rich supply of error handlers, see the list below, and users can also provide their own error handlers.
31545b666d6SBarry Smith 
316e5c89e4eSSatish Balay    Most users need not directly use this routine and the error handlers, but
317*811af0c4SBarry Smith    can instead use the simplified interface `PetscCall()` or `SETERRQ()`
318*811af0c4SBarry Smith 
319*811af0c4SBarry Smith    Set the error handler with `PetscPushErrorHandler()`.
320e5c89e4eSSatish Balay 
321e3081792SBarry Smith    Fortran Note:
322e3081792SBarry Smith    This routine is used differently from Fortran
323e3081792SBarry Smith $    PetscError(MPI_Comm comm,PetscErrorCode n,PetscErrorType p,char *message)
324e3081792SBarry Smith 
325*811af0c4SBarry Smith    Developer Note:
326*811af0c4SBarry Smith    Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes)
3273bf036e2SBarry Smith    BUT this routine does call regular PETSc functions that may call error handlers, this is problematic and could be fixed by never calling other PETSc routines
3283bf036e2SBarry Smith    but this annoying.
3293bf036e2SBarry Smith 
330db781477SPatrick Sanan .seealso: `PetscErrorCode`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`,
331db781477SPatrick Sanan           `PetscReturnErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscEmacsClientErrorHandler()`,
332db781477SPatrick Sanan           `SETERRQ()`, `PetscCall()`, `CHKMEMQ`, `SETERRQ()`, `SETERRQ()`, `PetscErrorMessage()`, `PETSCABORT()`
333e5c89e4eSSatish Balay @*/
3349371c9d4SSatish Balay PetscErrorCode PetscError(MPI_Comm comm, int line, const char *func, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, ...) {
335e5c89e4eSSatish Balay   va_list        Argp;
336c9a19010SBarry Smith   size_t         fullLength;
33702c9f0b5SLisandro Dalcin   char           buf[2048], *lbuf = NULL;
338fbfcfee5SBarry Smith   PetscBool      ismain;
3393bf036e2SBarry Smith   PetscErrorCode ierr;
340e5c89e4eSSatish Balay 
34139a651e2SJacob Faibussowitsch   if (!PetscErrorHandlingInitialized) return n;
3420d577829SBarry Smith   if (comm == MPI_COMM_NULL) comm = PETSC_COMM_SELF;
343e5c89e4eSSatish Balay 
344e5c89e4eSSatish Balay   /* Compose the message evaluating the print format */
345e5c89e4eSSatish Balay   if (mess) {
346e5c89e4eSSatish Balay     va_start(Argp, mess);
3472d609e63SMatthew Knepley     PetscVSNPrintf(buf, 2048, mess, &fullLength, Argp);
348e5c89e4eSSatish Balay     va_end(Argp);
349e5c89e4eSSatish Balay     lbuf = buf;
35078179f8bSBarry Smith     if (p == PETSC_ERROR_INITIAL) PetscStrncpy(PetscErrorBaseMessage, lbuf, 1023);
351e5c89e4eSSatish Balay   }
352e5c89e4eSSatish Balay 
3534ed0ab5bSBarry Smith   if (p == PETSC_ERROR_INITIAL && n != PETSC_ERR_MEMC) PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__);
3544ed0ab5bSBarry Smith 
35502c9f0b5SLisandro Dalcin   if (!eh) ierr = PetscTraceBackErrorHandler(comm, line, func, file, n, p, lbuf, NULL);
356efca3c55SSatish Balay   else ierr = (*eh->handler)(comm, line, func, file, n, p, lbuf, eh->ctx);
357362febeeSStefano Zampini   PetscStackClearTop;
358e5c89e4eSSatish Balay 
359e5c89e4eSSatish Balay   /*
3607233276eSBarry Smith       If this is called from the main() routine we call MPI_Abort() instead of
361e5c89e4eSSatish Balay     return to allow the parallel program to be properly shutdown.
362e5c89e4eSSatish Balay 
3637233276eSBarry Smith     Does not call PETSCABORT() since that would provide the wrong source file and line number information
364e5c89e4eSSatish Balay   */
36549c86fc7SBarry Smith   if (func) {
366e5c89e4eSSatish Balay     PetscStrncmp(func, "main", 4, &ismain);
3677233276eSBarry Smith     if (ismain) {
36849c86fc7SBarry Smith       if (petscwaitonerrorflg) PetscSleep(1000);
369660278c0SBarry Smith       PETSCABORT(comm, ierr);
3707233276eSBarry Smith     }
37149c86fc7SBarry Smith   }
3722c280183SJed Brown #if defined(PETSC_CLANGUAGE_CXX)
373ad540459SPierre Jolivet   if (p == PETSC_ERROR_IN_CXX) PetscCxxErrorThrow();
374d736bfebSBarry Smith #endif
375362febeeSStefano Zampini   return ierr;
376e5c89e4eSSatish Balay }
377e5c89e4eSSatish Balay 
378e5c89e4eSSatish Balay /* -------------------------------------------------------------------------*/
379e5c89e4eSSatish Balay 
380e5c89e4eSSatish Balay /*@C
381e5c89e4eSSatish Balay     PetscIntView - Prints an array of integers; useful for debugging.
382e5c89e4eSSatish Balay 
383*811af0c4SBarry Smith     Collective on viewer
384e5c89e4eSSatish Balay 
385e5c89e4eSSatish Balay     Input Parameters:
386e5c89e4eSSatish Balay +   N - number of integers in array
387e5c89e4eSSatish Balay .   idx - array of integers
388*811af0c4SBarry Smith -   viewer - location to print array,  `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
389e5c89e4eSSatish Balay 
390e5c89e4eSSatish Balay   Level: intermediate
391e5c89e4eSSatish Balay 
392*811af0c4SBarry Smith     Note:
393*811af0c4SBarry Smith     This may be called from within the debugger
394300a7f5bSBarry Smith 
395*811af0c4SBarry Smith     Developer Note:
396*811af0c4SBarry Smith     idx cannot be const because may be passed to binary viewer where temporary byte swapping may be done
397*811af0c4SBarry Smith 
398*811af0c4SBarry Smith .seealso: `PetscViewer`, `PetscRealView()`
399e5c89e4eSSatish Balay @*/
4009371c9d4SSatish Balay PetscErrorCode PetscIntView(PetscInt N, const PetscInt idx[], PetscViewer viewer) {
401ca0c3be5SJacob Faibussowitsch   PetscMPIInt rank, size;
402e5c89e4eSSatish Balay   PetscInt    j, i, n = N / 20, p = N % 20;
403ace3abfcSBarry Smith   PetscBool   iascii, isbinary;
404e5c89e4eSSatish Balay   MPI_Comm    comm;
405e5c89e4eSSatish Balay 
406e5c89e4eSSatish Balay   PetscFunctionBegin;
407e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
4080700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 3);
4095ab33896SBarry Smith   if (N) PetscValidIntPointer(idx, 2);
4109566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
4119566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
4129566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
413e5c89e4eSSatish Balay 
4149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4159566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
416e5c89e4eSSatish Balay   if (iascii) {
4179566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
418e5c89e4eSSatish Balay     for (i = 0; i < n; i++) {
419ca0c3be5SJacob Faibussowitsch       if (size > 1) {
4209566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, 20 * i));
421ca0c3be5SJacob Faibussowitsch       } else {
4229566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", 20 * i));
423ca0c3be5SJacob Faibussowitsch       }
42448a46eb9SPierre Jolivet       for (j = 0; j < 20; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[i * 20 + j]));
4259566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
426e5c89e4eSSatish Balay     }
427e5c89e4eSSatish Balay     if (p) {
428ca0c3be5SJacob Faibussowitsch       if (size > 1) {
4299566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, 20 * n));
430ca0c3be5SJacob Faibussowitsch       } else {
4319566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", 20 * n));
432ca0c3be5SJacob Faibussowitsch       }
4339566063dSJacob Faibussowitsch       for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[20 * n + i]));
4349566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
435e5c89e4eSSatish Balay     }
4369566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
4379566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
4386805f65bSBarry Smith   } else if (isbinary) {
439ca0c3be5SJacob Faibussowitsch     PetscMPIInt *sizes, Ntotal, *displs, NN;
440e5c89e4eSSatish Balay     PetscInt    *array;
441783b601eSJed Brown 
4429566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N, &NN));
443e5c89e4eSSatish Balay 
444e5c89e4eSSatish Balay     if (size > 1) {
445e5c89e4eSSatish Balay       if (rank) {
4469566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
4479566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_INT, NULL, NULL, NULL, MPIU_INT, 0, comm));
448e5c89e4eSSatish Balay       } else {
4499566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &sizes));
4509566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
451e5c89e4eSSatish Balay         Ntotal = sizes[0];
4529566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &displs));
453e5c89e4eSSatish Balay         displs[0] = 0;
454e5c89e4eSSatish Balay         for (i = 1; i < size; i++) {
455e5c89e4eSSatish Balay           Ntotal += sizes[i];
456e5c89e4eSSatish Balay           displs[i] = displs[i - 1] + sizes[i - 1];
457e5c89e4eSSatish Balay         }
4589566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(Ntotal, &array));
4599566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_INT, array, sizes, displs, MPIU_INT, 0, comm));
4609566063dSJacob Faibussowitsch         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_INT));
4619566063dSJacob Faibussowitsch         PetscCall(PetscFree(sizes));
4629566063dSJacob Faibussowitsch         PetscCall(PetscFree(displs));
4639566063dSJacob Faibussowitsch         PetscCall(PetscFree(array));
464e5c89e4eSSatish Balay       }
465e5c89e4eSSatish Balay     } else {
4669566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, idx, N, PETSC_INT));
467e5c89e4eSSatish Balay     }
468e5c89e4eSSatish Balay   } else {
469e5c89e4eSSatish Balay     const char *tname;
4709566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
47198921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
472e5c89e4eSSatish Balay   }
473e5c89e4eSSatish Balay   PetscFunctionReturn(0);
474e5c89e4eSSatish Balay }
475e5c89e4eSSatish Balay 
476e5c89e4eSSatish Balay /*@C
477e5c89e4eSSatish Balay     PetscRealView - Prints an array of doubles; useful for debugging.
478e5c89e4eSSatish Balay 
479*811af0c4SBarry Smith     Collective on viewer
480e5c89e4eSSatish Balay 
481e5c89e4eSSatish Balay     Input Parameters:
482*811af0c4SBarry Smith +   N - number of `PetscReal` in array
483*811af0c4SBarry Smith .   idx - array of `PetscReal`
484*811af0c4SBarry Smith -   viewer - location to print array,  `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
485e5c89e4eSSatish Balay 
486e5c89e4eSSatish Balay   Level: intermediate
487e5c89e4eSSatish Balay 
488*811af0c4SBarry Smith     Note:
489*811af0c4SBarry Smith     This may be called from within the debugger
490300a7f5bSBarry Smith 
491*811af0c4SBarry Smith     Developer Note:
492*811af0c4SBarry Smith     idx cannot be const because may be passed to binary viewer where temporary byte swapping may be done
493*811af0c4SBarry Smith 
494*811af0c4SBarry Smith .seealso: `PetscViewer`, `PetscIntView()`
495e5c89e4eSSatish Balay @*/
4969371c9d4SSatish Balay PetscErrorCode PetscRealView(PetscInt N, const PetscReal idx[], PetscViewer viewer) {
497ca0c3be5SJacob Faibussowitsch   PetscMPIInt rank, size;
498e5c89e4eSSatish Balay   PetscInt    j, i, n = N / 5, p = N % 5;
499ace3abfcSBarry Smith   PetscBool   iascii, isbinary;
500e5c89e4eSSatish Balay   MPI_Comm    comm;
501e5c89e4eSSatish Balay 
502e5c89e4eSSatish Balay   PetscFunctionBegin;
503e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
5040700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 3);
505064a246eSJacob Faibussowitsch   PetscValidRealPointer(idx, 2);
5069566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
5079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
5089566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
509e5c89e4eSSatish Balay 
5109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
5119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
512e5c89e4eSSatish Balay   if (iascii) {
5131a989b97SToby Isaac     PetscInt tab;
5141a989b97SToby Isaac 
5159566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
5169566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIGetTab(viewer, &tab));
517e5c89e4eSSatish Balay     for (i = 0; i < n; i++) {
5189566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, tab));
519ca0c3be5SJacob Faibussowitsch       if (size > 1) {
5209566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 5 * i));
521ca0c3be5SJacob Faibussowitsch       } else {
5229566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 5 * i));
523ca0c3be5SJacob Faibussowitsch       }
5249566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, 0));
52548a46eb9SPierre Jolivet       for (j = 0; j < 5; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * 5 + j]));
5269566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
527e5c89e4eSSatish Balay     }
528e5c89e4eSSatish Balay     if (p) {
5299566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, tab));
530ca0c3be5SJacob Faibussowitsch       if (size > 1) {
5319566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 5 * n));
532ca0c3be5SJacob Faibussowitsch       } else {
5339566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 5 * n));
534ca0c3be5SJacob Faibussowitsch       }
5359566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, 0));
5369566063dSJacob Faibussowitsch       for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[5 * n + i]));
5379566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
538e5c89e4eSSatish Balay     }
5399566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
5409566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISetTab(viewer, tab));
5419566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
5426805f65bSBarry Smith   } else if (isbinary) {
543ca0c3be5SJacob Faibussowitsch     PetscMPIInt *sizes, *displs, Ntotal, NN;
544e5c89e4eSSatish Balay     PetscReal   *array;
545e5c89e4eSSatish Balay 
5469566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N, &NN));
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay     if (size > 1) {
549e5c89e4eSSatish Balay       if (rank) {
5509566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
5519566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((PetscReal *)idx, NN, MPIU_REAL, NULL, NULL, NULL, MPIU_REAL, 0, comm));
552e5c89e4eSSatish Balay       } else {
5539566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &sizes));
5549566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
555e5c89e4eSSatish Balay         Ntotal = sizes[0];
5569566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &displs));
557e5c89e4eSSatish Balay         displs[0] = 0;
558e5c89e4eSSatish Balay         for (i = 1; i < size; i++) {
559e5c89e4eSSatish Balay           Ntotal += sizes[i];
560e5c89e4eSSatish Balay           displs[i] = displs[i - 1] + sizes[i - 1];
561e5c89e4eSSatish Balay         }
5629566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(Ntotal, &array));
5639566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((PetscReal *)idx, NN, MPIU_REAL, array, sizes, displs, MPIU_REAL, 0, comm));
5649566063dSJacob Faibussowitsch         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_REAL));
5659566063dSJacob Faibussowitsch         PetscCall(PetscFree(sizes));
5669566063dSJacob Faibussowitsch         PetscCall(PetscFree(displs));
5679566063dSJacob Faibussowitsch         PetscCall(PetscFree(array));
568e5c89e4eSSatish Balay       }
569e5c89e4eSSatish Balay     } else {
5709566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_REAL));
571e5c89e4eSSatish Balay     }
572e5c89e4eSSatish Balay   } else {
573e5c89e4eSSatish Balay     const char *tname;
5749566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
57598921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
576e5c89e4eSSatish Balay   }
577e5c89e4eSSatish Balay   PetscFunctionReturn(0);
578e5c89e4eSSatish Balay }
579e5c89e4eSSatish Balay 
580e5c89e4eSSatish Balay /*@C
581*811af0c4SBarry Smith     PetscScalarView - Prints an array of `PetscScalar`; useful for debugging.
582e5c89e4eSSatish Balay 
583*811af0c4SBarry Smith     Collective on viewer
584e5c89e4eSSatish Balay 
585e5c89e4eSSatish Balay     Input Parameters:
586e5c89e4eSSatish Balay +   N - number of scalars in array
587e5c89e4eSSatish Balay .   idx - array of scalars
588*811af0c4SBarry Smith -   viewer - location to print array,  `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
589e5c89e4eSSatish Balay 
590e5c89e4eSSatish Balay   Level: intermediate
591e5c89e4eSSatish Balay 
592*811af0c4SBarry Smith     Note:
593*811af0c4SBarry Smith     This may be called from within the debugger
594300a7f5bSBarry Smith 
595*811af0c4SBarry Smith     Developer Note:
596*811af0c4SBarry Smith     idx cannot be const because may be passed to binary viewer where byte swapping may be done
597*811af0c4SBarry Smith 
598*811af0c4SBarry Smith .seealso: `PetscViewer`, `PetscIntView()`, `PetscRealView()`
599e5c89e4eSSatish Balay @*/
6009371c9d4SSatish Balay PetscErrorCode PetscScalarView(PetscInt N, const PetscScalar idx[], PetscViewer viewer) {
601ca0c3be5SJacob Faibussowitsch   PetscMPIInt rank, size;
602e5c89e4eSSatish Balay   PetscInt    j, i, n = N / 3, p = N % 3;
603ace3abfcSBarry Smith   PetscBool   iascii, isbinary;
604e5c89e4eSSatish Balay   MPI_Comm    comm;
605e5c89e4eSSatish Balay 
606e5c89e4eSSatish Balay   PetscFunctionBegin;
607e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
608e5c89e4eSSatish Balay   PetscValidHeader(viewer, 3);
6098c34849bSStefano Zampini   if (N) PetscValidScalarPointer(idx, 2);
6109566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
6119566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
6129566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
613e5c89e4eSSatish Balay 
6149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
6159566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
616e5c89e4eSSatish Balay   if (iascii) {
6179566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
618e5c89e4eSSatish Balay     for (i = 0; i < n; i++) {
619ca0c3be5SJacob Faibussowitsch       if (size > 1) {
6209566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 3 * i));
621ca0c3be5SJacob Faibussowitsch       } else {
6229566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 3 * i));
623ca0c3be5SJacob Faibussowitsch       }
624e5c89e4eSSatish Balay       for (j = 0; j < 3; j++) {
625e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX)
6269566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[i * 3 + j]), (double)PetscImaginaryPart(idx[i * 3 + j])));
627e5c89e4eSSatish Balay #else
6289566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * 3 + j]));
629e5c89e4eSSatish Balay #endif
630e5c89e4eSSatish Balay       }
6319566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
632e5c89e4eSSatish Balay     }
633e5c89e4eSSatish Balay     if (p) {
634ca0c3be5SJacob Faibussowitsch       if (size > 1) {
6359566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 3 * n));
636ca0c3be5SJacob Faibussowitsch       } else {
6379566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 3 * n));
638ca0c3be5SJacob Faibussowitsch       }
639e5c89e4eSSatish Balay       for (i = 0; i < p; i++) {
640e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX)
6419566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[n * 3 + i]), (double)PetscImaginaryPart(idx[n * 3 + i])));
642e5c89e4eSSatish Balay #else
6439566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[3 * n + i]));
644e5c89e4eSSatish Balay #endif
645e5c89e4eSSatish Balay       }
6469566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
647e5c89e4eSSatish Balay     }
6489566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
6499566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
6506805f65bSBarry Smith   } else if (isbinary) {
651ca0c3be5SJacob Faibussowitsch     PetscMPIInt *sizes, Ntotal, *displs, NN;
652e5c89e4eSSatish Balay     PetscScalar *array;
653e5c89e4eSSatish Balay 
6549566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N, &NN));
655e5c89e4eSSatish Balay 
656e5c89e4eSSatish Balay     if (size > 1) {
657e5c89e4eSSatish Balay       if (rank) {
6589566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
6599566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, NULL, NULL, NULL, MPIU_SCALAR, 0, comm));
660e5c89e4eSSatish Balay       } else {
6619566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &sizes));
6629566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
663e5c89e4eSSatish Balay         Ntotal = sizes[0];
6649566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &displs));
665e5c89e4eSSatish Balay         displs[0] = 0;
666e5c89e4eSSatish Balay         for (i = 1; i < size; i++) {
667e5c89e4eSSatish Balay           Ntotal += sizes[i];
668e5c89e4eSSatish Balay           displs[i] = displs[i - 1] + sizes[i - 1];
669e5c89e4eSSatish Balay         }
6709566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(Ntotal, &array));
6719566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, array, sizes, displs, MPIU_SCALAR, 0, comm));
6729566063dSJacob Faibussowitsch         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_SCALAR));
6739566063dSJacob Faibussowitsch         PetscCall(PetscFree(sizes));
6749566063dSJacob Faibussowitsch         PetscCall(PetscFree(displs));
6759566063dSJacob Faibussowitsch         PetscCall(PetscFree(array));
676e5c89e4eSSatish Balay       }
677e5c89e4eSSatish Balay     } else {
6789566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_SCALAR));
679e5c89e4eSSatish Balay     }
680e5c89e4eSSatish Balay   } else {
681e5c89e4eSSatish Balay     const char *tname;
6829566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
68398921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
684e5c89e4eSSatish Balay   }
685e5c89e4eSSatish Balay   PetscFunctionReturn(0);
686e5c89e4eSSatish Balay }
687e5c89e4eSSatish Balay 
688e22e20c5SJunchao Zhang #if defined(PETSC_HAVE_CUDA)
689030f984aSJacob Faibussowitsch #include <petscdevice.h>
6909371c9d4SSatish Balay PETSC_EXTERN const char *PetscCUBLASGetErrorName(cublasStatus_t status) {
691e22e20c5SJunchao Zhang   switch (status) {
692e22e20c5SJunchao Zhang #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
693e22e20c5SJunchao Zhang   case CUBLAS_STATUS_SUCCESS: return "CUBLAS_STATUS_SUCCESS";
694e22e20c5SJunchao Zhang   case CUBLAS_STATUS_NOT_INITIALIZED: return "CUBLAS_STATUS_NOT_INITIALIZED";
695e22e20c5SJunchao Zhang   case CUBLAS_STATUS_ALLOC_FAILED: return "CUBLAS_STATUS_ALLOC_FAILED";
696e22e20c5SJunchao Zhang   case CUBLAS_STATUS_INVALID_VALUE: return "CUBLAS_STATUS_INVALID_VALUE";
697e22e20c5SJunchao Zhang   case CUBLAS_STATUS_ARCH_MISMATCH: return "CUBLAS_STATUS_ARCH_MISMATCH";
698e22e20c5SJunchao Zhang   case CUBLAS_STATUS_MAPPING_ERROR: return "CUBLAS_STATUS_MAPPING_ERROR";
699e22e20c5SJunchao Zhang   case CUBLAS_STATUS_EXECUTION_FAILED: return "CUBLAS_STATUS_EXECUTION_FAILED";
700e22e20c5SJunchao Zhang   case CUBLAS_STATUS_INTERNAL_ERROR: return "CUBLAS_STATUS_INTERNAL_ERROR";
701e22e20c5SJunchao Zhang   case CUBLAS_STATUS_NOT_SUPPORTED: return "CUBLAS_STATUS_NOT_SUPPORTED";
702e22e20c5SJunchao Zhang   case CUBLAS_STATUS_LICENSE_ERROR: return "CUBLAS_STATUS_LICENSE_ERROR";
703e22e20c5SJunchao Zhang #endif
704e22e20c5SJunchao Zhang   default: return "unknown error";
705e22e20c5SJunchao Zhang   }
706e22e20c5SJunchao Zhang }
7079371c9d4SSatish Balay PETSC_EXTERN const char *PetscCUSolverGetErrorName(cusolverStatus_t status) {
708a4b895e1SBarry Smith   switch (status) {
709a4b895e1SBarry Smith #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
710a4b895e1SBarry Smith   case CUSOLVER_STATUS_SUCCESS: return "CUSOLVER_STATUS_SUCCESS";
711a4b895e1SBarry Smith   case CUSOLVER_STATUS_NOT_INITIALIZED: return "CUSOLVER_STATUS_NOT_INITIALIZED";
712a4b895e1SBarry Smith   case CUSOLVER_STATUS_INVALID_VALUE: return "CUSOLVER_STATUS_INVALID_VALUE";
713a4b895e1SBarry Smith   case CUSOLVER_STATUS_ARCH_MISMATCH: return "CUSOLVER_STATUS_ARCH_MISMATCH";
714a4b895e1SBarry Smith   case CUSOLVER_STATUS_INTERNAL_ERROR: return "CUSOLVER_STATUS_INTERNAL_ERROR";
715030f984aSJacob Faibussowitsch #if (CUDART_VERSION >= 9000) /* CUDA 9.0 had these defined on June 2021 */
716030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_ALLOC_FAILED: return "CUSOLVER_STATUS_ALLOC_FAILED";
717030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_MAPPING_ERROR: return "CUSOLVER_STATUS_MAPPING_ERROR";
718030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_EXECUTION_FAILED: return "CUSOLVER_STATUS_EXECUTION_FAILED";
719030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED: return "CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
720030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_NOT_SUPPORTED: return "CUSOLVER_STATUS_NOT_SUPPORTED ";
721030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_ZERO_PIVOT: return "CUSOLVER_STATUS_ZERO_PIVOT";
722030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_INVALID_LICENSE: return "CUSOLVER_STATUS_INVALID_LICENSE";
723a4b895e1SBarry Smith #endif
724030f984aSJacob Faibussowitsch #endif
725030f984aSJacob Faibussowitsch   default: return "unknown error";
726030f984aSJacob Faibussowitsch   }
727030f984aSJacob Faibussowitsch }
7289371c9d4SSatish Balay PETSC_EXTERN const char *PetscCUFFTGetErrorName(cufftResult result) {
729030f984aSJacob Faibussowitsch   switch (result) {
730030f984aSJacob Faibussowitsch   case CUFFT_SUCCESS: return "CUFFT_SUCCESS";
731030f984aSJacob Faibussowitsch   case CUFFT_INVALID_PLAN: return "CUFFT_INVALID_PLAN";
732030f984aSJacob Faibussowitsch   case CUFFT_ALLOC_FAILED: return "CUFFT_ALLOC_FAILED";
733030f984aSJacob Faibussowitsch   case CUFFT_INVALID_TYPE: return "CUFFT_INVALID_TYPE";
734030f984aSJacob Faibussowitsch   case CUFFT_INVALID_VALUE: return "CUFFT_INVALID_VALUE";
735030f984aSJacob Faibussowitsch   case CUFFT_INTERNAL_ERROR: return "CUFFT_INTERNAL_ERROR";
736030f984aSJacob Faibussowitsch   case CUFFT_EXEC_FAILED: return "CUFFT_EXEC_FAILED";
737030f984aSJacob Faibussowitsch   case CUFFT_SETUP_FAILED: return "CUFFT_SETUP_FAILED";
738030f984aSJacob Faibussowitsch   case CUFFT_INVALID_SIZE: return "CUFFT_INVALID_SIZE";
739030f984aSJacob Faibussowitsch   case CUFFT_UNALIGNED_DATA: return "CUFFT_UNALIGNED_DATA";
740030f984aSJacob Faibussowitsch   case CUFFT_INCOMPLETE_PARAMETER_LIST: return "CUFFT_INCOMPLETE_PARAMETER_LIST";
741030f984aSJacob Faibussowitsch   case CUFFT_INVALID_DEVICE: return "CUFFT_INVALID_DEVICE";
742030f984aSJacob Faibussowitsch   case CUFFT_PARSE_ERROR: return "CUFFT_PARSE_ERROR";
743030f984aSJacob Faibussowitsch   case CUFFT_NO_WORKSPACE: return "CUFFT_NO_WORKSPACE";
744030f984aSJacob Faibussowitsch   case CUFFT_NOT_IMPLEMENTED: return "CUFFT_NOT_IMPLEMENTED";
745030f984aSJacob Faibussowitsch   case CUFFT_LICENSE_ERROR: return "CUFFT_LICENSE_ERROR";
746030f984aSJacob Faibussowitsch   case CUFFT_NOT_SUPPORTED: return "CUFFT_NOT_SUPPORTED";
747a4b895e1SBarry Smith   default: return "unknown error";
748a4b895e1SBarry Smith   }
749a4b895e1SBarry Smith }
750e22e20c5SJunchao Zhang #endif
75159af0bd3SScott Kruger 
75259af0bd3SScott Kruger #if defined(PETSC_HAVE_HIP)
753030f984aSJacob Faibussowitsch #include <petscdevice.h>
7549371c9d4SSatish Balay PETSC_EXTERN const char *PetscHIPBLASGetErrorName(hipblasStatus_t status) {
75559af0bd3SScott Kruger   switch (status) {
75659af0bd3SScott Kruger   case HIPBLAS_STATUS_SUCCESS: return "HIPBLAS_STATUS_SUCCESS";
75759af0bd3SScott Kruger   case HIPBLAS_STATUS_NOT_INITIALIZED: return "HIPBLAS_STATUS_NOT_INITIALIZED";
75859af0bd3SScott Kruger   case HIPBLAS_STATUS_ALLOC_FAILED: return "HIPBLAS_STATUS_ALLOC_FAILED";
75959af0bd3SScott Kruger   case HIPBLAS_STATUS_INVALID_VALUE: return "HIPBLAS_STATUS_INVALID_VALUE";
76059af0bd3SScott Kruger   case HIPBLAS_STATUS_ARCH_MISMATCH: return "HIPBLAS_STATUS_ARCH_MISMATCH";
76159af0bd3SScott Kruger   case HIPBLAS_STATUS_MAPPING_ERROR: return "HIPBLAS_STATUS_MAPPING_ERROR";
76259af0bd3SScott Kruger   case HIPBLAS_STATUS_EXECUTION_FAILED: return "HIPBLAS_STATUS_EXECUTION_FAILED";
76359af0bd3SScott Kruger   case HIPBLAS_STATUS_INTERNAL_ERROR: return "HIPBLAS_STATUS_INTERNAL_ERROR";
76459af0bd3SScott Kruger   case HIPBLAS_STATUS_NOT_SUPPORTED: return "HIPBLAS_STATUS_NOT_SUPPORTED";
76559af0bd3SScott Kruger   default: return "unknown error";
76659af0bd3SScott Kruger   }
76759af0bd3SScott Kruger }
76859af0bd3SScott Kruger #endif
769db9cea48SBarry Smith 
770db9cea48SBarry Smith /*@
771*811af0c4SBarry Smith       PetscMPIErrorString - Given an MPI error code returns the `MPI_Error_string()` appropriately
772db9cea48SBarry Smith            formatted for displaying with the PETSc error handlers.
773db9cea48SBarry Smith 
774db9cea48SBarry Smith  Input Parameter:
775db9cea48SBarry Smith .  err - the MPI error code
776db9cea48SBarry Smith 
777db9cea48SBarry Smith  Output Parameter:
778*811af0c4SBarry Smith .  string - the MPI error message, should declare its length to be larger than `MPI_MAX_ERROR_STRING`
779db9cea48SBarry Smith 
78049c86fc7SBarry Smith    Level: developer
78149c86fc7SBarry Smith 
782*811af0c4SBarry Smith  Note:
783db9cea48SBarry Smith     Does not return an error code or do error handling because it may be called from inside an error handler
784db9cea48SBarry Smith 
785db9cea48SBarry Smith @*/
7869371c9d4SSatish Balay void PetscMPIErrorString(PetscMPIInt err, char *string) {
787db9cea48SBarry Smith   char        errorstring[MPI_MAX_ERROR_STRING];
788db9cea48SBarry Smith   PetscMPIInt len, j = 0;
789db9cea48SBarry Smith 
790db9cea48SBarry Smith   MPI_Error_string(err, (char *)errorstring, &len);
791db9cea48SBarry Smith   for (PetscMPIInt i = 0; i < len; i++) {
792db9cea48SBarry Smith     string[j++] = errorstring[i];
793db9cea48SBarry Smith     if (errorstring[i] == '\n') {
794db9cea48SBarry Smith       for (PetscMPIInt k = 0; k < 16; k++) string[j++] = ' ';
795db9cea48SBarry Smith     }
796db9cea48SBarry Smith   }
797db9cea48SBarry Smith   string[j] = 0;
798db9cea48SBarry Smith }
799