Actual source code: err.c
2: /*
3: Code that allows one to set the error handlers
4: Portions of this code are under:
5: Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
6: */
7: #include <petsc/private/petscimpl.h>
8: #include <petscviewer.h>
10: typedef struct _EH *EH;
11: struct _EH {
12: PetscErrorCode (*handler)(MPI_Comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *);
13: void *ctx;
14: EH previous;
15: };
17: static EH eh = NULL;
19: /*@C
20: PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
21: load the file where the error occurred. Then calls the "previous" error handler.
23: Not Collective
25: Input Parameters:
26: + comm - communicator over which error occurred
27: . line - the line number of the error (indicated by __LINE__)
28: . file - the file in which the error was detected (indicated by __FILE__)
29: . mess - an error text string, usually just printed to the screen
30: . n - the generic error number
31: . p - specific error number
32: - ctx - error handler context
34: Options Database Key:
35: . -on_error_emacs <machinename> - will contact machinename to open the Emacs client there
37: Level: developer
39: Note:
40: You must put (server-start) in your .emacs file for the emacsclient software to work
42: Developer Note:
43: Since this is an error handler it cannot call `PetscCall()`; thus we just return if an error is detected.
44: But some of the functions it calls do perform error checking that may not be appropriate in a error handler call.
46: .seealso: `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`,
47: `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscReturnErrorHandler()`
48: @*/
49: PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx)
50: {
51: PetscErrorCode ierr;
52: char command[PETSC_MAX_PATH_LEN];
53: const char *pdir;
54: FILE *fp;
56: ierr = PetscGetPetscDir(&pdir);
57: if (ierr) return ierr;
58: ierr = PetscSNPrintf(command, PETSC_STATIC_ARRAY_LENGTH(command), "cd %s; emacsclient --no-wait +%d %s\n", pdir, line, file);
59: if (ierr) return ierr;
60: #if defined(PETSC_HAVE_POPEN)
61: ierr = PetscPOpen(MPI_COMM_WORLD, (char *)ctx, command, "r", &fp);
62: if (ierr) return ierr;
63: ierr = PetscPClose(MPI_COMM_WORLD, fp);
64: if (ierr) return ierr;
65: #else
66: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine");
67: #endif
68: ierr = PetscPopErrorHandler();
69: if (ierr) return ierr; /* remove this handler from the stack of handlers */
70: if (!eh) {
71: ierr = PetscTraceBackErrorHandler(comm, line, fun, file, n, p, mess, NULL);
72: if (ierr) return ierr;
73: } else {
74: ierr = (*eh->handler)(comm, line, fun, file, n, p, mess, eh->ctx);
75: if (ierr) return ierr;
76: }
77: return PETSC_SUCCESS;
78: }
80: /*@C
81: PetscPushErrorHandler - Sets a routine to be called on detection of errors.
83: Not Collective
85: Input Parameters:
86: + handler - error handler routine
87: - ctx - optional handler context that contains information needed by the handler (for
88: example file pointers for error messages etc.)
90: Calling sequence of handler:
91: $ int handler(MPI_Comm comm,int line,char *func,char *file,PetscErrorCode n,int p,char *mess,void *ctx);
93: + comm - communicator over which error occurred
94: . line - the line number of the error (indicated by __LINE__)
95: . file - the file in which the error was detected (indicated by __FILE__)
96: . n - the generic error number (see list defined in include/petscerror.h)
97: . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
98: . mess - an error text string, usually just printed to the screen
99: - ctx - the error handler context
101: Options Database Keys:
102: + -on_error_attach_debugger <noxterm,gdb or dbx> - starts up the debugger if an error occurs
103: - -on_error_abort - aborts the program if an error occurs
105: Level: intermediate
107: Note:
108: The currently available PETSc error handlers include `PetscTraceBackErrorHandler()`,
109: `PetscAttachDebuggerErrorHandler()`, `PetscAbortErrorHandler()`, and `PetscMPIAbortErrorHandler()`, `PetscReturnErrorHandler()`.
111: Fortran Note:
112: You can only push one error handler from Fortran before poping it.
114: .seealso: `PetscPopErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscAbortErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscPushSignalHandler()`
115: @*/
116: PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm comm, int, const char *, const char *, PetscErrorCode, PetscErrorType, const char *, void *), void *ctx)
117: {
118: EH neweh;
120: PetscFunctionBegin;
121: PetscCall(PetscNew(&neweh));
122: if (eh) neweh->previous = eh;
123: else neweh->previous = NULL;
124: neweh->handler = handler;
125: neweh->ctx = ctx;
126: eh = neweh;
127: PetscFunctionReturn(PETSC_SUCCESS);
128: }
130: /*@
131: PetscPopErrorHandler - Removes the latest error handler that was
132: pushed with `PetscPushErrorHandler()`.
134: Not Collective
136: Level: intermediate
138: .seealso: `PetscPushErrorHandler()`
139: @*/
140: PetscErrorCode PetscPopErrorHandler(void)
141: {
142: EH tmp;
144: PetscFunctionBegin;
145: if (!eh) PetscFunctionReturn(PETSC_SUCCESS);
146: tmp = eh;
147: eh = eh->previous;
148: PetscCall(PetscFree(tmp));
149: PetscFunctionReturn(PETSC_SUCCESS);
150: }
152: /*@C
153: PetscReturnErrorHandler - Error handler that causes a return without printing an error message.
155: Not Collective
157: Input Parameters:
158: + comm - communicator over which error occurred
159: . line - the line number of the error (indicated by __LINE__)
160: . file - the file in which the error was detected (indicated by __FILE__)
161: . mess - an error text string, usually just printed to the screen
162: . n - the generic error number
163: . p - specific error number
164: - ctx - error handler context
166: Level: developer
168: Notes:
169: Most users need not directly employ this routine and the other error
170: handlers, but can instead use the simplified interface `SETERRQ()`, which has
171: the calling sequence
172: $ SETERRQ(comm,number,mess)
174: `PetscIgnoreErrorHandler()` does the same thing as this function, but is deprecated, you should use this function.
176: Use `PetscPushErrorHandler()` to set the desired error handler.
178: .seealso: `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscError()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscTraceBackErrorHandler()`,
179: `PetscAttachDebuggerErrorHandler()`, `PetscEmacsClientErrorHandler()`
180: @*/
181: PetscErrorCode PetscReturnErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx)
182: {
183: return n;
184: }
186: static char PetscErrorBaseMessage[1024];
187: /*
188: The numerical values for these are defined in include/petscerror.h; any changes
189: there must also be made here
190: */
191: static const char *PetscErrorStrings[] = {
192: /*55 */ "Out of memory",
193: "No support for this operation for this object type",
194: "No support for this operation on this system",
195: /*58 */ "Operation done in wrong order",
196: /*59 */ "Signal received",
197: /*60 */ "Nonconforming object sizes",
198: "Argument aliasing not permitted",
199: "Invalid argument",
200: /*63 */ "Argument out of range",
201: "Corrupt argument: https://petsc.org/release/faq/#valgrind",
202: "Unable to open file",
203: "Read from file failed",
204: "Write to file failed",
205: "Invalid pointer",
206: /*69 */ "Arguments must have same type",
207: /*70 */ "Attempt to use a pointer that does not point to a valid accessible location",
208: /*71 */ "Zero pivot in LU factorization: https://petsc.org/release/faq/#zeropivot",
209: /*72 */ "Floating point exception",
210: /*73 */ "Object is in wrong state",
211: "Corrupted Petsc object",
212: "Arguments are incompatible",
213: "Error in external library",
214: /*77 */ "Petsc has generated inconsistent data",
215: "Memory corruption: https://petsc.org/release/faq/#valgrind",
216: "Unexpected data in file",
217: /*80 */ "Arguments must have same communicators",
218: /*81 */ "Zero pivot in Cholesky factorization: https://petsc.org/release/faq/#zeropivot",
219: "",
220: "",
221: "Overflow in integer operation: https://petsc.org/release/faq/#64-bit-indices",
222: /*85 */ "Null argument, when expecting valid pointer",
223: /*86 */ "Unknown type. Check for miss-spelling or missing package: https://petsc.org/release/install/install/#external-packages",
224: /*87 */ "MPI library at runtime is not compatible with MPI used at compile time",
225: /*88 */ "Error in system call",
226: /*89 */ "Object Type not set: https://petsc.org/release/faq/#object-type-not-set",
227: /*90 */ "",
228: /* */ "",
229: /*92 */ "See https://petsc.org/release/overview/linear_solve_table/ for possible LU and Cholesky solvers",
230: /*93 */ "You cannot overwrite this option since that will conflict with other previously set options",
231: /*94 */ "Example/application run with number of MPI ranks it does not support",
232: /*95 */ "Missing or incorrect user input",
233: /*96 */ "GPU resources unavailable",
234: /*97 */ "GPU error",
235: /*98 */ "General MPI error",
236: /*99 */ "PetscError() incorrectly returned an error code of 0"};
238: /*@C
239: PetscErrorMessage - Returns the text string associated with a PETSc error code.
241: Not Collective
243: Input Parameter:
244: . errnum - the error code
246: Output Parameters:
247: + text - the error message (`NULL` if not desired)
248: - specific - the specific error message that was set with `SETERRQ()` or
249: `PetscError()`. (`NULL` if not desired)
251: Level: developer
253: .seealso: `PetscErrorCode`, `PetscPushErrorHandler()`, `PetscAttachDebuggerErrorHandler()`,
254: `PetscError()`, `SETERRQ()`, `PetscCall()` `PetscAbortErrorHandler()`,
255: `PetscTraceBackErrorHandler()`
256: @*/
257: PetscErrorCode PetscErrorMessage(PetscErrorCode errnum, const char *text[], char **specific)
258: {
259: PetscFunctionBegin;
260: if (text) {
261: if (errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) {
262: size_t len;
264: *text = PetscErrorStrings[errnum - PETSC_ERR_MIN_VALUE - 1];
265: PetscCall(PetscStrlen(*text, &len));
266: if (!len) *text = NULL;
267: } else if (errnum == PETSC_ERR_BOOLEAN_MACRO_FAILURE) {
268: /* this "error code" arises from failures in boolean macros, where the || operator is
269: used to short-circuit the macro call in case of error. This has the side effect of
270: "returning" either 0 (PETSC_SUCCESS) or 1 (PETSC_ERR_UNKNONWN):
272: #define PETSC_FOO(x) ((PetscErrorCode)(PetscBar(x) || PetscBaz(x)))
274: If PetscBar() fails (returns nonzero) PetscBaz() is not executed but the result of
275: this expression is boolean false, hence PETSC_ERR_UNNOWN
276: */
277: *text = "Error occurred in boolean shortcuit in macro";
278: } else {
279: *text = NULL;
280: }
281: }
282: if (specific) *specific = PetscErrorBaseMessage;
283: PetscFunctionReturn(PETSC_SUCCESS);
284: }
286: #if defined(PETSC_CLANGUAGE_CXX)
287: /* C++ exceptions are formally not allowed to propagate through extern "C" code. In practice, far too much software
288: * would be broken if implementations did not handle it it some common cases. However, keep in mind
289: *
290: * Rule 62. Don't allow exceptions to propagate across module boundaries
291: *
292: * in "C++ Coding Standards" by Sutter and Alexandrescu. (This accounts for part of the ongoing C++ binary interface
293: * instability.) Having PETSc raise errors as C++ exceptions was probably misguided and should eventually be removed.
294: *
295: * Here is the problem: You have a C++ function call a PETSc function, and you would like to maintain the error message
296: * and stack information from the PETSc error. You could make everyone write exactly this code in their C++, but that
297: * seems crazy to me.
298: */
299: #include <sstream>
300: #include <stdexcept>
301: static void PetscCxxErrorThrow()
302: {
303: const char *str;
304: if (eh && eh->ctx) {
305: std::ostringstream *msg;
306: msg = (std::ostringstream *)eh->ctx;
307: str = msg->str().c_str();
308: } else str = "Error detected in C PETSc";
310: throw std::runtime_error(str);
311: }
312: #endif
314: /*@C
315: PetscError - Routine that is called when an error has been detected, usually called through the macro SETERRQ(PETSC_COMM_SELF,).
317: Collective
319: Input Parameters:
320: + comm - communicator over which error occurred. ALL ranks of this communicator MUST call this routine
321: . line - the line number of the error (indicated by __LINE__)
322: . func - the function name in which the error was detected
323: . file - the file in which the error was detected (indicated by __FILE__)
324: . n - the generic error number
325: . p - `PETSC_ERROR_INITIAL` indicates the error was initially detected, `PETSC_ERROR_REPEAT` indicates this is a traceback from a previously detected error
326: - mess - formatted message string - aka printf
328: Options Database Keys:
329: + -error_output_stdout - output the error messages to stdout instead of the default stderr
330: - -error_output_none - do not output the error messages
332: Level: intermediate
334: Notes:
335: PETSc error handling is done with error return codes. A non-zero return indicates an error
336: was detected. The return-value of this routine is what is ultimately returned by
337: `SETERRQ()`.
339: Note that numerical errors (potential divide by zero, for example) are not managed by the
340: error return codes; they are managed via, for example, `KSPGetConvergedReason()` that
341: indicates if the solve was successful or not. The option `-ksp_error_if_not_converged`, for
342: example, turns numerical failures into hard errors managed via `PetscError()`.
344: PETSc provides a rich supply of error handlers, see the list below, and users can also
345: provide their own error handlers.
347: If the user sets their own error handler (via `PetscPushErrorHandler()`) they may return any
348: arbitrary value from it, but are encouraged to return nonzero values. If the return value is
349: zero, `SETERRQ()` will ignore the value and return `PETSC_ERR_RETURN` (a nonzero value)
350: instead.
352: Most users need not directly use this routine and the error handlers, but can instead use
353: the simplified interface `PetscCall()` or `SETERRQ()`.
355: Fortran Note:
356: This routine is used differently from Fortran
357: $ PetscError(MPI_Comm comm,PetscErrorCode n,PetscErrorType p,char *message)
359: Developer Note:
360: Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes)
361: 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
362: but this annoying.
364: .seealso: `PetscErrorCode`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`, `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`,
365: `PetscReturnErrorHandler()`, `PetscAttachDebuggerErrorHandler()`, `PetscEmacsClientErrorHandler()`,
366: `SETERRQ()`, `PetscCall()`, `CHKMEMQ`, `SETERRQ()`, `SETERRQ()`, `PetscErrorMessage()`, `PETSCABORT()`
367: @*/
368: PetscErrorCode PetscError(MPI_Comm comm, int line, const char *func, const char *file, PetscErrorCode n, PetscErrorType p, const char *mess, ...)
369: {
370: va_list Argp;
371: size_t fullLength;
372: char buf[2048], *lbuf = NULL;
373: PetscBool ismain;
374: PetscErrorCode ierr;
376: if (!PetscErrorHandlingInitialized) return n;
377: if (comm == MPI_COMM_NULL) comm = PETSC_COMM_SELF;
379: /* Compose the message evaluating the print format */
380: if (mess) {
381: va_start(Argp, mess);
382: ierr = PetscVSNPrintf(buf, 2048, mess, &fullLength, Argp);
383: va_end(Argp);
384: lbuf = buf;
385: if (p == PETSC_ERROR_INITIAL) ierr = PetscStrncpy(PetscErrorBaseMessage, lbuf, sizeof(PetscErrorBaseMessage));
386: }
388: if (p == PETSC_ERROR_INITIAL && n != PETSC_ERR_MEMC) ierr = PetscMallocValidate(__LINE__, PETSC_FUNCTION_NAME, __FILE__);
390: if (!eh) ierr = PetscTraceBackErrorHandler(comm, line, func, file, n, p, lbuf, NULL);
391: else ierr = (*eh->handler)(comm, line, func, file, n, p, lbuf, eh->ctx);
392: PetscStackClearTop;
394: /*
395: If this is called from the main() routine we call MPI_Abort() instead of
396: return to allow the parallel program to be properly shutdown.
398: Does not call PETSCABORT() since that would provide the wrong source file and line number information
399: */
400: if (func) {
401: PetscErrorCode cmp_ierr = PetscStrncmp(func, "main", 4, &ismain);
402: if (ismain) {
403: if (petscwaitonerrorflg) cmp_ierr = PetscSleep(1000);
404: (void)cmp_ierr;
405: PETSCABORT(comm, ierr);
406: }
407: }
408: #if defined(PETSC_CLANGUAGE_CXX)
409: if (p == PETSC_ERROR_IN_CXX) PetscCxxErrorThrow();
410: #endif
411: return ierr;
412: }
414: /* -------------------------------------------------------------------------*/
416: /*@C
417: PetscIntView - Prints an array of integers; useful for debugging.
419: Collective
421: Input Parameters:
422: + N - number of integers in array
423: . idx - array of integers
424: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
426: Level: intermediate
428: Note:
429: This may be called from within the debugger
431: Developer Note:
432: idx cannot be const because may be passed to binary viewer where temporary byte swapping may be done
434: .seealso: `PetscViewer`, `PetscRealView()`
435: @*/
436: PetscErrorCode PetscIntView(PetscInt N, const PetscInt idx[], PetscViewer viewer)
437: {
438: PetscMPIInt rank, size;
439: PetscInt j, i, n = N / 20, p = N % 20;
440: PetscBool iascii, isbinary;
441: MPI_Comm comm;
443: PetscFunctionBegin;
444: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
447: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
448: PetscCallMPI(MPI_Comm_size(comm, &size));
449: PetscCallMPI(MPI_Comm_rank(comm, &rank));
451: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
452: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
453: if (iascii) {
454: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
455: for (i = 0; i < n; i++) {
456: if (size > 1) {
457: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, 20 * i));
458: } else {
459: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", 20 * i));
460: }
461: for (j = 0; j < 20; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[i * 20 + j]));
462: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
463: }
464: if (p) {
465: if (size > 1) {
466: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, 20 * n));
467: } else {
468: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", 20 * n));
469: }
470: for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[20 * n + i]));
471: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
472: }
473: PetscCall(PetscViewerFlush(viewer));
474: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
475: } else if (isbinary) {
476: PetscMPIInt *sizes, Ntotal, *displs, NN;
477: PetscInt *array;
479: PetscCall(PetscMPIIntCast(N, &NN));
481: if (size > 1) {
482: if (rank) {
483: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
484: PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_INT, NULL, NULL, NULL, MPIU_INT, 0, comm));
485: } else {
486: PetscCall(PetscMalloc1(size, &sizes));
487: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
488: Ntotal = sizes[0];
489: PetscCall(PetscMalloc1(size, &displs));
490: displs[0] = 0;
491: for (i = 1; i < size; i++) {
492: Ntotal += sizes[i];
493: displs[i] = displs[i - 1] + sizes[i - 1];
494: }
495: PetscCall(PetscMalloc1(Ntotal, &array));
496: PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_INT, array, sizes, displs, MPIU_INT, 0, comm));
497: PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_INT));
498: PetscCall(PetscFree(sizes));
499: PetscCall(PetscFree(displs));
500: PetscCall(PetscFree(array));
501: }
502: } else {
503: PetscCall(PetscViewerBinaryWrite(viewer, idx, N, PETSC_INT));
504: }
505: } else {
506: const char *tname;
507: PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
508: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
509: }
510: PetscFunctionReturn(PETSC_SUCCESS);
511: }
513: /*@C
514: PetscRealView - Prints an array of doubles; useful for debugging.
516: Collective
518: Input Parameters:
519: + N - number of `PetscReal` in array
520: . idx - array of `PetscReal`
521: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
523: Level: intermediate
525: Note:
526: This may be called from within the debugger
528: Developer Note:
529: idx cannot be const because may be passed to binary viewer where temporary byte swapping may be done
531: .seealso: `PetscViewer`, `PetscIntView()`
532: @*/
533: PetscErrorCode PetscRealView(PetscInt N, const PetscReal idx[], PetscViewer viewer)
534: {
535: PetscMPIInt rank, size;
536: PetscInt j, i, n = N / 5, p = N % 5;
537: PetscBool iascii, isbinary;
538: MPI_Comm comm;
540: PetscFunctionBegin;
541: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
544: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
545: PetscCallMPI(MPI_Comm_size(comm, &size));
546: PetscCallMPI(MPI_Comm_rank(comm, &rank));
548: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
549: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
550: if (iascii) {
551: PetscInt tab;
553: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
554: PetscCall(PetscViewerASCIIGetTab(viewer, &tab));
555: for (i = 0; i < n; i++) {
556: PetscCall(PetscViewerASCIISetTab(viewer, tab));
557: if (size > 1) {
558: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 5 * i));
559: } else {
560: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 5 * i));
561: }
562: PetscCall(PetscViewerASCIISetTab(viewer, 0));
563: for (j = 0; j < 5; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * 5 + j]));
564: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
565: }
566: if (p) {
567: PetscCall(PetscViewerASCIISetTab(viewer, tab));
568: if (size > 1) {
569: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 5 * n));
570: } else {
571: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 5 * n));
572: }
573: PetscCall(PetscViewerASCIISetTab(viewer, 0));
574: for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[5 * n + i]));
575: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
576: }
577: PetscCall(PetscViewerFlush(viewer));
578: PetscCall(PetscViewerASCIISetTab(viewer, tab));
579: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
580: } else if (isbinary) {
581: PetscMPIInt *sizes, *displs, Ntotal, NN;
582: PetscReal *array;
584: PetscCall(PetscMPIIntCast(N, &NN));
586: if (size > 1) {
587: if (rank) {
588: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
589: PetscCallMPI(MPI_Gatherv((PetscReal *)idx, NN, MPIU_REAL, NULL, NULL, NULL, MPIU_REAL, 0, comm));
590: } else {
591: PetscCall(PetscMalloc1(size, &sizes));
592: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
593: Ntotal = sizes[0];
594: PetscCall(PetscMalloc1(size, &displs));
595: displs[0] = 0;
596: for (i = 1; i < size; i++) {
597: Ntotal += sizes[i];
598: displs[i] = displs[i - 1] + sizes[i - 1];
599: }
600: PetscCall(PetscMalloc1(Ntotal, &array));
601: PetscCallMPI(MPI_Gatherv((PetscReal *)idx, NN, MPIU_REAL, array, sizes, displs, MPIU_REAL, 0, comm));
602: PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_REAL));
603: PetscCall(PetscFree(sizes));
604: PetscCall(PetscFree(displs));
605: PetscCall(PetscFree(array));
606: }
607: } else {
608: PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_REAL));
609: }
610: } else {
611: const char *tname;
612: PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
613: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
614: }
615: PetscFunctionReturn(PETSC_SUCCESS);
616: }
618: /*@C
619: PetscScalarView - Prints an array of `PetscScalar`; useful for debugging.
621: Collective
623: Input Parameters:
624: + N - number of scalars in array
625: . idx - array of scalars
626: - viewer - location to print array, `PETSC_VIEWER_STDOUT_WORLD`, `PETSC_VIEWER_STDOUT_SELF` or 0
628: Level: intermediate
630: Note:
631: This may be called from within the debugger
633: Developer Note:
634: idx cannot be const because may be passed to binary viewer where byte swapping may be done
636: .seealso: `PetscViewer`, `PetscIntView()`, `PetscRealView()`
637: @*/
638: PetscErrorCode PetscScalarView(PetscInt N, const PetscScalar idx[], PetscViewer viewer)
639: {
640: PetscMPIInt rank, size;
641: PetscInt j, i, n = N / 3, p = N % 3;
642: PetscBool iascii, isbinary;
643: MPI_Comm comm;
645: PetscFunctionBegin;
646: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
649: PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
650: PetscCallMPI(MPI_Comm_size(comm, &size));
651: PetscCallMPI(MPI_Comm_rank(comm, &rank));
653: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
654: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
655: if (iascii) {
656: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
657: for (i = 0; i < n; i++) {
658: if (size > 1) {
659: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 3 * i));
660: } else {
661: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 3 * i));
662: }
663: for (j = 0; j < 3; j++) {
664: #if defined(PETSC_USE_COMPLEX)
665: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[i * 3 + j]), (double)PetscImaginaryPart(idx[i * 3 + j])));
666: #else
667: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * 3 + j]));
668: #endif
669: }
670: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
671: }
672: if (p) {
673: if (size > 1) {
674: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, 3 * n));
675: } else {
676: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", 3 * n));
677: }
678: for (i = 0; i < p; i++) {
679: #if defined(PETSC_USE_COMPLEX)
680: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[n * 3 + i]), (double)PetscImaginaryPart(idx[n * 3 + i])));
681: #else
682: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[3 * n + i]));
683: #endif
684: }
685: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
686: }
687: PetscCall(PetscViewerFlush(viewer));
688: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
689: } else if (isbinary) {
690: PetscMPIInt *sizes, Ntotal, *displs, NN;
691: PetscScalar *array;
693: PetscCall(PetscMPIIntCast(N, &NN));
695: if (size > 1) {
696: if (rank) {
697: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
698: PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, NULL, NULL, NULL, MPIU_SCALAR, 0, comm));
699: } else {
700: PetscCall(PetscMalloc1(size, &sizes));
701: PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
702: Ntotal = sizes[0];
703: PetscCall(PetscMalloc1(size, &displs));
704: displs[0] = 0;
705: for (i = 1; i < size; i++) {
706: Ntotal += sizes[i];
707: displs[i] = displs[i - 1] + sizes[i - 1];
708: }
709: PetscCall(PetscMalloc1(Ntotal, &array));
710: PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, array, sizes, displs, MPIU_SCALAR, 0, comm));
711: PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_SCALAR));
712: PetscCall(PetscFree(sizes));
713: PetscCall(PetscFree(displs));
714: PetscCall(PetscFree(array));
715: }
716: } else {
717: PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_SCALAR));
718: }
719: } else {
720: const char *tname;
721: PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
722: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
723: }
724: PetscFunctionReturn(PETSC_SUCCESS);
725: }
727: #if defined(PETSC_HAVE_CUDA)
728: #include <petscdevice_cuda.h>
729: PETSC_EXTERN const char *PetscCUBLASGetErrorName(cublasStatus_t status)
730: {
731: switch (status) {
732: #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
733: case CUBLAS_STATUS_SUCCESS:
734: return "CUBLAS_STATUS_SUCCESS";
735: case CUBLAS_STATUS_NOT_INITIALIZED:
736: return "CUBLAS_STATUS_NOT_INITIALIZED";
737: case CUBLAS_STATUS_ALLOC_FAILED:
738: return "CUBLAS_STATUS_ALLOC_FAILED";
739: case CUBLAS_STATUS_INVALID_VALUE:
740: return "CUBLAS_STATUS_INVALID_VALUE";
741: case CUBLAS_STATUS_ARCH_MISMATCH:
742: return "CUBLAS_STATUS_ARCH_MISMATCH";
743: case CUBLAS_STATUS_MAPPING_ERROR:
744: return "CUBLAS_STATUS_MAPPING_ERROR";
745: case CUBLAS_STATUS_EXECUTION_FAILED:
746: return "CUBLAS_STATUS_EXECUTION_FAILED";
747: case CUBLAS_STATUS_INTERNAL_ERROR:
748: return "CUBLAS_STATUS_INTERNAL_ERROR";
749: case CUBLAS_STATUS_NOT_SUPPORTED:
750: return "CUBLAS_STATUS_NOT_SUPPORTED";
751: case CUBLAS_STATUS_LICENSE_ERROR:
752: return "CUBLAS_STATUS_LICENSE_ERROR";
753: #endif
754: default:
755: return "unknown error";
756: }
757: }
758: PETSC_EXTERN const char *PetscCUSolverGetErrorName(cusolverStatus_t status)
759: {
760: switch (status) {
761: #if (CUDART_VERSION >= 8000) /* At least CUDA 8.0 of Sep. 2016 had these */
762: case CUSOLVER_STATUS_SUCCESS:
763: return "CUSOLVER_STATUS_SUCCESS";
764: case CUSOLVER_STATUS_NOT_INITIALIZED:
765: return "CUSOLVER_STATUS_NOT_INITIALIZED";
766: case CUSOLVER_STATUS_INVALID_VALUE:
767: return "CUSOLVER_STATUS_INVALID_VALUE";
768: case CUSOLVER_STATUS_ARCH_MISMATCH:
769: return "CUSOLVER_STATUS_ARCH_MISMATCH";
770: case CUSOLVER_STATUS_INTERNAL_ERROR:
771: return "CUSOLVER_STATUS_INTERNAL_ERROR";
772: #if (CUDART_VERSION >= 9000) /* CUDA 9.0 had these defined on June 2021 */
773: case CUSOLVER_STATUS_ALLOC_FAILED:
774: return "CUSOLVER_STATUS_ALLOC_FAILED";
775: case CUSOLVER_STATUS_MAPPING_ERROR:
776: return "CUSOLVER_STATUS_MAPPING_ERROR";
777: case CUSOLVER_STATUS_EXECUTION_FAILED:
778: return "CUSOLVER_STATUS_EXECUTION_FAILED";
779: case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
780: return "CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
781: case CUSOLVER_STATUS_NOT_SUPPORTED:
782: return "CUSOLVER_STATUS_NOT_SUPPORTED ";
783: case CUSOLVER_STATUS_ZERO_PIVOT:
784: return "CUSOLVER_STATUS_ZERO_PIVOT";
785: case CUSOLVER_STATUS_INVALID_LICENSE:
786: return "CUSOLVER_STATUS_INVALID_LICENSE";
787: #endif
788: #endif
789: default:
790: return "unknown error";
791: }
792: }
793: PETSC_EXTERN const char *PetscCUFFTGetErrorName(cufftResult result)
794: {
795: switch (result) {
796: case CUFFT_SUCCESS:
797: return "CUFFT_SUCCESS";
798: case CUFFT_INVALID_PLAN:
799: return "CUFFT_INVALID_PLAN";
800: case CUFFT_ALLOC_FAILED:
801: return "CUFFT_ALLOC_FAILED";
802: case CUFFT_INVALID_TYPE:
803: return "CUFFT_INVALID_TYPE";
804: case CUFFT_INVALID_VALUE:
805: return "CUFFT_INVALID_VALUE";
806: case CUFFT_INTERNAL_ERROR:
807: return "CUFFT_INTERNAL_ERROR";
808: case CUFFT_EXEC_FAILED:
809: return "CUFFT_EXEC_FAILED";
810: case CUFFT_SETUP_FAILED:
811: return "CUFFT_SETUP_FAILED";
812: case CUFFT_INVALID_SIZE:
813: return "CUFFT_INVALID_SIZE";
814: case CUFFT_UNALIGNED_DATA:
815: return "CUFFT_UNALIGNED_DATA";
816: case CUFFT_INCOMPLETE_PARAMETER_LIST:
817: return "CUFFT_INCOMPLETE_PARAMETER_LIST";
818: case CUFFT_INVALID_DEVICE:
819: return "CUFFT_INVALID_DEVICE";
820: case CUFFT_PARSE_ERROR:
821: return "CUFFT_PARSE_ERROR";
822: case CUFFT_NO_WORKSPACE:
823: return "CUFFT_NO_WORKSPACE";
824: case CUFFT_NOT_IMPLEMENTED:
825: return "CUFFT_NOT_IMPLEMENTED";
826: case CUFFT_LICENSE_ERROR:
827: return "CUFFT_LICENSE_ERROR";
828: case CUFFT_NOT_SUPPORTED:
829: return "CUFFT_NOT_SUPPORTED";
830: default:
831: return "unknown error";
832: }
833: }
834: #endif
836: #if defined(PETSC_HAVE_HIP)
837: #include <petscdevice_hip.h>
838: PETSC_EXTERN const char *PetscHIPBLASGetErrorName(hipblasStatus_t status)
839: {
840: switch (status) {
841: case HIPBLAS_STATUS_SUCCESS:
842: return "HIPBLAS_STATUS_SUCCESS";
843: case HIPBLAS_STATUS_NOT_INITIALIZED:
844: return "HIPBLAS_STATUS_NOT_INITIALIZED";
845: case HIPBLAS_STATUS_ALLOC_FAILED:
846: return "HIPBLAS_STATUS_ALLOC_FAILED";
847: case HIPBLAS_STATUS_INVALID_VALUE:
848: return "HIPBLAS_STATUS_INVALID_VALUE";
849: case HIPBLAS_STATUS_ARCH_MISMATCH:
850: return "HIPBLAS_STATUS_ARCH_MISMATCH";
851: case HIPBLAS_STATUS_MAPPING_ERROR:
852: return "HIPBLAS_STATUS_MAPPING_ERROR";
853: case HIPBLAS_STATUS_EXECUTION_FAILED:
854: return "HIPBLAS_STATUS_EXECUTION_FAILED";
855: case HIPBLAS_STATUS_INTERNAL_ERROR:
856: return "HIPBLAS_STATUS_INTERNAL_ERROR";
857: case HIPBLAS_STATUS_NOT_SUPPORTED:
858: return "HIPBLAS_STATUS_NOT_SUPPORTED";
859: default:
860: return "unknown error";
861: }
862: }
863: PETSC_EXTERN const char *PetscHIPSPARSEGetErrorName(hipsparseStatus_t status)
864: {
865: switch (status) {
866: case HIPSPARSE_STATUS_SUCCESS:
867: return "HIPSPARSE_STATUS_SUCCESS";
868: case HIPSPARSE_STATUS_NOT_INITIALIZED:
869: return "HIPSPARSE_STATUS_NOT_INITIALIZED";
870: case HIPSPARSE_STATUS_ALLOC_FAILED:
871: return "HIPSPARSE_STATUS_ALLOC_FAILED";
872: case HIPSPARSE_STATUS_INVALID_VALUE:
873: return "HIPSPARSE_STATUS_INVALID_VALUE";
874: case HIPSPARSE_STATUS_ARCH_MISMATCH:
875: return "HIPSPARSE_STATUS_ARCH_MISMATCH";
876: case HIPSPARSE_STATUS_MAPPING_ERROR:
877: return "HIPSPARSE_STATUS_MAPPING_ERROR";
878: case HIPSPARSE_STATUS_EXECUTION_FAILED:
879: return "HIPSPARSE_STATUS_EXECUTION_FAILED";
880: case HIPSPARSE_STATUS_INTERNAL_ERROR:
881: return "HIPSPARSE_STATUS_INTERNAL_ERROR";
882: case HIPSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
883: return "HIPSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
884: case HIPSPARSE_STATUS_ZERO_PIVOT:
885: return "HIPSPARSE_STATUS_ZERO_PIVOT";
886: case HIPSPARSE_STATUS_NOT_SUPPORTED:
887: return "HIPSPARSE_STATUS_NOT_SUPPORTED";
888: case HIPSPARSE_STATUS_INSUFFICIENT_RESOURCES:
889: return "HIPSPARSE_STATUS_INSUFFICIENT_RESOURCES";
890: default:
891: return "unknown error";
892: }
893: }
894: PETSC_EXTERN const char *PetscHIPSolverGetErrorName(hipsolverStatus_t status)
895: {
896: switch (status) {
897: case HIPSOLVER_STATUS_SUCCESS:
898: return "HIPSOLVER_STATUS_SUCCESS";
899: case HIPSOLVER_STATUS_NOT_INITIALIZED:
900: return "HIPSOLVER_STATUS_NOT_INITIALIZED";
901: case HIPSOLVER_STATUS_ALLOC_FAILED:
902: return "HIPSOLVER_STATUS_ALLOC_FAILED";
903: case HIPSOLVER_STATUS_MAPPING_ERROR:
904: return "HIPSOLVER_STATUS_MAPPING_ERROR";
905: case HIPSOLVER_STATUS_INVALID_VALUE:
906: return "HIPSOLVER_STATUS_INVALID_VALUE";
907: case HIPSOLVER_STATUS_EXECUTION_FAILED:
908: return "HIPSOLVER_STATUS_EXECUTION_FAILED";
909: case HIPSOLVER_STATUS_INTERNAL_ERROR:
910: return "HIPSOLVER_STATUS_INTERNAL_ERROR";
911: case HIPSOLVER_STATUS_NOT_SUPPORTED:
912: return "HIPSOLVER_STATUS_NOT_SUPPORTED ";
913: case HIPSOLVER_STATUS_ARCH_MISMATCH:
914: return "HIPSOLVER_STATUS_ARCH_MISMATCH";
915: case HIPSOLVER_STATUS_HANDLE_IS_NULLPTR:
916: return "HIPSOLVER_STATUS_HANDLE_IS_NULLPTR";
917: case HIPSOLVER_STATUS_INVALID_ENUM:
918: return "HIPSOLVER_STATUS_INVALID_ENUM";
919: case HIPSOLVER_STATUS_UNKNOWN:
920: default:
921: return "HIPSOLVER_STATUS_UNKNOWN";
922: }
923: }
924: #endif
926: /*@
927: PetscMPIErrorString - Given an MPI error code returns the `MPI_Error_string()` appropriately
928: formatted for displaying with the PETSc error handlers.
930: Input Parameter:
931: . err - the MPI error code
933: Output Parameter:
934: . string - the MPI error message, should declare its length to be larger than `MPI_MAX_ERROR_STRING`
936: Level: developer
938: Note:
939: Does not return an error code or do error handling because it may be called from inside an error handler
941: @*/
942: void PetscMPIErrorString(PetscMPIInt err, char *string)
943: {
944: char errorstring[MPI_MAX_ERROR_STRING];
945: PetscMPIInt len, j = 0;
947: MPI_Error_string(err, (char *)errorstring, &len);
948: for (PetscMPIInt i = 0; i < len; i++) {
949: string[j++] = errorstring[i];
950: if (errorstring[i] == '\n') {
951: for (PetscMPIInt k = 0; k < 16; k++) string[j++] = ' ';
952: }
953: }
954: string[j] = 0;
955: }