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 117 currently available PETSc error handlers include PetscTraceBackErrorHandler(), 118 PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler(), PetscReturnErrorHandler(). 119 120 .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 121 122 @*/ 123 PetscErrorCode PETSC_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char *,const char*,const char*,PetscErrorCode,int,const char*,void*),void *ctx) 124 { 125 EH neweh; 126 PetscErrorCode ierr; 127 128 PetscFunctionBegin; 129 ierr = PetscNew(struct _EH,&neweh);CHKERRQ(ierr); 130 if (eh) {neweh->previous = eh;} 131 else {neweh->previous = 0;} 132 neweh->handler = handler; 133 neweh->ctx = ctx; 134 eh = neweh; 135 PetscFunctionReturn(0); 136 } 137 138 #undef __FUNCT__ 139 #define __FUNCT__ "PetscPopErrorHandler" 140 /*@ 141 PetscPopErrorHandler - Removes the latest error handler that was 142 pushed with PetscPushErrorHandler(). 143 144 Not Collective 145 146 Level: intermediate 147 148 Concepts: error handler^setting 149 150 .seealso: PetscPushErrorHandler() 151 @*/ 152 PetscErrorCode PETSC_DLLEXPORT PetscPopErrorHandler(void) 153 { 154 EH tmp; 155 PetscErrorCode ierr; 156 157 PetscFunctionBegin; 158 if (!eh) PetscFunctionReturn(0); 159 tmp = eh; 160 eh = eh->previous; 161 ierr = PetscFree(tmp);CHKERRQ(ierr); 162 163 PetscFunctionReturn(0); 164 } 165 166 #undef __FUNCT__ 167 #define __FUNCT__ "PetscReturnErrorHandler" 168 /*@C 169 PetscReturnErrorHandler - Error handler that causes a return to the current 170 level. 171 172 Not Collective 173 174 Input Parameters: 175 + line - the line number of the error (indicated by __LINE__) 176 . func - the function where error is detected (indicated by __FUNCT__) 177 . file - the file in which the error was detected (indicated by __FILE__) 178 . dir - the directory of the file (indicated by __SDIR__) 179 . mess - an error text string, usually just printed to the screen 180 . n - the generic error number 181 . p - specific error number 182 - ctx - error handler context 183 184 Level: developer 185 186 Notes: 187 Most users need not directly employ this routine and the other error 188 handlers, but can instead use the simplified interface SETERRQ, which has 189 the calling sequence 190 $ SETERRQ(number,p,mess) 191 192 Notes for experienced users: 193 This routine is good for catching errors such as zero pivots in preconditioners 194 or breakdown of iterative methods. It is not appropriate for memory violations 195 and similar errors. 196 197 Use PetscPushErrorHandler() to set the desired error handler. The 198 currently available PETSc error handlers include PetscTraceBackErrorHandler(), 199 PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler() 200 201 Concepts: error handler 202 203 .seealso: PetscPushErrorHandler(), PetscPopErrorHandler(). 204 @*/ 205 206 PetscErrorCode PETSC_DLLEXPORT PetscReturnErrorHandler(int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,void *ctx) 207 { 208 PetscFunctionBegin; 209 PetscFunctionReturn(n); 210 } 211 212 static char PetscErrorBaseMessage[1024]; 213 /* 214 The numerical values for these are defined in include/petscerror.h; any changes 215 there must also be made here 216 */ 217 static const char *PetscErrorStrings[] = { 218 /*55 */ "Out of memory", 219 "No support for this operation for this object type", 220 "No support for this operation on this system", 221 /*58 */ "Operation done in wrong order", 222 /*59 */ "Signal received", 223 /*60 */ "Nonconforming object sizes", 224 "Argument aliasing not permitted", 225 "Invalid argument", 226 /*63 */ "Argument out of range", 227 "Corrupt argument: see http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#Corrupt", 228 "Unable to open file", 229 "Read from file failed", 230 "Write to file failed", 231 "Invalid pointer", 232 /*69 */ "Arguments must have same type", 233 "", 234 /*71 */ "Detected zero pivot in LU factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot", 235 /*72 */ "Floating point exception", 236 /*73 */ "Object is in wrong state", 237 "Corrupted Petsc object", 238 "Arguments are incompatible", 239 "Error in external library", 240 /*77 */ "Petsc has generated inconsistent data", 241 "Memory corruption", 242 "Unexpected data in file", 243 /*80 */ "Arguments must have same communicators", 244 /*81 */ "Detected zero pivot in Cholesky factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot", 245 " ", 246 " ", 247 " ", 248 /*85 */ "Null argument, when expecting valid pointer", 249 /*86 */ "Unknown type. Check for miss-spelling or missing external package needed for type"}; 250 251 #undef __FUNCT__ 252 #define __FUNCT__ "PetscErrorMessage" 253 /*@C 254 PetscErrorMessage - returns the text string associated with a PETSc error code. 255 256 Not Collective 257 258 Input Parameter: 259 . errnum - the error code 260 261 Output Parameter: 262 + text - the error message (PETSC_NULL if not desired) 263 - specific - the specific error message that was set with SETERRxxx() or PetscError(). (PETSC_NULL if not desired) 264 265 Level: developer 266 267 Concepts: error handler^messages 268 269 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 270 PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 271 @*/ 272 PetscErrorCode PETSC_DLLEXPORT PetscErrorMessage(int errnum,const char *text[],char **specific) 273 { 274 PetscFunctionBegin; 275 if (text && errnum >= PETSC_ERR_MEM && errnum <= PETSC_ERR_MEM_MALLOC_0) { 276 *text = PetscErrorStrings[errnum-PETSC_ERR_MEM]; 277 } else if (text) *text = 0; 278 279 if (specific) { 280 *specific = PetscErrorBaseMessage; 281 } 282 PetscFunctionReturn(0); 283 } 284 285 #if defined(PETSC_USE_ERRORCHECKING) 286 PetscErrorCode PETSC_DLLEXPORT PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX] = {0}; 287 PetscInt PETSC_DLLEXPORT PetscErrorUncatchableCount = 0; 288 PetscErrorCode PETSC_DLLEXPORT PetscExceptions[PETSC_EXCEPTIONS_MAX] = {0}; 289 PetscInt PETSC_DLLEXPORT PetscExceptionsCount = 0; 290 PetscErrorCode PETSC_DLLEXPORT PetscExceptionTmp = 0; 291 292 #undef __FUNCT__ 293 #define __FUNCT__ "PetscErrorIsCatchable" 294 static PetscTruth PetscErrorIsCatchable(PetscErrorCode err) 295 { 296 PetscInt i; 297 for (i=0; i<PetscErrorUncatchableCount; i++) { 298 if (err == PetscErrorUncatchable[i]) return PETSC_FALSE; 299 } 300 return PETSC_TRUE; 301 } 302 303 #undef __FUNCT__ 304 #define __FUNCT__ "PetscErrorSetCatchable" 305 /*@ 306 PetscErrorSetCatchable - Sets if a PetscErrorCode can be caught with a PetscExceptionTry1() 307 PetscExceptionCaught() pair. By default all errors are catchable. 308 309 Input Parameters: 310 + err - error code 311 - flg - PETSC_TRUE means allow to be caught, PETSC_FALSE means do not allow to be caught 312 313 Level: advanced 314 315 Notes: 316 PETSc must not be configured using the option --with-errorchecking=0 for this to work 317 318 .seealso: PetscExceptionTry1(), PetscExceptionCaught() 319 @*/ 320 PetscErrorCode PETSC_DLLEXPORT PetscErrorSetCatchable(PetscErrorCode err,PetscTruth flg) 321 { 322 PetscFunctionBegin; 323 if (!flg && PetscErrorIsCatchable(err)) { 324 /* add to list of uncatchable */ 325 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"); 326 PetscErrorUncatchable[PetscErrorUncatchableCount++] = err; 327 } else if (flg && !PetscErrorIsCatchable(err)) { 328 /* remove from list of uncatchable */ 329 PetscInt i; 330 for (i=0; i<PetscErrorUncatchableCount; i++) { 331 if (PetscErrorUncatchable[i] == err) break; 332 } 333 for (;i<PetscErrorUncatchableCount; i++) { 334 PetscErrorUncatchable[i] = PetscErrorUncatchable[i+1]; 335 } 336 PetscErrorUncatchableCount--; 337 } 338 PetscFunctionReturn(0); 339 } 340 341 #undef __FUNCT__ 342 #define __FUNCT__ "PetscExceptionPush" 343 PetscErrorCode PETSC_DLLEXPORT PetscExceptionPush(PetscErrorCode err) 344 { 345 PetscFunctionBegin; 346 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"); 347 if (PetscErrorIsCatchable(err)) PetscExceptions[PetscExceptionsCount++] = err; 348 PetscFunctionReturn(0); 349 } 350 351 #undef __FUNCT__ 352 #define __FUNCT__ "PetscExceptionPop" 353 void PETSC_DLLEXPORT PetscExceptionPop(PetscErrorCode err) 354 { 355 /* if (PetscExceptionsCount <= 0)SETERRQ(PETSC_ERR_PLIB,"Stack for PetscExceptions is empty"); */ 356 if (PetscErrorIsCatchable(err)) PetscExceptionsCount--; 357 } 358 #endif 359 360 #undef __FUNCT__ 361 #define __FUNCT__ "PetscError" 362 /*@C 363 PetscError - Routine that is called when an error has been detected, 364 usually called through the macro SETERRQ(). 365 366 Not Collective 367 368 Input Parameters: 369 + line - the line number of the error (indicated by __LINE__) 370 . func - the function where the error occured (indicated by __FUNCT__) 371 . dir - the directory of file (indicated by __SDIR__) 372 . file - the file in which the error was detected (indicated by __FILE__) 373 . mess - an error text string, usually just printed to the screen 374 . n - the generic error number 375 . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a 376 previously detected error 377 - mess - formatted message string - aka printf 378 379 Level: intermediate 380 381 Notes: 382 Most users need not directly use this routine and the error handlers, but 383 can instead use the simplified interface SETERRQ, which has the calling 384 sequence 385 $ SETERRQ(n,mess) 386 387 Experienced users can set the error handler with PetscPushErrorHandler(). 388 389 Concepts: error^setting condition 390 391 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2() 392 @*/ 393 PetscErrorCode PETSC_DLLEXPORT PetscError(int line,const char *func,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,...) 394 { 395 va_list Argp; 396 PetscErrorCode ierr; 397 char buf[2048],*lbuf = 0; 398 PetscTruth ismain,isunknown; 399 #if defined(PETSC_USE_ERRORCHECKING) 400 PetscInt i; 401 #endif 402 403 if (!func) func = "User provided function"; 404 if (!file) file = "User file"; 405 if (!dir) dir = " "; 406 407 PetscFunctionBegin; 408 /* Compose the message evaluating the print format */ 409 if (mess) { 410 va_start(Argp,mess); 411 PetscVSNPrintf(buf,2048,mess,Argp); 412 va_end(Argp); 413 lbuf = buf; 414 if (p == 1) { 415 PetscStrncpy(PetscErrorBaseMessage,lbuf,1023); 416 } 417 } 418 419 #if defined(PETSC_USE_ERRORCHECKING) 420 /* check if user is catching this exception */ 421 for (i=0; i<PetscExceptionsCount; i++) { 422 if (n == PetscExceptions[i]) PetscFunctionReturn(n); 423 } 424 #endif 425 426 if (!eh) ierr = PetscTraceBackErrorHandler(line,func,file,dir,n,p,lbuf,0); 427 else ierr = (*eh->handler)(line,func,file,dir,n,p,lbuf,eh->ctx); 428 429 /* 430 If this is called from the main() routine we call MPI_Abort() instead of 431 return to allow the parallel program to be properly shutdown. 432 433 Since this is in the error handler we don't check the errors below. Of course, 434 PetscStrncmp() does its own error checking which is problamatic 435 */ 436 PetscStrncmp(func,"main",4,&ismain); 437 PetscStrncmp(func,"unknown",7,&isunknown); 438 if (ismain || isunknown) { 439 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 440 } 441 PetscFunctionReturn(ierr); 442 } 443 444 /* -------------------------------------------------------------------------*/ 445 446 #undef __FUNCT__ 447 #define __FUNCT__ "PetscIntView" 448 /*@C 449 PetscIntView - Prints an array of integers; useful for debugging. 450 451 Collective on PetscViewer 452 453 Input Parameters: 454 + N - number of integers in array 455 . idx - array of integers 456 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 457 458 Level: intermediate 459 460 .seealso: PetscRealView() 461 @*/ 462 PetscErrorCode PETSC_DLLEXPORT PetscIntView(PetscInt N,PetscInt idx[],PetscViewer viewer) 463 { 464 PetscErrorCode ierr; 465 PetscInt j,i,n = N/20,p = N % 20; 466 PetscTruth iascii,issocket; 467 MPI_Comm comm; 468 469 PetscFunctionBegin; 470 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 471 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,3); 472 PetscValidIntPointer(idx,2); 473 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 474 475 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 476 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 477 if (iascii) { 478 for (i=0; i<n; i++) { 479 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr); 480 for (j=0; j<20; j++) { 481 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr); 482 } 483 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 484 } 485 if (p) { 486 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr); 487 for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);} 488 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 489 } 490 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 491 #if defined(PETSC_USE_SOCKET_VIEWER) 492 } else if (issocket) { 493 PetscMPIInt rank,size,*sizes,Ntotal,*displs, NN = (PetscMPIInt)N; 494 PetscInt *array; 495 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 496 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 497 498 if (size > 1) { 499 if (rank) { 500 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 501 ierr = MPI_Gatherv(idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr); 502 } else { 503 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 504 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 505 Ntotal = sizes[0]; 506 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 507 displs[0] = 0; 508 for (i=1; i<size; i++) { 509 Ntotal += sizes[i]; 510 displs[i] = displs[i-1] + sizes[i-1]; 511 } 512 ierr = PetscMalloc(Ntotal*sizeof(PetscInt),&array);CHKERRQ(ierr); 513 ierr = MPI_Gatherv(idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr); 514 ierr = PetscViewerSocketPutInt(viewer,Ntotal,array);CHKERRQ(ierr); 515 ierr = PetscFree(sizes);CHKERRQ(ierr); 516 ierr = PetscFree(displs);CHKERRQ(ierr); 517 ierr = PetscFree(array);CHKERRQ(ierr); 518 } 519 } else { 520 ierr = PetscViewerSocketPutInt(viewer,N,idx);CHKERRQ(ierr); 521 } 522 #endif 523 } else { 524 const char *tname; 525 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 526 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 527 } 528 PetscFunctionReturn(0); 529 } 530 531 #undef __FUNCT__ 532 #define __FUNCT__ "PetscRealView" 533 /*@C 534 PetscRealView - Prints an array of doubles; useful for debugging. 535 536 Collective on PetscViewer 537 538 Input Parameters: 539 + N - number of doubles in array 540 . idx - array of doubles 541 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 542 543 Level: intermediate 544 545 .seealso: PetscIntView() 546 @*/ 547 PetscErrorCode PETSC_DLLEXPORT PetscRealView(PetscInt N,PetscReal idx[],PetscViewer viewer) 548 { 549 PetscErrorCode ierr; 550 PetscInt j,i,n = N/5,p = N % 5; 551 PetscTruth iascii,issocket; 552 MPI_Comm comm; 553 554 PetscFunctionBegin; 555 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 556 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,3); 557 PetscValidScalarPointer(idx,2); 558 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 559 560 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 561 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 562 if (iascii) { 563 for (i=0; i<n; i++) { 564 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr); 565 for (j=0; j<5; j++) { 566 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr); 567 } 568 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 569 } 570 if (p) { 571 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr); 572 for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);} 573 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 574 } 575 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 576 #if defined(PETSC_USE_SOCKET_VIEWER) 577 } else if (issocket) { 578 PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN = (PetscMPIInt)N; 579 PetscReal *array; 580 581 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 582 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 583 584 if (size > 1) { 585 if (rank) { 586 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 587 ierr = MPI_Gatherv(idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 588 } else { 589 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 590 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 591 Ntotal = sizes[0]; 592 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 593 displs[0] = 0; 594 for (i=1; i<size; i++) { 595 Ntotal += sizes[i]; 596 displs[i] = displs[i-1] + sizes[i-1]; 597 } 598 ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr); 599 ierr = MPI_Gatherv(idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 600 ierr = PetscViewerSocketPutReal(viewer,Ntotal,1,array);CHKERRQ(ierr); 601 ierr = PetscFree(sizes);CHKERRQ(ierr); 602 ierr = PetscFree(displs);CHKERRQ(ierr); 603 ierr = PetscFree(array);CHKERRQ(ierr); 604 } 605 } else { 606 ierr = PetscViewerSocketPutReal(viewer,N,1,idx);CHKERRQ(ierr); 607 } 608 #endif 609 } else { 610 const char *tname; 611 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 612 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 613 } 614 PetscFunctionReturn(0); 615 } 616 617 #undef __FUNCT__ 618 #define __FUNCT__ "PetscScalarView" 619 /*@C 620 PetscScalarView - Prints an array of scalars; useful for debugging. 621 622 Collective on PetscViewer 623 624 Input Parameters: 625 + N - number of scalars in array 626 . idx - array of scalars 627 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 628 629 Level: intermediate 630 631 .seealso: PetscIntView(), PetscRealView() 632 @*/ 633 PetscErrorCode PETSC_DLLEXPORT PetscScalarView(PetscInt N,PetscScalar idx[],PetscViewer viewer) 634 { 635 PetscErrorCode ierr; 636 PetscInt j,i,n = N/3,p = N % 3; 637 PetscTruth iascii,issocket; 638 MPI_Comm comm; 639 640 PetscFunctionBegin; 641 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 642 PetscValidHeader(viewer,3); 643 PetscValidScalarPointer(idx,2); 644 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 645 646 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 647 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 648 if (iascii) { 649 for (i=0; i<n; i++) { 650 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr); 651 for (j=0; j<3; j++) { 652 #if defined (PETSC_USE_COMPLEX) 653 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", 654 PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr); 655 #else 656 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr); 657 #endif 658 } 659 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 660 } 661 if (p) { 662 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr); 663 for (i=0; i<p; i++) { 664 #if defined (PETSC_USE_COMPLEX) 665 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", 666 PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 667 #else 668 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr); 669 #endif 670 } 671 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 672 } 673 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 674 #if defined(PETSC_USE_SOCKET_VIEWER) 675 } else if (issocket) { 676 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN = (PetscMPIInt)N; 677 PetscScalar *array; 678 679 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 680 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 681 682 if (size > 1) { 683 if (rank) { 684 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 685 ierr = MPI_Gatherv(idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 686 } else { 687 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 688 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 689 Ntotal = sizes[0]; 690 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 691 displs[0] = 0; 692 for (i=1; i<size; i++) { 693 Ntotal += sizes[i]; 694 displs[i] = displs[i-1] + sizes[i-1]; 695 } 696 ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr); 697 ierr = MPI_Gatherv(idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 698 ierr = PetscViewerSocketPutScalar(viewer,Ntotal,1,array);CHKERRQ(ierr); 699 ierr = PetscFree(sizes);CHKERRQ(ierr); 700 ierr = PetscFree(displs);CHKERRQ(ierr); 701 ierr = PetscFree(array);CHKERRQ(ierr); 702 } 703 } else { 704 ierr = PetscViewerSocketPutScalar(viewer,N,1,idx);CHKERRQ(ierr); 705 } 706 #endif 707 } else { 708 const char *tname; 709 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 710 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 711 } 712 PetscFunctionReturn(0); 713 } 714 715 716 717 718