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