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