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