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