1 2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 3 #include <fcntl.h> 4 #if defined(PETSC_HAVE_UNISTD_H) 5 #include <unistd.h> 6 #endif 7 #if defined(PETSC_HAVE_IO_H) 8 #include <io.h> 9 #endif 10 11 typedef struct { 12 int fdes; /* file descriptor, ignored if using MPI IO */ 13 #if defined(PETSC_HAVE_MPIIO) 14 PetscBool usempiio; 15 MPI_File mfdes; /* ignored unless using MPI IO */ 16 MPI_File mfsub; /* subviewer support */ 17 MPI_Offset moff; 18 #endif 19 PetscFileMode btype; /* read or write? */ 20 FILE *fdes_info; /* optional file containing info on binary file*/ 21 PetscBool storecompressed; /* gzip the write binary file when closing it*/ 22 char *filename; 23 char *ogzfilename; /* gzip can be run after the filename has been updated */ 24 PetscBool skipinfo; /* Don't create info file for writing; don't use for reading */ 25 PetscBool skipoptions; /* don't use PETSc options database when loading */ 26 PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */ 27 PetscBool skipheader; /* don't write header, only raw data */ 28 PetscBool matlabheaderwritten; /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */ 29 PetscBool setfromoptionscalled; 30 } PetscViewer_Binary; 31 32 static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer) 33 { 34 int rank; 35 PetscErrorCode ierr; 36 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 37 38 PetscFunctionBegin; 39 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 40 41 /* Return subviewer in process zero */ 42 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 43 if (!rank) { 44 PetscMPIInt flg; 45 46 ierr = MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);CHKERRQ(ierr); 47 if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERBINARY requires a singleton MPI_Comm"); 48 ierr = PetscViewerCreate(comm,outviewer);CHKERRQ(ierr); 49 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);CHKERRQ(ierr); 50 ierr = PetscMemcpy((*outviewer)->data,vbinary,sizeof(PetscViewer_Binary));CHKERRQ(ierr); 51 (*outviewer)->setupcalled = PETSC_TRUE; 52 } else { 53 *outviewer = NULL; 54 } 55 56 #if defined(PETSC_HAVE_MPIIO) 57 if (vbinary->usempiio && *outviewer) { 58 PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data; 59 /* Parent viewer opens a new MPI file handle on PETSC_COMM_SELF and keeps track of it for future reuse */ 60 if (vbinary->mfsub == MPI_FILE_NULL) { 61 int amode; 62 switch (vbinary->btype) { 63 case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break; 64 case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY; break; 65 default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->btype]); 66 } 67 ierr = MPI_File_open(PETSC_COMM_SELF,vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfsub);CHKERRQ(ierr); 68 } 69 /* Subviewer gets the MPI file handle on PETSC_COMM_SELF */ 70 obinary->mfdes = vbinary->mfsub; 71 obinary->mfsub = MPI_FILE_NULL; 72 obinary->moff = vbinary->moff; 73 } 74 #endif 75 PetscFunctionReturn(0); 76 } 77 78 static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer) 79 { 80 PetscMPIInt rank; 81 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 82 PetscErrorCode ierr; 83 #if defined(PETSC_HAVE_MPIIO) 84 MPI_Offset moff = 0; 85 #endif 86 87 PetscFunctionBegin; 88 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 89 if (rank && *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer"); 90 91 #if defined(PETSC_HAVE_MPIIO) 92 if (vbinary->usempiio && *outviewer) { 93 PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data; 94 if (obinary->mfdes != vbinary->mfsub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer"); 95 moff = obinary->moff; 96 } 97 #endif 98 99 if (*outviewer) { 100 PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data; 101 if (obinary->fdes != vbinary->fdes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer"); 102 ierr = PetscFree((*outviewer)->data);CHKERRQ(ierr); 103 ierr = PetscHeaderDestroy(outviewer);CHKERRQ(ierr); 104 } 105 106 #if defined(PETSC_HAVE_MPIIO) 107 if (vbinary->usempiio) { 108 PetscInt64 ioff = (PetscInt64)moff; /* We could use MPI_OFFSET datatype (requires MPI 2.2) */ 109 ierr = MPI_Bcast(&ioff,1,MPIU_INT64,0,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 110 vbinary->moff = (MPI_Offset)ioff; 111 } 112 #endif 113 PetscFunctionReturn(0); 114 } 115 116 #if defined(PETSC_HAVE_MPIIO) 117 /*@C 118 PetscViewerBinaryGetMPIIOOffset - Gets the current offset that should be passed to MPI_File_set_view() 119 120 Not Collective 121 122 Input Parameter: 123 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 124 125 Output Parameter: 126 . off - the current offset 127 128 Level: advanced 129 130 Fortran Note: 131 This routine is not supported in Fortran. 132 133 Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view. 134 135 136 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset() 137 @*/ 138 PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off) 139 { 140 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 141 142 PetscFunctionBegin; 143 *off = vbinary->moff; 144 PetscFunctionReturn(0); 145 } 146 147 /*@C 148 PetscViewerBinaryAddMPIIOOffset - Adds to the current offset that should be passed to MPI_File_set_view() 149 150 Not Collective 151 152 Input Parameters: 153 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 154 - off - the addition to the offset 155 156 Level: advanced 157 158 Fortran Note: 159 This routine is not supported in Fortran. 160 161 Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view() 162 163 164 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 165 @*/ 166 PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off) 167 { 168 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 169 170 PetscFunctionBegin; 171 vbinary->moff += off; 172 PetscFunctionReturn(0); 173 } 174 175 /*@C 176 PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer. 177 178 Not Collective 179 180 Input Parameter: 181 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 182 183 Output Parameter: 184 . fdes - file descriptor 185 186 Level: advanced 187 188 Fortran Note: 189 This routine is not supported in Fortran. 190 191 192 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 193 @*/ 194 PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes) 195 { 196 PetscErrorCode ierr; 197 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 198 199 PetscFunctionBegin; 200 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 201 *fdes = vbinary->mfdes; 202 PetscFunctionReturn(0); 203 } 204 205 static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *flg) 206 { 207 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 208 209 PetscFunctionBegin; 210 *flg = vbinary->usempiio; 211 PetscFunctionReturn(0); 212 } 213 #endif 214 215 216 /*@C 217 PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO. 218 219 Not Collective 220 221 Input Parameter: 222 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 223 224 Output Parameter: 225 - flg - PETSC_TRUE if MPI-IO is being used 226 227 Options Database: 228 -viewer_binary_mpiio : Flag for using MPI-IO 229 230 Level: advanced 231 232 Note: 233 If MPI-IO is not available, this function will always return PETSC_FALSE 234 235 Fortran Note: 236 This routine is not supported in Fortran. 237 238 239 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 240 @*/ 241 PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *flg) 242 { 243 PetscErrorCode ierr; 244 245 PetscFunctionBegin; 246 *flg = PETSC_FALSE; 247 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,flg));CHKERRQ(ierr); 248 PetscFunctionReturn(0); 249 } 250 251 static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc) 252 { 253 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 254 255 PetscFunctionBegin; 256 *fc = vbinary->flowcontrol; 257 PetscFunctionReturn(0); 258 } 259 260 /*@C 261 PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes 262 263 Not Collective 264 265 Input Parameter: 266 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 267 268 Output Parameter: 269 . fc - the number of messages 270 271 Level: advanced 272 273 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl() 274 275 @*/ 276 PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc) 277 { 278 PetscErrorCode ierr; 279 280 PetscFunctionBegin; 281 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));CHKERRQ(ierr); 282 PetscFunctionReturn(0); 283 } 284 285 static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc) 286 { 287 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 288 289 PetscFunctionBegin; 290 if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc); 291 vbinary->flowcontrol = fc; 292 PetscFunctionReturn(0); 293 } 294 295 /*@C 296 PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes 297 298 Not Collective 299 300 Input Parameter: 301 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 302 - fc - the number of messages, defaults to 256 if this function was not called 303 304 Level: advanced 305 306 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl() 307 308 @*/ 309 PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc) 310 { 311 PetscErrorCode ierr; 312 313 PetscFunctionBegin; 314 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));CHKERRQ(ierr); 315 PetscFunctionReturn(0); 316 } 317 318 /*@C 319 PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer. 320 321 Collective On PetscViewer 322 323 Input Parameter: 324 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 325 326 Output Parameter: 327 . fdes - file descriptor 328 329 Level: advanced 330 331 Notes: 332 For writable binary PetscViewers, the descriptor will only be valid for the 333 first processor in the communicator that shares the PetscViewer. For readable 334 files it will only be valid on nodes that have the file. If node 0 does not 335 have the file it generates an error even if another node does have the file. 336 337 Fortran Note: 338 This routine is not supported in Fortran. 339 340 Developer Notes: 341 This must be called on all processes because Dave May changed 342 the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered. 343 344 345 346 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer() 347 @*/ 348 PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes) 349 { 350 PetscErrorCode ierr; 351 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 352 353 PetscFunctionBegin; 354 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 355 *fdes = vbinary->fdes; 356 PetscFunctionReturn(0); 357 } 358 359 /*@ 360 PetscViewerBinarySkipInfo - Binary file will not have .info file created with it 361 362 Not Collective 363 364 Input Paramter: 365 . viewer - PetscViewer context, obtained from PetscViewerCreate() 366 367 Options Database Key: 368 . -viewer_binary_skip_info 369 370 Level: advanced 371 372 Notes: 373 This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then 374 you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the 375 viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo(). 376 377 The .info contains meta information about the data in the binary file, for example the block size if it was 378 set for a vector or matrix. 379 380 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(), 381 PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo() 382 @*/ 383 PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer) 384 { 385 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 386 387 PetscFunctionBegin; 388 vbinary->skipinfo = PETSC_TRUE; 389 PetscFunctionReturn(0); 390 } 391 392 static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip) 393 { 394 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 395 396 PetscFunctionBegin; 397 vbinary->skipinfo = skip; 398 PetscFunctionReturn(0); 399 } 400 401 /*@ 402 PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it 403 404 Not Collective 405 406 Input Paramter: 407 . viewer - PetscViewer context, obtained from PetscViewerCreate() 408 409 Options Database Key: 410 . -viewer_binary_skip_info 411 412 Level: advanced 413 414 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(), 415 PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo() 416 @*/ 417 PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip) 418 { 419 PetscErrorCode ierr; 420 421 PetscFunctionBegin; 422 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 423 PetscFunctionReturn(0); 424 } 425 426 static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip) 427 { 428 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 429 430 PetscFunctionBegin; 431 *skip = vbinary->skipinfo; 432 PetscFunctionReturn(0); 433 } 434 435 /*@ 436 PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file 437 438 Not Collective 439 440 Input Parameter: 441 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 442 443 Output Parameter: 444 . skip - PETSC_TRUE implies the .info file was not generated 445 446 Level: advanced 447 448 Notes: 449 This must be called after PetscViewerSetType() 450 451 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 452 PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo() 453 @*/ 454 PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip) 455 { 456 PetscErrorCode ierr; 457 458 PetscFunctionBegin; 459 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 460 PetscFunctionReturn(0); 461 } 462 463 static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip) 464 { 465 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 466 467 PetscFunctionBegin; 468 vbinary->skipoptions = skip; 469 PetscFunctionReturn(0); 470 } 471 472 /*@ 473 PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects 474 475 Not Collective 476 477 Input Parameters: 478 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 479 - skip - PETSC_TRUE means do not use 480 481 Options Database Key: 482 . -viewer_binary_skip_options 483 484 Level: advanced 485 486 Notes: 487 This must be called after PetscViewerSetType() 488 489 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 490 PetscViewerBinaryGetSkipOptions() 491 @*/ 492 PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip) 493 { 494 PetscErrorCode ierr; 495 496 PetscFunctionBegin; 497 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 498 PetscFunctionReturn(0); 499 } 500 501 static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip) 502 { 503 PetscViewer_Binary *vbinary; 504 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 507 vbinary = (PetscViewer_Binary*)viewer->data; 508 *skip = vbinary->skipoptions; 509 PetscFunctionReturn(0); 510 } 511 512 /*@ 513 PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects 514 515 Not Collective 516 517 Input Parameter: 518 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 519 520 Output Parameter: 521 . skip - PETSC_TRUE means do not use 522 523 Level: advanced 524 525 Notes: 526 This must be called after PetscViewerSetType() 527 528 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 529 PetscViewerBinarySetSkipOptions() 530 @*/ 531 PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip) 532 { 533 PetscErrorCode ierr; 534 535 PetscFunctionBegin; 536 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 537 PetscFunctionReturn(0); 538 } 539 540 static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip) 541 { 542 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 543 544 PetscFunctionBegin; 545 vbinary->skipheader = skip; 546 PetscFunctionReturn(0); 547 } 548 549 /*@ 550 PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data 551 552 Not Collective 553 554 Input Parameters: 555 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 556 - skip - PETSC_TRUE means do not write header 557 558 Options Database Key: 559 . -viewer_binary_skip_header 560 561 Level: advanced 562 563 Notes: 564 This must be called after PetscViewerSetType() 565 566 Can ONLY be called on a binary viewer 567 568 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 569 PetscViewerBinaryGetSkipHeader() 570 @*/ 571 PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip) 572 { 573 PetscErrorCode ierr; 574 575 PetscFunctionBegin; 576 ierr = PetscUseMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr); 577 PetscFunctionReturn(0); 578 } 579 580 static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip) 581 { 582 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 583 584 PetscFunctionBegin; 585 *skip = vbinary->skipheader; 586 PetscFunctionReturn(0); 587 } 588 589 /*@ 590 PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data 591 592 Not Collective 593 594 Input Parameter: 595 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 596 597 Output Parameter: 598 . skip - PETSC_TRUE means do not write header 599 600 Level: advanced 601 602 Notes: 603 This must be called after PetscViewerSetType() 604 605 Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it. 606 607 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(), 608 PetscViewerBinarySetSkipHeader() 609 @*/ 610 PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip) 611 { 612 PetscErrorCode ierr; 613 614 PetscFunctionBegin; 615 *skip = PETSC_FALSE; 616 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr); 617 PetscFunctionReturn(0); 618 } 619 620 static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file) 621 { 622 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 623 PetscErrorCode ierr; 624 MPI_Comm comm; 625 626 PetscFunctionBegin; 627 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 628 *file = vbinary->fdes_info; 629 if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) { 630 vbinary->matlabheaderwritten = PETSC_TRUE; 631 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 632 ierr = PetscFPrintf(comm,*file,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 633 ierr = PetscFPrintf(comm,*file,"#$$ Set.filename = '%s';\n",vbinary->filename);CHKERRQ(ierr); 634 ierr = PetscFPrintf(comm,*file,"#$$ fd = PetscOpenFile(Set.filename);\n");CHKERRQ(ierr); 635 ierr = PetscFPrintf(comm,*file,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 636 } 637 PetscFunctionReturn(0); 638 } 639 640 /*@C 641 PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII 642 info file associated with a binary file. 643 644 Not Collective 645 646 Input Parameter: 647 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen() 648 649 Output Parameter: 650 . file - file pointer Always returns NULL if not a binary viewer 651 652 Level: advanced 653 654 Notes: 655 For writable binary PetscViewers, the descriptor will only be valid for the 656 first processor in the communicator that shares the PetscViewer. 657 658 Fortran Note: 659 This routine is not supported in Fortran. 660 661 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor() 662 @*/ 663 PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file) 664 { 665 PetscErrorCode ierr; 666 667 PetscFunctionBegin; 668 *file = NULL; 669 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));CHKERRQ(ierr); 670 PetscFunctionReturn(0); 671 } 672 673 static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v) 674 { 675 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 676 PetscErrorCode ierr; 677 PetscMPIInt rank; 678 int err; 679 680 PetscFunctionBegin; 681 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);CHKERRQ(ierr); 682 if ((!rank || vbinary->btype == FILE_MODE_READ) && vbinary->fdes) { 683 close(vbinary->fdes); 684 if (!rank && vbinary->storecompressed) { 685 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN]; 686 FILE *fp; 687 /* compress the file */ 688 ierr = PetscStrncpy(par,"gzip -f ",sizeof(par));CHKERRQ(ierr); 689 ierr = PetscStrlcat(par,vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename,sizeof(par));CHKERRQ(ierr); 690 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 691 #if defined(PETSC_HAVE_POPEN) 692 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr); 693 if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",par,buf); 694 ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr); 695 #else 696 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 697 #endif 698 } 699 } 700 if (vbinary->fdes_info) { 701 err = fclose(vbinary->fdes_info); 702 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 703 } 704 PetscFunctionReturn(0); 705 } 706 707 #if defined(PETSC_HAVE_MPIIO) 708 static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v) 709 { 710 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 711 int err; 712 PetscErrorCode ierr; 713 714 PetscFunctionBegin; 715 if (vbinary->mfdes != MPI_FILE_NULL) { 716 ierr = MPI_File_close(&vbinary->mfdes);CHKERRQ(ierr); 717 } 718 if (vbinary->mfsub != MPI_FILE_NULL) { 719 ierr = MPI_File_close(&vbinary->mfsub);CHKERRQ(ierr); 720 } 721 if (vbinary->fdes_info) { 722 err = fclose(vbinary->fdes_info); 723 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 724 } 725 PetscFunctionReturn(0); 726 } 727 #endif 728 729 static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v) 730 { 731 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 732 PetscErrorCode ierr; 733 734 PetscFunctionBegin; 735 if (v->format == PETSC_VIEWER_BINARY_MATLAB) { 736 MPI_Comm comm; 737 FILE *info; 738 739 ierr = PetscObjectGetComm((PetscObject)v,&comm);CHKERRQ(ierr); 740 ierr = PetscViewerBinaryGetInfoPointer(v,&info);CHKERRQ(ierr); 741 ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr); 742 ierr = PetscFPrintf(comm,info,"#$$ close(fd);\n");CHKERRQ(ierr); 743 ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr); 744 } 745 #if defined(PETSC_HAVE_MPIIO) 746 if (vbinary->usempiio) { 747 ierr = PetscViewerFileClose_BinaryMPIIO(v);CHKERRQ(ierr); 748 } else { 749 #endif 750 ierr = PetscViewerFileClose_Binary(v);CHKERRQ(ierr); 751 #if defined(PETSC_HAVE_MPIIO) 752 } 753 #endif 754 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 755 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 756 ierr = PetscFree(vbinary);CHKERRQ(ierr); 757 PetscFunctionReturn(0); 758 } 759 760 /*@C 761 PetscViewerBinaryOpen - Opens a file for binary input/output. 762 763 Collective 764 765 Input Parameters: 766 + comm - MPI communicator 767 . name - name of file 768 - type - type of file 769 $ FILE_MODE_WRITE - create new file for binary output 770 $ FILE_MODE_READ - open existing file for binary input 771 $ FILE_MODE_APPEND - open existing file for binary output 772 773 Output Parameter: 774 . binv - PetscViewer for binary input/output to use with the specified file 775 776 Options Database Keys: 777 + -viewer_binary_filename <name> - 778 . -viewer_binary_skip_info - 779 . -viewer_binary_skip_options - 780 . -viewer_binary_skip_header - 781 - -viewer_binary_mpiio - 782 783 Level: beginner 784 785 Note: 786 This PetscViewer should be destroyed with PetscViewerDestroy(). 787 788 For reading files, the filename may begin with ftp:// or http:// and/or 789 end with .gz; in this case file is brought over and uncompressed. 790 791 For creating files, if the file name ends with .gz it is automatically 792 compressed when closed. 793 794 For writing files it only opens the file on processor 0 in the communicator. 795 For readable files it opens the file on all nodes that have the file. If 796 node 0 does not have the file it generates an error even if other nodes 797 do have the file. 798 799 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 800 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 801 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(), 802 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset() 803 @*/ 804 PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode type,PetscViewer *binv) 805 { 806 PetscErrorCode ierr; 807 808 PetscFunctionBegin; 809 ierr = PetscViewerCreate(comm,binv);CHKERRQ(ierr); 810 ierr = PetscViewerSetType(*binv,PETSCVIEWERBINARY);CHKERRQ(ierr); 811 ierr = PetscViewerFileSetMode(*binv,type);CHKERRQ(ierr); 812 ierr = PetscViewerFileSetName(*binv,name);CHKERRQ(ierr); 813 ierr = PetscViewerSetFromOptions(*binv);CHKERRQ(ierr); 814 PetscFunctionReturn(0); 815 } 816 817 #if defined(PETSC_HAVE_MPIIO) 818 static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write) 819 { 820 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 821 PetscErrorCode ierr; 822 MPI_File mfdes; 823 MPI_Datatype mdtype; 824 PetscMPIInt cnt; 825 MPI_Status status; 826 MPI_Aint ul,dsize; 827 828 PetscFunctionBegin; 829 mfdes = vbinary->mfdes; 830 ierr = PetscMPIIntCast(num,&cnt);CHKERRQ(ierr); 831 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr); 832 ierr = MPI_File_set_view(mfdes,vbinary->moff,mdtype,mdtype,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr); 833 if (write) { 834 ierr = MPIU_File_write_all(mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 835 } else { 836 ierr = MPIU_File_read_all(mfdes,data,cnt,mdtype,&status);CHKERRQ(ierr); 837 if (cnt > 0) {ierr = MPI_Get_count(&status,mdtype,&cnt);CHKERRQ(ierr);} 838 } 839 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr); 840 841 vbinary->moff += dsize*cnt; 842 if (count) *count = cnt; 843 PetscFunctionReturn(0); 844 } 845 #endif 846 847 /*@C 848 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result 849 850 Collective 851 852 Input Parameters: 853 + viewer - the binary viewer 854 . data - location of the data to be written 855 . num - number of items of data to read 856 - dtype - type of data to read 857 858 Output Parameters: 859 . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num. 860 861 Level: beginner 862 863 Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves. 864 865 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 866 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 867 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 868 @*/ 869 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 870 { 871 PetscErrorCode ierr; 872 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 873 874 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 875 #if defined(PETSC_HAVE_MPIIO) 876 if (vbinary->usempiio) { 877 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 878 } else { 879 #endif 880 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);CHKERRQ(ierr); 881 #if defined(PETSC_HAVE_MPIIO) 882 } 883 #endif 884 PetscFunctionReturn(0); 885 } 886 887 /*@C 888 PetscViewerBinaryWrite - writes to a binary file, only from the first process 889 890 Collective 891 892 Input Parameters: 893 + viewer - the binary viewer 894 . data - location of data 895 . count - number of items of data to write 896 . dtype - type of data to write 897 - istemp - data may be overwritten 898 899 Level: beginner 900 901 Notes: 902 because byte-swapping may be done on the values in data it cannot be declared const 903 904 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 905 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 906 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 907 @*/ 908 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp) 909 { 910 PetscErrorCode ierr; 911 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 912 913 PetscFunctionBegin; 914 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 915 #if defined(PETSC_HAVE_MPIIO) 916 if (vbinary->usempiio) { 917 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);CHKERRQ(ierr); 918 } else { 919 #endif 920 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr); 921 #if defined(PETSC_HAVE_MPIIO) 922 } 923 #endif 924 PetscFunctionReturn(0); 925 } 926 927 /*@C 928 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 929 930 Collective 931 932 Input Parameters: 933 + viewer - the binary viewer 934 - data - location of the array of strings 935 936 937 Level: intermediate 938 939 Notes: 940 array of strings is null terminated 941 942 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 943 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 944 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 945 @*/ 946 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data) 947 { 948 PetscErrorCode ierr; 949 PetscInt i,n = 0,*sizes; 950 951 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 952 /* count number of strings */ 953 while (data[n++]) ; 954 n--; 955 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr); 956 sizes[0] = n; 957 for (i=0; i<n; i++) { 958 size_t tmp; 959 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 960 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 961 } 962 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 963 for (i=0; i<n; i++) { 964 ierr = PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 965 } 966 ierr = PetscFree(sizes);CHKERRQ(ierr); 967 PetscFunctionReturn(0); 968 } 969 970 /*@C 971 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 972 973 Collective 974 975 Input Parameter: 976 . viewer - the binary viewer 977 978 Output Parameter: 979 . data - location of the array of strings 980 981 Level: intermediate 982 983 Notes: 984 array of strings is null terminated 985 986 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 987 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 988 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 989 @*/ 990 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 991 { 992 PetscErrorCode ierr; 993 PetscInt i,n,*sizes,N = 0; 994 995 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 996 /* count number of strings */ 997 ierr = PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);CHKERRQ(ierr); 998 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 999 ierr = PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);CHKERRQ(ierr); 1000 for (i=0; i<n; i++) N += sizes[i]; 1001 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 1002 (*data)[0] = (char*)((*data) + n + 1); 1003 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 1004 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);CHKERRQ(ierr); 1005 1006 (*data)[n] = 0; 1007 1008 ierr = PetscFree(sizes);CHKERRQ(ierr); 1009 PetscFunctionReturn(0); 1010 } 1011 1012 static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 1013 { 1014 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1015 1016 PetscFunctionBegin; 1017 *name = vbinary->filename; 1018 PetscFunctionReturn(0); 1019 } 1020 1021 /*@C 1022 PetscViewerFileGetMode - Gets the type of file to be open 1023 1024 Not Collective 1025 1026 Input Parameter: 1027 . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1028 1029 Output Parameter: 1030 . type - type of file 1031 $ FILE_MODE_WRITE - create new file for binary output 1032 $ FILE_MODE_READ - open existing file for binary input 1033 $ FILE_MODE_APPEND - open existing file for binary output 1034 1035 Level: advanced 1036 1037 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1038 1039 @*/ 1040 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 1041 { 1042 PetscErrorCode ierr; 1043 1044 PetscFunctionBegin; 1045 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1046 PetscValidPointer(type,2); 1047 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 1048 PetscFunctionReturn(0); 1049 } 1050 1051 /*@ 1052 PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called 1053 before PetscViewerFileSetName() 1054 1055 Logically Collective on PetscViewer 1056 1057 Input Parameters: 1058 + viewer - the PetscViewer; must be a binary 1059 - flg - PETSC_TRUE means MPI-IO will be used 1060 1061 Options Database: 1062 -viewer_binary_mpiio : Flag for using MPI-IO 1063 1064 Level: advanced 1065 1066 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(), 1067 PetscViewerBinaryGetUseMPIIO() 1068 1069 @*/ 1070 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg) 1071 { 1072 PetscErrorCode ierr; 1073 1074 PetscFunctionBegin; 1075 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1076 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));CHKERRQ(ierr); 1077 PetscFunctionReturn(0); 1078 } 1079 1080 /*@C 1081 PetscViewerFileSetMode - Sets the type of file to be open 1082 1083 Logically Collective on PetscViewer 1084 1085 Input Parameters: 1086 + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1087 - type - type of file 1088 $ FILE_MODE_WRITE - create new file for output 1089 $ FILE_MODE_READ - open existing file for input 1090 $ FILE_MODE_APPEND - open existing file for output 1091 1092 Level: advanced 1093 1094 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1095 1096 @*/ 1097 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1098 { 1099 PetscErrorCode ierr; 1100 1101 PetscFunctionBegin; 1102 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1103 PetscValidLogicalCollectiveEnum(viewer,type,2); 1104 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1105 PetscFunctionReturn(0); 1106 } 1107 1108 static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1109 { 1110 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1111 1112 PetscFunctionBegin; 1113 *type = vbinary->btype; 1114 PetscFunctionReturn(0); 1115 } 1116 1117 static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1118 { 1119 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1120 1121 PetscFunctionBegin; 1122 vbinary->btype = type; 1123 PetscFunctionReturn(0); 1124 } 1125 1126 static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1127 { 1128 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1129 PetscErrorCode ierr; 1130 1131 PetscFunctionBegin; 1132 if (vbinary->filename) { 1133 /* gzip can be run after the file with the previous filename has been closed */ 1134 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 1135 ierr = PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);CHKERRQ(ierr); 1136 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 1137 viewer->setupcalled = PETSC_FALSE; 1138 } 1139 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1140 PetscFunctionReturn(0); 1141 } 1142 /* 1143 Actually opens the file 1144 */ 1145 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer) 1146 { 1147 PetscMPIInt rank; 1148 PetscErrorCode ierr; 1149 size_t len; 1150 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1151 const char *fname; 1152 char bname[PETSC_MAX_PATH_LEN],*gz; 1153 PetscBool found; 1154 PetscFileMode type = vbinary->btype; 1155 1156 PetscFunctionBegin; 1157 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1158 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1159 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1160 1161 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1162 1163 /* if ends in .gz strip that off and note user wants file compressed */ 1164 vbinary->storecompressed = PETSC_FALSE; 1165 if (!rank && type == FILE_MODE_WRITE) { 1166 /* remove .gz if it ends library name */ 1167 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1168 if (gz) { 1169 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1170 if (len == 3) { 1171 *gz = 0; 1172 vbinary->storecompressed = PETSC_TRUE; 1173 } 1174 } 1175 } 1176 1177 /* only first processor opens file if writeable */ 1178 if (!rank || type == FILE_MODE_READ) { 1179 1180 if (type == FILE_MODE_READ) { 1181 /* possibly get the file from remote site or compressed file */ 1182 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1183 fname = bname; 1184 /* comm below may be global as all ranks go here for FILE_MODE_READ and output 'found' of PetscFileRetrieve() is valid on all processes */ 1185 if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1186 } else fname = vbinary->filename; 1187 if (type == FILE_MODE_APPEND) { /* check if asked to append to a non-existing file */ 1188 ierr = PetscTestFile(fname,'\0',&found);CHKERRQ(ierr); 1189 } 1190 1191 #if defined(PETSC_HAVE_O_BINARY) 1192 if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) { 1193 if ((vbinary->fdes = open(fname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1194 } else if (type == FILE_MODE_READ && fname) { 1195 if ((vbinary->fdes = open(fname,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1196 } else if (type == FILE_MODE_APPEND) { 1197 if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname); 1198 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1199 #else 1200 if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) { 1201 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1202 } else if (type == FILE_MODE_READ && fname) { 1203 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1204 } else if (type == FILE_MODE_APPEND) { 1205 if ((vbinary->fdes = open(fname,O_WRONLY|O_APPEND,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for writing",fname); 1206 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1207 #endif 1208 } else vbinary->fdes = -1; 1209 1210 /* 1211 try to open info file: all processors open this file if read only 1212 */ 1213 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1214 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1215 1216 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1217 /* remove .gz if it ends library name */ 1218 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1219 if (gz) { 1220 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1221 if (len == 3) *gz = 0; 1222 } 1223 1224 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1225 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1226 if (type == FILE_MODE_READ) { 1227 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1228 if (found) { 1229 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1230 } 1231 } else { 1232 vbinary->fdes_info = fopen(infoname,"w"); 1233 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1234 } 1235 } 1236 #if defined(PETSC_USE_LOG) 1237 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1238 #endif 1239 PetscFunctionReturn(0); 1240 } 1241 1242 #if defined(PETSC_HAVE_MPIIO) 1243 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1244 { 1245 PetscMPIInt rank; 1246 PetscErrorCode ierr; 1247 size_t len; 1248 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1249 char *gz; 1250 PetscBool found; 1251 PetscFileMode type = vbinary->btype; 1252 int amode; 1253 1254 PetscFunctionBegin; 1255 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1256 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1257 ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr); 1258 1259 vbinary->storecompressed = PETSC_FALSE; 1260 1261 switch (type) { 1262 case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break; 1263 case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break; 1264 default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[type]); 1265 } 1266 ierr = MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1267 1268 /* 1269 try to open info file: all processors open this file if read only 1270 1271 Below is identical code to the code for Binary above, should be put in separate routine 1272 */ 1273 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1274 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1275 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1276 1277 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1278 /* remove .gz if it ends library name */ 1279 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1280 if (gz) { 1281 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1282 if (len == 3) *gz = 0; 1283 } 1284 1285 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1286 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1287 if (type == FILE_MODE_READ) { 1288 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1289 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1290 } else { 1291 vbinary->fdes_info = fopen(infoname,"w"); 1292 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1293 } 1294 } 1295 #if defined(PETSC_USE_LOG) 1296 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1297 #endif 1298 PetscFunctionReturn(0); 1299 } 1300 1301 static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg) 1302 { 1303 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1304 PetscFunctionBegin; 1305 vbinary->usempiio = flg; 1306 PetscFunctionReturn(0); 1307 } 1308 #endif 1309 1310 static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1311 { 1312 PetscErrorCode ierr; 1313 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1314 1315 PetscFunctionBegin; 1316 if (binary->filename) { 1317 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1318 } 1319 PetscFunctionReturn(0); 1320 } 1321 1322 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v) 1323 { 1324 PetscErrorCode ierr; 1325 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1326 1327 PetscFunctionBegin; 1328 if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); } 1329 1330 #if defined(PETSC_HAVE_MPIIO) 1331 if (binary->usempiio) { 1332 ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr); 1333 } else { 1334 #endif 1335 ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr); 1336 #if defined(PETSC_HAVE_MPIIO) 1337 } 1338 #endif 1339 PetscFunctionReturn(0); 1340 } 1341 1342 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v) 1343 { 1344 PetscErrorCode ierr; 1345 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1346 char defaultname[PETSC_MAX_PATH_LEN]; 1347 PetscBool flg; 1348 1349 PetscFunctionBegin; 1350 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1351 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr); 1352 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); 1353 if (flg) { ierr = PetscViewerFileSetName_Binary(v,defaultname);CHKERRQ(ierr); } 1354 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);CHKERRQ(ierr); 1355 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);CHKERRQ(ierr); 1356 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);CHKERRQ(ierr); 1357 #if defined(PETSC_HAVE_MPIIO) 1358 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);CHKERRQ(ierr); 1359 #elif defined(PETSC_HAVE_MPIUNI) 1360 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);CHKERRQ(ierr); 1361 #endif 1362 ierr = PetscOptionsTail();CHKERRQ(ierr); 1363 binary->setfromoptionscalled = PETSC_TRUE; 1364 PetscFunctionReturn(0); 1365 } 1366 1367 /*MC 1368 PETSCVIEWERBINARY - A viewer that saves to binary files 1369 1370 1371 .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(), 1372 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW, 1373 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(), 1374 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO() 1375 1376 Level: beginner 1377 1378 M*/ 1379 1380 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1381 { 1382 PetscErrorCode ierr; 1383 PetscViewer_Binary *vbinary; 1384 1385 PetscFunctionBegin; 1386 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1387 v->data = (void*)vbinary; 1388 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1389 v->ops->destroy = PetscViewerDestroy_Binary; 1390 v->ops->view = PetscViewerView_Binary; 1391 v->ops->setup = PetscViewerSetUp_Binary; 1392 v->ops->flush = NULL; 1393 vbinary->fdes = 0; 1394 #if defined(PETSC_HAVE_MPIIO) 1395 vbinary->mfdes = MPI_FILE_NULL; 1396 vbinary->mfsub = MPI_FILE_NULL; 1397 #endif 1398 vbinary->fdes_info = 0; 1399 vbinary->skipinfo = PETSC_FALSE; 1400 vbinary->skipoptions = PETSC_TRUE; 1401 vbinary->skipheader = PETSC_FALSE; 1402 vbinary->setfromoptionscalled = PETSC_FALSE; 1403 v->ops->getsubviewer = PetscViewerGetSubViewer_Binary; 1404 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary; 1405 v->ops->read = PetscViewerBinaryRead; 1406 vbinary->btype = (PetscFileMode) -1; 1407 vbinary->storecompressed = PETSC_FALSE; 1408 vbinary->filename = NULL; 1409 vbinary->ogzfilename = NULL; 1410 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1411 1412 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1413 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1414 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1415 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1416 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr); 1417 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr); 1418 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr); 1419 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr); 1420 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1421 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1422 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1423 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1424 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1425 #if defined(PETSC_HAVE_MPIIO) 1426 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr); 1427 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr); 1428 #endif 1429 PetscFunctionReturn(0); 1430 } 1431 1432 /* ---------------------------------------------------------------------*/ 1433 /* 1434 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1435 is attached to a communicator, in this case the attribute is a PetscViewer. 1436 */ 1437 PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1438 1439 /*@C 1440 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1441 in a communicator. 1442 1443 Collective 1444 1445 Input Parameter: 1446 . comm - the MPI communicator to share the binary PetscViewer 1447 1448 Level: intermediate 1449 1450 Options Database Keys: 1451 + -viewer_binary_filename <name> 1452 . -viewer_binary_skip_info 1453 . -viewer_binary_skip_options 1454 . -viewer_binary_skip_header 1455 - -viewer_binary_mpiio 1456 1457 Environmental variables: 1458 - PETSC_VIEWER_BINARY_FILENAME 1459 1460 Notes: 1461 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1462 an error code. The binary PetscViewer is usually used in the form 1463 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1464 1465 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1466 PetscViewerDestroy() 1467 @*/ 1468 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1469 { 1470 PetscErrorCode ierr; 1471 PetscBool flg; 1472 PetscViewer viewer; 1473 char fname[PETSC_MAX_PATH_LEN]; 1474 MPI_Comm ncomm; 1475 1476 PetscFunctionBegin; 1477 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1478 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1479 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1480 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1481 } 1482 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1483 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1484 if (!flg) { /* PetscViewer not yet created */ 1485 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1486 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1487 if (!flg) { 1488 ierr = PetscStrcpy(fname,"binaryoutput"); 1489 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1490 } 1491 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1492 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1493 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1494 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1495 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1496 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1497 } 1498 ierr = PetscCommDestroy(&ncomm); 1499 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1500 PetscFunctionReturn(viewer); 1501 } 1502