xref: /petsc/src/sys/error/err.c (revision e809461d9f7290842cfe5ed4460a2407e96d5060)
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 
37811af0c4SBarry 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:
41811af0c4SBarry Smith    Since this is an error handler it cannot call `PetscCall()`; thus we just return if an error is detected.
42811af0c4SBarry 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 
103811af0c4SBarry Smith    Note:
104811af0c4SBarry Smith    The currently available PETSc error handlers include `PetscTraceBackErrorHandler()`,
105811af0c4SBarry Smith    `PetscAttachDebuggerErrorHandler()`, `PetscAbortErrorHandler()`, and `PetscMPIAbortErrorHandler()`, `PetscReturnErrorHandler()`.
106e93bc3c1Svictor 
107811af0c4SBarry 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
127811af0c4SBarry 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
164811af0c4SBarry Smith    handlers, but can instead use the simplified interface `SETERRQ()`, which has
165e93bc3c1Svictor    the calling sequence
166e32f2f54SBarry Smith $     SETERRQ(comm,number,mess)
167e93bc3c1Svictor 
168811af0c4SBarry Smith    `PetscIgnoreErrorHandler()` does the same thing as this function, but is deprecated, you should use this function.
169e93bc3c1Svictor 
170811af0c4SBarry 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",
228*e809461dSJacob Faibussowitsch   /*98 */ "General MPI error",
229*e809461dSJacob Faibussowitsch   /*99 */ "PetscError() incorrectly returned an error code of 0"};
230e5c89e4eSSatish Balay 
231e5c89e4eSSatish Balay /*@C
232e5c89e4eSSatish Balay    PetscErrorMessage - returns the text string associated with a PETSc error code.
233e5c89e4eSSatish Balay 
234e5c89e4eSSatish Balay    Not Collective
235e5c89e4eSSatish Balay 
236e5c89e4eSSatish Balay    Input Parameter:
237e5c89e4eSSatish Balay .   errnum - the error code
238e5c89e4eSSatish Balay 
239d8d19677SJose E. Roman    Output Parameters:
2400298fd71SBarry Smith +  text - the error message (NULL if not desired)
241811af0c4SBarry Smith -  specific - the specific error message that was set with `SETERRQ()` or `PetscError()`.  (NULL if not desired)
242e5c89e4eSSatish Balay 
243e5c89e4eSSatish Balay    Level: developer
244e5c89e4eSSatish Balay 
245db781477SPatrick Sanan .seealso: `PetscPushErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscError()`, `SETERRQ()`, `PetscCall()`
246db781477SPatrick Sanan           `PetscAbortErrorHandler()`, `PetscTraceBackErrorHandler()`
247e5c89e4eSSatish Balay  @*/
2489371c9d4SSatish Balay PetscErrorCode PetscErrorMessage(int errnum, const char *text[], char **specific) {
249c35ec7c7SPierre Jolivet   size_t len;
250c35ec7c7SPierre Jolivet 
251e5c89e4eSSatish Balay   PetscFunctionBegin;
252c35ec7c7SPierre Jolivet   if (text && errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) {
253c35ec7c7SPierre Jolivet     *text = PetscErrorStrings[errnum - PETSC_ERR_MIN_VALUE - 1];
254c35ec7c7SPierre Jolivet     PetscCall(PetscStrlen(*text, &len));
255c35ec7c7SPierre Jolivet     if (!len) *text = NULL;
2569371c9d4SSatish Balay   } else if (text) *text = NULL;
257e5c89e4eSSatish Balay 
258a297a907SKarl Rupp   if (specific) *specific = PetscErrorBaseMessage;
259e5c89e4eSSatish Balay   PetscFunctionReturn(0);
260e5c89e4eSSatish Balay }
261e5c89e4eSSatish Balay 
262984a1229SMatthew G. Knepley #if defined(PETSC_CLANGUAGE_CXX)
263984a1229SMatthew G. Knepley /* C++ exceptions are formally not allowed to propagate through extern "C" code. In practice, far too much software
264984a1229SMatthew G. Knepley  * would be broken if implementations did not handle it it some common cases. However, keep in mind
265984a1229SMatthew G. Knepley  *
266984a1229SMatthew G. Knepley  *   Rule 62. Don't allow exceptions to propagate across module boundaries
267984a1229SMatthew G. Knepley  *
268984a1229SMatthew G. Knepley  * in "C++ Coding Standards" by Sutter and Alexandrescu. (This accounts for part of the ongoing C++ binary interface
269984a1229SMatthew G. Knepley  * instability.) Having PETSc raise errors as C++ exceptions was probably misguided and should eventually be removed.
270984a1229SMatthew G. Knepley  *
271984a1229SMatthew G. Knepley  * Here is the problem: You have a C++ function call a PETSc function, and you would like to maintain the error message
272984a1229SMatthew G. Knepley  * and stack information from the PETSc error. You could make everyone write exactly this code in their C++, but that
273984a1229SMatthew G. Knepley  * seems crazy to me.
274984a1229SMatthew G. Knepley  */
275984a1229SMatthew G. Knepley #include <sstream>
2764c94c282SMatthew G. Knepley #include <stdexcept>
2779371c9d4SSatish Balay static void PetscCxxErrorThrow() {
278984a1229SMatthew G. Knepley   const char *str;
279984a1229SMatthew G. Knepley   if (eh && eh->ctx) {
280984a1229SMatthew G. Knepley     std::ostringstream *msg;
281984a1229SMatthew G. Knepley     msg = (std::ostringstream *)eh->ctx;
282984a1229SMatthew G. Knepley     str = msg->str().c_str();
283984a1229SMatthew G. Knepley   } else str = "Error detected in C PETSc";
284984a1229SMatthew G. Knepley 
285984a1229SMatthew G. Knepley   throw std::runtime_error(str);
286984a1229SMatthew G. Knepley }
287984a1229SMatthew G. Knepley #endif
288984a1229SMatthew G. Knepley 
289e5c89e4eSSatish Balay /*@C
29045b666d6SBarry Smith    PetscError - Routine that is called when an error has been detected, usually called through the macro SETERRQ(PETSC_COMM_SELF,).
291e5c89e4eSSatish Balay 
292811af0c4SBarry Smith   Collective
293e5c89e4eSSatish Balay 
294e5c89e4eSSatish Balay    Input Parameters:
295e32f2f54SBarry Smith +  comm - communicator over which error occurred.  ALL ranks of this communicator MUST call this routine
296e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
2973de71b31SHong Zhang .  func - the function name in which the error was detected
298e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
299e5c89e4eSSatish Balay .  n - the generic error number
300811af0c4SBarry Smith .  p - `PETSC_ERROR_INITIAL` indicates the error was initially detected, `PETSC_ERROR_REPEAT` indicates this is a traceback from a previously detected error
301e5c89e4eSSatish Balay -  mess - formatted message string - aka printf
302e5c89e4eSSatish Balay 
303811af0c4SBarry Smith   Options Database Keys:
30445b666d6SBarry Smith +  -error_output_stdout - output the error messages to stdout instead of the default stderr
30545b666d6SBarry Smith -  -error_output_none - do not output the error messages
30645b666d6SBarry Smith 
307e5c89e4eSSatish Balay   Level: intermediate
308e5c89e4eSSatish Balay 
309e5c89e4eSSatish Balay    Notes:
310*e809461dSJacob Faibussowitsch    PETSc error handling is done with error return codes. A non-zero return indicates an error
311*e809461dSJacob Faibussowitsch    was detected. The return-value of this routine is what is ultimately returned by
312*e809461dSJacob Faibussowitsch    `SETERRQ()`.
31345b666d6SBarry Smith 
314*e809461dSJacob Faibussowitsch    Note that numerical errors (potential divide by zero, for example) are not managed by the
315*e809461dSJacob Faibussowitsch    error return codes; they are managed via, for example, `KSPGetConvergedReason()` that
316*e809461dSJacob Faibussowitsch    indicates if the solve was successful or not. The option `-ksp_error_if_not_converged`, for
317*e809461dSJacob Faibussowitsch    example, turns numerical failures into hard errors managed via `PetscError()`.
31845b666d6SBarry Smith 
319*e809461dSJacob Faibussowitsch    PETSc provides a rich supply of error handlers, see the list below, and users can also
320*e809461dSJacob Faibussowitsch    provide their own error handlers.
321811af0c4SBarry Smith 
322*e809461dSJacob Faibussowitsch    If the user sets their own error handler (via `PetscPushErrorHandler()`) they may return any
323*e809461dSJacob Faibussowitsch    arbitrary value from it, but are encouraged to return nonzero values. If the return value is
324*e809461dSJacob Faibussowitsch    zero, `SETERRQ()` will ignore the value and return `PETSC_ERR_RETURN` (a nonzero value)
325*e809461dSJacob Faibussowitsch    instead.
326*e809461dSJacob Faibussowitsch 
327*e809461dSJacob Faibussowitsch    Most users need not directly use this routine and the error handlers, but can instead use
328*e809461dSJacob Faibussowitsch    the simplified interface `PetscCall()` or `SETERRQ()`.
329e5c89e4eSSatish Balay 
330e3081792SBarry Smith    Fortran Note:
331e3081792SBarry Smith    This routine is used differently from Fortran
332e3081792SBarry Smith $    PetscError(MPI_Comm comm,PetscErrorCode n,PetscErrorType p,char *message)
333e3081792SBarry Smith 
334811af0c4SBarry Smith    Developer Note:
335811af0c4SBarry Smith    Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes)
3363bf036e2SBarry 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
3373bf036e2SBarry Smith    but this annoying.
3383bf036e2SBarry Smith 
339db781477SPatrick Sanan .seealso: `PetscErrorCode`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`,
340db781477SPatrick Sanan           `PetscReturnErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscEmacsClientErrorHandler()`,
341db781477SPatrick Sanan           `SETERRQ()`, `PetscCall()`, `CHKMEMQ`, `SETERRQ()`, `SETERRQ()`, `PetscErrorMessage()`, `PETSCABORT()`
342e5c89e4eSSatish Balay @*/
3439371c9d4SSatish Balay PetscErrorCode PetscError(MPI_Comm comm, int line, const char *func, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, ...) {
344e5c89e4eSSatish Balay   va_list        Argp;
345c9a19010SBarry Smith   size_t         fullLength;
34602c9f0b5SLisandro Dalcin   char           buf[2048], *lbuf = NULL;
347fbfcfee5SBarry Smith   PetscBool      ismain;
3483bf036e2SBarry Smith   PetscErrorCode ierr;
349e5c89e4eSSatish Balay 
35039a651e2SJacob Faibussowitsch   if (!PetscErrorHandlingInitialized) return n;
3510d577829SBarry Smith   if (comm == MPI_COMM_NULL) comm = PETSC_COMM_SELF;
352e5c89e4eSSatish Balay 
353e5c89e4eSSatish Balay   /* Compose the message evaluating the print format */
354e5c89e4eSSatish Balay   if (mess) {
355e5c89e4eSSatish Balay     va_start(Argp, mess);
3562d609e63SMatthew Knepley     PetscVSNPrintf(buf, 2048, mess, &fullLength, Argp);
357e5c89e4eSSatish Balay     va_end(Argp);
358e5c89e4eSSatish Balay     lbuf = buf;
35978179f8bSBarry Smith     if (p == PETSC_ERROR_INITIAL) PetscStrncpy(PetscErrorBaseMessage, lbuf, 1023);
360e5c89e4eSSatish Balay   }
361e5c89e4eSSatish Balay 
3624ed0ab5bSBarry Smith   if (p == PETSC_ERROR_INITIAL && n != PETSC_ERR_MEMC) PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__);
3634ed0ab5bSBarry Smith 
36402c9f0b5SLisandro Dalcin   if (!eh) ierr = PetscTraceBackErrorHandler(comm, line, func, file, n, p, lbuf, NULL);
365efca3c55SSatish Balay   else ierr = (*eh->handler)(comm, line, func, file, n, p, lbuf, eh->ctx);
366362febeeSStefano Zampini   PetscStackClearTop;
367e5c89e4eSSatish Balay 
368e5c89e4eSSatish Balay   /*
3697233276eSBarry Smith       If this is called from the main() routine we call MPI_Abort() instead of
370e5c89e4eSSatish Balay     return to allow the parallel program to be properly shutdown.
371e5c89e4eSSatish Balay 
3727233276eSBarry Smith     Does not call PETSCABORT() since that would provide the wrong source file and line number information
373e5c89e4eSSatish Balay   */
37449c86fc7SBarry Smith   if (func) {
375e5c89e4eSSatish Balay     PetscStrncmp(func, "main", 4, &ismain);
3767233276eSBarry Smith     if (ismain) {
37749c86fc7SBarry Smith       if (petscwaitonerrorflg) PetscSleep(1000);
378660278c0SBarry Smith       PETSCABORT(comm, ierr);
3797233276eSBarry Smith     }
38049c86fc7SBarry Smith   }
3812c280183SJed Brown #if defined(PETSC_CLANGUAGE_CXX)
382ad540459SPierre Jolivet   if (p == PETSC_ERROR_IN_CXX) PetscCxxErrorThrow();
383d736bfebSBarry Smith #endif
384362febeeSStefano Zampini   return ierr;
385e5c89e4eSSatish Balay }
386e5c89e4eSSatish Balay 
387e5c89e4eSSatish Balay /* -------------------------------------------------------------------------*/
388e5c89e4eSSatish Balay 
389e5c89e4eSSatish Balay /*@C
390e5c89e4eSSatish Balay     PetscIntView - Prints an array of integers; useful for debugging.
391e5c89e4eSSatish Balay 
392811af0c4SBarry Smith     Collective on viewer
393e5c89e4eSSatish Balay 
394e5c89e4eSSatish Balay     Input Parameters:
395e5c89e4eSSatish Balay +   N - number of integers in array
396e5c89e4eSSatish Balay .   idx - array of integers
397811af0c4SBarry Smith -   viewer - location to print array,  `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
398e5c89e4eSSatish Balay 
399e5c89e4eSSatish Balay   Level: intermediate
400e5c89e4eSSatish Balay 
401811af0c4SBarry Smith     Note:
402811af0c4SBarry Smith     This may be called from within the debugger
403300a7f5bSBarry Smith 
404811af0c4SBarry Smith     Developer Note:
405811af0c4SBarry Smith     idx cannot be const because may be passed to binary viewer where temporary byte swapping may be done
406811af0c4SBarry Smith 
407811af0c4SBarry Smith .seealso: `PetscViewer`, `PetscRealView()`
408e5c89e4eSSatish Balay @*/
4099371c9d4SSatish Balay PetscErrorCode PetscIntView(PetscInt N, const PetscInt idx[], PetscViewer viewer) {
410ca0c3be5SJacob Faibussowitsch   PetscMPIInt rank, size;
411e5c89e4eSSatish Balay   PetscInt    j, i, n = N / 20, p = N % 20;
412ace3abfcSBarry Smith   PetscBool   iascii, isbinary;
413e5c89e4eSSatish Balay   MPI_Comm    comm;
414e5c89e4eSSatish Balay 
415e5c89e4eSSatish Balay   PetscFunctionBegin;
416e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
4170700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 3);
4185ab33896SBarry Smith   if (N) PetscValidIntPointer(idx, 2);
4199566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
4209566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
4219566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
422e5c89e4eSSatish Balay 
4239566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
4249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
425e5c89e4eSSatish Balay   if (iascii) {
4269566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
427e5c89e4eSSatish Balay     for (i = 0; i < n; i++) {
428ca0c3be5SJacob Faibussowitsch       if (size > 1) {
4299566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, 20 * i));
430ca0c3be5SJacob Faibussowitsch       } else {
4319566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", 20 * i));
432ca0c3be5SJacob Faibussowitsch       }
43348a46eb9SPierre Jolivet       for (j = 0; j < 20; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[i * 20 + j]));
4349566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
435e5c89e4eSSatish Balay     }
436e5c89e4eSSatish Balay     if (p) {
437ca0c3be5SJacob Faibussowitsch       if (size > 1) {
4389566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, 20 * n));
439ca0c3be5SJacob Faibussowitsch       } else {
4409566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", 20 * n));
441ca0c3be5SJacob Faibussowitsch       }
4429566063dSJacob Faibussowitsch       for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[20 * n + i]));
4439566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
444e5c89e4eSSatish Balay     }
4459566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
4469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
4476805f65bSBarry Smith   } else if (isbinary) {
448ca0c3be5SJacob Faibussowitsch     PetscMPIInt *sizes, Ntotal, *displs, NN;
449e5c89e4eSSatish Balay     PetscInt    *array;
450783b601eSJed Brown 
4519566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N, &NN));
452e5c89e4eSSatish Balay 
453e5c89e4eSSatish Balay     if (size > 1) {
454e5c89e4eSSatish Balay       if (rank) {
4559566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
4569566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_INT, NULL, NULL, NULL, MPIU_INT, 0, comm));
457e5c89e4eSSatish Balay       } else {
4589566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &sizes));
4599566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
460e5c89e4eSSatish Balay         Ntotal = sizes[0];
4619566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &displs));
462e5c89e4eSSatish Balay         displs[0] = 0;
463e5c89e4eSSatish Balay         for (i = 1; i < size; i++) {
464e5c89e4eSSatish Balay           Ntotal += sizes[i];
465e5c89e4eSSatish Balay           displs[i] = displs[i - 1] + sizes[i - 1];
466e5c89e4eSSatish Balay         }
4679566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(Ntotal, &array));
4689566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_INT, array, sizes, displs, MPIU_INT, 0, comm));
4699566063dSJacob Faibussowitsch         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_INT));
4709566063dSJacob Faibussowitsch         PetscCall(PetscFree(sizes));
4719566063dSJacob Faibussowitsch         PetscCall(PetscFree(displs));
4729566063dSJacob Faibussowitsch         PetscCall(PetscFree(array));
473e5c89e4eSSatish Balay       }
474e5c89e4eSSatish Balay     } else {
4759566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, idx, N, PETSC_INT));
476e5c89e4eSSatish Balay     }
477e5c89e4eSSatish Balay   } else {
478e5c89e4eSSatish Balay     const char *tname;
4799566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
48098921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
481e5c89e4eSSatish Balay   }
482e5c89e4eSSatish Balay   PetscFunctionReturn(0);
483e5c89e4eSSatish Balay }
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay /*@C
486e5c89e4eSSatish Balay     PetscRealView - Prints an array of doubles; useful for debugging.
487e5c89e4eSSatish Balay 
488811af0c4SBarry Smith     Collective on viewer
489e5c89e4eSSatish Balay 
490e5c89e4eSSatish Balay     Input Parameters:
491811af0c4SBarry Smith +   N - number of `PetscReal` in array
492811af0c4SBarry Smith .   idx - array of `PetscReal`
493811af0c4SBarry Smith -   viewer - location to print array,  `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
494e5c89e4eSSatish Balay 
495e5c89e4eSSatish Balay   Level: intermediate
496e5c89e4eSSatish Balay 
497811af0c4SBarry Smith     Note:
498811af0c4SBarry Smith     This may be called from within the debugger
499300a7f5bSBarry Smith 
500811af0c4SBarry Smith     Developer Note:
501811af0c4SBarry Smith     idx cannot be const because may be passed to binary viewer where temporary byte swapping may be done
502811af0c4SBarry Smith 
503811af0c4SBarry Smith .seealso: `PetscViewer`, `PetscIntView()`
504e5c89e4eSSatish Balay @*/
5059371c9d4SSatish Balay PetscErrorCode PetscRealView(PetscInt N, const PetscReal idx[], PetscViewer viewer) {
506ca0c3be5SJacob Faibussowitsch   PetscMPIInt rank, size;
507e5c89e4eSSatish Balay   PetscInt    j, i, n = N / 5, p = N % 5;
508ace3abfcSBarry Smith   PetscBool   iascii, isbinary;
509e5c89e4eSSatish Balay   MPI_Comm    comm;
510e5c89e4eSSatish Balay 
511e5c89e4eSSatish Balay   PetscFunctionBegin;
512e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
5130700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 3);
514064a246eSJacob Faibussowitsch   PetscValidRealPointer(idx, 2);
5159566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
5169566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
5179566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
518e5c89e4eSSatish Balay 
5199566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
5209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
521e5c89e4eSSatish Balay   if (iascii) {
5221a989b97SToby Isaac     PetscInt tab;
5231a989b97SToby Isaac 
5249566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
5259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIGetTab(viewer, &tab));
526e5c89e4eSSatish Balay     for (i = 0; i < n; i++) {
5279566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, tab));
528ca0c3be5SJacob Faibussowitsch       if (size > 1) {
5299566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 5 * i));
530ca0c3be5SJacob Faibussowitsch       } else {
5319566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 5 * i));
532ca0c3be5SJacob Faibussowitsch       }
5339566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, 0));
53448a46eb9SPierre Jolivet       for (j = 0; j < 5; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * 5 + j]));
5359566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
536e5c89e4eSSatish Balay     }
537e5c89e4eSSatish Balay     if (p) {
5389566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, tab));
539ca0c3be5SJacob Faibussowitsch       if (size > 1) {
5409566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 5 * n));
541ca0c3be5SJacob Faibussowitsch       } else {
5429566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 5 * n));
543ca0c3be5SJacob Faibussowitsch       }
5449566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISetTab(viewer, 0));
5459566063dSJacob Faibussowitsch       for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[5 * n + i]));
5469566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
547e5c89e4eSSatish Balay     }
5489566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
5499566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISetTab(viewer, tab));
5509566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
5516805f65bSBarry Smith   } else if (isbinary) {
552ca0c3be5SJacob Faibussowitsch     PetscMPIInt *sizes, *displs, Ntotal, NN;
553e5c89e4eSSatish Balay     PetscReal   *array;
554e5c89e4eSSatish Balay 
5559566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N, &NN));
556e5c89e4eSSatish Balay 
557e5c89e4eSSatish Balay     if (size > 1) {
558e5c89e4eSSatish Balay       if (rank) {
5599566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
5609566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((PetscReal *)idx, NN, MPIU_REAL, NULL, NULL, NULL, MPIU_REAL, 0, comm));
561e5c89e4eSSatish Balay       } else {
5629566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &sizes));
5639566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
564e5c89e4eSSatish Balay         Ntotal = sizes[0];
5659566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &displs));
566e5c89e4eSSatish Balay         displs[0] = 0;
567e5c89e4eSSatish Balay         for (i = 1; i < size; i++) {
568e5c89e4eSSatish Balay           Ntotal += sizes[i];
569e5c89e4eSSatish Balay           displs[i] = displs[i - 1] + sizes[i - 1];
570e5c89e4eSSatish Balay         }
5719566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(Ntotal, &array));
5729566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((PetscReal *)idx, NN, MPIU_REAL, array, sizes, displs, MPIU_REAL, 0, comm));
5739566063dSJacob Faibussowitsch         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_REAL));
5749566063dSJacob Faibussowitsch         PetscCall(PetscFree(sizes));
5759566063dSJacob Faibussowitsch         PetscCall(PetscFree(displs));
5769566063dSJacob Faibussowitsch         PetscCall(PetscFree(array));
577e5c89e4eSSatish Balay       }
578e5c89e4eSSatish Balay     } else {
5799566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_REAL));
580e5c89e4eSSatish Balay     }
581e5c89e4eSSatish Balay   } else {
582e5c89e4eSSatish Balay     const char *tname;
5839566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
58498921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
585e5c89e4eSSatish Balay   }
586e5c89e4eSSatish Balay   PetscFunctionReturn(0);
587e5c89e4eSSatish Balay }
588e5c89e4eSSatish Balay 
589e5c89e4eSSatish Balay /*@C
590811af0c4SBarry Smith     PetscScalarView - Prints an array of `PetscScalar`; useful for debugging.
591e5c89e4eSSatish Balay 
592811af0c4SBarry Smith     Collective on viewer
593e5c89e4eSSatish Balay 
594e5c89e4eSSatish Balay     Input Parameters:
595e5c89e4eSSatish Balay +   N - number of scalars in array
596e5c89e4eSSatish Balay .   idx - array of scalars
597811af0c4SBarry Smith -   viewer - location to print array,  `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
598e5c89e4eSSatish Balay 
599e5c89e4eSSatish Balay   Level: intermediate
600e5c89e4eSSatish Balay 
601811af0c4SBarry Smith     Note:
602811af0c4SBarry Smith     This may be called from within the debugger
603300a7f5bSBarry Smith 
604811af0c4SBarry Smith     Developer Note:
605811af0c4SBarry Smith     idx cannot be const because may be passed to binary viewer where byte swapping may be done
606811af0c4SBarry Smith 
607811af0c4SBarry Smith .seealso: `PetscViewer`, `PetscIntView()`, `PetscRealView()`
608e5c89e4eSSatish Balay @*/
6099371c9d4SSatish Balay PetscErrorCode PetscScalarView(PetscInt N, const PetscScalar idx[], PetscViewer viewer) {
610ca0c3be5SJacob Faibussowitsch   PetscMPIInt rank, size;
611e5c89e4eSSatish Balay   PetscInt    j, i, n = N / 3, p = N % 3;
612ace3abfcSBarry Smith   PetscBool   iascii, isbinary;
613e5c89e4eSSatish Balay   MPI_Comm    comm;
614e5c89e4eSSatish Balay 
615e5c89e4eSSatish Balay   PetscFunctionBegin;
616e5c89e4eSSatish Balay   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
617e5c89e4eSSatish Balay   PetscValidHeader(viewer, 3);
6188c34849bSStefano Zampini   if (N) PetscValidScalarPointer(idx, 2);
6199566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
6209566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
6219566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
622e5c89e4eSSatish Balay 
6239566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
6249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
625e5c89e4eSSatish Balay   if (iascii) {
6269566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
627e5c89e4eSSatish Balay     for (i = 0; i < n; i++) {
628ca0c3be5SJacob Faibussowitsch       if (size > 1) {
6299566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 3 * i));
630ca0c3be5SJacob Faibussowitsch       } else {
6319566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 3 * i));
632ca0c3be5SJacob Faibussowitsch       }
633e5c89e4eSSatish Balay       for (j = 0; j < 3; j++) {
634e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX)
6359566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[i * 3 + j]), (double)PetscImaginaryPart(idx[i * 3 + j])));
636e5c89e4eSSatish Balay #else
6379566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * 3 + j]));
638e5c89e4eSSatish Balay #endif
639e5c89e4eSSatish Balay       }
6409566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
641e5c89e4eSSatish Balay     }
642e5c89e4eSSatish Balay     if (p) {
643ca0c3be5SJacob Faibussowitsch       if (size > 1) {
6449566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 3 * n));
645ca0c3be5SJacob Faibussowitsch       } else {
6469566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 3 * n));
647ca0c3be5SJacob Faibussowitsch       }
648e5c89e4eSSatish Balay       for (i = 0; i < p; i++) {
649e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX)
6509566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[n * 3 + i]), (double)PetscImaginaryPart(idx[n * 3 + i])));
651e5c89e4eSSatish Balay #else
6529566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[3 * n + i]));
653e5c89e4eSSatish Balay #endif
654e5c89e4eSSatish Balay       }
6559566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
656e5c89e4eSSatish Balay     }
6579566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
6589566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
6596805f65bSBarry Smith   } else if (isbinary) {
660ca0c3be5SJacob Faibussowitsch     PetscMPIInt *sizes, Ntotal, *displs, NN;
661e5c89e4eSSatish Balay     PetscScalar *array;
662e5c89e4eSSatish Balay 
6639566063dSJacob Faibussowitsch     PetscCall(PetscMPIIntCast(N, &NN));
664e5c89e4eSSatish Balay 
665e5c89e4eSSatish Balay     if (size > 1) {
666e5c89e4eSSatish Balay       if (rank) {
6679566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
6689566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, NULL, NULL, NULL, MPIU_SCALAR, 0, comm));
669e5c89e4eSSatish Balay       } else {
6709566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &sizes));
6719566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
672e5c89e4eSSatish Balay         Ntotal = sizes[0];
6739566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &displs));
674e5c89e4eSSatish Balay         displs[0] = 0;
675e5c89e4eSSatish Balay         for (i = 1; i < size; i++) {
676e5c89e4eSSatish Balay           Ntotal += sizes[i];
677e5c89e4eSSatish Balay           displs[i] = displs[i - 1] + sizes[i - 1];
678e5c89e4eSSatish Balay         }
6799566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(Ntotal, &array));
6809566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, array, sizes, displs, MPIU_SCALAR, 0, comm));
6819566063dSJacob Faibussowitsch         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_SCALAR));
6829566063dSJacob Faibussowitsch         PetscCall(PetscFree(sizes));
6839566063dSJacob Faibussowitsch         PetscCall(PetscFree(displs));
6849566063dSJacob Faibussowitsch         PetscCall(PetscFree(array));
685e5c89e4eSSatish Balay       }
686e5c89e4eSSatish Balay     } else {
6879566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_SCALAR));
688e5c89e4eSSatish Balay     }
689e5c89e4eSSatish Balay   } else {
690e5c89e4eSSatish Balay     const char *tname;
6919566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
69298921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
693e5c89e4eSSatish Balay   }
694e5c89e4eSSatish Balay   PetscFunctionReturn(0);
695e5c89e4eSSatish Balay }
696e5c89e4eSSatish Balay 
697e22e20c5SJunchao Zhang #if defined(PETSC_HAVE_CUDA)
6980e6b6b59SJacob Faibussowitsch #include <petscdevice_cuda.h>
6999371c9d4SSatish Balay PETSC_EXTERN const char *PetscCUBLASGetErrorName(cublasStatus_t status) {
700e22e20c5SJunchao Zhang   switch (status) {
701e22e20c5SJunchao Zhang #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
702e22e20c5SJunchao Zhang   case CUBLAS_STATUS_SUCCESS: return "CUBLAS_STATUS_SUCCESS";
703e22e20c5SJunchao Zhang   case CUBLAS_STATUS_NOT_INITIALIZED: return "CUBLAS_STATUS_NOT_INITIALIZED";
704e22e20c5SJunchao Zhang   case CUBLAS_STATUS_ALLOC_FAILED: return "CUBLAS_STATUS_ALLOC_FAILED";
705e22e20c5SJunchao Zhang   case CUBLAS_STATUS_INVALID_VALUE: return "CUBLAS_STATUS_INVALID_VALUE";
706e22e20c5SJunchao Zhang   case CUBLAS_STATUS_ARCH_MISMATCH: return "CUBLAS_STATUS_ARCH_MISMATCH";
707e22e20c5SJunchao Zhang   case CUBLAS_STATUS_MAPPING_ERROR: return "CUBLAS_STATUS_MAPPING_ERROR";
708e22e20c5SJunchao Zhang   case CUBLAS_STATUS_EXECUTION_FAILED: return "CUBLAS_STATUS_EXECUTION_FAILED";
709e22e20c5SJunchao Zhang   case CUBLAS_STATUS_INTERNAL_ERROR: return "CUBLAS_STATUS_INTERNAL_ERROR";
710e22e20c5SJunchao Zhang   case CUBLAS_STATUS_NOT_SUPPORTED: return "CUBLAS_STATUS_NOT_SUPPORTED";
711e22e20c5SJunchao Zhang   case CUBLAS_STATUS_LICENSE_ERROR: return "CUBLAS_STATUS_LICENSE_ERROR";
712e22e20c5SJunchao Zhang #endif
713e22e20c5SJunchao Zhang   default: return "unknown error";
714e22e20c5SJunchao Zhang   }
715e22e20c5SJunchao Zhang }
7169371c9d4SSatish Balay PETSC_EXTERN const char *PetscCUSolverGetErrorName(cusolverStatus_t status) {
717a4b895e1SBarry Smith   switch (status) {
718a4b895e1SBarry Smith #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
719a4b895e1SBarry Smith   case CUSOLVER_STATUS_SUCCESS: return "CUSOLVER_STATUS_SUCCESS";
720a4b895e1SBarry Smith   case CUSOLVER_STATUS_NOT_INITIALIZED: return "CUSOLVER_STATUS_NOT_INITIALIZED";
721a4b895e1SBarry Smith   case CUSOLVER_STATUS_INVALID_VALUE: return "CUSOLVER_STATUS_INVALID_VALUE";
722a4b895e1SBarry Smith   case CUSOLVER_STATUS_ARCH_MISMATCH: return "CUSOLVER_STATUS_ARCH_MISMATCH";
723a4b895e1SBarry Smith   case CUSOLVER_STATUS_INTERNAL_ERROR: return "CUSOLVER_STATUS_INTERNAL_ERROR";
724030f984aSJacob Faibussowitsch #if (CUDART_VERSION >= 9000) /* CUDA 9.0 had these defined on June 2021 */
725030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_ALLOC_FAILED: return "CUSOLVER_STATUS_ALLOC_FAILED";
726030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_MAPPING_ERROR: return "CUSOLVER_STATUS_MAPPING_ERROR";
727030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_EXECUTION_FAILED: return "CUSOLVER_STATUS_EXECUTION_FAILED";
728030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED: return "CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
729030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_NOT_SUPPORTED: return "CUSOLVER_STATUS_NOT_SUPPORTED ";
730030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_ZERO_PIVOT: return "CUSOLVER_STATUS_ZERO_PIVOT";
731030f984aSJacob Faibussowitsch   case CUSOLVER_STATUS_INVALID_LICENSE: return "CUSOLVER_STATUS_INVALID_LICENSE";
732a4b895e1SBarry Smith #endif
733030f984aSJacob Faibussowitsch #endif
734030f984aSJacob Faibussowitsch   default: return "unknown error";
735030f984aSJacob Faibussowitsch   }
736030f984aSJacob Faibussowitsch }
7379371c9d4SSatish Balay PETSC_EXTERN const char *PetscCUFFTGetErrorName(cufftResult result) {
738030f984aSJacob Faibussowitsch   switch (result) {
739030f984aSJacob Faibussowitsch   case CUFFT_SUCCESS: return "CUFFT_SUCCESS";
740030f984aSJacob Faibussowitsch   case CUFFT_INVALID_PLAN: return "CUFFT_INVALID_PLAN";
741030f984aSJacob Faibussowitsch   case CUFFT_ALLOC_FAILED: return "CUFFT_ALLOC_FAILED";
742030f984aSJacob Faibussowitsch   case CUFFT_INVALID_TYPE: return "CUFFT_INVALID_TYPE";
743030f984aSJacob Faibussowitsch   case CUFFT_INVALID_VALUE: return "CUFFT_INVALID_VALUE";
744030f984aSJacob Faibussowitsch   case CUFFT_INTERNAL_ERROR: return "CUFFT_INTERNAL_ERROR";
745030f984aSJacob Faibussowitsch   case CUFFT_EXEC_FAILED: return "CUFFT_EXEC_FAILED";
746030f984aSJacob Faibussowitsch   case CUFFT_SETUP_FAILED: return "CUFFT_SETUP_FAILED";
747030f984aSJacob Faibussowitsch   case CUFFT_INVALID_SIZE: return "CUFFT_INVALID_SIZE";
748030f984aSJacob Faibussowitsch   case CUFFT_UNALIGNED_DATA: return "CUFFT_UNALIGNED_DATA";
749030f984aSJacob Faibussowitsch   case CUFFT_INCOMPLETE_PARAMETER_LIST: return "CUFFT_INCOMPLETE_PARAMETER_LIST";
750030f984aSJacob Faibussowitsch   case CUFFT_INVALID_DEVICE: return "CUFFT_INVALID_DEVICE";
751030f984aSJacob Faibussowitsch   case CUFFT_PARSE_ERROR: return "CUFFT_PARSE_ERROR";
752030f984aSJacob Faibussowitsch   case CUFFT_NO_WORKSPACE: return "CUFFT_NO_WORKSPACE";
753030f984aSJacob Faibussowitsch   case CUFFT_NOT_IMPLEMENTED: return "CUFFT_NOT_IMPLEMENTED";
754030f984aSJacob Faibussowitsch   case CUFFT_LICENSE_ERROR: return "CUFFT_LICENSE_ERROR";
755030f984aSJacob Faibussowitsch   case CUFFT_NOT_SUPPORTED: return "CUFFT_NOT_SUPPORTED";
756a4b895e1SBarry Smith   default: return "unknown error";
757a4b895e1SBarry Smith   }
758a4b895e1SBarry Smith }
759e22e20c5SJunchao Zhang #endif
76059af0bd3SScott Kruger 
76159af0bd3SScott Kruger #if defined(PETSC_HAVE_HIP)
7620e6b6b59SJacob Faibussowitsch #include <petscdevice_hip.h>
7639371c9d4SSatish Balay PETSC_EXTERN const char *PetscHIPBLASGetErrorName(hipblasStatus_t status) {
76459af0bd3SScott Kruger   switch (status) {
76559af0bd3SScott Kruger   case HIPBLAS_STATUS_SUCCESS: return "HIPBLAS_STATUS_SUCCESS";
76659af0bd3SScott Kruger   case HIPBLAS_STATUS_NOT_INITIALIZED: return "HIPBLAS_STATUS_NOT_INITIALIZED";
76759af0bd3SScott Kruger   case HIPBLAS_STATUS_ALLOC_FAILED: return "HIPBLAS_STATUS_ALLOC_FAILED";
76859af0bd3SScott Kruger   case HIPBLAS_STATUS_INVALID_VALUE: return "HIPBLAS_STATUS_INVALID_VALUE";
76959af0bd3SScott Kruger   case HIPBLAS_STATUS_ARCH_MISMATCH: return "HIPBLAS_STATUS_ARCH_MISMATCH";
77059af0bd3SScott Kruger   case HIPBLAS_STATUS_MAPPING_ERROR: return "HIPBLAS_STATUS_MAPPING_ERROR";
77159af0bd3SScott Kruger   case HIPBLAS_STATUS_EXECUTION_FAILED: return "HIPBLAS_STATUS_EXECUTION_FAILED";
77259af0bd3SScott Kruger   case HIPBLAS_STATUS_INTERNAL_ERROR: return "HIPBLAS_STATUS_INTERNAL_ERROR";
77359af0bd3SScott Kruger   case HIPBLAS_STATUS_NOT_SUPPORTED: return "HIPBLAS_STATUS_NOT_SUPPORTED";
77459af0bd3SScott Kruger   default: return "unknown error";
77559af0bd3SScott Kruger   }
77659af0bd3SScott Kruger }
77759af0bd3SScott Kruger #endif
778db9cea48SBarry Smith 
779db9cea48SBarry Smith /*@
780811af0c4SBarry Smith       PetscMPIErrorString - Given an MPI error code returns the `MPI_Error_string()` appropriately
781db9cea48SBarry Smith            formatted for displaying with the PETSc error handlers.
782db9cea48SBarry Smith 
783db9cea48SBarry Smith  Input Parameter:
784db9cea48SBarry Smith .  err - the MPI error code
785db9cea48SBarry Smith 
786db9cea48SBarry Smith  Output Parameter:
787811af0c4SBarry Smith .  string - the MPI error message, should declare its length to be larger than `MPI_MAX_ERROR_STRING`
788db9cea48SBarry Smith 
78949c86fc7SBarry Smith    Level: developer
79049c86fc7SBarry Smith 
791811af0c4SBarry Smith  Note:
792db9cea48SBarry Smith     Does not return an error code or do error handling because it may be called from inside an error handler
793db9cea48SBarry Smith 
794db9cea48SBarry Smith @*/
7959371c9d4SSatish Balay void PetscMPIErrorString(PetscMPIInt err, char *string) {
796db9cea48SBarry Smith   char        errorstring[MPI_MAX_ERROR_STRING];
797db9cea48SBarry Smith   PetscMPIInt len, j = 0;
798db9cea48SBarry Smith 
799db9cea48SBarry Smith   MPI_Error_string(err, (char *)errorstring, &len);
800db9cea48SBarry Smith   for (PetscMPIInt i = 0; i < len; i++) {
801db9cea48SBarry Smith     string[j++] = errorstring[i];
802db9cea48SBarry Smith     if (errorstring[i] == '\n') {
803db9cea48SBarry Smith       for (PetscMPIInt k = 0; k < 16; k++) string[j++] = ' ';
804db9cea48SBarry Smith     }
805db9cea48SBarry Smith   }
806db9cea48SBarry Smith   string[j] = 0;
807db9cea48SBarry Smith }
808