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