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