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 (PETSC_NULL if not desired) 279 - specific - the specific error message that was set with SETERRxxx() or PetscError(). (PETSC_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) { 292 *text = PetscErrorStrings[errnum-PETSC_ERR_MIN_VALUE-1]; 293 } else if (text) *text = 0; 294 295 if (specific) { 296 *specific = PetscErrorBaseMessage; 297 } 298 PetscFunctionReturn(0); 299 } 300 301 #undef __FUNCT__ 302 #define __FUNCT__ "PetscError" 303 /*@C 304 PetscError - Routine that is called when an error has been detected, 305 usually called through the macro SETERRQ(PETSC_COMM_SELF,). 306 307 Not Collective 308 309 Input Parameters: 310 + comm - communicator over which error occurred. ALL ranks of this communicator MUST call this routine 311 . line - the line number of the error (indicated by __LINE__) 312 . func - the function where the error occured (indicated by __FUNCT__) 313 . dir - the directory of file (indicated by __SDIR__) 314 . file - the file in which the error was detected (indicated by __FILE__) 315 . mess - an error text string, usually just printed to the screen 316 . n - the generic error number 317 . p - PETSC_ERROR_INITIAL indicates the error was initially detected, PETSC_ERROR_REPEAT indicates this is a traceback from a previously detected error 318 - mess - formatted message string - aka printf 319 320 Level: intermediate 321 322 Notes: 323 Most users need not directly use this routine and the error handlers, but 324 can instead use the simplified interface SETERRQ, which has the calling 325 sequence 326 $ SETERRQ(comm,n,mess) 327 328 Experienced users can set the error handler with PetscPushErrorHandler(). 329 330 Developer Note: Since this is called after an error condition it should not be calling any error handlers (currently it ignores any error codes) 331 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 332 but this annoying. 333 334 Concepts: error^setting condition 335 336 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2() 337 @*/ 338 PetscErrorCode PetscError(MPI_Comm comm,int line,const char *func,const char* file,const char *dir,PetscErrorCode n,PetscErrorType p,const char *mess,...) 339 { 340 va_list Argp; 341 size_t fullLength; 342 char buf[2048],*lbuf = 0; 343 PetscBool ismain,isunknown; 344 PetscErrorCode ierr; 345 346 if (!func) func = "User provided function"; 347 if (!file) file = "User file"; 348 if (!dir) dir = " "; 349 350 PetscFunctionBegin; 351 /* Compose the message evaluating the print format */ 352 if (mess) { 353 va_start(Argp,mess); 354 PetscVSNPrintf(buf,2048,mess,&fullLength,Argp); 355 va_end(Argp); 356 lbuf = buf; 357 if (p == 1) { 358 PetscStrncpy(PetscErrorBaseMessage,lbuf,1023); 359 } 360 } 361 362 if (!eh) ierr = PetscTraceBackErrorHandler(comm,line,func,file,dir,n,p,lbuf,0); 363 else ierr = (*eh->handler)(comm,line,func,file,dir,n,p,lbuf,eh->ctx); 364 365 /* 366 If this is called from the main() routine we call MPI_Abort() instead of 367 return to allow the parallel program to be properly shutdown. 368 369 Since this is in the error handler we don't check the errors below. Of course, 370 PetscStrncmp() does its own error checking which is problamatic 371 */ 372 PetscStrncmp(func,"main",4,&ismain); 373 PetscStrncmp(func,"unknown",7,&isunknown); 374 if (ismain || isunknown) { 375 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 376 } 377 #if defined(PETSC_CLANGUAGE_CXX) && !defined(PETSC_USE_EXTERN_CXX) 378 if (p == PETSC_ERROR_IN_CXX) { 379 const char *str; 380 if (eh && eh->ctx) { 381 std::ostringstream *msg; 382 msg = (std::ostringstream*) eh->ctx; 383 str = msg->str().c_str(); 384 } else { 385 str = "Error detected in C PETSc"; 386 } 387 throw PETSc::Exception(str); 388 } 389 #endif 390 PetscFunctionReturn(ierr); 391 } 392 393 /* -------------------------------------------------------------------------*/ 394 395 #undef __FUNCT__ 396 #define __FUNCT__ "PetscIntView" 397 /*@C 398 PetscIntView - Prints an array of integers; useful for debugging. 399 400 Collective on PetscViewer 401 402 Input Parameters: 403 + N - number of integers in array 404 . idx - array of integers 405 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 406 407 Level: intermediate 408 409 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 410 411 .seealso: PetscRealView() 412 @*/ 413 PetscErrorCode PetscIntView(PetscInt N,const PetscInt idx[],PetscViewer viewer) 414 { 415 PetscErrorCode ierr; 416 PetscInt j,i,n = N/20,p = N % 20; 417 PetscBool iascii,isbinary; 418 MPI_Comm comm; 419 420 PetscFunctionBegin; 421 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 422 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3); 423 if (N) PetscValidIntPointer(idx,2); 424 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 425 426 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 427 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 428 if (iascii) { 429 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 430 for (i=0; i<n; i++) { 431 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr); 432 for (j=0; j<20; j++) { 433 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr); 434 } 435 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 436 } 437 if (p) { 438 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr); 439 for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);} 440 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 441 } 442 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 443 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 444 } else if (isbinary) { 445 PetscMPIInt rank,size,*sizes,Ntotal,*displs,NN; 446 PetscInt *array; 447 448 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 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; 535 PetscReal *array; 536 537 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 538 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 539 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 540 541 if (size > 1) { 542 if (rank) { 543 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 544 ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 545 } else { 546 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 547 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 548 Ntotal = sizes[0]; 549 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 550 displs[0] = 0; 551 for (i=1; i<size; i++) { 552 Ntotal += sizes[i]; 553 displs[i] = displs[i-1] + sizes[i-1]; 554 } 555 ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr); 556 ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 557 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_REAL,PETSC_TRUE);CHKERRQ(ierr); 558 ierr = PetscFree(sizes);CHKERRQ(ierr); 559 ierr = PetscFree(displs);CHKERRQ(ierr); 560 ierr = PetscFree(array);CHKERRQ(ierr); 561 } 562 } else { 563 ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr); 564 } 565 } else { 566 const char *tname; 567 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 568 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 569 } 570 PetscFunctionReturn(0); 571 } 572 573 #undef __FUNCT__ 574 #define __FUNCT__ "PetscScalarView" 575 /*@C 576 PetscScalarView - Prints an array of scalars; useful for debugging. 577 578 Collective on PetscViewer 579 580 Input Parameters: 581 + N - number of scalars in array 582 . idx - array of scalars 583 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 584 585 Level: intermediate 586 587 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 588 589 .seealso: PetscIntView(), PetscRealView() 590 @*/ 591 PetscErrorCode PetscScalarView(PetscInt N,const PetscScalar idx[],PetscViewer viewer) 592 { 593 PetscErrorCode ierr; 594 PetscInt j,i,n = N/3,p = N % 3; 595 PetscBool iascii,isbinary; 596 MPI_Comm comm; 597 598 PetscFunctionBegin; 599 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 600 PetscValidHeader(viewer,3); 601 PetscValidScalarPointer(idx,2); 602 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 603 604 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 605 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 606 if (iascii) { 607 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 608 for (i=0; i<n; i++) { 609 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr); 610 for (j=0; j<3; j++) { 611 #if defined (PETSC_USE_COMPLEX) 612 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr); 613 #else 614 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr); 615 #endif 616 } 617 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 618 } 619 if (p) { 620 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr); 621 for (i=0; i<p; i++) { 622 #if defined (PETSC_USE_COMPLEX) 623 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 624 #else 625 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr); 626 #endif 627 } 628 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 629 } 630 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 631 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 632 } else if (isbinary) { 633 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN; 634 PetscScalar *array; 635 636 ierr = PetscMPIIntCast(N,&NN);CHKERRQ(ierr); 637 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 638 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 639 640 if (size > 1) { 641 if (rank) { 642 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 643 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 644 } else { 645 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 646 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 647 Ntotal = sizes[0]; 648 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 649 displs[0] = 0; 650 for (i=1; i<size; i++) { 651 Ntotal += sizes[i]; 652 displs[i] = displs[i-1] + sizes[i-1]; 653 } 654 ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr); 655 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 656 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr); 657 ierr = PetscFree(sizes);CHKERRQ(ierr); 658 ierr = PetscFree(displs);CHKERRQ(ierr); 659 ierr = PetscFree(array);CHKERRQ(ierr); 660 } 661 } else { 662 ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 663 } 664 } else { 665 const char *tname; 666 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 667 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 668 } 669 PetscFunctionReturn(0); 670 } 671 672 673 674 675