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