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