Actual source code: err.c
1: /*
2: Code that allows one to set the error handlers
3: Portions of this code are under:
4: Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
5: */
6: #include <petsc/private/petscimpl.h>
7: #include <petscviewer.h>
9: typedef struct _EH *EH;
10: struct _EH {
11: PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *);
12: void *ctx;
13: EH previous;
14: };
16: /* This is here to allow the traceback error handler (or potentially other error handlers)
17: to certify that PETSCABORT is being called on all MPI processes, and that it should be possible to call
18: MPI_Finalize() and exit(). This should only be used when `PetscCIEnabledPortabeErrorOutput == PETSC_TRUE`
19: to allow testing of error messages. Do not rely on this for clean exit in production. */
20: PetscBool petscabortmpifinalize = PETSC_FALSE;
22: static EH eh = NULL;
24: /*@C
25: PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
26: load the file where the error occurred. Then calls the "previous" error handler.
28: Not Collective, No Fortran Support
30: Input Parameters:
31: + comm - communicator over which error occurred
32: . line - the line number of the error (usually indicated by `__LINE__` in the calling routine)
33: . file - the file in which the error was detected (usually indicated by `__FILE__` in the calling routine)
34: . fun - the function name of the calling routine
35: . mess - an error text string, usually just printed to the screen
36: . n - the generic error number
37: . p - `PETSC_ERROR_INITIAL` indicates this is the first time the error handler is being called while `PETSC_ERROR_REPEAT` indicates it was previously called
38: - ctx - error handler context
40: Options Database Key:
41: . -on_error_emacs <machinename> - will contact machinename to open the Emacs client there
43: Level: developer
45: Note:
46: You must put (server-start) in your .emacs file for the emacsclient software to work
48: Developer Note:
49: Since this is an error handler it cannot call `PetscCall()`; thus we just return if an error is detected.
50: But some of the functions it calls do perform error checking that may not be appropriate in a error handler call.
52: .seealso: `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`,
53: `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscReturnErrorHandler()`,
54: `PetscErrorType`, `PETSC_ERROR_INITIAL`, `PETSC_ERROR_REPEAT`, `PetscErrorCode`
55: @*/
56: PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx)
57: {
58: PetscErrorCode ierr;
59: char command[PETSC_MAX_PATH_LEN];
60: const char *pdir;
61: FILE *fp;
63: ierr = PetscGetPetscDir(&pdir);
64: if (ierr) return ierr;
65: ierr = PetscSNPrintf(command, PETSC_STATIC_ARRAY_LENGTH(command), "cd %s; emacsclient --no-wait +%d %s\n", pdir, line, file);
66: if (ierr) return ierr;
67: #if defined(PETSC_HAVE_POPEN)
68: ierr = PetscPOpen(MPI_COMM_WORLD, (char *)ctx, command, "r", &fp);
69: if (ierr) return ierr;
70: ierr = PetscPClose(MPI_COMM_WORLD, fp);
71: if (ierr) return ierr;
72: #else
73: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine");
74: #endif
75: ierr = PetscPopErrorHandler();
76: if (ierr) return ierr; /* remove this handler from the stack of handlers */
77: if (!eh) {
78: ierr = PetscTraceBackErrorHandler(comm, line, fun, file, n, p, mess, NULL);
79: if (ierr) return ierr;
80: } else {
81: ierr = (*eh->handler)(comm, line, fun, file, n, p, mess, eh->ctx);
82: if (ierr) return ierr;
83: }
84: return PETSC_SUCCESS;
85: }
87: /*@C
88: PetscPushErrorHandler - Sets a routine to be called on detection of errors.
90: Not Collective, No Fortran Support
92: Input Parameters:
93: + handler - error handler routine
94: - ctx - optional handler context that contains information needed by the handler (for
95: example file pointers for error messages etc.)
97: Calling sequence of `handler`:
98: + comm - communicator over which error occurred
99: . line - the line number of the error (usually indicated by `__LINE__` in the calling routine)
100: . file - the file in which the error was detected (usually indicated by `__FILE__` in the calling routine)
101: . fun - the function name of the calling routine
102: . n - the generic error number (see list defined in include/petscerror.h)
103: . p - `PETSC_ERROR_INITIAL` if error just detected, otherwise `PETSC_ERROR_REPEAT`
104: . mess - an error text string, usually just printed to the screen
105: - ctx - the error handler context
107: Options Database Keys:
108: + -on_error_attach_debugger <noxterm,lldb or gdb> - starts up the debugger if an error occurs
109: - -on_error_abort - aborts the program if an error occurs
111: Level: intermediate
113: Note:
114: The currently available PETSc error handlers include `PetscTraceBackErrorHandler()`,
115: `PetscAttachDebuggerErrorHandler()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, and `PetscReturnErrorHandler()`.
117: Fortran Note:
118: You can only push a single error handler from Fortran before popping it.
120: .seealso: `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscAbortErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscPushSignalHandler()`,
121: `PetscErrorType`, `PETSC_ERROR_INITIAL`, `PETSC_ERROR_REPEAT`, `PetscErrorCode`
122: @*/
123: PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx), void *ctx)
124: {
125: EH neweh;
127: PetscFunctionBegin;
128: PetscCall(PetscNew(&neweh));
129: if (eh) neweh->previous = eh;
130: else neweh->previous = NULL;
131: neweh->handler = handler;
132: neweh->ctx = ctx;
133: eh = neweh;
134: PetscFunctionReturn(PETSC_SUCCESS);
135: }
137: /*@
138: PetscPopErrorHandler - Removes the latest error handler that was
139: pushed with `PetscPushErrorHandler()`.
141: Not Collective
143: Level: intermediate
145: .seealso: `PetscPushErrorHandler()`
146: @*/
147: PetscErrorCode PetscPopErrorHandler(void)
148: {
149: EH tmp;
151: PetscFunctionBegin;
152: if (!eh) PetscFunctionReturn(PETSC_SUCCESS);
153: tmp = eh;
154: eh = eh->previous;
155: PetscCall(PetscFree(tmp));
156: PetscFunctionReturn(PETSC_SUCCESS);
157: }
159: /*@C
160: PetscReturnErrorHandler - Error handler that causes a return without printing an error message.
162: Not Collective, No Fortran Support
164: Input Parameters:
165: + comm - communicator over which error occurred
166: . line - the line number of the error (usually indicated by `__LINE__` in the calling routine)
167: . fun - the function name
168: . file - the file in which the error was detected (usually indicated by `__FILE__` in the calling routine)
169: . mess - an error text string, usually just printed to the screen
170: . n - the generic error number
171: . p - `PETSC_ERROR_INITIAL` indicates this is the first time the error handler is being called while `PETSC_ERROR_REPEAT` indicates it was previously called
172: - ctx - error handler context
174: Level: developer
176: Notes:
177: Users do not directly employ this routine
179: Use `PetscPushErrorHandler()` to set the desired error handler. The
180: currently available PETSc error handlers include `PetscTraceBackErrorHandler()`,
181: `PetscAttachDebuggerErrorHandler()`, and `PetscAbortErrorHandler()`.
183: .seealso: `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscError()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscTraceBackErrorHandler()`,
184: `PetscAttachDebuggerErrorHandler()`, `PetscEmacsClientErrorHandler()`,
185: `PetscErrorType`, `PETSC_ERROR_INITIAL`, `PETSC_ERROR_REPEAT`, `PetscErrorCode`
186: @*/
187: PetscErrorCode PetscReturnErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx)
188: {
189: (void)comm;
190: (void)line;
191: (void)fun;
192: (void)file;
193: (void)p;
194: (void)mess;
195: (void)ctx;
196: return n;
197: }
199: static char PetscErrorBaseMessage[1024];
200: /*
201: The numerical values for these are defined in include/petscerror.h; any changes
202: there must also be made here
203: */
204: static const char *PetscErrorStrings[] = {
205: /*55 */ "Out of memory",
206: "No support for this operation for this object type",
207: "No support for this operation on this system",
208: /*58 */ "Operation done in wrong order",
209: /*59 */ "Signal received",
210: /*60 */ "Nonconforming object sizes",
211: "Argument aliasing not permitted",
212: "Invalid argument",
213: /*63 */ "Argument out of range",
214: "Corrupt argument: https://petsc.org/release/faq/#valgrind",
215: "Unable to open file",
216: "Read from file failed",
217: "Write to file failed",
218: "Invalid pointer",
219: /*69 */ "Arguments must have same type",
220: /*70 */ "Attempt to use a pointer that does not point to a valid accessible location",
221: /*71 */ "Zero pivot in LU factorization: https://petsc.org/release/faq/#zeropivot",
222: /*72 */ "Floating point exception",
223: /*73 */ "Object is in wrong state",
224: "Corrupted Petsc object",
225: "Arguments are incompatible",
226: "Error in external library",
227: /*77 */ "Petsc has generated inconsistent data",
228: "Memory corruption: https://petsc.org/release/faq/#valgrind",
229: "Unexpected data in file",
230: /*80 */ "Arguments must have same communicators",
231: /*81 */ "Zero pivot in Cholesky factorization: https://petsc.org/release/faq/#zeropivot",
232: "",
233: "",
234: "Overflow in integer operation: https://petsc.org/release/faq/#64-bit-indices",
235: /*85 */ "Null argument, when expecting valid pointer",
236: /*86 */ "Unknown type. Check for miss-spelling or missing package: https://petsc.org/release/install/install/#external-packages",
237: /*87 */ "MPI library at runtime is not compatible with MPI used at compile time",
238: /*88 */ "Error in system call",
239: /*89 */ "Object Type not set: https://petsc.org/release/faq/#object-type-not-set",
240: /*90 */ "",
241: /* */ "",
242: /*92 */ "See https://petsc.org/release/overview/linear_solve_table/ for possible LU and Cholesky solvers",
243: /*93 */ "You cannot overwrite this option since that will conflict with other previously set options",
244: /*94 */ "Example/application run with number of MPI ranks it does not support",
245: /*95 */ "Missing or incorrect user input",
246: /*96 */ "GPU resources unavailable",
247: /*97 */ "GPU error",
248: /*98 */ "General MPI error",
249: /*99 */ "PetscError() incorrectly returned an error code of 0",
250: /* */ "",
251: /*101*/ "Unhandled Python Exception",
252: NULL};
254: /*@C
255: PetscErrorMessage - Returns the text string associated with a PETSc error code.
257: Not Collective, No Fortran Support
259: Input Parameter:
260: . errnum - the error code
262: Output Parameters:
263: + text - the error message (`NULL` if not desired)
264: - specific - the specific error message that was set with `SETERRQ()` or
265: `PetscError()`. (`NULL` if not desired)
267: Level: developer
269: .seealso: `PetscErrorCode`, `PetscPushErrorHandler()`, `PetscAttachDebuggerErrorHandler()`,
270: `PetscError()`, `SETERRQ()`, `PetscCall()` `PetscAbortErrorHandler()`,
271: `PetscTraceBackErrorHandler()`
272: @*/
273: PetscErrorCode PetscErrorMessage(PetscErrorCode errnum, const char *text[], char *specific[])
274: {
275: PetscFunctionBegin;
276: if (text) {
277: if (errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) {
278: size_t len;
280: *text = PetscErrorStrings[errnum - PETSC_ERR_MIN_VALUE - 1];
281: PetscCall(PetscStrlen(*text, &len));
282: if (!len) *text = NULL;
283: } else if (errnum == PETSC_ERR_BOOLEAN_MACRO_FAILURE) {
284: /* this "error code" arises from failures in boolean macros, where the || operator is
285: used to short-circuit the macro call in case of error. This has the side effect of
286: "returning" either 0 (PETSC_SUCCESS) or 1 (PETSC_ERR_UNKNONWN):
288: #define PETSC_FOO(x) ((PetscErrorCode)(PetscBar(x) || PetscBaz(x)))
290: If PetscBar() fails (returns nonzero) PetscBaz() is not executed but the result of
291: this expression is boolean false, hence PETSC_ERR_UNNOWN
292: */
293: *text = "Error occurred in boolean shortcuit in macro";
294: } else {
295: *text = NULL;
296: }
297: }
298: if (specific) *specific = PetscErrorBaseMessage;
299: PetscFunctionReturn(PETSC_SUCCESS);
300: }
302: #if defined(PETSC_CLANGUAGE_CXX)
303: /* C++ exceptions are formally not allowed to propagate through extern "C" code. In practice, far too much software
304: * would be broken if implementations did not handle it in some common cases. However, keep in mind
305: *
306: * Rule 62. Don't allow exceptions to propagate across module boundaries
307: *
308: * in "C++ Coding Standards" by Sutter and Alexandrescu. (This accounts for part of the ongoing C++ binary interface
309: * instability.) Having PETSc raise errors as C++ exceptions was probably misguided and should eventually be removed.
310: *
311: * Here is the problem: You have a C++ function call a PETSc function, and you would like to maintain the error message
312: * and stack information from the PETSc error. You could make everyone write exactly this code in their C++, but that
313: * seems crazy to me.
314: */
315: #include <sstream>
316: #include <stdexcept>
317: static void PetscCxxErrorThrow()
318: {
319: const char *str;
320: if (eh && eh->ctx) {
321: std::ostringstream *msg;
322: msg = (std::ostringstream *)eh->ctx;
323: str = msg->str().c_str();
324: } else str = "Error detected in C PETSc";
326: throw std::runtime_error(str);
327: }
328: #endif
330: /*@C
331: PetscError - Routine that is called when an error has been detected, usually called through the macro `SETERRQ`(`PETSC_COMM_SELF`,)` or by `PetscCall()`.
333: Collective
335: Input Parameters:
336: + comm - communicator over which error occurred. ALL MPI processes of this communicator MUST call this routine
337: . line - the line number of the error (usually indicated by `__LINE__` in the calling routine)
338: . func - the function name in which the error was detected
339: . file - the file in which the error was detected (usually indicated by `__FILE__` in the calling routine)
340: . n - the generic error number
341: . p - `PETSC_ERROR_INITIAL` indicates the error was initially detected, `PETSC_ERROR_REPEAT` indicates this is a traceback from a previously detected error
342: - mess - formatted message string - aka printf
344: Options Database Keys:
345: + -error_output_stdout - output the error messages to `stdout` instead of the default `stderr`
346: - -error_output_none - do not output the error messages
348: Level: intermediate
350: Notes:
351: PETSc error handling is done with error return codes. A non-zero return indicates an error
352: was detected. The return-value of this routine is what is ultimately returned by
353: `SETERRQ()`.
355: Numerical errors (potential divide by zero, for example) are not managed by the
356: error return codes; they are managed via, for example, `KSPGetConvergedReason()` that
357: indicates if the solve was successful or not. The option `-ksp_error_if_not_converged`, for
358: example, turns numerical failures into hard errors managed via `PetscError()`.
360: PETSc provides a rich supply of error handlers, see the list below, and users can also
361: provide their own error handlers.
363: If the user sets their own error handler (via `PetscPushErrorHandler()`) they may return any
364: arbitrary value from it, but are encouraged to return nonzero values. If the return value is
365: zero, `SETERRQ()` will ignore the value and return `PETSC_ERR_RETURN` (a nonzero value)
366: instead.
368: Most users need not directly use this routine and the error handlers, but can instead use
369: the simplified interface `PetscCall()` or `SETERRQ()`.
371: Fortran Note:
372: This routine is used differently from Fortran
373: .vb
374: PetscError(MPI_Comm comm, PetscErrorCode n, PetscErrorType p, char *message)
375: .ve
377: Developer Note:
378: Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes)
379: 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
380: but this annoying.
382: .seealso: `PetscErrorCode`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`,
383: `PetscReturnErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscEmacsClientErrorHandler()`,
384: `SETERRQ()`, `PetscCall()`, `CHKMEMQ`, `PetscErrorMessage()`, `PETSCABORT()`, `PetscErrorType`, `PETSC_ERROR_INITIAL`, `PETSC_ERROR_REPEAT`
385: @*/
386: PetscErrorCode PetscError(MPI_Comm comm, int line, const char *func, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, ...)
387: {
388: va_list Argp;
389: size_t fullLength;
390: char buf[2048], *lbuf = NULL;
391: PetscBool ismain;
392: PetscErrorCode ierr;
394: if (!PetscErrorHandlingInitialized) return n;
395: if (comm == MPI_COMM_NULL) comm = PETSC_COMM_SELF;
397: /* Compose the message evaluating the print format */
398: if (mess) {
399: va_start(Argp, mess);
400: (void)PetscVSNPrintf(buf, 2048, mess, &fullLength, Argp);
401: va_end(Argp);
402: lbuf = buf;
403: if (p == PETSC_ERROR_INITIAL) (void)PetscStrncpy(PetscErrorBaseMessage, lbuf, sizeof(PetscErrorBaseMessage));
404: }
406: if (p == PETSC_ERROR_INITIAL && n != PETSC_ERR_MEMC) (void)PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__);
408: if (!eh) ierr = PetscTraceBackErrorHandler(comm, line, func, file, n, p, lbuf, NULL);
409: else ierr = (*eh->handler)(comm, line, func, file, n, p, lbuf, eh->ctx);
410: PetscStackClearTop;
412: /*
413: If this is called from the main() routine we abort the program.
414: We cannot just return because them some MPI processes may continue to attempt to run
415: while this process simply exits.
416: */
417: if (func) {
418: (void)PetscStrncmp(func, "main", 4, &ismain);
419: if (ismain) {
420: if (petscwaitonerrorflg) (void)PetscSleep(1000);
421: PETSCABORT(comm, ierr);
422: }
423: }
424: #if defined(PETSC_CLANGUAGE_CXX)
425: if (p == PETSC_ERROR_IN_CXX) PetscCxxErrorThrow();
426: #endif
427: return ierr;
428: }
430: /*@
431: PetscIntViewNumColumns - Prints an array of integers; useful for debugging.
433: Collective
435: Input Parameters:
436: + N - number of integers in array
437: . Ncol - number of integers to print per row
438: . idx - array of integers
439: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
441: Level: intermediate
443: Note:
444: This may be called from within the debugger, passing 0 as the viewer
446: This API may be removed in the future.
448: Developer Note:
449: `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done
451: .seealso: `PetscViewer`, `PetscIntView()`, `PetscRealView()`
452: @*/
453: PetscErrorCode PetscIntViewNumColumns(PetscInt N, PetscInt Ncol, const PetscInt idx[], PetscViewer viewer)
454: {
455: PetscMPIInt rank, size;
456: PetscInt j, i, n = N / Ncol, p = N % Ncol;
457: PetscBool iascii, isbinary;
458: MPI_Comm comm;
460: PetscFunctionBegin;
461: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
462: if (N) PetscAssertPointer(idx, 3);
464: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
465: PetscCallMPI(MPI_Comm_size(comm, &size));
466: PetscCallMPI(MPI_Comm_rank(comm, &rank));
468: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
469: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
470: if (iascii) {
471: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
472: for (i = 0; i < n; i++) {
473: if (size > 1) {
474: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, Ncol * i));
475: } else {
476: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", Ncol * i));
477: }
478: for (j = 0; j < Ncol; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[i * Ncol + j]));
479: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
480: }
481: if (p) {
482: if (size > 1) {
483: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, Ncol * n));
484: } else {
485: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", Ncol * n));
486: }
487: for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[Ncol * n + i]));
488: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
489: }
490: PetscCall(PetscViewerFlush(viewer));
491: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
492: } else if (isbinary) {
493: PetscMPIInt *sizes, Ntotal, *displs, NN;
494: PetscInt *array;
496: PetscCall(PetscMPIIntCast(N, &NN));
498: if (size > 1) {
499: if (rank) {
500: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
501: PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_INT, NULL, NULL, NULL, MPIU_INT, 0, comm));
502: } else {
503: PetscCall(PetscMalloc1(size, &sizes));
504: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
505: Ntotal = sizes[0];
506: PetscCall(PetscMalloc1(size, &displs));
507: displs[0] = 0;
508: for (i = 1; i < size; i++) {
509: Ntotal += sizes[i];
510: displs[i] = displs[i - 1] + sizes[i - 1];
511: }
512: PetscCall(PetscMalloc1(Ntotal, &array));
513: PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_INT, array, sizes, displs, MPIU_INT, 0, comm));
514: PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_INT));
515: PetscCall(PetscFree(sizes));
516: PetscCall(PetscFree(displs));
517: PetscCall(PetscFree(array));
518: }
519: } else {
520: PetscCall(PetscViewerBinaryWrite(viewer, idx, N, PETSC_INT));
521: }
522: } else {
523: const char *tname;
524: PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
525: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
526: }
527: PetscFunctionReturn(PETSC_SUCCESS);
528: }
530: /*@
531: PetscRealViewNumColumns - Prints an array of doubles; useful for debugging.
533: Collective
535: Input Parameters:
536: + N - number of `PetscReal` in array
537: . Ncol - number of `PetscReal` to print per row
538: . idx - array of `PetscReal`
539: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
541: Level: intermediate
543: Note:
544: This may be called from within the debugger, passing 0 as the viewer
546: This API may be removed in the future.
548: Developer Note:
549: `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done
551: .seealso: `PetscViewer`, `PetscRealView()`, `PetscIntView()`
552: @*/
553: PetscErrorCode PetscRealViewNumColumns(PetscInt N, PetscInt Ncol, const PetscReal idx[], PetscViewer viewer)
554: {
555: PetscMPIInt rank, size;
556: PetscInt j, i, n = N / Ncol, p = N % Ncol;
557: PetscBool iascii, isbinary;
558: MPI_Comm comm;
560: PetscFunctionBegin;
561: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
562: if (N) PetscAssertPointer(idx, 3);
564: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
565: PetscCallMPI(MPI_Comm_size(comm, &size));
566: PetscCallMPI(MPI_Comm_rank(comm, &rank));
568: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
569: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
570: if (iascii) {
571: PetscInt tab;
573: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
574: PetscCall(PetscViewerASCIIGetTab(viewer, &tab));
575: for (i = 0; i < n; i++) {
576: PetscCall(PetscViewerASCIISetTab(viewer, tab));
577: if (size > 1) {
578: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * i));
579: } else {
580: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * i));
581: }
582: PetscCall(PetscViewerASCIISetTab(viewer, 0));
583: for (j = 0; j < Ncol; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * Ncol + j]));
584: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
585: }
586: if (p) {
587: PetscCall(PetscViewerASCIISetTab(viewer, tab));
588: if (size > 1) {
589: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * n));
590: } else {
591: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * n));
592: }
593: PetscCall(PetscViewerASCIISetTab(viewer, 0));
594: for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[Ncol * n + i]));
595: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
596: }
597: PetscCall(PetscViewerFlush(viewer));
598: PetscCall(PetscViewerASCIISetTab(viewer, tab));
599: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
600: } else if (isbinary) {
601: PetscMPIInt *sizes, *displs, Ntotal, NN;
602: PetscReal *array;
604: PetscCall(PetscMPIIntCast(N, &NN));
606: if (size > 1) {
607: if (rank) {
608: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
609: PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_REAL, NULL, NULL, NULL, MPIU_REAL, 0, comm));
610: } else {
611: PetscCall(PetscMalloc1(size, &sizes));
612: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
613: Ntotal = sizes[0];
614: PetscCall(PetscMalloc1(size, &displs));
615: displs[0] = 0;
616: for (i = 1; i < size; i++) {
617: Ntotal += sizes[i];
618: displs[i] = displs[i - 1] + sizes[i - 1];
619: }
620: PetscCall(PetscMalloc1(Ntotal, &array));
621: PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_REAL, array, sizes, displs, MPIU_REAL, 0, comm));
622: PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_REAL));
623: PetscCall(PetscFree(sizes));
624: PetscCall(PetscFree(displs));
625: PetscCall(PetscFree(array));
626: }
627: } else {
628: PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_REAL));
629: }
630: } else {
631: const char *tname;
632: PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
633: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
634: }
635: PetscFunctionReturn(PETSC_SUCCESS);
636: }
638: /*@
639: PetscScalarViewNumColumns - Prints an array of doubles; useful for debugging.
641: Collective
643: Input Parameters:
644: + N - number of `PetscScalar` in array
645: . Ncol - number of `PetscScalar` to print per row
646: . idx - array of `PetscScalar`
647: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
649: Level: intermediate
651: Note:
652: This may be called from within the debugger, passing 0 as the viewer
654: This API may be removed in the future.
656: Developer Note:
657: `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done
659: .seealso: `PetscViewer`, `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`
660: @*/
661: PetscErrorCode PetscScalarViewNumColumns(PetscInt N, PetscInt Ncol, const PetscScalar idx[], PetscViewer viewer)
662: {
663: PetscMPIInt rank, size;
664: PetscInt j, i, n = N / Ncol, p = N % Ncol;
665: PetscBool iascii, isbinary;
666: MPI_Comm comm;
668: PetscFunctionBegin;
669: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
670: if (N) PetscAssertPointer(idx, 3);
672: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
673: PetscCallMPI(MPI_Comm_size(comm, &size));
674: PetscCallMPI(MPI_Comm_rank(comm, &rank));
676: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
677: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
678: if (iascii) {
679: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
680: for (i = 0; i < n; i++) {
681: if (size > 1) {
682: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * i));
683: } else {
684: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * i));
685: }
686: for (j = 0; j < Ncol; j++) {
687: #if defined(PETSC_USE_COMPLEX)
688: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[i * Ncol + j]), (double)PetscImaginaryPart(idx[i * Ncol + j])));
689: #else
690: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * Ncol + j]));
691: #endif
692: }
693: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
694: }
695: if (p) {
696: if (size > 1) {
697: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * n));
698: } else {
699: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * n));
700: }
701: for (i = 0; i < p; i++) {
702: #if defined(PETSC_USE_COMPLEX)
703: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[n * Ncol + i]), (double)PetscImaginaryPart(idx[n * Ncol + i])));
704: #else
705: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[Ncol * n + i]));
706: #endif
707: }
708: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
709: }
710: PetscCall(PetscViewerFlush(viewer));
711: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
712: } else if (isbinary) {
713: PetscMPIInt *sizes, Ntotal, *displs, NN;
714: PetscScalar *array;
716: PetscCall(PetscMPIIntCast(N, &NN));
718: if (size > 1) {
719: if (rank) {
720: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
721: PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, NULL, NULL, NULL, MPIU_SCALAR, 0, comm));
722: } else {
723: PetscCall(PetscMalloc1(size, &sizes));
724: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
725: Ntotal = sizes[0];
726: PetscCall(PetscMalloc1(size, &displs));
727: displs[0] = 0;
728: for (i = 1; i < size; i++) {
729: Ntotal += sizes[i];
730: displs[i] = displs[i - 1] + sizes[i - 1];
731: }
732: PetscCall(PetscMalloc1(Ntotal, &array));
733: PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, array, sizes, displs, MPIU_SCALAR, 0, comm));
734: PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_SCALAR));
735: PetscCall(PetscFree(sizes));
736: PetscCall(PetscFree(displs));
737: PetscCall(PetscFree(array));
738: }
739: } else {
740: PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_SCALAR));
741: }
742: } else {
743: const char *tname;
744: PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
745: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
746: }
747: PetscFunctionReturn(PETSC_SUCCESS);
748: }
750: /*@
751: PetscIntView - Prints an array of integers; useful for debugging.
753: Collective
755: Input Parameters:
756: + N - number of integers in array
757: . idx - array of integers
758: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
760: Level: intermediate
762: Note:
763: This may be called from within the debugger, passing 0 as the viewer
765: This API may be removed in the future.
767: Same as `PetscIntViewNumColumns()` with 20 values per row
769: Developer Note:
770: `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done
772: .seealso: `PetscViewer`, `PetscIntViewNumColumns()`, `PetscRealView()`
773: @*/
774: PetscErrorCode PetscIntView(PetscInt N, const PetscInt idx[], PetscViewer viewer)
775: {
776: PetscFunctionBegin;
777: PetscCall(PetscIntViewNumColumns(N, 20, idx, viewer));
778: PetscFunctionReturn(PETSC_SUCCESS);
779: }
781: /*@
782: PetscRealView - Prints an array of doubles; useful for debugging.
784: Collective
786: Input Parameters:
787: + N - number of `PetscReal` in array
788: . idx - array of `PetscReal`
789: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
791: Level: intermediate
793: Note:
794: This may be called from within the debugger, passing 0 as the viewer
796: This API may be removed in the future.
798: Same as `PetscRealViewNumColumns()` with 5 values per row
800: Developer Note:
801: `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done
803: .seealso: `PetscViewer`, `PetscIntView()`
804: @*/
805: PetscErrorCode PetscRealView(PetscInt N, const PetscReal idx[], PetscViewer viewer)
806: {
807: PetscFunctionBegin;
808: PetscCall(PetscRealViewNumColumns(N, 5, idx, viewer));
809: PetscFunctionReturn(PETSC_SUCCESS);
810: }
812: /*@
813: PetscScalarView - Prints an array of `PetscScalar`; useful for debugging.
815: Collective
817: Input Parameters:
818: + N - number of scalars in array
819: . idx - array of scalars
820: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
822: Level: intermediate
824: Note:
825: This may be called from within the debugger, passing 0 as the viewer
827: This API may be removed in the future.
829: Same as `PetscScalarViewNumColumns()` with 3 values per row
831: Developer Note:
832: `idx` cannot be const because may be passed to binary viewer where byte swapping may be done
834: .seealso: `PetscViewer`, `PetscIntView()`, `PetscRealView()`
835: @*/
836: PetscErrorCode PetscScalarView(PetscInt N, const PetscScalar idx[], PetscViewer viewer)
837: {
838: PetscFunctionBegin;
839: PetscCall(PetscScalarViewNumColumns(N, 3, idx, viewer));
840: PetscFunctionReturn(PETSC_SUCCESS);
841: }
843: #if defined(PETSC_HAVE_CUDA)
844: #include <petscdevice_cuda.h>
845: PETSC_EXTERN const char *PetscCUBLASGetErrorName(cublasStatus_t status)
846: {
847: switch (status) {
848: #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
849: case CUBLAS_STATUS_SUCCESS:
850: return "CUBLAS_STATUS_SUCCESS";
851: case CUBLAS_STATUS_NOT_INITIALIZED:
852: return "CUBLAS_STATUS_NOT_INITIALIZED";
853: case CUBLAS_STATUS_ALLOC_FAILED:
854: return "CUBLAS_STATUS_ALLOC_FAILED";
855: case CUBLAS_STATUS_INVALID_VALUE:
856: return "CUBLAS_STATUS_INVALID_VALUE";
857: case CUBLAS_STATUS_ARCH_MISMATCH:
858: return "CUBLAS_STATUS_ARCH_MISMATCH";
859: case CUBLAS_STATUS_MAPPING_ERROR:
860: return "CUBLAS_STATUS_MAPPING_ERROR";
861: case CUBLAS_STATUS_EXECUTION_FAILED:
862: return "CUBLAS_STATUS_EXECUTION_FAILED";
863: case CUBLAS_STATUS_INTERNAL_ERROR:
864: return "CUBLAS_STATUS_INTERNAL_ERROR";
865: case CUBLAS_STATUS_NOT_SUPPORTED:
866: return "CUBLAS_STATUS_NOT_SUPPORTED";
867: case CUBLAS_STATUS_LICENSE_ERROR:
868: return "CUBLAS_STATUS_LICENSE_ERROR";
869: #endif
870: default:
871: return "unknown error";
872: }
873: }
874: PETSC_EXTERN const char *PetscCUSolverGetErrorName(cusolverStatus_t status)
875: {
876: switch (status) {
877: #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
878: case CUSOLVER_STATUS_SUCCESS:
879: return "CUSOLVER_STATUS_SUCCESS";
880: case CUSOLVER_STATUS_NOT_INITIALIZED:
881: return "CUSOLVER_STATUS_NOT_INITIALIZED";
882: case CUSOLVER_STATUS_INVALID_VALUE:
883: return "CUSOLVER_STATUS_INVALID_VALUE";
884: case CUSOLVER_STATUS_ARCH_MISMATCH:
885: return "CUSOLVER_STATUS_ARCH_MISMATCH";
886: case CUSOLVER_STATUS_INTERNAL_ERROR:
887: return "CUSOLVER_STATUS_INTERNAL_ERROR";
888: #if (CUDART_VERSION >= 9000) /* CUDA 9.0 had these defined on June 2021 */
889: case CUSOLVER_STATUS_ALLOC_FAILED:
890: return "CUSOLVER_STATUS_ALLOC_FAILED";
891: case CUSOLVER_STATUS_MAPPING_ERROR:
892: return "CUSOLVER_STATUS_MAPPING_ERROR";
893: case CUSOLVER_STATUS_EXECUTION_FAILED:
894: return "CUSOLVER_STATUS_EXECUTION_FAILED";
895: case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
896: return "CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
897: case CUSOLVER_STATUS_NOT_SUPPORTED:
898: return "CUSOLVER_STATUS_NOT_SUPPORTED ";
899: case CUSOLVER_STATUS_ZERO_PIVOT:
900: return "CUSOLVER_STATUS_ZERO_PIVOT";
901: case CUSOLVER_STATUS_INVALID_LICENSE:
902: return "CUSOLVER_STATUS_INVALID_LICENSE";
903: #endif
904: #endif
905: default:
906: return "unknown error";
907: }
908: }
909: PETSC_EXTERN const char *PetscCUFFTGetErrorName(cufftResult result)
910: {
911: switch (result) {
912: case CUFFT_SUCCESS:
913: return "CUFFT_SUCCESS";
914: case CUFFT_INVALID_PLAN:
915: return "CUFFT_INVALID_PLAN";
916: case CUFFT_ALLOC_FAILED:
917: return "CUFFT_ALLOC_FAILED";
918: case CUFFT_INVALID_TYPE:
919: return "CUFFT_INVALID_TYPE";
920: case CUFFT_INVALID_VALUE:
921: return "CUFFT_INVALID_VALUE";
922: case CUFFT_INTERNAL_ERROR:
923: return "CUFFT_INTERNAL_ERROR";
924: case CUFFT_EXEC_FAILED:
925: return "CUFFT_EXEC_FAILED";
926: case CUFFT_SETUP_FAILED:
927: return "CUFFT_SETUP_FAILED";
928: case CUFFT_INVALID_SIZE:
929: return "CUFFT_INVALID_SIZE";
930: case CUFFT_UNALIGNED_DATA:
931: return "CUFFT_UNALIGNED_DATA";
932: case CUFFT_INCOMPLETE_PARAMETER_LIST:
933: return "CUFFT_INCOMPLETE_PARAMETER_LIST";
934: case CUFFT_INVALID_DEVICE:
935: return "CUFFT_INVALID_DEVICE";
936: case CUFFT_PARSE_ERROR:
937: return "CUFFT_PARSE_ERROR";
938: case CUFFT_NO_WORKSPACE:
939: return "CUFFT_NO_WORKSPACE";
940: case CUFFT_NOT_IMPLEMENTED:
941: return "CUFFT_NOT_IMPLEMENTED";
942: case CUFFT_LICENSE_ERROR:
943: return "CUFFT_LICENSE_ERROR";
944: case CUFFT_NOT_SUPPORTED:
945: return "CUFFT_NOT_SUPPORTED";
946: default:
947: return "unknown error";
948: }
949: }
950: #endif
952: #if defined(PETSC_HAVE_HIP)
953: #include <petscdevice_hip.h>
954: PETSC_EXTERN const char *PetscHIPBLASGetErrorName(hipblasStatus_t status)
955: {
956: switch (status) {
957: case HIPBLAS_STATUS_SUCCESS:
958: return "HIPBLAS_STATUS_SUCCESS";
959: case HIPBLAS_STATUS_NOT_INITIALIZED:
960: return "HIPBLAS_STATUS_NOT_INITIALIZED";
961: case HIPBLAS_STATUS_ALLOC_FAILED:
962: return "HIPBLAS_STATUS_ALLOC_FAILED";
963: case HIPBLAS_STATUS_INVALID_VALUE:
964: return "HIPBLAS_STATUS_INVALID_VALUE";
965: case HIPBLAS_STATUS_ARCH_MISMATCH:
966: return "HIPBLAS_STATUS_ARCH_MISMATCH";
967: case HIPBLAS_STATUS_MAPPING_ERROR:
968: return "HIPBLAS_STATUS_MAPPING_ERROR";
969: case HIPBLAS_STATUS_EXECUTION_FAILED:
970: return "HIPBLAS_STATUS_EXECUTION_FAILED";
971: case HIPBLAS_STATUS_INTERNAL_ERROR:
972: return "HIPBLAS_STATUS_INTERNAL_ERROR";
973: case HIPBLAS_STATUS_NOT_SUPPORTED:
974: return "HIPBLAS_STATUS_NOT_SUPPORTED";
975: default:
976: return "unknown error";
977: }
978: }
979: PETSC_EXTERN const char *PetscHIPSPARSEGetErrorName(hipsparseStatus_t status)
980: {
981: switch (status) {
982: case HIPSPARSE_STATUS_SUCCESS:
983: return "HIPSPARSE_STATUS_SUCCESS";
984: case HIPSPARSE_STATUS_NOT_INITIALIZED:
985: return "HIPSPARSE_STATUS_NOT_INITIALIZED";
986: case HIPSPARSE_STATUS_ALLOC_FAILED:
987: return "HIPSPARSE_STATUS_ALLOC_FAILED";
988: case HIPSPARSE_STATUS_INVALID_VALUE:
989: return "HIPSPARSE_STATUS_INVALID_VALUE";
990: case HIPSPARSE_STATUS_ARCH_MISMATCH:
991: return "HIPSPARSE_STATUS_ARCH_MISMATCH";
992: case HIPSPARSE_STATUS_MAPPING_ERROR:
993: return "HIPSPARSE_STATUS_MAPPING_ERROR";
994: case HIPSPARSE_STATUS_EXECUTION_FAILED:
995: return "HIPSPARSE_STATUS_EXECUTION_FAILED";
996: case HIPSPARSE_STATUS_INTERNAL_ERROR:
997: return "HIPSPARSE_STATUS_INTERNAL_ERROR";
998: case HIPSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
999: return "HIPSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
1000: case HIPSPARSE_STATUS_ZERO_PIVOT:
1001: return "HIPSPARSE_STATUS_ZERO_PIVOT";
1002: case HIPSPARSE_STATUS_NOT_SUPPORTED:
1003: return "HIPSPARSE_STATUS_NOT_SUPPORTED";
1004: case HIPSPARSE_STATUS_INSUFFICIENT_RESOURCES:
1005: return "HIPSPARSE_STATUS_INSUFFICIENT_RESOURCES";
1006: default:
1007: return "unknown error";
1008: }
1009: }
1010: PETSC_EXTERN const char *PetscHIPSolverGetErrorName(hipsolverStatus_t status)
1011: {
1012: switch (status) {
1013: case HIPSOLVER_STATUS_SUCCESS:
1014: return "HIPSOLVER_STATUS_SUCCESS";
1015: case HIPSOLVER_STATUS_NOT_INITIALIZED:
1016: return "HIPSOLVER_STATUS_NOT_INITIALIZED";
1017: case HIPSOLVER_STATUS_ALLOC_FAILED:
1018: return "HIPSOLVER_STATUS_ALLOC_FAILED";
1019: case HIPSOLVER_STATUS_MAPPING_ERROR:
1020: return "HIPSOLVER_STATUS_MAPPING_ERROR";
1021: case HIPSOLVER_STATUS_INVALID_VALUE:
1022: return "HIPSOLVER_STATUS_INVALID_VALUE";
1023: case HIPSOLVER_STATUS_EXECUTION_FAILED:
1024: return "HIPSOLVER_STATUS_EXECUTION_FAILED";
1025: case HIPSOLVER_STATUS_INTERNAL_ERROR:
1026: return "HIPSOLVER_STATUS_INTERNAL_ERROR";
1027: case HIPSOLVER_STATUS_NOT_SUPPORTED:
1028: return "HIPSOLVER_STATUS_NOT_SUPPORTED ";
1029: case HIPSOLVER_STATUS_ARCH_MISMATCH:
1030: return "HIPSOLVER_STATUS_ARCH_MISMATCH";
1031: case HIPSOLVER_STATUS_HANDLE_IS_NULLPTR:
1032: return "HIPSOLVER_STATUS_HANDLE_IS_NULLPTR";
1033: case HIPSOLVER_STATUS_INVALID_ENUM:
1034: return "HIPSOLVER_STATUS_INVALID_ENUM";
1035: case HIPSOLVER_STATUS_UNKNOWN:
1036: default:
1037: return "HIPSOLVER_STATUS_UNKNOWN";
1038: }
1039: }
1040: #endif
1042: /*@C
1043: PetscMPIErrorString - Given an MPI error code returns the `MPI_Error_string()` appropriately
1044: formatted for displaying with the PETSc error handlers.
1046: Not Collective, No Fortran Support
1048: Input Parameters:
1049: + err - the MPI error code
1050: - slen - length of `string`, should be at least as large as `MPI_MAX_ERROR_STRING`
1052: Output Parameter:
1053: . string - the MPI error message
1055: Level: developer
1057: Note:
1058: Does not return an error code or do error handling because it may be called from inside an error handler
1060: .seealso: `PetscErrorCode` `PetscErrorMessage()`
1061: @*/
1062: void PetscMPIErrorString(PetscMPIInt err, size_t slen, char *string)
1063: {
1064: char errorstring[MPI_MAX_ERROR_STRING];
1065: PetscMPIInt len;
1066: size_t j = 0;
1068: MPI_Error_string(err, (char *)errorstring, &len);
1069: for (PetscMPIInt i = 0; i < len && j < slen - 2; i++) {
1070: string[j++] = errorstring[i];
1071: if (errorstring[i] == '\n') {
1072: for (PetscMPIInt k = 0; k < 16 && j < slen - 2; k++) string[j++] = ' ';
1073: }
1074: }
1075: string[j] = 0;
1076: }