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