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 . func - the function where the error occured (indicated by __FUNCT__) 102 . line - the line number of the error (indicated by __LINE__) 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(struct _EH,&neweh);CHKERRQ(ierr); 131 if (eh) neweh->previous = eh; 132 else neweh->previous = 0; 133 neweh->handler = handler; 134 neweh->ctx = ctx; 135 eh = neweh; 136 PetscFunctionReturn(0); 137 } 138 139 #undef __FUNCT__ 140 #define __FUNCT__ "PetscPopErrorHandler" 141 /*@ 142 PetscPopErrorHandler - Removes the latest error handler that was 143 pushed with PetscPushErrorHandler(). 144 145 Not Collective 146 147 Level: intermediate 148 149 Concepts: error handler^setting 150 151 .seealso: PetscPushErrorHandler() 152 @*/ 153 PetscErrorCode 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:\nsee 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 */ "Detected zero pivot in LU factorization:\nsee 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", 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/documentation/faq.html#ZeroPivot", 245 " ", 246 " ", 247 "Overflow in integer operation:\nsee 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 external package needed for type:\nsee 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:\nsee http://www.mcs.anl.gov/petsc/documentation/faq.html#objecttypenotset" 253 /*90 */ " ", 254 /* */ " ", 255 /* */ " ", 256 /* */ " ", 257 /* */ " ", 258 /*95 */ " ", 259 }; 260 261 #undef __FUNCT__ 262 #define __FUNCT__ "PetscErrorMessage" 263 /*@C 264 PetscErrorMessage - returns the text string associated with a PETSc error code. 265 266 Not Collective 267 268 Input Parameter: 269 . errnum - the error code 270 271 Output Parameter: 272 + text - the error message (NULL if not desired) 273 - specific - the specific error message that was set with SETERRxxx() or PetscError(). (NULL if not desired) 274 275 Level: developer 276 277 Concepts: error handler^messages 278 279 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 280 PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 281 @*/ 282 PetscErrorCode PetscErrorMessage(int errnum,const char *text[],char **specific) 283 { 284 PetscFunctionBegin; 285 if (text && errnum > PETSC_ERR_MIN_VALUE && errnum < PETSC_ERR_MAX_VALUE) *text = PetscErrorStrings[errnum-PETSC_ERR_MIN_VALUE-1]; 286 else if (text) *text = 0; 287 288 if (specific) *specific = PetscErrorBaseMessage; 289 PetscFunctionReturn(0); 290 } 291 292 #if defined(PETSC_CLANGUAGE_CXX) 293 /* C++ exceptions are formally not allowed to propagate through extern "C" code. In practice, far too much software 294 * would be broken if implementations did not handle it it some common cases. However, keep in mind 295 * 296 * Rule 62. Don't allow exceptions to propagate across module boundaries 297 * 298 * in "C++ Coding Standards" by Sutter and Alexandrescu. (This accounts for part of the ongoing C++ binary interface 299 * instability.) Having PETSc raise errors as C++ exceptions was probably misguided and should eventually be removed. 300 */ 301 static void PetscCxxErrorThrow() { 302 const char *str; 303 if (eh && eh->ctx) { 304 std::ostringstream *msg; 305 msg = (std::ostringstream*) eh->ctx; 306 str = msg->str().c_str(); 307 } else str = "Error detected in C PETSc"; 308 309 throw PETSc::Exception(str); 310 } 311 #endif 312 313 #undef __FUNCT__ 314 #define __FUNCT__ "PetscError" 315 /*@C 316 PetscError - Routine that is called when an error has been detected, 317 usually called through the macro SETERRQ(PETSC_COMM_SELF,). 318 319 Not Collective 320 321 Input Parameters: 322 + comm - communicator over which error occurred. ALL ranks of this communicator MUST call this routine 323 . line - the line number of the error (indicated by __LINE__) 324 . func - the function where the error occured (indicated by __FUNCT__) 325 . file - the file in which the error was detected (indicated by __FILE__) 326 . mess - an error text string, usually just printed to the screen 327 . n - the generic error number 328 . p - PETSC_ERROR_INITIAL indicates the error was initially detected, PETSC_ERROR_REPEAT indicates this is a traceback from a previously detected error 329 - mess - formatted message string - aka printf 330 331 Level: intermediate 332 333 Notes: 334 Most users need not directly use this routine and the error handlers, but 335 can instead use the simplified interface SETERRQ, which has the calling 336 sequence 337 $ SETERRQ(comm,n,mess) 338 339 Experienced users can set the error handler with PetscPushErrorHandler(). 340 341 Developer Note: Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes) 342 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 343 but this annoying. 344 345 Concepts: error^setting condition 346 347 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2() 348 @*/ 349 PetscErrorCode PetscError(MPI_Comm comm,int line,const char *func,const char *file,PetscErrorCode n,PetscErrorType p,const char *mess,...) 350 { 351 va_list Argp; 352 size_t fullLength; 353 char buf[2048],*lbuf = 0; 354 PetscBool ismain,isunknown; 355 PetscErrorCode ierr; 356 357 PetscFunctionBegin; 358 if (!func) func = "User provided function"; 359 if (!file) file = "User file"; 360 if (comm == MPI_COMM_NULL) comm = PETSC_COMM_SELF; 361 362 /* Compose the message evaluating the print format */ 363 if (mess) { 364 va_start(Argp,mess); 365 PetscVSNPrintf(buf,2048,mess,&fullLength,Argp); 366 va_end(Argp); 367 lbuf = buf; 368 if (p == 1) PetscStrncpy(PetscErrorBaseMessage,lbuf,1023); 369 } 370 371 if (!eh) ierr = PetscTraceBackErrorHandler(comm,line,func,file,n,p,lbuf,0); 372 else ierr = (*eh->handler)(comm,line,func,file,n,p,lbuf,eh->ctx); 373 374 /* 375 If this is called from the main() routine we call MPI_Abort() instead of 376 return to allow the parallel program to be properly shutdown. 377 378 Since this is in the error handler we don't check the errors below. Of course, 379 PetscStrncmp() does its own error checking which is problamatic 380 */ 381 PetscStrncmp(func,"main",4,&ismain); 382 PetscStrncmp(func,"unknown",7,&isunknown); 383 if (ismain || isunknown) MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 384 385 #if defined(PETSC_CLANGUAGE_CXX) 386 if (p == PETSC_ERROR_IN_CXX) { 387 PetscCxxErrorThrow(); 388 } 389 #endif 390 PetscFunctionReturn(ierr); 391 } 392 393 /* -------------------------------------------------------------------------*/ 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "PetscIntView" 397 /*@C 398 PetscIntView - Prints an array of integers; useful for debugging. 399 400 Collective on PetscViewer 401 402 Input Parameters: 403 + N - number of integers in array 404 . idx - array of integers 405 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 406 407 Level: intermediate 408 409 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 410 411 .seealso: PetscRealView() 412 @*/ 413 PetscErrorCode PetscIntView(PetscInt N,const PetscInt idx[],PetscViewer viewer) 414 { 415 PetscErrorCode ierr; 416 PetscInt j,i,n = N/20,p = N % 20; 417 PetscBool iascii,isbinary; 418 MPI_Comm comm; 419 420 PetscFunctionBegin; 421 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 422 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3); 423 if (N) PetscValidIntPointer(idx,2); 424 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 425 426 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 427 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 428 if (iascii) { 429 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 430 for (i=0; i<n; i++) { 431 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr); 432 for (j=0; j<20; j++) { 433 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr); 434 } 435 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 436 } 437 if (p) { 438 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr); 439 for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);} 440 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 441 } 442 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 443 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 444 } else if (isbinary) { 445 PetscMPIInt rank,size,*sizes,Ntotal,*displs,NN; 446 PetscInt *array; 447 448 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 449 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 450 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 451 452 if (size > 1) { 453 if (rank) { 454 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 455 ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr); 456 } else { 457 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 458 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 459 Ntotal = sizes[0]; 460 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 461 displs[0] = 0; 462 for (i=1; i<size; i++) { 463 Ntotal += sizes[i]; 464 displs[i] = displs[i-1] + sizes[i-1]; 465 } 466 ierr = PetscMalloc(Ntotal*sizeof(PetscInt),&array);CHKERRQ(ierr); 467 ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr); 468 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 469 ierr = PetscFree(sizes);CHKERRQ(ierr); 470 ierr = PetscFree(displs);CHKERRQ(ierr); 471 ierr = PetscFree(array);CHKERRQ(ierr); 472 } 473 } else { 474 ierr = PetscViewerBinaryWrite(viewer,(void*) idx,N,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 475 } 476 } else { 477 const char *tname; 478 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 479 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 480 } 481 PetscFunctionReturn(0); 482 } 483 484 #undef __FUNCT__ 485 #define __FUNCT__ "PetscRealView" 486 /*@C 487 PetscRealView - Prints an array of doubles; useful for debugging. 488 489 Collective on PetscViewer 490 491 Input Parameters: 492 + N - number of doubles in array 493 . idx - array of doubles 494 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 495 496 Level: intermediate 497 498 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 499 500 .seealso: PetscIntView() 501 @*/ 502 PetscErrorCode PetscRealView(PetscInt N,const PetscReal idx[],PetscViewer viewer) 503 { 504 PetscErrorCode ierr; 505 PetscInt j,i,n = N/5,p = N % 5; 506 PetscBool iascii,isbinary; 507 MPI_Comm comm; 508 509 PetscFunctionBegin; 510 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 511 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3); 512 PetscValidScalarPointer(idx,2); 513 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 514 515 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 516 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 517 if (iascii) { 518 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 519 for (i=0; i<n; i++) { 520 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr); 521 for (j=0; j<5; j++) { 522 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr); 523 } 524 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 525 } 526 if (p) { 527 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr); 528 for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);} 529 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 530 } 531 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 532 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 533 } else if (isbinary) { 534 PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN; 535 PetscReal *array; 536 537 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 538 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 539 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 540 541 if (size > 1) { 542 if (rank) { 543 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 544 ierr = MPI_Gatherv((PetscReal*)idx,NN,MPIU_REAL,0,0,0,MPIU_REAL,0,comm);CHKERRQ(ierr); 545 } else { 546 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 547 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 548 Ntotal = sizes[0]; 549 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 550 displs[0] = 0; 551 for (i=1; i<size; i++) { 552 Ntotal += sizes[i]; 553 displs[i] = displs[i-1] + sizes[i-1]; 554 } 555 ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr); 556 ierr = MPI_Gatherv((PetscReal*)idx,NN,MPIU_REAL,array,sizes,displs,MPIU_REAL,0,comm);CHKERRQ(ierr); 557 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_REAL,PETSC_TRUE);CHKERRQ(ierr); 558 ierr = PetscFree(sizes);CHKERRQ(ierr); 559 ierr = PetscFree(displs);CHKERRQ(ierr); 560 ierr = PetscFree(array);CHKERRQ(ierr); 561 } 562 } else { 563 ierr = PetscViewerBinaryWrite(viewer,(void*) idx,N,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr); 564 } 565 } else { 566 const char *tname; 567 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 568 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 569 } 570 PetscFunctionReturn(0); 571 } 572 573 #undef __FUNCT__ 574 #define __FUNCT__ "PetscScalarView" 575 /*@C 576 PetscScalarView - Prints an array of scalars; useful for debugging. 577 578 Collective on PetscViewer 579 580 Input Parameters: 581 + N - number of scalars in array 582 . idx - array of scalars 583 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 584 585 Level: intermediate 586 587 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 588 589 .seealso: PetscIntView(), PetscRealView() 590 @*/ 591 PetscErrorCode PetscScalarView(PetscInt N,const PetscScalar idx[],PetscViewer viewer) 592 { 593 PetscErrorCode ierr; 594 PetscInt j,i,n = N/3,p = N % 3; 595 PetscBool iascii,isbinary; 596 MPI_Comm comm; 597 598 PetscFunctionBegin; 599 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 600 PetscValidHeader(viewer,3); 601 PetscValidScalarPointer(idx,2); 602 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 603 604 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 605 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 606 if (iascii) { 607 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 608 for (i=0; i<n; i++) { 609 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr); 610 for (j=0; j<3; j++) { 611 #if defined(PETSC_USE_COMPLEX) 612 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr); 613 #else 614 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr); 615 #endif 616 } 617 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 618 } 619 if (p) { 620 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr); 621 for (i=0; i<p; i++) { 622 #if defined(PETSC_USE_COMPLEX) 623 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 624 #else 625 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr); 626 #endif 627 } 628 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 629 } 630 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 631 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 632 } else if (isbinary) { 633 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN; 634 PetscScalar *array; 635 636 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 637 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 638 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 639 640 if (size > 1) { 641 if (rank) { 642 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 643 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 644 } else { 645 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 646 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 647 Ntotal = sizes[0]; 648 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 649 displs[0] = 0; 650 for (i=1; i<size; i++) { 651 Ntotal += sizes[i]; 652 displs[i] = displs[i-1] + sizes[i-1]; 653 } 654 ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr); 655 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 656 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr); 657 ierr = PetscFree(sizes);CHKERRQ(ierr); 658 ierr = PetscFree(displs);CHKERRQ(ierr); 659 ierr = PetscFree(array);CHKERRQ(ierr); 660 } 661 } else { 662 ierr = PetscViewerBinaryWrite(viewer,(void*) idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 663 } 664 } else { 665 const char *tname; 666 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 667 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 668 } 669 PetscFunctionReturn(0); 670 } 671 672 673 674 675