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