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