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