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