1 #define PETSC_DLL 2 /* 3 Code that allows one to set the error handlers 4 */ 5 #include "petsc.h" /*I "petsc.h" I*/ 6 #include "petscsys.h" 7 #include <stdarg.h> 8 #if defined(PETSC_HAVE_STDLIB_H) 9 #include <stdlib.h> 10 #endif 11 12 typedef struct _EH *EH; 13 struct _EH { 14 int cookie; 15 PetscErrorCode (*handler)(int,const char*,const char*,const char *,PetscErrorCode,int,const char*,void *); 16 void *ctx; 17 EH previous; 18 }; 19 20 static EH eh = 0; 21 22 #undef __FUNCT__ 23 #define __FUNCT__ "PetscEmacsClientErrorHandler" 24 /*@C 25 PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to 26 load the file where the error occured. Then calls the "previous" error handler. 27 28 Not Collective 29 30 Input Parameters: 31 + line - the line number of the error (indicated by __LINE__) 32 . func - the function where error is detected (indicated by __FUNCT__) 33 . file - the file in which the error was detected (indicated by __FILE__) 34 . dir - the directory of the file (indicated by __SDIR__) 35 . mess - an error text string, usually just printed to the screen 36 . n - the generic error number 37 . p - specific error number 38 - ctx - error handler context 39 40 Options Database Key: 41 . -on_error_emacs <machinename> 42 43 Level: developer 44 45 Notes: 46 You must put (server-start) in your .emacs file for the emacsclient software to work 47 48 Most users need not directly employ this routine and the other error 49 handlers, but can instead use the simplified interface SETERRQ, which has 50 the calling sequence 51 $ SETERRQ(number,p,mess) 52 53 Notes for experienced users: 54 Use PetscPushErrorHandler() to set the desired error handler. 55 56 Concepts: emacs^going to on error 57 Concepts: error handler^going to line in emacs 58 59 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 60 PetscAbortErrorHandler() 61 @*/ 62 PetscErrorCode PETSC_DLLEXPORT PetscEmacsClientErrorHandler(int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,void *ctx) 63 { 64 PetscErrorCode ierr; 65 char command[PETSC_MAX_PATH_LEN]; 66 const char *pdir; 67 FILE *fp; 68 69 PetscFunctionBegin; 70 /* Note: don't check error codes since this an error handler :-) */ 71 ierr = PetscGetPetscDir(&pdir);CHKERRQ(ierr); 72 sprintf(command,"emacsclient +%d %s/%s%s\n",line,pdir,dir,file); 73 #if defined(PETSC_HAVE_POPEN) 74 ierr = PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp); 75 ierr = PetscPClose(MPI_COMM_WORLD,fp); 76 #else 77 SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 78 #endif 79 ierr = PetscPopErrorHandler(); /* remove this handler from the stack of handlers */ 80 if (!eh) ierr = PetscTraceBackErrorHandler(line,fun,file,dir,n,p,mess,0); 81 else ierr = (*eh->handler)(line,fun,file,dir,n,p,mess,eh->ctx); 82 PetscFunctionReturn(ierr); 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "PetscPushErrorHandler" 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 $ int handler(int line,char *func,char *file,char *dir,PetscErrorCode n,int p,char *mess,void *ctx); 99 100 + func - the function where the error occured (indicated by __FUNCT__) 101 . line - the line number of the error (indicated by __LINE__) 102 . file - the file in which the error was detected (indicated by __FILE__) 103 . dir - the directory of the file (indicated by __SDIR__) 104 . n - the generic error number (see list defined in include/petscerror.h) 105 . p - the specific error number 106 . mess - an error text string, usually just printed to the screen 107 - ctx - the error handler context 108 109 Options Database Keys: 110 + -on_error_attach_debugger <noxterm,gdb or dbx> 111 - -on_error_abort 112 113 Level: intermediate 114 115 Notes: 116 The currently available PETSc error handlers include PetscTraceBackErrorHandler(), 117 PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscMPIAbortErrorHandler(), PetscReturnErrorHandler(). 118 119 Fortran Notes: You can only push one error handler from Fortran before poping it. 120 121 .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 122 123 @*/ 124 PetscErrorCode PETSC_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char *,const char*,const char*,PetscErrorCode,int,const char*,void*),void *ctx) 125 { 126 EH neweh; 127 PetscErrorCode ierr; 128 129 PetscFunctionBegin; 130 ierr = PetscNew(struct _EH,&neweh);CHKERRQ(ierr); 131 if (eh) {neweh->previous = eh;} 132 else {neweh->previous = 0;} 133 neweh->handler = handler; 134 neweh->ctx = ctx; 135 eh = neweh; 136 PetscFunctionReturn(0); 137 } 138 139 #undef __FUNCT__ 140 #define __FUNCT__ "PetscPopErrorHandler" 141 /*@ 142 PetscPopErrorHandler - Removes the latest error handler that was 143 pushed with PetscPushErrorHandler(). 144 145 Not Collective 146 147 Level: intermediate 148 149 Concepts: error handler^setting 150 151 .seealso: PetscPushErrorHandler() 152 @*/ 153 PetscErrorCode PETSC_DLLEXPORT PetscPopErrorHandler(void) 154 { 155 EH tmp; 156 PetscErrorCode ierr; 157 158 PetscFunctionBegin; 159 if (!eh) PetscFunctionReturn(0); 160 tmp = eh; 161 eh = eh->previous; 162 ierr = PetscFree(tmp);CHKERRQ(ierr); 163 164 PetscFunctionReturn(0); 165 } 166 167 #undef __FUNCT__ 168 #define __FUNCT__ "PetscReturnErrorHandler" 169 /*@C 170 PetscReturnErrorHandler - Error handler that causes a return to the current 171 level. 172 173 Not Collective 174 175 Input Parameters: 176 + line - the line number of the error (indicated by __LINE__) 177 . func - the function where error is detected (indicated by __FUNCT__) 178 . file - the file in which the error was detected (indicated by __FILE__) 179 . dir - the directory of the file (indicated by __SDIR__) 180 . mess - an error text string, usually just printed to the screen 181 . n - the generic error number 182 . p - specific error number 183 - ctx - error handler context 184 185 Level: developer 186 187 Notes: 188 Most users need not directly employ this routine and the other error 189 handlers, but can instead use the simplified interface SETERRQ, which has 190 the calling sequence 191 $ SETERRQ(number,p,mess) 192 193 Notes for experienced users: 194 This routine is good for catching errors such as zero pivots in preconditioners 195 or breakdown of iterative methods. It is not appropriate for memory violations 196 and similar errors. 197 198 Use PetscPushErrorHandler() to set the desired error handler. The 199 currently available PETSc error handlers include PetscTraceBackErrorHandler(), 200 PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscAbortErrorHandler() 201 202 Concepts: error handler 203 204 .seealso: PetscPushErrorHandler(), PetscPopErrorHandler(). 205 @*/ 206 207 PetscErrorCode PETSC_DLLEXPORT PetscReturnErrorHandler(int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,void *ctx) 208 { 209 PetscFunctionBegin; 210 PetscFunctionReturn(n); 211 } 212 213 static char PetscErrorBaseMessage[1024]; 214 /* 215 The numerical values for these are defined in include/petscerror.h; any changes 216 there must also be made here 217 */ 218 static const char *PetscErrorStrings[] = { 219 /*55 */ "Out of memory", 220 "No support for this operation for this object type", 221 "No support for this operation on this system", 222 /*58 */ "Operation done in wrong order", 223 /*59 */ "Signal received", 224 /*60 */ "Nonconforming object sizes", 225 "Argument aliasing not permitted", 226 "Invalid argument", 227 /*63 */ "Argument out of range", 228 "Corrupt argument: see http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#Corrupt", 229 "Unable to open file", 230 "Read from file failed", 231 "Write to file failed", 232 "Invalid pointer", 233 /*69 */ "Arguments must have same type", 234 "", 235 /*71 */ "Detected zero pivot in LU factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot", 236 /*72 */ "Floating point exception", 237 /*73 */ "Object is in wrong state", 238 "Corrupted Petsc object", 239 "Arguments are incompatible", 240 "Error in external library", 241 /*77 */ "Petsc has generated inconsistent data", 242 "Memory corruption", 243 "Unexpected data in file", 244 /*80 */ "Arguments must have same communicators", 245 /*81 */ "Detected zero pivot in Cholesky factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot", 246 " ", 247 " ", 248 " ", 249 /*85 */ "Null argument, when expecting valid pointer", 250 /*86 */ "Unknown type. Check for miss-spelling or missing external package needed for type"}; 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "PetscErrorMessage" 254 /*@C 255 PetscErrorMessage - returns the text string associated with a PETSc error code. 256 257 Not Collective 258 259 Input Parameter: 260 . errnum - the error code 261 262 Output Parameter: 263 + text - the error message (PETSC_NULL if not desired) 264 - specific - the specific error message that was set with SETERRxxx() or PetscError(). (PETSC_NULL if not desired) 265 266 Level: developer 267 268 Concepts: error handler^messages 269 270 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 271 PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 272 @*/ 273 PetscErrorCode PETSC_DLLEXPORT PetscErrorMessage(int errnum,const char *text[],char **specific) 274 { 275 PetscFunctionBegin; 276 if (text && errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) { 277 *text = PetscErrorStrings[errnum-PETSC_ERR_MIN_VALUE-1]; 278 } else if (text) *text = 0; 279 280 if (specific) { 281 *specific = PetscErrorBaseMessage; 282 } 283 PetscFunctionReturn(0); 284 } 285 286 #if defined(PETSC_USE_ERRORCHECKING) 287 PetscErrorCode PETSC_DLLEXPORT PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX] = {0}; 288 PetscInt PETSC_DLLEXPORT PetscErrorUncatchableCount = 0; 289 PetscErrorCode PETSC_DLLEXPORT PetscExceptions[PETSC_EXCEPTIONS_MAX] = {0}; 290 PetscInt PETSC_DLLEXPORT PetscExceptionsCount = 0; 291 PetscErrorCode PETSC_DLLEXPORT PetscExceptionTmp = 0; 292 PetscErrorCode PETSC_DLLEXPORT PetscExceptionTmp1 = 0; 293 294 #undef __FUNCT__ 295 #define __FUNCT__ "PetscErrorIsCatchable" 296 /*@C 297 PetscErrorIsCatchable - Returns if a PetscErrorCode can be caught with a PetscExceptionTry1() or 298 PetscExceptionPush() 299 300 Input Parameters: 301 . err - error code 302 303 Level: advanced 304 305 Notes: 306 PETSc must not be configured using the option --with-errorchecking=0 for this to work 307 308 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop(), PetscErrorSetCatchable() 309 @*/ 310 PetscTruth PETSC_DLLEXPORT PetscErrorIsCatchable(PetscErrorCode err) 311 { 312 PetscInt i; 313 for (i=0; i<PetscErrorUncatchableCount; i++) { 314 if (err == PetscErrorUncatchable[i]) return PETSC_FALSE; 315 } 316 return PETSC_TRUE; 317 } 318 319 #undef __FUNCT__ 320 #define __FUNCT__ "PetscErrorSetCatchable" 321 /*@ 322 PetscErrorSetCatchable - Sets if a PetscErrorCode can be caught with a PetscExceptionTry1() 323 PetscExceptionCaught() pair, or PetscExceptionPush(). By default all errors are catchable. 324 325 Input Parameters: 326 + err - error code 327 - flg - PETSC_TRUE means allow to be caught, PETSC_FALSE means do not allow to be caught 328 329 Level: advanced 330 331 Notes: 332 PETSc must not be configured using the option --with-errorchecking=0 for this to work 333 334 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop(), PetscErrorIsCatchable() 335 @*/ 336 PetscErrorCode PETSC_DLLEXPORT PetscErrorSetCatchable(PetscErrorCode err,PetscTruth flg) 337 { 338 PetscFunctionBegin; 339 if (!flg && PetscErrorIsCatchable(err)) { 340 /* add to list of uncatchable */ 341 if (PetscErrorUncatchableCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_ERR_PLIB,"Stack for PetscErrorUncatchable is overflowed, recompile \nsrc/sysd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX"); 342 PetscErrorUncatchable[PetscErrorUncatchableCount++] = err; 343 } else if (flg && !PetscErrorIsCatchable(err)) { 344 /* remove from list of uncatchable */ 345 PetscInt i; 346 for (i=0; i<PetscErrorUncatchableCount; i++) { 347 if (PetscErrorUncatchable[i] == err) break; 348 } 349 for (;i<PetscErrorUncatchableCount; i++) { 350 PetscErrorUncatchable[i] = PetscErrorUncatchable[i+1]; 351 } 352 PetscErrorUncatchableCount--; 353 } 354 PetscFunctionReturn(0); 355 } 356 357 #undef __FUNCT__ 358 #define __FUNCT__ "PetscExceptionPush" 359 /*@ 360 PetscExceptionPush - Adds the exception as one to be caught and passed up. If passed up 361 can be checked with PetscExceptionCaught() or PetscExceptionValue() 362 363 Input Parameters: 364 . err - the exception to catch 365 366 Level: advanced 367 368 Notes: 369 PETSc must not be configured using the option --with-errorchecking=0 for this to work 370 371 Use PetscExceptionPop() to remove this as a value to be caught 372 373 This is not usually needed in C/C++ rather use PetscExceptionTry1() 374 375 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop() 376 @*/ 377 PetscErrorCode PETSC_DLLEXPORT PetscExceptionPush(PetscErrorCode err) 378 { 379 PetscFunctionBegin; 380 if (PetscExceptionsCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_ERR_PLIB,"Stack for PetscExceptions is overflowed, recompile \nsrc/sysd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX"); 381 if (PetscErrorIsCatchable(err)) PetscExceptions[PetscExceptionsCount++] = err; 382 PetscFunctionReturn(0); 383 } 384 385 #undef __FUNCT__ 386 #define __FUNCT__ "PetscExceptionPop" 387 /*@ 388 PetscExceptionPop - Removes the most recent exception asked to be caught with PetscExceptionPush() 389 390 Input Parameters: 391 . err - the exception that was pushed 392 393 Level: advanced 394 395 Notes: 396 PETSc must not be configured using the option --with-errorchecking=0 for this to work 397 398 This is not usually needed in C/C++ rather use PetscExceptionTry1() 399 400 .seealso: PetscExceptionTry1(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop() 401 @*/ 402 PetscErrorCode PETSC_DLLEXPORT PetscExceptionPop(PetscErrorCode err) 403 { 404 PetscFunctionBegin; 405 if (PetscExceptionsCount <= 0)SETERRQ(PETSC_ERR_PLIB,"Stack for PetscExceptions is empty"); 406 if (PetscErrorIsCatchable(err)) PetscExceptionsCount--; 407 PetscFunctionReturn(0); 408 } 409 #endif 410 411 #undef __FUNCT__ 412 #define __FUNCT__ "PetscError" 413 /*@C 414 PetscError - Routine that is called when an error has been detected, 415 usually called through the macro SETERRQ(). 416 417 Not Collective 418 419 Input Parameters: 420 + line - the line number of the error (indicated by __LINE__) 421 . func - the function where the error occured (indicated by __FUNCT__) 422 . dir - the directory of file (indicated by __SDIR__) 423 . file - the file in which the error was detected (indicated by __FILE__) 424 . mess - an error text string, usually just printed to the screen 425 . n - the generic error number 426 . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a 427 previously detected error 428 - mess - formatted message string - aka printf 429 430 Level: intermediate 431 432 Notes: 433 Most users need not directly use this routine and the error handlers, but 434 can instead use the simplified interface SETERRQ, which has the calling 435 sequence 436 $ SETERRQ(n,mess) 437 438 Experienced users can set the error handler with PetscPushErrorHandler(). 439 440 Concepts: error^setting condition 441 442 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2() 443 @*/ 444 PetscErrorCode PETSC_DLLEXPORT PetscError(int line,const char *func,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,...) 445 { 446 va_list Argp; 447 PetscErrorCode ierr; 448 char buf[2048],*lbuf = 0; 449 PetscTruth ismain,isunknown; 450 #if defined(PETSC_USE_ERRORCHECKING) 451 PetscInt i; 452 #endif 453 454 if (!func) func = "User provided function"; 455 if (!file) file = "User file"; 456 if (!dir) dir = " "; 457 458 PetscFunctionBegin; 459 /* Compose the message evaluating the print format */ 460 if (mess) { 461 va_start(Argp,mess); 462 PetscVSNPrintf(buf,2048,mess,Argp); 463 va_end(Argp); 464 lbuf = buf; 465 if (p == 1) { 466 PetscStrncpy(PetscErrorBaseMessage,lbuf,1023); 467 } 468 } 469 470 #if defined(PETSC_USE_ERRORCHECKING) 471 /* check if user is catching this exception */ 472 for (i=0; i<PetscExceptionsCount; i++) { 473 if (n == PetscExceptions[i]) PetscFunctionReturn(n); 474 } 475 #endif 476 477 if (!eh) ierr = PetscTraceBackErrorHandler(line,func,file,dir,n,p,lbuf,0); 478 else ierr = (*eh->handler)(line,func,file,dir,n,p,lbuf,eh->ctx); 479 480 /* 481 If this is called from the main() routine we call MPI_Abort() instead of 482 return to allow the parallel program to be properly shutdown. 483 484 Since this is in the error handler we don't check the errors below. Of course, 485 PetscStrncmp() does its own error checking which is problamatic 486 */ 487 PetscStrncmp(func,"main",4,&ismain); 488 PetscStrncmp(func,"unknown",7,&isunknown); 489 if (ismain || isunknown) { 490 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 491 } 492 PetscFunctionReturn(ierr); 493 } 494 495 #ifdef PETSC_CLANGUAGE_CXX 496 #undef __FUNCT__ 497 #define __FUNCT__ "PetscErrorCxx" 498 /*@C 499 PetscErrorCxx - Routine that is called when an error has been detected, 500 usually called through the macro SETERROR(). 501 502 Not Collective 503 504 Input Parameters: 505 + line - the line number of the error (indicated by __LINE__) 506 . func - the function where the error occured (indicated by __FUNCT__) 507 . dir - the directory of file (indicated by __SDIR__) 508 . file - the file in which the error was detected (indicated by __FILE__) 509 . n - the generic error number 510 . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a 511 previously detected error 512 513 Level: intermediate 514 515 Notes: 516 Most users need not directly use this routine and the error handlers, but 517 can instead use the simplified interface SETERRQ, which has the calling 518 sequence 519 $ SETERRQ(n,mess) 520 521 Experienced users can set the error handler with PetscPushErrorHandler(). 522 523 Concepts: error^setting condition 524 525 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2() 526 @*/ 527 void PETSC_DLLEXPORT PetscErrorCxx(int line,const char *func,const char* file,const char *dir,PetscErrorCode n,int p) 528 { 529 PetscTruth ismain, isunknown; 530 #if 0 531 #if defined(PETSC_USE_ERRORCHECKING) 532 PetscInt i; 533 #endif 534 #endif 535 536 if (!func) func = "User provided function"; 537 if (!file) file = "User file"; 538 if (!dir) dir = " "; 539 540 #if 0 541 #if defined(PETSC_USE_ERRORCHECKING) 542 /* check if user is catching this exception */ 543 for (i=0; i<PetscExceptionsCount; i++) { 544 if (n == PetscExceptions[i]) PetscFunctionReturn(n); 545 } 546 #endif 547 #endif 548 549 std::ostringstream msg; 550 551 PetscTraceBackErrorHandlerCxx(line, func, file, dir, n, p, msg); 552 553 /* 554 If this is called from the main() routine we call MPI_Abort() instead of 555 return to allow the parallel program to be properly shutdown. 556 557 Since this is in the error handler we don't check the errors below. Of course, 558 PetscStrncmp() does its own error checking which is problamatic 559 */ 560 PetscStrncmp(func,"main",4,&ismain); 561 PetscStrncmp(func,"unknown",7,&isunknown); 562 if (ismain || isunknown) { 563 MPI_Abort(PETSC_COMM_WORLD, (int) n); 564 } 565 throw PETSc::Exception(msg.str().c_str()); 566 } 567 #endif 568 569 /* -------------------------------------------------------------------------*/ 570 571 #undef __FUNCT__ 572 #define __FUNCT__ "PetscIntView" 573 /*@C 574 PetscIntView - Prints an array of integers; useful for debugging. 575 576 Collective on PetscViewer 577 578 Input Parameters: 579 + N - number of integers in array 580 . idx - array of integers 581 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 582 583 Level: intermediate 584 585 .seealso: PetscRealView() 586 @*/ 587 PetscErrorCode PETSC_DLLEXPORT PetscIntView(PetscInt N,PetscInt idx[],PetscViewer viewer) 588 { 589 PetscErrorCode ierr; 590 PetscInt j,i,n = N/20,p = N % 20; 591 PetscTruth iascii,isbinary; 592 MPI_Comm comm; 593 594 PetscFunctionBegin; 595 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 596 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,3); 597 PetscValidIntPointer(idx,2); 598 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 599 600 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 601 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 602 if (iascii) { 603 for (i=0; i<n; i++) { 604 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr); 605 for (j=0; j<20; j++) { 606 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr); 607 } 608 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 609 } 610 if (p) { 611 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr); 612 for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);} 613 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 614 } 615 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 616 } else if (isbinary) { 617 PetscMPIInt rank,size,*sizes,Ntotal,*displs, NN = PetscMPIIntCast(N); 618 PetscInt *array; 619 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 620 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 621 622 if (size > 1) { 623 if (rank) { 624 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 625 ierr = MPI_Gatherv(idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr); 626 } else { 627 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 628 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 629 Ntotal = sizes[0]; 630 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 631 displs[0] = 0; 632 for (i=1; i<size; i++) { 633 Ntotal += sizes[i]; 634 displs[i] = displs[i-1] + sizes[i-1]; 635 } 636 ierr = PetscMalloc(Ntotal*sizeof(PetscInt),&array);CHKERRQ(ierr); 637 ierr = MPI_Gatherv(idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr); 638 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 639 ierr = PetscFree(sizes);CHKERRQ(ierr); 640 ierr = PetscFree(displs);CHKERRQ(ierr); 641 ierr = PetscFree(array);CHKERRQ(ierr); 642 } 643 } else { 644 ierr = PetscViewerBinaryWrite(viewer,idx,N,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 645 } 646 } else { 647 const char *tname; 648 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 649 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 650 } 651 PetscFunctionReturn(0); 652 } 653 654 #undef __FUNCT__ 655 #define __FUNCT__ "PetscRealView" 656 /*@C 657 PetscRealView - Prints an array of doubles; useful for debugging. 658 659 Collective on PetscViewer 660 661 Input Parameters: 662 + N - number of doubles in array 663 . idx - array of doubles 664 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 665 666 Level: intermediate 667 668 .seealso: PetscIntView() 669 @*/ 670 PetscErrorCode PETSC_DLLEXPORT PetscRealView(PetscInt N,PetscReal idx[],PetscViewer viewer) 671 { 672 PetscErrorCode ierr; 673 PetscInt j,i,n = N/5,p = N % 5; 674 PetscTruth iascii,isbinary; 675 MPI_Comm comm; 676 677 PetscFunctionBegin; 678 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 679 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,3); 680 PetscValidScalarPointer(idx,2); 681 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 682 683 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 684 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 685 if (iascii) { 686 for (i=0; i<n; i++) { 687 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr); 688 for (j=0; j<5; j++) { 689 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr); 690 } 691 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 692 } 693 if (p) { 694 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr); 695 for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);} 696 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 697 } 698 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 699 } else if (isbinary) { 700 PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN = PetscMPIIntCast(N); 701 PetscReal *array; 702 703 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 704 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 705 706 if (size > 1) { 707 if (rank) { 708 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 709 ierr = MPI_Gatherv(idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 710 } else { 711 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 712 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 713 Ntotal = sizes[0]; 714 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 715 displs[0] = 0; 716 for (i=1; i<size; i++) { 717 Ntotal += sizes[i]; 718 displs[i] = displs[i-1] + sizes[i-1]; 719 } 720 ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr); 721 ierr = MPI_Gatherv(idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 722 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_REAL,PETSC_TRUE);CHKERRQ(ierr); 723 ierr = PetscFree(sizes);CHKERRQ(ierr); 724 ierr = PetscFree(displs);CHKERRQ(ierr); 725 ierr = PetscFree(array);CHKERRQ(ierr); 726 } 727 } else { 728 ierr = PetscViewerBinaryWrite(viewer,idx,N,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr); 729 } 730 } else { 731 const char *tname; 732 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 733 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 734 } 735 PetscFunctionReturn(0); 736 } 737 738 #undef __FUNCT__ 739 #define __FUNCT__ "PetscScalarView" 740 /*@C 741 PetscScalarView - Prints an array of scalars; useful for debugging. 742 743 Collective on PetscViewer 744 745 Input Parameters: 746 + N - number of scalars in array 747 . idx - array of scalars 748 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 749 750 Level: intermediate 751 752 .seealso: PetscIntView(), PetscRealView() 753 @*/ 754 PetscErrorCode PETSC_DLLEXPORT PetscScalarView(PetscInt N,PetscScalar idx[],PetscViewer viewer) 755 { 756 PetscErrorCode ierr; 757 PetscInt j,i,n = N/3,p = N % 3; 758 PetscTruth iascii,isbinary; 759 MPI_Comm comm; 760 761 PetscFunctionBegin; 762 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 763 PetscValidHeader(viewer,3); 764 PetscValidScalarPointer(idx,2); 765 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 766 767 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 768 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 769 if (iascii) { 770 for (i=0; i<n; i++) { 771 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr); 772 for (j=0; j<3; j++) { 773 #if defined (PETSC_USE_COMPLEX) 774 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", 775 PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr); 776 #else 777 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr); 778 #endif 779 } 780 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 781 } 782 if (p) { 783 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr); 784 for (i=0; i<p; i++) { 785 #if defined (PETSC_USE_COMPLEX) 786 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", 787 PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 788 #else 789 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr); 790 #endif 791 } 792 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 793 } 794 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 795 } else if (isbinary) { 796 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN = PetscMPIIntCast(N); 797 PetscScalar *array; 798 799 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 800 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 801 802 if (size > 1) { 803 if (rank) { 804 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 805 ierr = MPI_Gatherv(idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 806 } else { 807 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 808 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 809 Ntotal = sizes[0]; 810 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 811 displs[0] = 0; 812 for (i=1; i<size; i++) { 813 Ntotal += sizes[i]; 814 displs[i] = displs[i-1] + sizes[i-1]; 815 } 816 ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr); 817 ierr = MPI_Gatherv(idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 818 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr); 819 ierr = PetscFree(sizes);CHKERRQ(ierr); 820 ierr = PetscFree(displs);CHKERRQ(ierr); 821 ierr = PetscFree(array);CHKERRQ(ierr); 822 } 823 } else { 824 ierr = PetscViewerBinaryWrite(viewer,idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 825 } 826 } else { 827 const char *tname; 828 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 829 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 830 } 831 PetscFunctionReturn(0); 832 } 833 834 835 836 837