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