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 #undef __FUNCT__ 296 #define __FUNCT__ "PetscError" 297 /*@C 298 PetscError - Routine that is called when an error has been detected, 299 usually called through the macro SETERRQ(PETSC_COMM_SELF,). 300 301 Not Collective 302 303 Input Parameters: 304 + comm - communicator over which error occurred. ALL ranks of this communicator MUST call this routine 305 . line - the line number of the error (indicated by __LINE__) 306 . func - the function where the error occured (indicated by __FUNCT__) 307 . dir - the directory of file (indicated by __SDIR__) 308 . file - the file in which the error was detected (indicated by __FILE__) 309 . mess - an error text string, usually just printed to the screen 310 . n - the generic error number 311 . p - PETSC_ERROR_INITIAL indicates the error was initially detected, PETSC_ERROR_REPEAT indicates this is a traceback from a previously detected error 312 - mess - formatted message string - aka printf 313 314 Level: intermediate 315 316 Notes: 317 Most users need not directly use this routine and the error handlers, but 318 can instead use the simplified interface SETERRQ, which has the calling 319 sequence 320 $ SETERRQ(comm,n,mess) 321 322 Experienced users can set the error handler with PetscPushErrorHandler(). 323 324 Developer Note: Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes) 325 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 326 but this annoying. 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 char buf[2048],*lbuf = 0; 337 PetscBool ismain,isunknown; 338 PetscErrorCode ierr; 339 340 PetscFunctionBegin; 341 if (!func) func = "User provided function"; 342 if (!file) file = "User file"; 343 if (!dir) dir = " "; 344 if (comm == MPI_COMM_NULL) comm = PETSC_COMM_SELF; 345 346 /* Compose the message evaluating the print format */ 347 if (mess) { 348 va_start(Argp,mess); 349 PetscVSNPrintf(buf,2048,mess,&fullLength,Argp); 350 va_end(Argp); 351 lbuf = buf; 352 if (p == 1) PetscStrncpy(PetscErrorBaseMessage,lbuf,1023); 353 } 354 355 if (!eh) ierr = PetscTraceBackErrorHandler(comm,line,func,file,dir,n,p,lbuf,0); 356 else ierr = (*eh->handler)(comm,line,func,file,dir,n,p,lbuf,eh->ctx); 357 358 /* 359 If this is called from the main() routine we call MPI_Abort() instead of 360 return to allow the parallel program to be properly shutdown. 361 362 Since this is in the error handler we don't check the errors below. Of course, 363 PetscStrncmp() does its own error checking which is problamatic 364 */ 365 PetscStrncmp(func,"main",4,&ismain); 366 PetscStrncmp(func,"unknown",7,&isunknown); 367 if (ismain || isunknown) MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 368 369 #if defined(PETSC_CLANGUAGE_CXX) && !defined(PETSC_USE_EXTERN_CXX) 370 if (p == PETSC_ERROR_IN_CXX) { 371 const char *str; 372 if (eh && eh->ctx) { 373 std::ostringstream *msg; 374 msg = (std::ostringstream*) eh->ctx; 375 str = msg->str().c_str(); 376 } else str = "Error detected in C PETSc"; 377 378 throw PETSc::Exception(str); 379 } 380 #endif 381 PetscFunctionReturn(ierr); 382 } 383 384 /* -------------------------------------------------------------------------*/ 385 386 #undef __FUNCT__ 387 #define __FUNCT__ "PetscIntView" 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 swappping 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 = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);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 = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);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 = PetscMalloc(size*sizeof(PetscMPIInt),&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 = PetscMalloc(size*sizeof(PetscMPIInt),&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 = PetscMalloc(Ntotal*sizeof(PetscInt),&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 #undef __FUNCT__ 476 #define __FUNCT__ "PetscRealView" 477 /*@C 478 PetscRealView - Prints an array of doubles; useful for debugging. 479 480 Collective on PetscViewer 481 482 Input Parameters: 483 + N - number of doubles in array 484 . idx - array of doubles 485 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 486 487 Level: intermediate 488 489 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 490 491 .seealso: PetscIntView() 492 @*/ 493 PetscErrorCode PetscRealView(PetscInt N,const PetscReal idx[],PetscViewer viewer) 494 { 495 PetscErrorCode ierr; 496 PetscInt j,i,n = N/5,p = N % 5; 497 PetscBool iascii,isbinary; 498 MPI_Comm comm; 499 500 PetscFunctionBegin; 501 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 502 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3); 503 PetscValidScalarPointer(idx,2); 504 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 505 506 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 507 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 508 if (iascii) { 509 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 510 for (i=0; i<n; i++) { 511 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr); 512 for (j=0; j<5; j++) { 513 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr); 514 } 515 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 516 } 517 if (p) { 518 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr); 519 for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);} 520 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 521 } 522 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 523 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 524 } else if (isbinary) { 525 PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN; 526 PetscReal *array; 527 528 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 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((PetscReal*)idx,NN,MPIU_REAL,0,0,0,MPIU_REAL,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((PetscReal*)idx,NN,MPIU_REAL,array,sizes,displs,MPIU_REAL,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)", PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr); 604 #else 605 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr); 606 #endif 607 } 608 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 609 } 610 if (p) { 611 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr); 612 for (i=0; i<p; i++) { 613 #if defined(PETSC_USE_COMPLEX) 614 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 615 #else 616 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr); 617 #endif 618 } 619 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 620 } 621 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 622 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 623 } else if (isbinary) { 624 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN; 625 PetscScalar *array; 626 627 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 628 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 629 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 630 631 if (size > 1) { 632 if (rank) { 633 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 634 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 635 } else { 636 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 637 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 638 Ntotal = sizes[0]; 639 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 640 displs[0] = 0; 641 for (i=1; i<size; i++) { 642 Ntotal += sizes[i]; 643 displs[i] = displs[i-1] + sizes[i-1]; 644 } 645 ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr); 646 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 647 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr); 648 ierr = PetscFree(sizes);CHKERRQ(ierr); 649 ierr = PetscFree(displs);CHKERRQ(ierr); 650 ierr = PetscFree(array);CHKERRQ(ierr); 651 } 652 } else { 653 ierr = PetscViewerBinaryWrite(viewer,(void*) idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 654 } 655 } else { 656 const char *tname; 657 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 658 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 659 } 660 PetscFunctionReturn(0); 661 } 662 663 664 665 666