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);CHKERRMPI(ierr); 34 } 35 if (vbinary->mfdes != MPI_FILE_NULL) { 36 ierr = MPI_Barrier(PetscObjectComm((PetscObject)viewer));CHKERRMPI(ierr); 37 ierr = MPI_File_sync(vbinary->mfdes);CHKERRMPI(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);CHKERRMPI(ierr); 54 if (!rank) { 55 PetscMPIInt flg; 56 57 ierr = MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);CHKERRMPI(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);CHKERRMPI(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);CHKERRMPI(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);CHKERRMPI(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));CHKERRMPI(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 - true indicates do not generate .info file 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 - true indicates do not generate .info file 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 the options from the options database 557 558 Options Database Key: 559 . -viewer_binary_skip_options - true means do not use the options from the options database 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 - PETSC_TRUE means do not write header 639 640 Level: advanced 641 642 Notes: 643 This must be called after PetscViewerSetType() 644 645 Is ignored on anything but 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);CHKERRMPI(ierr); 777 } 778 if (vbinary->mfsub != MPI_FILE_NULL) { 779 ierr = MPI_File_close(&vbinary->mfsub);CHKERRMPI(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);CHKERRMPI(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);CHKERRMPI(ierr);} 956 } 957 ierr = MPI_Bcast(&cnt,1,MPI_INT,0,comm);CHKERRMPI(ierr); 958 ierr = MPI_Bcast(data,cnt,mdtype,0,comm);CHKERRMPI(ierr); 959 } 960 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRMPI(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, PetscViewerBinaryRead() 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, PetscViewerBinaryRead() 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 PETSC_UNUSED MPI_Aint lb; 1054 MPI_Aint dsize; 1055 PetscBool useMPIIO; 1056 PetscErrorCode ierr; 1057 1058 PetscFunctionBegin; 1059 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY); 1060 PetscValidLogicalCollectiveBool(viewer,((start>=0)||(start==PETSC_DETERMINE)),4); 1061 PetscValidLogicalCollectiveBool(viewer,((total>=0)||(total==PETSC_DETERMINE)),5); 1062 PetscValidLogicalCollectiveInt(viewer,total,5); 1063 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 1064 1065 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr); 1066 ierr = MPI_Type_get_extent(mdtype,&lb,&dsize);CHKERRMPI(ierr); 1067 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 1068 ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 1069 1070 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr); 1071 #if defined(PETSC_HAVE_MPIIO) 1072 if (useMPIIO) { 1073 MPI_File mfdes; 1074 MPI_Offset off; 1075 PetscMPIInt cnt; 1076 1077 if (start == PETSC_DETERMINE) { 1078 ierr = MPI_Scan(&count,&start,1,MPIU_INT,MPI_SUM,comm);CHKERRMPI(ierr); 1079 start -= count; 1080 } 1081 if (total == PETSC_DETERMINE) { 1082 total = start + count; 1083 ierr = MPI_Bcast(&total,1,MPIU_INT,size-1,comm);CHKERRMPI(ierr); 1084 } 1085 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr); 1086 ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr); 1087 ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr); 1088 off += (MPI_Offset)(start*dsize); 1089 if (write) { 1090 ierr = MPIU_File_write_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);CHKERRQ(ierr); 1091 } else { 1092 ierr = MPIU_File_read_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);CHKERRQ(ierr); 1093 } 1094 off = (MPI_Offset)(total*dsize); 1095 ierr = PetscViewerBinaryAddMPIIOOffset(viewer,off);CHKERRQ(ierr); 1096 PetscFunctionReturn(0); 1097 } 1098 #endif 1099 { 1100 int fdes; 1101 char *workbuf = NULL; 1102 PetscInt tcount = !rank ? 0 : count,maxcount=0,message_count,flowcontrolcount; 1103 PetscMPIInt tag,cnt,maxcnt,scnt=0,rcnt=0,j; 1104 MPI_Status status; 1105 1106 ierr = PetscCommGetNewTag(comm,&tag);CHKERRQ(ierr); 1107 ierr = MPI_Reduce(&tcount,&maxcount,1,MPIU_INT,MPI_MAX,0,comm);CHKERRMPI(ierr); 1108 ierr = PetscMPIIntCast(maxcount,&maxcnt);CHKERRQ(ierr); 1109 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr); 1110 1111 ierr = PetscViewerBinaryGetDescriptor(viewer,&fdes);CHKERRQ(ierr); 1112 ierr = PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);CHKERRQ(ierr); 1113 if (!rank) { 1114 ierr = PetscMalloc(maxcnt*dsize,&workbuf);CHKERRQ(ierr); 1115 if (write) { 1116 ierr = PetscBinaryWrite(fdes,data,cnt,dtype);CHKERRQ(ierr); 1117 } else { 1118 ierr = PetscBinaryRead(fdes,data,cnt,NULL,dtype);CHKERRQ(ierr); 1119 } 1120 for (j=1; j<size; j++) { 1121 ierr = PetscViewerFlowControlStepMain(viewer,j,&message_count,flowcontrolcount);CHKERRQ(ierr); 1122 if (write) { 1123 ierr = MPI_Recv(workbuf,maxcnt,mdtype,j,tag,comm,&status);CHKERRMPI(ierr); 1124 ierr = MPI_Get_count(&status,mdtype,&rcnt);CHKERRMPI(ierr); 1125 ierr = PetscBinaryWrite(fdes,workbuf,rcnt,dtype);CHKERRQ(ierr); 1126 } else { 1127 ierr = MPI_Recv(&scnt,1,MPI_INT,j,tag,comm,MPI_STATUS_IGNORE);CHKERRMPI(ierr); 1128 ierr = PetscBinaryRead(fdes,workbuf,scnt,NULL,dtype);CHKERRQ(ierr); 1129 ierr = MPI_Send(workbuf,scnt,mdtype,j,tag,comm);CHKERRMPI(ierr); 1130 } 1131 } 1132 ierr = PetscFree(workbuf);CHKERRQ(ierr); 1133 ierr = PetscViewerFlowControlEndMain(viewer,&message_count);CHKERRQ(ierr); 1134 } else { 1135 ierr = PetscViewerFlowControlStepWorker(viewer,rank,&message_count);CHKERRQ(ierr); 1136 if (write) { 1137 ierr = MPI_Send(data,cnt,mdtype,0,tag,comm);CHKERRMPI(ierr); 1138 } else { 1139 ierr = MPI_Send(&cnt,1,MPI_INT,0,tag,comm);CHKERRMPI(ierr); 1140 ierr = MPI_Recv(data,cnt,mdtype,0,tag,comm,MPI_STATUS_IGNORE);CHKERRMPI(ierr); 1141 } 1142 ierr = PetscViewerFlowControlEndWorker(viewer,&message_count);CHKERRQ(ierr); 1143 } 1144 } 1145 PetscFunctionReturn(0); 1146 } 1147 1148 /*@C 1149 PetscViewerBinaryReadAll - reads from a binary file from all processes 1150 1151 Collective 1152 1153 Input Parameters: 1154 + viewer - the binary viewer 1155 . data - location of data 1156 . count - local number of items of data to read 1157 . start - local start, can be PETSC_DETERMINE 1158 . total - global number of items of data to read, can be PETSC_DETERMINE 1159 - dtype - type of data to read 1160 1161 Level: advanced 1162 1163 .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryRead(), PetscViewerBinaryWriteAll() 1164 @*/ 1165 PetscErrorCode PetscViewerBinaryReadAll(PetscViewer viewer,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype) 1166 { 1167 PetscErrorCode ierr; 1168 PetscFunctionBegin; 1169 ierr = PetscViewerBinaryWriteReadAll(viewer,PETSC_FALSE,data,count,start,total,dtype);CHKERRQ(ierr); 1170 PetscFunctionReturn(0); 1171 } 1172 1173 /*@C 1174 PetscViewerBinaryWriteAll - writes to a binary file from all processes 1175 1176 Collective 1177 1178 Input Parameters: 1179 + viewer - the binary viewer 1180 . data - location of data 1181 . count - local number of items of data to write 1182 . start - local start, can be PETSC_DETERMINE 1183 . total - global number of items of data to write, can be PETSC_DETERMINE 1184 - dtype - type of data to write 1185 1186 Level: advanced 1187 1188 .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryWriteAll(), PetscViewerBinaryReadAll() 1189 @*/ 1190 PetscErrorCode PetscViewerBinaryWriteAll(PetscViewer viewer,const void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype) 1191 { 1192 PetscErrorCode ierr; 1193 PetscFunctionBegin; 1194 ierr = PetscViewerBinaryWriteReadAll(viewer,PETSC_TRUE,(void*)data,count,start,total,dtype);CHKERRQ(ierr); 1195 PetscFunctionReturn(0); 1196 } 1197 1198 /*@C 1199 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 1200 1201 Collective 1202 1203 Input Parameters: 1204 + viewer - the binary viewer 1205 - data - location of the array of strings 1206 1207 1208 Level: intermediate 1209 1210 Notes: 1211 array of strings is null terminated 1212 1213 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 1214 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 1215 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead() 1216 @*/ 1217 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data) 1218 { 1219 PetscErrorCode ierr; 1220 PetscInt i,n = 0,*sizes; 1221 size_t len; 1222 1223 PetscFunctionBegin; 1224 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 1225 /* count number of strings */ 1226 while (data[n++]); 1227 n--; 1228 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr); 1229 sizes[0] = n; 1230 for (i=0; i<n; i++) { 1231 ierr = PetscStrlen(data[i],&len);CHKERRQ(ierr); 1232 sizes[i+1] = (PetscInt)len + 1; /* size includes space for the null terminator */ 1233 } 1234 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT);CHKERRQ(ierr); 1235 for (i=0; i<n; i++) { 1236 ierr = PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR);CHKERRQ(ierr); 1237 } 1238 ierr = PetscFree(sizes);CHKERRQ(ierr); 1239 PetscFunctionReturn(0); 1240 } 1241 1242 /*@C 1243 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 1244 1245 Collective 1246 1247 Input Parameter: 1248 . viewer - the binary viewer 1249 1250 Output Parameter: 1251 . data - location of the array of strings 1252 1253 Level: intermediate 1254 1255 Notes: 1256 array of strings is null terminated 1257 1258 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), 1259 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 1260 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead() 1261 @*/ 1262 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 1263 { 1264 PetscErrorCode ierr; 1265 PetscInt i,n,*sizes,N = 0; 1266 1267 PetscFunctionBegin; 1268 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 1269 /* count number of strings */ 1270 ierr = PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);CHKERRQ(ierr); 1271 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr); 1272 ierr = PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);CHKERRQ(ierr); 1273 for (i=0; i<n; i++) N += sizes[i]; 1274 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 1275 (*data)[0] = (char*)((*data) + n + 1); 1276 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1]; 1277 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);CHKERRQ(ierr); 1278 (*data)[n] = NULL; 1279 ierr = PetscFree(sizes);CHKERRQ(ierr); 1280 PetscFunctionReturn(0); 1281 } 1282 1283 /*@C 1284 PetscViewerFileSetMode - Sets the open mode of file 1285 1286 Logically Collective on PetscViewer 1287 1288 Input Parameters: 1289 + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1290 - mode - open mode of file 1291 $ FILE_MODE_WRITE - create new file for output 1292 $ FILE_MODE_READ - open existing file for input 1293 $ FILE_MODE_APPEND - open existing file for output 1294 1295 Level: advanced 1296 1297 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1298 1299 @*/ 1300 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode mode) 1301 { 1302 PetscErrorCode ierr; 1303 1304 PetscFunctionBegin; 1305 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1306 PetscValidLogicalCollectiveEnum(viewer,mode,2); 1307 if (mode == FILE_MODE_UNDEFINED) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot set FILE_MODE_UNDEFINED"); 1308 else if (mode < FILE_MODE_UNDEFINED || mode > FILE_MODE_APPEND_UPDATE) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Invalid file mode %d",(int)mode); 1309 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,mode));CHKERRQ(ierr); 1310 PetscFunctionReturn(0); 1311 } 1312 1313 static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode mode) 1314 { 1315 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1316 1317 PetscFunctionBegin; 1318 if (viewer->setupcalled && vbinary->filemode != mode) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change mode to %s after setup",PetscFileModes[mode]); 1319 vbinary->filemode = mode; 1320 PetscFunctionReturn(0); 1321 } 1322 1323 /*@C 1324 PetscViewerFileGetMode - Gets the open mode of file 1325 1326 Not Collective 1327 1328 Input Parameter: 1329 . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer 1330 1331 Output Parameter: 1332 . mode - open mode of file 1333 $ FILE_MODE_WRITE - create new file for binary output 1334 $ FILE_MODE_READ - open existing file for binary input 1335 $ FILE_MODE_APPEND - open existing file for binary output 1336 1337 Level: advanced 1338 1339 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 1340 1341 @*/ 1342 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *mode) 1343 { 1344 PetscErrorCode ierr; 1345 1346 PetscFunctionBegin; 1347 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1348 PetscValidPointer(mode,2); 1349 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,mode));CHKERRQ(ierr); 1350 PetscFunctionReturn(0); 1351 } 1352 1353 static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *mode) 1354 { 1355 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1356 1357 PetscFunctionBegin; 1358 *mode = vbinary->filemode; 1359 PetscFunctionReturn(0); 1360 } 1361 1362 static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1363 { 1364 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1365 PetscErrorCode ierr; 1366 1367 PetscFunctionBegin; 1368 if (viewer->setupcalled && vbinary->filename) { 1369 /* gzip can be run after the file with the previous filename has been closed */ 1370 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr); 1371 ierr = PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);CHKERRQ(ierr); 1372 } 1373 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr); 1374 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1375 viewer->setupcalled = PETSC_FALSE; 1376 PetscFunctionReturn(0); 1377 } 1378 1379 static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 1380 { 1381 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1382 1383 PetscFunctionBegin; 1384 *name = vbinary->filename; 1385 PetscFunctionReturn(0); 1386 } 1387 1388 #if defined(PETSC_HAVE_MPIIO) 1389 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer) 1390 { 1391 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1392 int amode; 1393 PetscErrorCode ierr; 1394 1395 PetscFunctionBegin; 1396 vbinary->storecompressed = PETSC_FALSE; 1397 1398 vbinary->moff = 0; 1399 switch (vbinary->filemode) { 1400 case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break; 1401 case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break; 1402 case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_APPEND; break; 1403 case FILE_MODE_UNDEFINED: SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER, "Must call PetscViewerFileSetMode() before PetscViewerSetUp()"); 1404 default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]); 1405 } 1406 ierr = MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);CHKERRMPI(ierr); 1407 /* 1408 The MPI standard does not have MPI_MODE_TRUNCATE. We emulate this behavior by setting the file size to zero. 1409 */ 1410 if (vbinary->filemode == FILE_MODE_WRITE) {ierr = MPI_File_set_size(vbinary->mfdes,0);CHKERRMPI(ierr);} 1411 /* 1412 Initially, all processes view the file as a linear byte stream. Therefore, for files opened with MPI_MODE_APPEND, 1413 MPI_File_get_position[_shared](fh, &offset) returns the absolute byte position at the end of file. 1414 Otherwise, we would need to call MPI_File_get_byte_offset(fh, offset, &byte_offset) to convert 1415 the offset in etype units to an absolute byte position. 1416 */ 1417 if (vbinary->filemode == FILE_MODE_APPEND) {ierr = MPI_File_get_position(vbinary->mfdes,&vbinary->moff);CHKERRMPI(ierr);} 1418 PetscFunctionReturn(0); 1419 } 1420 #endif 1421 1422 static PetscErrorCode PetscViewerFileSetUp_BinarySTDIO(PetscViewer viewer) 1423 { 1424 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1425 const char *fname; 1426 char bname[PETSC_MAX_PATH_LEN],*gz; 1427 PetscBool found; 1428 PetscMPIInt rank; 1429 PetscErrorCode ierr; 1430 1431 PetscFunctionBegin; 1432 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr); 1433 1434 /* if file name ends in .gz strip that off and note user wants file compressed */ 1435 vbinary->storecompressed = PETSC_FALSE; 1436 if (vbinary->filemode == FILE_MODE_WRITE) { 1437 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1438 if (gz && gz[3] == 0) {*gz = 0; vbinary->storecompressed = PETSC_TRUE;} 1439 } 1440 #if !defined(PETSC_HAVE_POPEN) 1441 if (vbinary->storecompressed) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP_SYS,"Cannot run gzip on this machine"); 1442 #endif 1443 1444 1445 fname = vbinary->filename; 1446 if (vbinary->filemode == FILE_MODE_READ) { /* possibly get the file from remote site or compressed file */ 1447 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),fname,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1448 if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s",fname); 1449 fname = bname; 1450 } 1451 1452 vbinary->fdes = -1; 1453 if (!rank) { /* only first processor opens file*/ 1454 PetscFileMode mode = vbinary->filemode; 1455 if (mode == FILE_MODE_APPEND) { 1456 /* check if asked to append to a non-existing file */ 1457 ierr = PetscTestFile(fname,'\0',&found);CHKERRQ(ierr); 1458 if (!found) mode = FILE_MODE_WRITE; 1459 } 1460 ierr = PetscBinaryOpen(fname,mode,&vbinary->fdes);CHKERRQ(ierr); 1461 } 1462 PetscFunctionReturn(0); 1463 } 1464 1465 static PetscErrorCode PetscViewerFileSetUp_BinaryInfo(PetscViewer viewer) 1466 { 1467 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1468 PetscMPIInt rank; 1469 PetscBool found; 1470 PetscErrorCode ierr; 1471 1472 PetscFunctionBegin; 1473 vbinary->fdes_info = NULL; 1474 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr); 1475 if (!vbinary->skipinfo && (vbinary->filemode == FILE_MODE_READ || !rank)) { 1476 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN],*gz; 1477 1478 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr); 1479 /* remove .gz if it ends file name */ 1480 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1481 if (gz && gz[3] == 0) *gz = 0; 1482 1483 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr); 1484 if (vbinary->filemode == FILE_MODE_READ) { 1485 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1486 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1487 if (found) {ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr);} 1488 } else if (!rank) { /* write or append */ 1489 const char *omode = (vbinary->filemode == FILE_MODE_APPEND) ? "a" : "w"; 1490 vbinary->fdes_info = fopen(infoname,omode); 1491 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1492 } 1493 } 1494 PetscFunctionReturn(0); 1495 } 1496 1497 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer viewer) 1498 { 1499 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1500 PetscBool usempiio; 1501 PetscErrorCode ierr; 1502 1503 PetscFunctionBegin; 1504 if (!vbinary->setfromoptionscalled) {ierr = PetscViewerSetFromOptions(viewer);CHKERRQ(ierr);} 1505 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()"); 1506 if (vbinary->filemode == (PetscFileMode)-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()"); 1507 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1508 1509 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&usempiio);CHKERRQ(ierr); 1510 if (usempiio) { 1511 #if defined(PETSC_HAVE_MPIIO) 1512 ierr = PetscViewerFileSetUp_BinaryMPIIO(viewer);CHKERRQ(ierr); 1513 #endif 1514 } else { 1515 ierr = PetscViewerFileSetUp_BinarySTDIO(viewer);CHKERRQ(ierr); 1516 } 1517 ierr = PetscViewerFileSetUp_BinaryInfo(viewer);CHKERRQ(ierr); 1518 1519 ierr = PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);CHKERRQ(ierr); 1520 PetscFunctionReturn(0); 1521 } 1522 1523 static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1524 { 1525 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data; 1526 const char *fname = vbinary->filename ? vbinary->filename : "not yet set"; 1527 const char *fmode = vbinary->filemode != (PetscFileMode) -1 ? PetscFileModes[vbinary->filemode] : "not yet set"; 1528 PetscBool usempiio; 1529 PetscErrorCode ierr; 1530 1531 PetscFunctionBegin; 1532 ierr = PetscViewerBinaryGetUseMPIIO(v,&usempiio);CHKERRQ(ierr); 1533 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",fname);CHKERRQ(ierr); 1534 ierr = PetscViewerASCIIPrintf(viewer,"Mode: %s (%s)\n",fmode,usempiio ? "mpiio" : "stdio");CHKERRQ(ierr); 1535 PetscFunctionReturn(0); 1536 } 1537 1538 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer viewer) 1539 { 1540 PetscViewer_Binary *binary = (PetscViewer_Binary*)viewer->data; 1541 char defaultname[PETSC_MAX_PATH_LEN]; 1542 PetscBool flg; 1543 PetscErrorCode ierr; 1544 1545 PetscFunctionBegin; 1546 if (viewer->setupcalled) PetscFunctionReturn(0); 1547 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr); 1548 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr); 1549 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,sizeof(defaultname),&flg);CHKERRQ(ierr); 1550 if (flg) { ierr = PetscViewerFileSetName_Binary(viewer,defaultname);CHKERRQ(ierr); } 1551 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",binary->skipinfo,&binary->skipinfo,NULL);CHKERRQ(ierr); 1552 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing Vec/Mat load options","PetscViewerBinarySetSkipOptions",binary->skipoptions,&binary->skipoptions,NULL);CHKERRQ(ierr); 1553 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",binary->skipheader,&binary->skipheader,NULL);CHKERRQ(ierr); 1554 #if defined(PETSC_HAVE_MPIIO) 1555 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",binary->usempiio,&binary->usempiio,NULL);CHKERRQ(ierr); 1556 #else 1557 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file (NOT AVAILABLE)","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);CHKERRQ(ierr); 1558 #endif 1559 ierr = PetscOptionsTail();CHKERRQ(ierr); 1560 binary->setfromoptionscalled = PETSC_TRUE; 1561 PetscFunctionReturn(0); 1562 } 1563 1564 /*MC 1565 PETSCVIEWERBINARY - A viewer that saves to binary files 1566 1567 1568 .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(), 1569 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW, 1570 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(), 1571 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO() 1572 1573 Level: beginner 1574 1575 M*/ 1576 1577 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1578 { 1579 PetscErrorCode ierr; 1580 PetscViewer_Binary *vbinary; 1581 1582 PetscFunctionBegin; 1583 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr); 1584 v->data = (void*)vbinary; 1585 1586 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary; 1587 v->ops->destroy = PetscViewerDestroy_Binary; 1588 v->ops->view = PetscViewerView_Binary; 1589 v->ops->setup = PetscViewerSetUp_Binary; 1590 v->ops->flush = NULL; /* Should we support Flush() ? */ 1591 v->ops->getsubviewer = PetscViewerGetSubViewer_Binary; 1592 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary; 1593 v->ops->read = PetscViewerBinaryRead; 1594 1595 vbinary->fdes = -1; 1596 #if defined(PETSC_HAVE_MPIIO) 1597 vbinary->usempiio = PETSC_FALSE; 1598 vbinary->mfdes = MPI_FILE_NULL; 1599 vbinary->mfsub = MPI_FILE_NULL; 1600 #endif 1601 vbinary->filename = NULL; 1602 vbinary->filemode = FILE_MODE_UNDEFINED; 1603 vbinary->fdes_info = NULL; 1604 vbinary->skipinfo = PETSC_FALSE; 1605 vbinary->skipoptions = PETSC_TRUE; 1606 vbinary->skipheader = PETSC_FALSE; 1607 vbinary->storecompressed = PETSC_FALSE; 1608 vbinary->ogzfilename = NULL; 1609 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1610 1611 vbinary->setfromoptionscalled = PETSC_FALSE; 1612 1613 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1614 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1615 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1616 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1617 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr); 1618 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr); 1619 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr); 1620 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr); 1621 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1622 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1623 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1624 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1625 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1626 #if defined(PETSC_HAVE_MPIIO) 1627 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr); 1628 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr); 1629 #endif 1630 PetscFunctionReturn(0); 1631 } 1632 1633 /* ---------------------------------------------------------------------*/ 1634 /* 1635 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1636 is attached to a communicator, in this case the attribute is a PetscViewer. 1637 */ 1638 PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1639 1640 /*@C 1641 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1642 in a communicator. 1643 1644 Collective 1645 1646 Input Parameter: 1647 . comm - the MPI communicator to share the binary PetscViewer 1648 1649 Level: intermediate 1650 1651 Options Database Keys: 1652 + -viewer_binary_filename <name> - filename in which to store the binary data, defaults to binaryoutput 1653 . -viewer_binary_skip_info - true means do not create .info file for this viewer 1654 . -viewer_binary_skip_options - true means do not use the options database for this viewer 1655 . -viewer_binary_skip_header - true means do not store the usual header information in the binary file 1656 - -viewer_binary_mpiio - true means use the file via MPI-IO, maybe faster for large files and many MPI ranks 1657 1658 Environmental variables: 1659 - PETSC_VIEWER_BINARY_FILENAME - filename in which to store the binary data, defaults to binaryoutput 1660 1661 Notes: 1662 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1663 an error code. The binary PetscViewer is usually used in the form 1664 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1665 1666 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1667 PetscViewerDestroy() 1668 @*/ 1669 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1670 { 1671 PetscErrorCode ierr; 1672 PetscBool flg; 1673 PetscViewer viewer; 1674 char fname[PETSC_MAX_PATH_LEN]; 1675 MPI_Comm ncomm; 1676 1677 PetscFunctionBegin; 1678 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1679 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1680 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL); 1681 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1682 } 1683 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1684 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1685 if (!flg) { /* PetscViewer not yet created */ 1686 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1687 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 1688 if (!flg) { 1689 ierr = PetscStrcpy(fname,"binaryoutput"); 1690 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 1691 } 1692 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1693 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 1694 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1695 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 1696 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1697 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);} 1698 } 1699 ierr = PetscCommDestroy(&ncomm); 1700 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_REPEAT," ");PetscFunctionReturn(NULL);} 1701 PetscFunctionReturn(viewer); 1702 } 1703