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