1 #define PETSC_DLL 2 /* 3 Code that allows one to set the error handlers 4 */ 5 #include "petsc.h" /*I "petsc.h" I*/ 6 #include "petscsys.h" 7 #include <stdarg.h> 8 #if defined(PETSC_HAVE_STDLIB_H) 9 #include <stdlib.h> 10 #endif 11 12 typedef struct _EH *EH; 13 struct _EH { 14 int cookie; 15 PetscErrorCode (*handler)(int,const char*,const char*,const char *,PetscErrorCode,int,const char*,void *); 16 void *ctx; 17 EH previous; 18 }; 19 20 static EH eh = 0; 21 22 #undef __FUNCT__ 23 #define __FUNCT__ "PetscEmacsClientErrorHandler" 24 /*@C 25 PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to 26 load the file where the error occured. Then calls the "previous" error handler. 27 28 Not Collective 29 30 Input Parameters: 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(number,p,mess) 52 53 Notes for experienced users: 54 Use PetscPushErrorHandler() to set the desired error handler. The 55 currently available PETSc error handlers include PetscTraceBackErrorHandler(), 56 PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler() 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 PETSC_DLLEXPORT PetscEmacsClientErrorHandler(int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,int 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 71 PetscFunctionBegin; 72 /* Note: don't check error codes since this an error handler :-) */ 73 ierr = PetscGetPetscDir(&pdir);CHKERRQ(ierr); 74 sprintf(command,"emacsclient +%d %s/%s%s\n",line,pdir,dir,file); 75 #if defined(PETSC_HAVE_POPEN) 76 ierr = PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp); 77 ierr = PetscPClose(MPI_COMM_WORLD,fp); 78 #else 79 SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 80 #endif 81 ierr = PetscPopErrorHandler(); /* remove this handler from the stack of handlers */ 82 if (!eh) ierr = PetscTraceBackErrorHandler(line,fun,file,dir,n,p,mess,0); 83 else ierr = (*eh->handler)(line,fun,file,dir,n,p,mess,eh->ctx); 84 PetscFunctionReturn(ierr); 85 } 86 87 #undef __FUNCT__ 88 #define __FUNCT__ "PetscPushErrorHandler" 89 /*@C 90 PetscPushErrorHandler - Sets a routine to be called on detection of errors. 91 92 Not Collective 93 94 Input Parameters: 95 + handler - error handler routine 96 - ctx - optional handler context that contains information needed by the handler (for 97 example file pointers for error messages etc.) 98 99 Calling sequence of handler: 100 $ int handler(int line,char *func,char *file,char *dir,PetscErrorCode n,int p,char *mess,void *ctx); 101 102 + func - the function where the error occured (indicated by __FUNCT__) 103 . line - the line number of the error (indicated by __LINE__) 104 . file - the file in which the error was detected (indicated by __FILE__) 105 . dir - the directory of the file (indicated by __SDIR__) 106 . n - the generic error number (see list defined in include/petscerror.h) 107 . p - the specific error number 108 . mess - an error text string, usually just printed to the screen 109 - ctx - the error handler context 110 111 Options Database Keys: 112 + -on_error_attach_debugger <noxterm,gdb or dbx> 113 - -on_error_abort 114 115 Level: intermediate 116 117 .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 118 119 @*/ 120 PetscErrorCode PETSC_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char *,const char*,const char*,PetscErrorCode,int,const char*,void*),void *ctx) 121 { 122 EH neweh; 123 PetscErrorCode ierr; 124 125 PetscFunctionBegin; 126 ierr = PetscNew(struct _EH,&neweh);CHKERRQ(ierr); 127 if (eh) {neweh->previous = eh;} 128 else {neweh->previous = 0;} 129 neweh->handler = handler; 130 neweh->ctx = ctx; 131 eh = neweh; 132 PetscFunctionReturn(0); 133 } 134 135 #undef __FUNCT__ 136 #define __FUNCT__ "PetscPopErrorHandler" 137 /*@C 138 PetscPopErrorHandler - Removes the latest error handler that was 139 pushed with PetscPushErrorHandler(). 140 141 Not Collective 142 143 Level: intermediate 144 145 Concepts: error handler^setting 146 147 .seealso: PetscPushErrorHandler() 148 @*/ 149 PetscErrorCode PETSC_DLLEXPORT PetscPopErrorHandler(void) 150 { 151 EH tmp; 152 PetscErrorCode ierr; 153 154 PetscFunctionBegin; 155 if (!eh) PetscFunctionReturn(0); 156 tmp = eh; 157 eh = eh->previous; 158 ierr = PetscFree(tmp);CHKERRQ(ierr); 159 160 PetscFunctionReturn(0); 161 } 162 163 static char PetscErrorBaseMessage[1024]; 164 /* 165 The numerical values for these are defined in include/petscerror.h; any changes 166 there must also be made here 167 */ 168 static const char *PetscErrorStrings[] = { 169 /*55 */ "Out of memory", 170 "No support for this operation for this object type", 171 "No support for this operation on this system", 172 /*58 */ "Operation done in wrong order", 173 /*59 */ "Signal received", 174 /*60 */ "Nonconforming object sizes", 175 "Argument aliasing not permitted", 176 "Invalid argument", 177 /*63 */ "Argument out of range", 178 "Corrupt argument: see http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#Corrupt", 179 "Unable to open file", 180 "Read from file failed", 181 "Write to file failed", 182 "Invalid pointer", 183 /*69 */ "Arguments must have same type", 184 "", 185 /*71 */ "Detected zero pivot in LU factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot", 186 /*72 */ "Floating point exception", 187 /*73 */ "Object is in wrong state", 188 "Corrupted Petsc object", 189 "Arguments are incompatible", 190 "Error in external library", 191 /*77 */ "Petsc has generated inconsistent data", 192 "Memory corruption", 193 "Unexpected data in file", 194 /*80 */ "Arguments must have same communicators", 195 /*81 */ "Detected zero pivot in Cholesky factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot", 196 " ", 197 " ", 198 " ", 199 /*85 */ "Null argument, when expecting valid pointer", 200 /*86 */ "Unknown type. Check for miss-spelling or missing external package needed for type"}; 201 202 #undef __FUNCT__ 203 #define __FUNCT__ "PetscErrorMessage" 204 /*@C 205 PetscErrorMessage - returns the text string associated with a PETSc error code. 206 207 Not Collective 208 209 Input Parameter: 210 . errnum - the error code 211 212 Output Parameter: 213 + text - the error message (PETSC_NULL if not desired) 214 - specific - the specific error message that was set with SETERRxxx() or PetscError(). (PETSC_NULL if not desired) 215 216 Level: developer 217 218 Concepts: error handler^messages 219 220 .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(), 221 PetscAbortErrorHandler(), PetscTraceBackErrorHandler() 222 @*/ 223 PetscErrorCode PETSC_DLLEXPORT PetscErrorMessage(int errnum,const char *text[],char **specific) 224 { 225 PetscFunctionBegin; 226 if (text && errnum >= PETSC_ERR_MEM && errnum <= PETSC_ERR_MEM_MALLOC_0) { 227 *text = PetscErrorStrings[errnum-PETSC_ERR_MEM]; 228 } else if (text) *text = 0; 229 230 if (specific) { 231 *specific = PetscErrorBaseMessage; 232 } 233 PetscFunctionReturn(0); 234 } 235 236 #if defined(PETSC_USE_ERRORCHECKING) 237 PetscErrorCode PETSC_DLLEXPORT PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX] = {0}; 238 PetscInt PETSC_DLLEXPORT PetscErrorUncatchableCount = 0; 239 PetscErrorCode PETSC_DLLEXPORT PetscExceptions[PETSC_EXCEPTIONS_MAX] = {0}; 240 PetscInt PETSC_DLLEXPORT PetscExceptionsCount = 0; 241 PetscErrorCode PETSC_DLLEXPORT PetscExceptionTmp = 0; 242 243 #undef __FUNCT__ 244 #define __FUNCT__ "PetscErrorIsCatchable" 245 static PetscTruth PetscErrorIsCatchable(PetscErrorCode err) 246 { 247 PetscInt i; 248 for (i=0; i<PetscErrorUncatchableCount; i++) { 249 if (err == PetscErrorUncatchable[i]) return PETSC_FALSE; 250 } 251 return PETSC_TRUE; 252 } 253 254 #undef __FUNCT__ 255 #define __FUNCT__ "PetscErrorSetCatchable" 256 /*@ 257 PetscErrorSetCatchable - Sets if a PetscErrorCode can be caught with a PetscExceptionTry1() 258 PetscExceptionCaught() pair. By default all errors are catchable. 259 260 Input Parameters: 261 + err - error code 262 - flg - PETSC_TRUE means allow to be caught, PETSC_FALSE means do not allow to be caught 263 264 Level: advanced 265 266 Notes: 267 PETSc must not be configured using the option --with-errorchecking=0 for this to work 268 269 .seealso: PetscExceptionTry1(), PetscExceptionCaught() 270 @*/ 271 PetscErrorCode PETSC_DLLEXPORT PetscErrorSetCatchable(PetscErrorCode err,PetscTruth flg) 272 { 273 PetscFunctionBegin; 274 if (!flg && PetscErrorIsCatchable(err)) { 275 /* add to list of uncatchable */ 276 if (PetscErrorUncatchableCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_ERR_PLIB,"Stack for PetscErrorUncatchable is overflowed, recompile \nsrc/sysd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX"); 277 PetscErrorUncatchable[PetscErrorUncatchableCount++] = err; 278 } else if (flg && !PetscErrorIsCatchable(err)) { 279 /* remove from list of uncatchable */ 280 PetscInt i; 281 for (i=0; i<PetscErrorUncatchableCount; i++) { 282 if (PetscErrorUncatchable[i] == err) break; 283 } 284 for (;i<PetscErrorUncatchableCount; i++) { 285 PetscErrorUncatchable[i] = PetscErrorUncatchable[i+1]; 286 } 287 PetscErrorUncatchableCount--; 288 } 289 PetscFunctionReturn(0); 290 } 291 292 #undef __FUNCT__ 293 #define __FUNCT__ "PetscExceptionPush" 294 PetscErrorCode PETSC_DLLEXPORT PetscExceptionPush(PetscErrorCode err) 295 { 296 PetscFunctionBegin; 297 if (PetscExceptionsCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_ERR_PLIB,"Stack for PetscExceptions is overflowed, recompile \nsrc/sysd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX"); 298 if (PetscErrorIsCatchable(err)) PetscExceptions[PetscExceptionsCount++] = err; 299 PetscFunctionReturn(0); 300 } 301 302 #undef __FUNCT__ 303 #define __FUNCT__ "PetscExceptionPop" 304 void PETSC_DLLEXPORT PetscExceptionPop(PetscErrorCode err) 305 { 306 /* if (PetscExceptionsCount <= 0)SETERRQ(PETSC_ERR_PLIB,"Stack for PetscExceptions is empty"); */ 307 if (PetscErrorIsCatchable(err)) PetscExceptionsCount--; 308 } 309 #endif 310 311 #undef __FUNCT__ 312 #define __FUNCT__ "PetscError" 313 /*@C 314 PetscError - Routine that is called when an error has been detected, 315 usually called through the macro SETERRQ(). 316 317 Not Collective 318 319 Input Parameters: 320 + line - the line number of the error (indicated by __LINE__) 321 . func - the function where the error occured (indicated by __FUNCT__) 322 . dir - the directory of file (indicated by __SDIR__) 323 . file - the file in which the error was detected (indicated by __FILE__) 324 . mess - an error text string, usually just printed to the screen 325 . n - the generic error number 326 . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a 327 previously detected error 328 - mess - formatted message string - aka printf 329 330 Level: intermediate 331 332 Notes: 333 Most users need not directly use this routine and the error handlers, but 334 can instead use the simplified interface SETERRQ, which has the calling 335 sequence 336 $ SETERRQ(n,mess) 337 338 Experienced users can set the error handler with PetscPushErrorHandler(). 339 340 Concepts: error^setting condition 341 342 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2() 343 @*/ 344 PetscErrorCode PETSC_DLLEXPORT PetscError(int line,const char *func,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,...) 345 { 346 va_list Argp; 347 PetscErrorCode ierr; 348 char buf[2048],*lbuf = 0; 349 PetscTruth ismain,isunknown; 350 #if defined(PETSC_USE_ERRORCHECKING) 351 PetscInt i; 352 #endif 353 354 if (!func) func = "User provided function"; 355 if (!file) file = "User file"; 356 if (!dir) dir = " "; 357 358 PetscFunctionBegin; 359 /* Compose the message evaluating the print format */ 360 if (mess) { 361 va_start(Argp,mess); 362 PetscVSNPrintf(buf,2048,mess,Argp); 363 va_end(Argp); 364 lbuf = buf; 365 if (p == 1) { 366 PetscStrncpy(PetscErrorBaseMessage,lbuf,1023); 367 } 368 } 369 370 #if defined(PETSC_USE_ERRORCHECKING) 371 /* check if user is catching this exception */ 372 for (i=0; i<PetscExceptionsCount; i++) { 373 if (n == PetscExceptions[i]) PetscFunctionReturn(n); 374 } 375 #endif 376 377 if (!eh) ierr = PetscTraceBackErrorHandler(line,func,file,dir,n,p,lbuf,0); 378 else ierr = (*eh->handler)(line,func,file,dir,n,p,lbuf,eh->ctx); 379 380 /* 381 If this is called from the main() routine we call MPI_Abort() instead of 382 return to allow the parallel program to be properly shutdown. 383 384 Since this is in the error handler we don't check the errors below. Of course, 385 PetscStrncmp() does its own error checking which is problamatic 386 */ 387 PetscStrncmp(func,"main",4,&ismain); 388 PetscStrncmp(func,"unknown",7,&isunknown); 389 if (ismain || isunknown) { 390 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 391 } 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 .seealso: PetscRealView() 412 @*/ 413 PetscErrorCode PETSC_DLLEXPORT PetscIntView(PetscInt N,PetscInt idx[],PetscViewer viewer) 414 { 415 PetscErrorCode ierr; 416 PetscInt j,i,n = N/20,p = N % 20; 417 PetscTruth iascii,issocket; 418 MPI_Comm comm; 419 420 PetscFunctionBegin; 421 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 422 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,3); 423 PetscValidIntPointer(idx,2); 424 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 425 426 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 427 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 428 if (iascii) { 429 for (i=0; i<n; i++) { 430 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);CHKERRQ(ierr); 431 for (j=0; j<20; j++) { 432 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);CHKERRQ(ierr); 433 } 434 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 435 } 436 if (p) { 437 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);CHKERRQ(ierr); 438 for (i=0; i<p; i++) { ierr = PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);CHKERRQ(ierr);} 439 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 440 } 441 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 442 #if defined(PETSC_USE_SOCKET_VIEWER) 443 } else if (issocket) { 444 PetscMPIInt rank,size,*sizes,Ntotal,*displs, NN = (PetscMPIInt)N; 445 PetscInt *array; 446 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 447 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 448 449 if (size > 1) { 450 if (rank) { 451 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 452 ierr = MPI_Gatherv(idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);CHKERRQ(ierr); 453 } else { 454 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 455 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPIU_INT,0,comm);CHKERRQ(ierr); 456 Ntotal = sizes[0]; 457 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 458 displs[0] = 0; 459 for (i=1; i<size; i++) { 460 Ntotal += sizes[i]; 461 displs[i] = displs[i-1] + sizes[i-1]; 462 } 463 ierr = PetscMalloc(Ntotal*sizeof(PetscInt),&array);CHKERRQ(ierr); 464 ierr = MPI_Gatherv(idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);CHKERRQ(ierr); 465 ierr = PetscViewerSocketPutInt(viewer,Ntotal,array);CHKERRQ(ierr); 466 ierr = PetscFree(sizes);CHKERRQ(ierr); 467 ierr = PetscFree(displs);CHKERRQ(ierr); 468 ierr = PetscFree(array);CHKERRQ(ierr); 469 } 470 } else { 471 ierr = PetscViewerSocketPutInt(viewer,N,idx);CHKERRQ(ierr); 472 } 473 #endif 474 } else { 475 const char *tname; 476 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 477 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 478 } 479 PetscFunctionReturn(0); 480 } 481 482 #undef __FUNCT__ 483 #define __FUNCT__ "PetscRealView" 484 /*@C 485 PetscRealView - Prints an array of doubles; useful for debugging. 486 487 Collective on PetscViewer 488 489 Input Parameters: 490 + N - number of doubles in array 491 . idx - array of doubles 492 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 493 494 Level: intermediate 495 496 .seealso: PetscIntView() 497 @*/ 498 PetscErrorCode PETSC_DLLEXPORT PetscRealView(PetscInt N,PetscReal idx[],PetscViewer viewer) 499 { 500 PetscErrorCode ierr; 501 PetscInt j,i,n = N/5,p = N % 5; 502 PetscTruth iascii,issocket; 503 MPI_Comm comm; 504 505 PetscFunctionBegin; 506 if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 507 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,3); 508 PetscValidScalarPointer(idx,2); 509 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 510 511 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 512 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 513 if (iascii) { 514 for (i=0; i<n; i++) { 515 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);CHKERRQ(ierr); 516 for (j=0; j<5; j++) { 517 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);CHKERRQ(ierr); 518 } 519 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 520 } 521 if (p) { 522 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);CHKERRQ(ierr); 523 for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);CHKERRQ(ierr);} 524 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 525 } 526 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 527 #if defined(PETSC_USE_SOCKET_VIEWER) 528 } else if (issocket) { 529 PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN = (PetscMPIInt)N; 530 PetscReal *array; 531 532 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 533 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 534 535 if (size > 1) { 536 if (rank) { 537 ierr = MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);CHKERRQ(ierr); 538 ierr = MPI_Gatherv(idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 539 } else { 540 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&sizes);CHKERRQ(ierr); 541 ierr = MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);CHKERRQ(ierr); 542 Ntotal = sizes[0]; 543 ierr = PetscMalloc(size*sizeof(PetscMPIInt),&displs);CHKERRQ(ierr); 544 displs[0] = 0; 545 for (i=1; i<size; i++) { 546 Ntotal += sizes[i]; 547 displs[i] = displs[i-1] + sizes[i-1]; 548 } 549 ierr = PetscMalloc(Ntotal*sizeof(PetscReal),&array);CHKERRQ(ierr); 550 ierr = MPI_Gatherv(idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);CHKERRQ(ierr); 551 ierr = PetscViewerSocketPutReal(viewer,Ntotal,1,array);CHKERRQ(ierr); 552 ierr = PetscFree(sizes);CHKERRQ(ierr); 553 ierr = PetscFree(displs);CHKERRQ(ierr); 554 ierr = PetscFree(array);CHKERRQ(ierr); 555 } 556 } else { 557 ierr = PetscViewerSocketPutReal(viewer,N,1,idx);CHKERRQ(ierr); 558 } 559 #endif 560 } else { 561 const char *tname; 562 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 563 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 564 } 565 PetscFunctionReturn(0); 566 } 567 568 #undef __FUNCT__ 569 #define __FUNCT__ "PetscScalarView" 570 /*@C 571 PetscScalarView - Prints an array of scalars; useful for debugging. 572 573 Collective on PetscViewer 574 575 Input Parameters: 576 + N - number of scalars in array 577 . idx - array of scalars 578 - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0 579 580 Level: intermediate 581 582 .seealso: PetscIntView(), PetscRealView() 583 @*/ 584 PetscErrorCode PETSC_DLLEXPORT PetscScalarView(PetscInt N,PetscScalar idx[],PetscViewer viewer) 585 { 586 PetscErrorCode ierr; 587 PetscInt j,i,n = N/3,p = N % 3; 588 PetscTruth iascii,issocket; 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 = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); 598 ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 599 if (iascii) { 600 for (i=0; i<n; i++) { 601 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);CHKERRQ(ierr); 602 for (j=0; j<3; j++) { 603 #if defined (PETSC_USE_COMPLEX) 604 ierr = PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)", 605 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)", 617 PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));CHKERRQ(ierr); 618 #else 619 ierr = PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);CHKERRQ(ierr); 620 #endif 621 } 622 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"\n");CHKERRQ(ierr); 623 } 624 ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 625 #if defined(PETSC_USE_SOCKET_VIEWER) 626 } else if (issocket) { 627 PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN = (PetscMPIInt)N; 628 PetscScalar *array; 629 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(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(idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);CHKERRQ(ierr); 649 ierr = PetscViewerSocketPutScalar(viewer,Ntotal,1,array);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 = PetscViewerSocketPutScalar(viewer,N,1,idx);CHKERRQ(ierr); 656 } 657 #endif 658 } else { 659 const char *tname; 660 ierr = PetscObjectGetName((PetscObject)viewer,&tname);CHKERRQ(ierr); 661 SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname); 662 } 663 PetscFunctionReturn(0); 664 } 665 666 667 668 669