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