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