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