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