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 = 0; 16 17 #undef __FUNCT__ 18 #define __FUNCT__ "PetscEmacsClientErrorHandler" 19 /*@C 20 PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to 21 load the file where the error occured. Then calls the "previous" error handler. 22 23 Not Collective 24 25 Input Parameters: 26 + comm - communicator over which error occured 27 . line - the line number of the error (indicated by __LINE__) 28 . func - the function where error is detected (indicated by __FUNCT__) 29 . file - the file in which the error was detected (indicated by __FILE__) 30 . mess - an error text string, usually just printed to the screen 31 . n - the generic error number 32 . p - specific error number 33 - ctx - error handler context 34 35 Options Database Key: 36 . -on_error_emacs <machinename> 37 38 Level: developer 39 40 Notes: 41 You must put (server-start) in your .emacs file for the emacsclient software to work 42 43 Most users need not directly employ this routine and the other error 44 handlers, but can instead use the simplified interface SETERRQ, which has 45 the calling sequence 46 $ SETERRQ(PETSC_COMM_SELF,number,p,mess) 47 48 Notes for experienced users: 49 Use PetscPushErrorHandler() to set the desired error handler. 50 51 Developer Note: Since this is an error handler it cannot call CHKERRQ(); thus we just return if an error is detected. 52 53 Concepts: emacs^going to on error 54 Concepts: error handler^going to line in emacs 55 56 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 57 PetscAbortErrorHandler() 58 @*/ 59 PetscErrorCode PetscEmacsClientErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,void *ctx) 60 { 61 PetscErrorCode ierr; 62 char command[PETSC_MAX_PATH_LEN]; 63 const char *pdir; 64 FILE *fp; 65 int rval; 66 67 PetscFunctionBegin; 68 ierr = PetscGetPetscDir(&pdir);if (ierr) PetscFunctionReturn(ierr); 69 sprintf(command,"cd %s; emacsclient --no-wait +%d %s\n",pdir,line,file); 70 #if defined(PETSC_HAVE_POPEN) 71 ierr = PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp);if (ierr) PetscFunctionReturn(ierr); 72 ierr = PetscPClose(MPI_COMM_WORLD,fp,&rval);if (ierr) PetscFunctionReturn(ierr); 73 #else 74 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 75 #endif 76 ierr = PetscPopErrorHandler();if (ierr) PetscFunctionReturn(ierr); /* remove this handler from the stack of handlers */ 77 if (!eh) { 78 ierr = PetscTraceBackErrorHandler(comm,line,fun,file,n,p,mess,0);if (ierr) PetscFunctionReturn(ierr); 79 } else { 80 ierr = (*eh->handler)(comm,line,fun,file,n,p,mess,eh->ctx);if (ierr) PetscFunctionReturn(ierr); 81 } 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(MPI_Comm comm,int line,char *func,char *file,PetscErrorCode n,int p,char *mess,void *ctx); 99 100 + comm - communicator over which error occured 101 . line - the line number of the error (indicated by __LINE__) 102 . func - the function where the error occured (indicated by __FUNCT__) 103 . file - the file in which the error was detected (indicated by __FILE__) 104 . n - the generic error number (see list defined in include/petscerror.h) 105 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 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(), PetscPushSignalHandler() 122 123 @*/ 124 PetscErrorCode PetscPushErrorHandler(PetscErrorCode (*handler)(MPI_Comm comm,int,const char*,const char*,PetscErrorCode,PetscErrorType,const char*,void*),void *ctx) 125 { 126 EH neweh; 127 PetscErrorCode ierr; 128 129 PetscFunctionBegin; 130 ierr = PetscNew(&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 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 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 + comm - communicator over which error occurred 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 . 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(comm,number,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 PetscAbortErrorHandler() 200 201 Concepts: error handler 202 203 .seealso: PetscPushErrorHandler(), PetscPopErrorHandler(). 204 @*/ 205 206 PetscErrorCode PetscReturnErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode n,PetscErrorType 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: http://www.mcs.anl.gov/petsc/documentation/faq.html#valgrind", 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 /*70 */ "Attempt to use a pointer that does not point to a valid accessible location", 234 /*71 */ "Zero pivot in LU factorization: http://www.mcs.anl.gov/petsc/documentation/faq.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: http://www.mcs.anl.gov/petsc/documentation/installation.html#valgrind", 242 "Unexpected data in file", 243 /*80 */ "Arguments must have same communicators", 244 /*81 */ "Zero pivot in Cholesky factorization: http://www.mcs.anl.gov/petsc/documentation/faq.html#zeropivot", 245 " ", 246 " ", 247 "Overflow in integer operation: http://www.mcs.anl.gov/petsc/documentation/faq.html#64-bit-indices", 248 /*85 */ "Null argument, when expecting valid pointer", 249 /*86 */ "Unknown type. Check for miss-spelling or missing package: http://www.mcs.anl.gov/petsc/documentation/installation.html#external", 250 /*87 */ "Not used", 251 /*88 */ "Error in system call", 252 /*89 */ "Object Type not set: http://www.mcs.anl.gov/petsc/documentation/faq.html#objecttypenotset" 253 /*90 */ " ", 254 /* */ " ", 255 /* */ " ", 256 /*93 */ "See http://www.mcs.anl.gov/petsc/documentation/linearsolvertable.html for possible LU and Cholesky solvers", 257 /* */ "You cannot overwrite this option since that will conflict with other previously set options", 258 /* */ " ", 259 /*96 */ " ", 260 }; 261 262 #undef __FUNCT__ 263 #define __FUNCT__ "PetscErrorMessage" 264 /*@C 265 PetscErrorMessage - returns the text string associated with a PETSc error code. 266 267 Not Collective 268 269 Input Parameter: 270 . errnum - the error code 271 272 Output Parameter: 273 + text - the error message (NULL if not desired) 274 - specific - the specific error message that was set with SETERRxxx() or PetscError(). (NULL if not desired) 275 276 Level: developer 277 278 Concepts: error handler^messages 279 280 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 281 PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 282 @*/ 283 PetscErrorCode PetscErrorMessage(int errnum,const char *text[],char **specific) 284 { 285 PetscFunctionBegin; 286 if (text && errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) *text = PetscErrorStrings[errnum-PETSC_ERR_MIN_VALUE-1]; 287 else if (text) *text = 0; 288 289 if (specific) *specific = PetscErrorBaseMessage; 290 PetscFunctionReturn(0); 291 } 292 293 #if defined(PETSC_CLANGUAGE_CXX) 294 /* C++ exceptions are formally not allowed to propagate through extern "C" code. In practice, far too much software 295 * would be broken if implementations did not handle it it some common cases. However, keep in mind 296 * 297 * Rule 62. Don't allow exceptions to propagate across module boundaries 298 * 299 * in "C++ Coding Standards" by Sutter and Alexandrescu. (This accounts for part of the ongoing C++ binary interface 300 * instability.) Having PETSc raise errors as C++ exceptions was probably misguided and should eventually be removed. 301 * 302 * Here is the problem: You have a C++ function call a PETSc function, and you would like to maintain the error message 303 * and stack information from the PETSc error. You could make everyone write exactly this code in their C++, but that 304 * seems crazy to me. 305 */ 306 #include <sstream> 307 #include <stdexcept> 308 static void PetscCxxErrorThrow() { 309 const char *str; 310 if (eh && eh->ctx) { 311 std::ostringstream *msg; 312 msg = (std::ostringstream*) eh->ctx; 313 str = msg->str().c_str(); 314 } else str = "Error detected in C PETSc"; 315 316 throw std::runtime_error(str); 317 } 318 #endif 319 320 #undef __FUNCT__ 321 #define __FUNCT__ "PetscError" 322 /*@C 323 PetscError - Routine that is called when an error has been detected, 324 usually called through the macro SETERRQ(PETSC_COMM_SELF,). 325 326 Not Collective 327 328 Input Parameters: 329 + comm - communicator over which error occurred. ALL ranks of this communicator MUST call this routine 330 . line - the line number of the error (indicated by __LINE__) 331 . func - the function where the error occured (indicated by __FUNCT__) 332 . file - the file in which the error was detected (indicated by __FILE__) 333 . mess - an error text string, usually just printed to the screen 334 . n - the generic error number 335 . p - PETSC_ERROR_INITIAL indicates the error was initially detected, PETSC_ERROR_REPEAT indicates this is a traceback from a previously detected error 336 - mess - formatted message string - aka printf 337 338 Level: intermediate 339 340 Notes: 341 Most users need not directly use this routine and the error handlers, but 342 can instead use the simplified interface SETERRQ, which has the calling 343 sequence 344 $ SETERRQ(comm,n,mess) 345 346 Experienced users can set the error handler with PetscPushErrorHandler(). 347 348 Developer Note: Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes) 349 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 350 but this annoying. 351 352 Concepts: error^setting condition 353 354 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2() 355 @*/ 356 PetscErrorCode PetscError(MPI_Comm comm,int line,const char *func,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,...) 357 { 358 va_list Argp; 359 size_t fullLength; 360 char buf[2048],*lbuf = 0; 361 PetscBool ismain,isunknown; 362 PetscErrorCode ierr; 363 364 PetscFunctionBegin; 365 if (!func) func = "User provided function"; 366 if (!file) file = "User file"; 367 if (comm == MPI_COMM_NULL) comm = PETSC_COMM_SELF; 368 369 /* Compose the message evaluating the print format */ 370 if (mess) { 371 va_start(Argp,mess); 372 PetscVSNPrintf(buf,2048,mess,&fullLength,Argp); 373 va_end(Argp); 374 lbuf = buf; 375 if (p == 1) PetscStrncpy(PetscErrorBaseMessage,lbuf,1023); 376 } 377 378 if (!eh) ierr = PetscTraceBackErrorHandler(comm,line,func,file,n,p,lbuf,0); 379 else ierr = (*eh->handler)(comm,line,func,file,n,p,lbuf,eh->ctx); 380 381 /* 382 If this is called from the main() routine we call MPI_Abort() instead of 383 return to allow the parallel program to be properly shutdown. 384 385 Since this is in the error handler we don't check the errors below. Of course, 386 PetscStrncmp() does its own error checking which is problamatic 387 */ 388 PetscStrncmp(func,"main",4,&ismain); 389 PetscStrncmp(func,"unknown",7,&isunknown); 390 if (ismain || isunknown) MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 391 392 #if defined(PETSC_CLANGUAGE_CXX) 393 if (p == PETSC_ERROR_IN_CXX) { 394 PetscCxxErrorThrow(); 395 } 396 #endif 397 PetscFunctionReturn(ierr); 398 } 399 400 /* -------------------------------------------------------------------------*/ 401 402 #undef __FUNCT__ 403 #define __FUNCT__ "PetscIntView" 404 /*@C 405 PetscIntView - Prints an array of integers; useful for debugging. 406 407 Collective on PetscViewer 408 409 Input Parameters: 410 + N - number of integers in array 411 . idx - array of integers 412 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 413 414 Level: intermediate 415 416 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 417 418 .seealso: PetscRealView() 419 @*/ 420 PetscErrorCode PetscIntView(PetscInt N,const PetscInt idx[],PetscViewer viewer) 421 { 422 PetscErrorCode ierr; 423 PetscInt j,i,n = N/20,p = N % 20; 424 PetscBool iascii,isbinary; 425 MPI_Comm comm; 426 427 PetscFunctionBegin; 428 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 429 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3); 430 if (N) PetscValidIntPointer(idx,2); 431 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 432 433 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 434 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 435 if (iascii) { 436 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 437 for (i=0; i<n; i++) { 438 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr); 439 for (j=0; j<20; j++) { 440 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr); 441 } 442 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 443 } 444 if (p) { 445 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr); 446 for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);} 447 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 448 } 449 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 450 ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 451 } else if (isbinary) { 452 PetscMPIInt rank,size,*sizes,Ntotal,*displs,NN; 453 PetscInt *array; 454 455 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 456 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 457 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 458 459 if (size > 1) { 460 if (rank) { 461 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 462 ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr); 463 } else { 464 ierr = PetscMalloc1(size,&sizes);CHKERRQ(ierr); 465 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 466 Ntotal = sizes[0]; 467 ierr = PetscMalloc1(size,&displs);CHKERRQ(ierr); 468 displs[0] = 0; 469 for (i=1; i<size; i++) { 470 Ntotal += sizes[i]; 471 displs[i] = displs[i-1] + sizes[i-1]; 472 } 473 ierr = PetscMalloc1(Ntotal,&array);CHKERRQ(ierr); 474 ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr); 475 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 476 ierr = PetscFree(sizes);CHKERRQ(ierr); 477 ierr = PetscFree(displs);CHKERRQ(ierr); 478 ierr = PetscFree(array);CHKERRQ(ierr); 479 } 480 } else { 481 ierr = PetscViewerBinaryWrite(viewer,(void*) idx,N,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 482 } 483 } else { 484 const char *tname; 485 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 486 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 487 } 488 PetscFunctionReturn(0); 489 } 490 491 #undef __FUNCT__ 492 #define __FUNCT__ "PetscRealView" 493 /*@C 494 PetscRealView - Prints an array of doubles; useful for debugging. 495 496 Collective on PetscViewer 497 498 Input Parameters: 499 + N - number of PetscReal in array 500 . idx - array of PetscReal 501 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 502 503 Level: intermediate 504 505 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 506 507 .seealso: PetscIntView() 508 @*/ 509 PetscErrorCode PetscRealView(PetscInt N,const PetscReal idx[],PetscViewer viewer) 510 { 511 PetscErrorCode ierr; 512 PetscInt j,i,n = N/5,p = N % 5; 513 PetscBool iascii,isbinary; 514 MPI_Comm comm; 515 516 PetscFunctionBegin; 517 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 518 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3); 519 PetscValidScalarPointer(idx,2); 520 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 521 522 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 523 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 524 if (iascii) { 525 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 526 for (i=0; i<n; i++) { 527 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",(int)5*i);CHKERRQ(ierr); 528 for (j=0; j<5; j++) { 529 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",(double)idx[i*5+j]);CHKERRQ(ierr); 530 } 531 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 532 } 533 if (p) { 534 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",(int)5*n);CHKERRQ(ierr); 535 for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",(double)idx[5*n+i]);CHKERRQ(ierr);} 536 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 537 } 538 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 539 ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 540 } else if (isbinary) { 541 PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN; 542 PetscReal *array; 543 544 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 545 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 546 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 547 548 if (size > 1) { 549 if (rank) { 550 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 551 ierr = MPI_Gatherv((PetscReal*)idx,NN,MPIU_REAL,0,0,0,MPIU_REAL,0,comm);CHKERRQ(ierr); 552 } else { 553 ierr = PetscMalloc1(size,&sizes);CHKERRQ(ierr); 554 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 555 Ntotal = sizes[0]; 556 ierr = PetscMalloc1(size,&displs);CHKERRQ(ierr); 557 displs[0] = 0; 558 for (i=1; i<size; i++) { 559 Ntotal += sizes[i]; 560 displs[i] = displs[i-1] + sizes[i-1]; 561 } 562 ierr = PetscMalloc1(Ntotal,&array);CHKERRQ(ierr); 563 ierr = MPI_Gatherv((PetscReal*)idx,NN,MPIU_REAL,array,sizes,displs,MPIU_REAL,0,comm);CHKERRQ(ierr); 564 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_REAL,PETSC_TRUE);CHKERRQ(ierr); 565 ierr = PetscFree(sizes);CHKERRQ(ierr); 566 ierr = PetscFree(displs);CHKERRQ(ierr); 567 ierr = PetscFree(array);CHKERRQ(ierr); 568 } 569 } else { 570 ierr = PetscViewerBinaryWrite(viewer,(void*) idx,N,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr); 571 } 572 } else { 573 const char *tname; 574 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 575 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 576 } 577 PetscFunctionReturn(0); 578 } 579 580 #undef __FUNCT__ 581 #define __FUNCT__ "PetscScalarView" 582 /*@C 583 PetscScalarView - Prints an array of scalars; useful for debugging. 584 585 Collective on PetscViewer 586 587 Input Parameters: 588 + N - number of scalars in array 589 . idx - array of scalars 590 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 591 592 Level: intermediate 593 594 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 595 596 .seealso: PetscIntView(), PetscRealView() 597 @*/ 598 PetscErrorCode PetscScalarView(PetscInt N,const PetscScalar idx[],PetscViewer viewer) 599 { 600 PetscErrorCode ierr; 601 PetscInt j,i,n = N/3,p = N % 3; 602 PetscBool iascii,isbinary; 603 MPI_Comm comm; 604 605 PetscFunctionBegin; 606 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 607 PetscValidHeader(viewer,3); 608 if (N) PetscValidScalarPointer(idx,2); 609 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 610 611 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 612 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 613 if (iascii) { 614 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 615 for (i=0; i<n; i++) { 616 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr); 617 for (j=0; j<3; j++) { 618 #if defined(PETSC_USE_COMPLEX) 619 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", (double)PetscRealPart(idx[i*3+j]),(double)PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr); 620 #else 621 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",(double)idx[i*3+j]);CHKERRQ(ierr); 622 #endif 623 } 624 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 625 } 626 if (p) { 627 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr); 628 for (i=0; i<p; i++) { 629 #if defined(PETSC_USE_COMPLEX) 630 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", (double)PetscRealPart(idx[n*3+i]),(double)PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 631 #else 632 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",(double)idx[3*n+i]);CHKERRQ(ierr); 633 #endif 634 } 635 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 636 } 637 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 638 ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 639 } else if (isbinary) { 640 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN; 641 PetscScalar *array; 642 643 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 644 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 645 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 646 647 if (size > 1) { 648 if (rank) { 649 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 650 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 651 } else { 652 ierr = PetscMalloc1(size,&sizes);CHKERRQ(ierr); 653 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 654 Ntotal = sizes[0]; 655 ierr = PetscMalloc1(size,&displs);CHKERRQ(ierr); 656 displs[0] = 0; 657 for (i=1; i<size; i++) { 658 Ntotal += sizes[i]; 659 displs[i] = displs[i-1] + sizes[i-1]; 660 } 661 ierr = PetscMalloc1(Ntotal,&array);CHKERRQ(ierr); 662 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 663 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr); 664 ierr = PetscFree(sizes);CHKERRQ(ierr); 665 ierr = PetscFree(displs);CHKERRQ(ierr); 666 ierr = PetscFree(array);CHKERRQ(ierr); 667 } 668 } else { 669 ierr = PetscViewerBinaryWrite(viewer,(void*) idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 670 } 671 } else { 672 const char *tname; 673 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 674 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 675 } 676 PetscFunctionReturn(0); 677 } 678 679 680 681 682