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; 448 PetscInt *array; 449 450 NN = PetscMPIIntCast(N); 451 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 452 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 453 454 if (size > 1) { 455 if (rank) { 456 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 457 ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr); 458 } else { 459 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 460 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 461 Ntotal = sizes[0]; 462 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 463 displs[0] = 0; 464 for (i=1; i<size; i++) { 465 Ntotal += sizes[i]; 466 displs[i] = displs[i-1] + sizes[i-1]; 467 } 468 ierr = PetscMalloc(Ntotal*sizeof(PetscInt),&array);CHKERRQ(ierr); 469 ierr = MPI_Gatherv((void*)idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr); 470 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 471 ierr = PetscFree(sizes);CHKERRQ(ierr); 472 ierr = PetscFree(displs);CHKERRQ(ierr); 473 ierr = PetscFree(array);CHKERRQ(ierr); 474 } 475 } else { 476 ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 477 } 478 } else { 479 const char *tname; 480 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 481 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 482 } 483 PetscFunctionReturn(0); 484 } 485 486 #undef __FUNCT__ 487 #define __FUNCT__ "PetscRealView" 488 /*@C 489 PetscRealView - Prints an array of doubles; useful for debugging. 490 491 Collective on PetscViewer 492 493 Input Parameters: 494 + N - number of doubles in array 495 . idx - array of doubles 496 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 497 498 Level: intermediate 499 500 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 501 502 .seealso: PetscIntView() 503 @*/ 504 PetscErrorCode PetscRealView(PetscInt N,const PetscReal idx[],PetscViewer viewer) 505 { 506 PetscErrorCode ierr; 507 PetscInt j,i,n = N/5,p = N % 5; 508 PetscBool iascii,isbinary; 509 MPI_Comm comm; 510 511 PetscFunctionBegin; 512 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 513 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,3); 514 PetscValidScalarPointer(idx,2); 515 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 516 517 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 518 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 519 if (iascii) { 520 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 521 for (i=0; i<n; i++) { 522 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr); 523 for (j=0; j<5; j++) { 524 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr); 525 } 526 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 527 } 528 if (p) { 529 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr); 530 for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);} 531 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 532 } 533 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 534 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 535 } else if (isbinary) { 536 PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN; 537 PetscReal *array; 538 539 NN = PetscMPIIntCast(N); 540 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 541 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 542 543 if (size > 1) { 544 if (rank) { 545 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 546 ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 547 } else { 548 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 549 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 550 Ntotal = sizes[0]; 551 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 552 displs[0] = 0; 553 for (i=1; i<size; i++) { 554 Ntotal += sizes[i]; 555 displs[i] = displs[i-1] + sizes[i-1]; 556 } 557 ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr); 558 ierr = MPI_Gatherv((void*)idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 559 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_REAL,PETSC_TRUE);CHKERRQ(ierr); 560 ierr = PetscFree(sizes);CHKERRQ(ierr); 561 ierr = PetscFree(displs);CHKERRQ(ierr); 562 ierr = PetscFree(array);CHKERRQ(ierr); 563 } 564 } else { 565 ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_REAL,PETSC_FALSE);CHKERRQ(ierr); 566 } 567 } else { 568 const char *tname; 569 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 570 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 571 } 572 PetscFunctionReturn(0); 573 } 574 575 #undef __FUNCT__ 576 #define __FUNCT__ "PetscScalarView" 577 /*@C 578 PetscScalarView - Prints an array of scalars; useful for debugging. 579 580 Collective on PetscViewer 581 582 Input Parameters: 583 + N - number of scalars in array 584 . idx - array of scalars 585 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 586 587 Level: intermediate 588 589 Developer Notes: idx cannot be const because may be passed to binary viewer where byte swappping is done 590 591 .seealso: PetscIntView(), PetscRealView() 592 @*/ 593 PetscErrorCode PetscScalarView(PetscInt N,const PetscScalar idx[],PetscViewer viewer) 594 { 595 PetscErrorCode ierr; 596 PetscInt j,i,n = N/3,p = N % 3; 597 PetscBool iascii,isbinary; 598 MPI_Comm comm; 599 600 PetscFunctionBegin; 601 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 602 PetscValidHeader(viewer,3); 603 PetscValidScalarPointer(idx,2); 604 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 605 606 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 607 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 608 if (iascii) { 609 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr); 610 for (i=0; i<n; i++) { 611 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr); 612 for (j=0; j<3; j++) { 613 #if defined (PETSC_USE_COMPLEX) 614 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));CHKERRQ(ierr); 615 #else 616 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);CHKERRQ(ierr); 617 #endif 618 } 619 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 620 } 621 if (p) { 622 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);CHKERRQ(ierr); 623 for (i=0; i<p; i++) { 624 #if defined (PETSC_USE_COMPLEX) 625 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 626 #else 627 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr); 628 #endif 629 } 630 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 631 } 632 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 633 ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_FALSE);CHKERRQ(ierr); 634 } else if (isbinary) { 635 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN; 636 PetscScalar *array; 637 638 NN = PetscMPIIntCast(N); 639 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 640 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 641 642 if (size > 1) { 643 if (rank) { 644 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 645 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 646 } else { 647 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 648 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 649 Ntotal = sizes[0]; 650 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 651 displs[0] = 0; 652 for (i=1; i<size; i++) { 653 Ntotal += sizes[i]; 654 displs[i] = displs[i-1] + sizes[i-1]; 655 } 656 ierr = PetscMalloc(Ntotal*sizeof(PetscScalar),&array);CHKERRQ(ierr); 657 ierr = MPI_Gatherv((void*)idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 658 ierr = PetscViewerBinaryWrite(viewer,array,Ntotal,PETSC_SCALAR,PETSC_TRUE);CHKERRQ(ierr); 659 ierr = PetscFree(sizes);CHKERRQ(ierr); 660 ierr = PetscFree(displs);CHKERRQ(ierr); 661 ierr = PetscFree(array);CHKERRQ(ierr); 662 } 663 } else { 664 ierr = PetscViewerBinaryWrite(viewer,(void *) idx,N,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 665 } 666 } else { 667 const char *tname; 668 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 669 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 670 } 671 PetscFunctionReturn(0); 672 } 673 674 675 676 677