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 Parameter: 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 Parameter: 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 rank,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_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 833 if (write) { 834 if (!rank) { 835 ierr = MPIU_File_write_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);CHKERRQ(ierr); 836 } 837 } else { 838 if (!rank) { 839 ierr = MPIU_File_read_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);CHKERRQ(ierr); 840 if (cnt > 0) {ierr = MPI_Get_count(&status,mdtype,&cnt);CHKERRQ(ierr);} 841 } 842 ierr = MPI_Bcast(&cnt,1,MPI_INT,0,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 843 ierr = MPI_Bcast(data,cnt,mdtype,0,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr); 844 } 845 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr); 846 847 vbinary->moff += dsize*cnt; 848 if (count) *count = cnt; 849 PetscFunctionReturn(0); 850 } 851 #endif 852 853 /*@C 854 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result 855 856 Collective 857 858 Input Parameters: 859 + viewer - the binary viewer 860 . data - location of the data to be written 861 . num - number of items of data to read 862 - dtype - type of data to read 863 864 Output Parameters: 865 . count - number of items of data actually read, or NULL. Unless an error is generated this is always set to the input parameter num. 866 867 Level: beginner 868 869 Developer Note: Since count is always set to num it is not clear what purpose the output argument count serves. 870 871 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 872 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 873 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 874 @*/ 875 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype) 876 { 877 PetscErrorCode ierr; 878 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 879 880 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 881 #if defined(PETSC_HAVE_MPIIO) 882 if (vbinary->usempiio) { 883 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 884 } else { 885 #endif 886 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);CHKERRQ(ierr); 887 #if defined(PETSC_HAVE_MPIIO) 888 } 889 #endif 890 PetscFunctionReturn(0); 891 } 892 893 /*@C 894 PetscViewerBinaryWrite - writes to a binary file, only from the first process 895 896 Collective 897 898 Input Parameters: 899 + viewer - the binary viewer 900 . data - location of data 901 . count - number of items of data to write 902 . dtype - type of data to write 903 - istemp - data may be overwritten 904 905 Level: beginner 906 907 Notes: 908 because byte-swapping may be done on the values in data it cannot be declared const 909 910 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 911 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 912 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 913 @*/ 914 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp) 915 { 916 PetscErrorCode ierr; 917 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 918 919 PetscFunctionBegin; 920 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 921 #if defined(PETSC_HAVE_MPIIO) 922 if (vbinary->usempiio) { 923 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,count,NULL,dtype,PETSC_TRUE);CHKERRQ(ierr); 924 } else { 925 #endif 926 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr); 927 #if defined(PETSC_HAVE_MPIIO) 928 } 929 #endif 930 PetscFunctionReturn(0); 931 } 932 933 /*@C 934 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 935 936 Collective 937 938 Input Parameters: 939 + viewer - the binary viewer 940 - data - location of the array of strings 941 942 943 Level: intermediate 944 945 Notes: 946 array of strings is null terminated 947 948 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 949 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 950 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 951 @*/ 952 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data) 953 { 954 PetscErrorCode ierr; 955 PetscInt i,n = 0,*sizes; 956 957 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 958 /* count number of strings */ 959 while (data[n++]) ; 960 n--; 961 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr); 962 sizes[0] = n; 963 for (i=0; i<n; i++) { 964 size_t tmp; 965 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 966 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 967 } 968 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 969 for (i=0; i<n; i++) { 970 ierr = PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 971 } 972 ierr = PetscFree(sizes);CHKERRQ(ierr); 973 PetscFunctionReturn(0); 974 } 975 976 /*@C 977 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 978 979 Collective 980 981 Input Parameter: 982 . viewer - the binary viewer 983 984 Output Parameter: 985 . data - location of the array of strings 986 987 Level: intermediate 988 989 Notes: 990 array of strings is null terminated 991 992 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 993 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 994 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 995 @*/ 996 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 997 { 998 PetscErrorCode ierr; 999 PetscInt i,n,*sizes,N = 0; 1000 1001 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 1002 /* count number of strings */ 1003 ierr = PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);CHKERRQ(ierr); 1004 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 1005 ierr = PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);CHKERRQ(ierr); 1006 for (i=0; i<n; i++) N += sizes[i]; 1007 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 1008 (*data)[0] = (char*)((*data) + n + 1); 1009 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 1010 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);CHKERRQ(ierr); 1011 1012 (*data)[n] = NULL; 1013 1014 ierr = PetscFree(sizes);CHKERRQ(ierr); 1015 PetscFunctionReturn(0); 1016 } 1017 1018 static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 1019 { 1020 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1021 1022 PetscFunctionBegin; 1023 *name = vbinary->filename; 1024 PetscFunctionReturn(0); 1025 } 1026 1027 /*@C 1028 PetscViewerFileGetMode - Gets the type of file to be open 1029 1030 Not Collective 1031 1032 Input Parameter: 1033 . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1034 1035 Output Parameter: 1036 . type - type of file 1037 $ FILE_MODE_WRITE - create new file for binary output 1038 $ FILE_MODE_READ - open existing file for binary input 1039 $ FILE_MODE_APPEND - open existing file for binary output 1040 1041 Level: advanced 1042 1043 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1044 1045 @*/ 1046 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 1047 { 1048 PetscErrorCode ierr; 1049 1050 PetscFunctionBegin; 1051 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1052 PetscValidPointer(type,2); 1053 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 1054 PetscFunctionReturn(0); 1055 } 1056 1057 /*@ 1058 PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called 1059 before PetscViewerFileSetName() 1060 1061 Logically Collective on PetscViewer 1062 1063 Input Parameters: 1064 + viewer - the PetscViewer; must be a binary 1065 - flg - PETSC_TRUE means MPI-IO will be used 1066 1067 Options Database: 1068 -viewer_binary_mpiio : Flag for using MPI-IO 1069 1070 Level: advanced 1071 1072 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(), 1073 PetscViewerBinaryGetUseMPIIO() 1074 1075 @*/ 1076 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool flg) 1077 { 1078 PetscErrorCode ierr; 1079 1080 PetscFunctionBegin; 1081 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1082 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,flg));CHKERRQ(ierr); 1083 PetscFunctionReturn(0); 1084 } 1085 1086 /*@C 1087 PetscViewerFileSetMode - Sets the type of file to be open 1088 1089 Logically Collective on PetscViewer 1090 1091 Input Parameters: 1092 + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1093 - type - type of file 1094 $ FILE_MODE_WRITE - create new file for output 1095 $ FILE_MODE_READ - open existing file for input 1096 $ FILE_MODE_APPEND - open existing file for output 1097 1098 Level: advanced 1099 1100 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1101 1102 @*/ 1103 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 1104 { 1105 PetscErrorCode ierr; 1106 1107 PetscFunctionBegin; 1108 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1109 PetscValidLogicalCollectiveEnum(viewer,type,2); 1110 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1111 PetscFunctionReturn(0); 1112 } 1113 1114 static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1115 { 1116 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1117 1118 PetscFunctionBegin; 1119 *type = vbinary->btype; 1120 PetscFunctionReturn(0); 1121 } 1122 1123 static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1124 { 1125 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1126 1127 PetscFunctionBegin; 1128 vbinary->btype = type; 1129 PetscFunctionReturn(0); 1130 } 1131 1132 static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1133 { 1134 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1135 PetscErrorCode ierr; 1136 1137 PetscFunctionBegin; 1138 if (vbinary->filename) { 1139 /* gzip can be run after the file with the previous filename has been closed */ 1140 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 1141 ierr = PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);CHKERRQ(ierr); 1142 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 1143 viewer->setupcalled = PETSC_FALSE; 1144 } 1145 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1146 PetscFunctionReturn(0); 1147 } 1148 /* 1149 Actually opens the file 1150 */ 1151 static PetscErrorCode PetscViewerFileSetUp_Binary(PetscViewer viewer) 1152 { 1153 PetscMPIInt rank; 1154 PetscErrorCode ierr; 1155 size_t len; 1156 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1157 const char *fname; 1158 char bname[PETSC_MAX_PATH_LEN],*gz; 1159 PetscBool found; 1160 PetscFileMode type = vbinary->btype; 1161 1162 PetscFunctionBegin; 1163 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1164 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1165 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1166 1167 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1168 1169 /* if ends in .gz strip that off and note user wants file compressed */ 1170 vbinary->storecompressed = PETSC_FALSE; 1171 if (!rank && type == FILE_MODE_WRITE) { 1172 /* remove .gz if it ends library name */ 1173 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1174 if (gz) { 1175 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1176 if (len == 3) { 1177 *gz = 0; 1178 vbinary->storecompressed = PETSC_TRUE; 1179 } 1180 } 1181 } 1182 1183 /* only first processor opens file if writeable */ 1184 if (!rank || type == FILE_MODE_READ) { 1185 1186 if (type == FILE_MODE_READ) { 1187 /* possibly get the file from remote site or compressed file */ 1188 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1189 fname = bname; 1190 /* comm below may be global as all ranks go here for FILE_MODE_READ and output 'found' of PetscFileRetrieve() is valid on all processes */ 1191 if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1192 } else fname = vbinary->filename; 1193 if (type == FILE_MODE_APPEND) { /* check if asked to append to a non-existing file */ 1194 ierr = PetscTestFile(fname,'\0',&found);CHKERRQ(ierr); 1195 } 1196 1197 #if defined(PETSC_HAVE_O_BINARY) 1198 if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) { 1199 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); 1200 } else if (type == FILE_MODE_READ && fname) { 1201 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); 1202 } else if (type == FILE_MODE_APPEND) { 1203 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); 1204 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1205 #else 1206 if (type == FILE_MODE_WRITE || (type == FILE_MODE_APPEND && !found) ) { 1207 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1208 } else if (type == FILE_MODE_READ && fname) { 1209 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1210 } else if (type == FILE_MODE_APPEND) { 1211 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); 1212 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1213 #endif 1214 } else vbinary->fdes = -1; 1215 1216 /* 1217 try to open info file: all processors open this file if read only 1218 */ 1219 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1220 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1221 1222 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1223 /* remove .gz if it ends library name */ 1224 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1225 if (gz) { 1226 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1227 if (len == 3) *gz = 0; 1228 } 1229 1230 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1231 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1232 if (type == FILE_MODE_READ) { 1233 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1234 if (found) { 1235 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1236 } 1237 } else { 1238 vbinary->fdes_info = fopen(infoname,"w"); 1239 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1240 } 1241 } 1242 #if defined(PETSC_USE_LOG) 1243 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1244 #endif 1245 PetscFunctionReturn(0); 1246 } 1247 1248 #if defined(PETSC_HAVE_MPIIO) 1249 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1250 { 1251 PetscMPIInt rank; 1252 PetscErrorCode ierr; 1253 size_t len; 1254 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1255 char *gz; 1256 PetscBool found; 1257 PetscFileMode type = vbinary->btype; 1258 int amode; 1259 1260 PetscFunctionBegin; 1261 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1262 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1263 ierr = PetscViewerFileClose_BinaryMPIIO(viewer);CHKERRQ(ierr); 1264 1265 vbinary->storecompressed = PETSC_FALSE; 1266 1267 switch (type) { 1268 case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break; 1269 case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break; 1270 default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[type]); 1271 } 1272 ierr = MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1273 1274 /* 1275 try to open info file: all processors open this file if read only 1276 1277 Below is identical code to the code for Binary above, should be put in separate routine 1278 */ 1279 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1280 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1281 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1282 1283 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1284 /* remove .gz if it ends library name */ 1285 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1286 if (gz) { 1287 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1288 if (len == 3) *gz = 0; 1289 } 1290 1291 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1292 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1293 if (type == FILE_MODE_READ) { 1294 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1295 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr); 1296 } else { 1297 vbinary->fdes_info = fopen(infoname,"w"); 1298 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1299 } 1300 } 1301 #if defined(PETSC_USE_LOG) 1302 PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename); 1303 #endif 1304 PetscFunctionReturn(0); 1305 } 1306 1307 static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool flg) 1308 { 1309 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1310 PetscFunctionBegin; 1311 vbinary->usempiio = flg; 1312 PetscFunctionReturn(0); 1313 } 1314 #endif 1315 1316 static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1317 { 1318 PetscErrorCode ierr; 1319 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1320 1321 PetscFunctionBegin; 1322 if (binary->filename) { 1323 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1324 } 1325 PetscFunctionReturn(0); 1326 } 1327 1328 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer v) 1329 { 1330 PetscErrorCode ierr; 1331 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1332 1333 PetscFunctionBegin; 1334 if (!binary->setfromoptionscalled) { ierr = PetscViewerSetFromOptions(v);CHKERRQ(ierr); } 1335 1336 #if defined(PETSC_HAVE_MPIIO) 1337 if (binary->usempiio) { 1338 ierr = PetscViewerFileSetUp_BinaryMPIIO(v);CHKERRQ(ierr); 1339 } else { 1340 #endif 1341 ierr = PetscViewerFileSetUp_Binary(v);CHKERRQ(ierr); 1342 #if defined(PETSC_HAVE_MPIIO) 1343 } 1344 #endif 1345 PetscFunctionReturn(0); 1346 } 1347 1348 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer v) 1349 { 1350 PetscErrorCode ierr; 1351 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1352 char defaultname[PETSC_MAX_PATH_LEN]; 1353 PetscBool flg; 1354 1355 PetscFunctionBegin; 1356 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1357 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr); 1358 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,PETSC_MAX_PATH_LEN-1,&flg);CHKERRQ(ierr); 1359 if (flg) { ierr = PetscViewerFileSetName_Binary(v,defaultname);CHKERRQ(ierr); } 1360 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",PETSC_FALSE,&binary->skipinfo,NULL);CHKERRQ(ierr); 1361 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing vec load options","PetscViewerBinarySetSkipOptions",PETSC_TRUE,&binary->skipoptions,NULL);CHKERRQ(ierr); 1362 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",PETSC_FALSE,&binary->skipheader,NULL);CHKERRQ(ierr); 1363 #if defined(PETSC_HAVE_MPIIO) 1364 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,&binary->usempiio,NULL);CHKERRQ(ierr); 1365 #elif defined(PETSC_HAVE_MPIUNI) 1366 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);CHKERRQ(ierr); 1367 #endif 1368 ierr = PetscOptionsTail();CHKERRQ(ierr); 1369 binary->setfromoptionscalled = PETSC_TRUE; 1370 PetscFunctionReturn(0); 1371 } 1372 1373 /*MC 1374 PETSCVIEWERBINARY - A viewer that saves to binary files 1375 1376 1377 .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(), 1378 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW, 1379 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(), 1380 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO() 1381 1382 Level: beginner 1383 1384 M*/ 1385 1386 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1387 { 1388 PetscErrorCode ierr; 1389 PetscViewer_Binary *vbinary; 1390 1391 PetscFunctionBegin; 1392 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1393 v->data = (void*)vbinary; 1394 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1395 v->ops->destroy = PetscViewerDestroy_Binary; 1396 v->ops->view = PetscViewerView_Binary; 1397 v->ops->setup = PetscViewerSetUp_Binary; 1398 v->ops->flush = NULL; 1399 vbinary->fdes = 0; 1400 #if defined(PETSC_HAVE_MPIIO) 1401 vbinary->mfdes = MPI_FILE_NULL; 1402 vbinary->mfsub = MPI_FILE_NULL; 1403 #endif 1404 vbinary->fdes_info = NULL; 1405 vbinary->skipinfo = PETSC_FALSE; 1406 vbinary->skipoptions = PETSC_TRUE; 1407 vbinary->skipheader = PETSC_FALSE; 1408 vbinary->setfromoptionscalled = PETSC_FALSE; 1409 v->ops->getsubviewer = PetscViewerGetSubViewer_Binary; 1410 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary; 1411 v->ops->read = PetscViewerBinaryRead; 1412 vbinary->btype = (PetscFileMode) -1; 1413 vbinary->storecompressed = PETSC_FALSE; 1414 vbinary->filename = NULL; 1415 vbinary->ogzfilename = NULL; 1416 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1417 1418 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1419 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1420 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1421 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1422 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr); 1423 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr); 1424 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr); 1425 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr); 1426 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1427 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1428 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1429 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1430 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1431 #if defined(PETSC_HAVE_MPIIO) 1432 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr); 1433 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr); 1434 #endif 1435 PetscFunctionReturn(0); 1436 } 1437 1438 /* ---------------------------------------------------------------------*/ 1439 /* 1440 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1441 is attached to a communicator, in this case the attribute is a PetscViewer. 1442 */ 1443 PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1444 1445 /*@C 1446 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1447 in a communicator. 1448 1449 Collective 1450 1451 Input Parameter: 1452 . comm - the MPI communicator to share the binary PetscViewer 1453 1454 Level: intermediate 1455 1456 Options Database Keys: 1457 + -viewer_binary_filename <name> 1458 . -viewer_binary_skip_info 1459 . -viewer_binary_skip_options 1460 . -viewer_binary_skip_header 1461 - -viewer_binary_mpiio 1462 1463 Environmental variables: 1464 - PETSC_VIEWER_BINARY_FILENAME 1465 1466 Notes: 1467 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1468 an error code. The binary PetscViewer is usually used in the form 1469 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1470 1471 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1472 PetscViewerDestroy() 1473 @*/ 1474 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1475 { 1476 PetscErrorCode ierr; 1477 PetscBool flg; 1478 PetscViewer viewer; 1479 char fname[PETSC_MAX_PATH_LEN]; 1480 MPI_Comm ncomm; 1481 1482 PetscFunctionBegin; 1483 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1484 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1485 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL); 1486 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1487 } 1488 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1489 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1490 if (!flg) { /* PetscViewer not yet created */ 1491 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1492 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1493 if (!flg) { 1494 ierr = PetscStrcpy(fname,"binaryoutput"); 1495 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1496 } 1497 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1498 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1499 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1500 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1501 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1502 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1503 } 1504 ierr = PetscCommDestroy(&ncomm); 1505 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1506 PetscFunctionReturn(viewer); 1507 } 1508