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 = (PetscViewer_Binary*)viewer->data; 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 = PetscMPIIntCast(count); 714 MPI_Status status; 715 MPI_Aint ul,dsize; 716 717 PetscFunctionBegin; 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 vbinary->moff += dsize*cnt; 727 PetscFunctionReturn(0); 728 } 729 #endif 730 731 #undef __FUNCT__ 732 #define __FUNCT__ "PetscViewerBinaryRead" 733 /*@C 734 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result 735 736 Collective on MPI_Comm 737 738 Input Parameters: 739 + viewer - the binary viewer 740 . data - location to write the data 741 . count - number of items of data to read 742 - datatype - type of data to read 743 744 Level: beginner 745 746 Concepts: binary files 747 748 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 749 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 750 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 751 @*/ 752 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype) 753 { 754 PetscErrorCode ierr; 755 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 756 757 #if defined(PETSC_HAVE_MPIIO) 758 if (vbinary->MPIIO) { 759 ierr = PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_FALSE);CHKERRQ(ierr); 760 } else { 761 #endif 762 ierr = PetscBinarySynchronizedRead(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype);CHKERRQ(ierr); 763 #if defined(PETSC_HAVE_MPIIO) 764 } 765 #endif 766 PetscFunctionReturn(0); 767 } 768 769 770 #undef __FUNCT__ 771 #define __FUNCT__ "PetscViewerBinaryWrite" 772 /*@C 773 PetscViewerBinaryWrite - writes to a binary file, only from the first process 774 775 Collective on MPI_Comm 776 777 Input Parameters: 778 + viewer - the binary viewer 779 . data - location of data 780 . count - number of items of data to read 781 . dtype - type of data to read 782 - istemp - data may be overwritten 783 784 Level: beginner 785 786 Notes: because byte-swapping may be done on the values in data it cannot be declared const 787 788 Concepts: binary files 789 790 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 791 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType 792 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 793 @*/ 794 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype,PetscBool istemp) 795 { 796 PetscErrorCode ierr; 797 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 798 799 PetscFunctionBegin; 800 #if defined(PETSC_HAVE_MPIIO) 801 if (vbinary->MPIIO) { 802 ierr = PetscViewerBinaryMPIIO(viewer,data,count,dtype,PETSC_TRUE);CHKERRQ(ierr); 803 } else { 804 #endif 805 ierr = PetscBinarySynchronizedWrite(((PetscObject)viewer)->comm,vbinary->fdes,data,count,dtype,istemp);CHKERRQ(ierr); 806 #if defined(PETSC_HAVE_MPIIO) 807 } 808 #endif 809 PetscFunctionReturn(0); 810 } 811 812 #undef __FUNCT__ 813 #define __FUNCT__ "PetscViewerBinaryWriteStringArray" 814 /*@C 815 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings 816 817 Collective on MPI_Comm 818 819 Input Parameters: 820 + viewer - the binary viewer 821 - data - location of the array of strings 822 823 824 Level: intermediate 825 826 Concepts: binary files 827 828 Notes: array of strings is null terminated 829 830 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 831 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 832 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 833 @*/ 834 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,char **data) 835 { 836 PetscErrorCode ierr; 837 PetscInt i,n = 0,*sizes; 838 839 /* count number of strings */ 840 while (data[n++]); 841 n--; 842 ierr = PetscMalloc((n+1)*sizeof(PetscInt),&sizes);CHKERRQ(ierr); 843 sizes[0] = n; 844 for (i=0; i<n; i++) { 845 size_t tmp; 846 ierr = PetscStrlen(data[i],&tmp);CHKERRQ(ierr); 847 sizes[i+1] = tmp + 1; /* size includes space for the null terminator */ 848 } 849 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 850 for (i=0; i<n; i++) { 851 ierr = PetscViewerBinaryWrite(viewer,data[i],sizes[i+1],PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr); 852 } 853 ierr = PetscFree(sizes);CHKERRQ(ierr); 854 PetscFunctionReturn(0); 855 } 856 857 /*@C 858 PetscViewerBinaryReadStringArray - reads a binary file an array of strings 859 860 Collective on MPI_Comm 861 862 Input Parameter: 863 . viewer - the binary viewer 864 865 Output Parameter: 866 . data - location of the array of strings 867 868 Level: intermediate 869 870 Concepts: binary files 871 872 Notes: array of strings is null terminated 873 874 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(), 875 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), 876 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead() 877 @*/ 878 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data) 879 { 880 PetscErrorCode ierr; 881 PetscInt i,n,*sizes,N = 0; 882 883 /* count number of strings */ 884 ierr = PetscViewerBinaryRead(viewer,&n,1,PETSC_INT);CHKERRQ(ierr); 885 ierr = PetscMalloc(n*sizeof(PetscInt),&sizes);CHKERRQ(ierr); 886 ierr = PetscViewerBinaryRead(viewer,sizes,n,PETSC_INT);CHKERRQ(ierr); 887 for (i=0; i<n; i++) { 888 N += sizes[i]; 889 } 890 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr); 891 (*data)[0] = (char*)((*data) + n + 1); 892 for (i=1; i<n; i++) { 893 (*data)[i] = (*data)[i-1] + sizes[i-1]; 894 } 895 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,PETSC_CHAR);CHKERRQ(ierr); 896 (*data)[n] = 0; 897 ierr = PetscFree(sizes);CHKERRQ(ierr); 898 PetscFunctionReturn(0); 899 } 900 901 EXTERN_C_BEGIN 902 #undef __FUNCT__ 903 #define __FUNCT__ "PetscViewerFileGetName_Binary" 904 PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name) 905 { 906 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 907 908 PetscFunctionBegin; 909 *name = vbinary->filename; 910 PetscFunctionReturn(0); 911 } 912 EXTERN_C_END 913 914 #undef __FUNCT__ 915 #define __FUNCT__ "PetscViewerFileGetMode" 916 /*@C 917 PetscViewerFileGetMode - Gets the type of file to be open 918 919 Not Collective 920 921 Input Parameter: 922 . viewer - the PetscViewer; must be a binary, MATLAB, hdf, or netcdf PetscViewer 923 924 Output Parameter: 925 . type - type of file 926 $ FILE_MODE_WRITE - create new file for binary output 927 $ FILE_MODE_READ - open existing file for binary input 928 $ FILE_MODE_APPEND - open existing file for binary output 929 930 Level: advanced 931 932 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 933 934 @*/ 935 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *type) 936 { 937 PetscErrorCode ierr; 938 939 PetscFunctionBegin; 940 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 941 PetscValidPointer(type,2); 942 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,type));CHKERRQ(ierr); 943 PetscFunctionReturn(0); 944 } 945 946 #undef __FUNCT__ 947 #define __FUNCT__ "PetscViewerBinarySetMPIIO" 948 /*@ 949 PetscViewerBinarySetMPIIO - Sets a binary viewer to use MPI IO for reading/writing. Must be called 950 before PetscViewerFileSetName() 951 952 Logically Collective on PetscViewer 953 954 Input Parameters: 955 . viewer - the PetscViewer; must be a binary 956 957 Options Database: 958 -viewer_binary_mpiio : Flag for using MPI-IO 959 960 Notes: turns off the default usage of the .info file since that is not scalable 961 962 Level: advanced 963 964 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 965 966 @*/ 967 PetscErrorCode PetscViewerBinarySetMPIIO(PetscViewer viewer) 968 { 969 PetscErrorCode ierr; 970 971 PetscFunctionBegin; 972 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 973 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetMPIIO_C",(PetscViewer),(viewer));CHKERRQ(ierr); 974 PetscFunctionReturn(0); 975 } 976 977 978 #undef __FUNCT__ 979 #define __FUNCT__ "PetscViewerFileSetMode" 980 /*@C 981 PetscViewerFileSetMode - Sets the type of file to be open 982 983 Logically Collective on PetscViewer 984 985 Input Parameters: 986 + viewer - the PetscViewer; must be a binary, Matlab, hdf, or netcdf PetscViewer 987 - type - type of file 988 $ FILE_MODE_WRITE - create new file for binary output 989 $ FILE_MODE_READ - open existing file for binary input 990 $ FILE_MODE_APPEND - open existing file for binary output 991 992 Level: advanced 993 994 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen() 995 996 @*/ 997 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode type) 998 { 999 PetscErrorCode ierr; 1000 1001 PetscFunctionBegin; 1002 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 1003 PetscValidLogicalCollectiveEnum(viewer,type,2); 1004 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,type));CHKERRQ(ierr); 1005 PetscFunctionReturn(0); 1006 } 1007 1008 EXTERN_C_BEGIN 1009 #undef __FUNCT__ 1010 #define __FUNCT__ "PetscViewerFileGetMode_Binary" 1011 PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *type) 1012 { 1013 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1014 1015 PetscFunctionBegin; 1016 *type = vbinary->btype; 1017 PetscFunctionReturn(0); 1018 } 1019 EXTERN_C_END 1020 1021 EXTERN_C_BEGIN 1022 #undef __FUNCT__ 1023 #define __FUNCT__ "PetscViewerFileSetMode_Binary" 1024 PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode type) 1025 { 1026 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1027 1028 PetscFunctionBegin; 1029 vbinary->btype = type; 1030 PetscFunctionReturn(0); 1031 } 1032 EXTERN_C_END 1033 1034 /* 1035 Actually opens the file 1036 */ 1037 EXTERN_C_BEGIN 1038 #undef __FUNCT__ 1039 #define __FUNCT__ "PetscViewerFileSetName_Binary" 1040 PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[]) 1041 { 1042 PetscMPIInt rank; 1043 PetscErrorCode ierr; 1044 size_t len; 1045 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1046 const char *fname; 1047 char bname[PETSC_MAX_PATH_LEN],*gz; 1048 PetscBool found; 1049 PetscFileMode type = vbinary->btype; 1050 1051 PetscFunctionBegin; 1052 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 1053 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr); 1054 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);CHKERRQ(ierr); 1055 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);CHKERRQ(ierr); 1056 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_header",&vbinary->skipheader,PETSC_NULL);CHKERRQ(ierr); 1057 1058 ierr = MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);CHKERRQ(ierr); 1059 1060 /* copy name so we can edit it */ 1061 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1062 1063 /* if ends in .gz strip that off and note user wants file compressed */ 1064 vbinary->storecompressed = PETSC_FALSE; 1065 if (!rank && type == FILE_MODE_WRITE) { 1066 /* remove .gz if it ends library name */ 1067 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr); 1068 if (gz) { 1069 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1070 if (len == 3) { 1071 *gz = 0; 1072 vbinary->storecompressed = PETSC_TRUE; 1073 } 1074 } 1075 } 1076 1077 /* only first processor opens file if writeable */ 1078 if (!rank || type == FILE_MODE_READ) { 1079 1080 if (type == FILE_MODE_READ){ 1081 /* possibly get the file from remote site or compressed file */ 1082 ierr = PetscFileRetrieve(((PetscObject)viewer)->comm,vbinary->filename,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1083 fname = bname; 1084 if (!rank && !found) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot locate file: %s on node zero",vbinary->filename); 1085 else if (!found) { 1086 ierr = PetscInfo(viewer,"Nonzero processor did not locate readonly file\n");CHKERRQ(ierr); 1087 fname = 0; 1088 } 1089 } else { 1090 fname = vbinary->filename; 1091 } 1092 1093 #if defined(PETSC_HAVE_O_BINARY) 1094 if (type == FILE_MODE_WRITE) { 1095 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); 1096 } else if (type == FILE_MODE_READ && fname) { 1097 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); 1098 } else if (type == FILE_MODE_APPEND) { 1099 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); 1100 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1101 #else 1102 if (type == FILE_MODE_WRITE) { 1103 if ((vbinary->fdes = creat(fname,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file %s for writing",fname); 1104 } else if (type == FILE_MODE_READ && fname) { 1105 if ((vbinary->fdes = open(fname,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file %s for reading",fname); 1106 } else if (type == FILE_MODE_APPEND) { 1107 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); 1108 } else if (fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file type"); 1109 #endif 1110 } else vbinary->fdes = -1; 1111 viewer->format = PETSC_VIEWER_NOFORMAT; 1112 1113 /* 1114 try to open info file: all processors open this file if read only 1115 */ 1116 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1117 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1118 1119 ierr = PetscStrcpy(infoname,name);CHKERRQ(ierr); 1120 /* remove .gz if it ends library name */ 1121 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1122 if (gz) { 1123 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1124 if (len == 3) { 1125 *gz = 0; 1126 } 1127 } 1128 1129 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1130 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1131 if (type == FILE_MODE_READ) { 1132 ierr = PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1133 ierr = PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);CHKERRQ(ierr); 1134 } else { 1135 vbinary->fdes_info = fopen(infoname,"w"); 1136 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1137 } 1138 } 1139 1140 #if defined(PETSC_USE_LOG) 1141 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 1142 #endif 1143 PetscFunctionReturn(0); 1144 } 1145 EXTERN_C_END 1146 1147 #if defined(PETSC_HAVE_MPIIO) 1148 EXTERN_C_BEGIN 1149 #undef __FUNCT__ 1150 #define __FUNCT__ "PetscViewerFileSetName_MPIIO" 1151 PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[]) 1152 { 1153 PetscMPIInt rank; 1154 PetscErrorCode ierr; 1155 size_t len; 1156 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1157 char *gz; 1158 PetscBool found; 1159 PetscFileMode type = vbinary->btype; 1160 1161 PetscFunctionBegin; 1162 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 1163 ierr = PetscViewerFileClose_MPIIO(viewer);CHKERRQ(ierr); 1164 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,PETSC_NULL);CHKERRQ(ierr); 1165 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,PETSC_NULL);CHKERRQ(ierr); 1166 1167 ierr = MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);CHKERRQ(ierr); 1168 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1169 vbinary->storecompressed = PETSC_FALSE; 1170 1171 1172 /* only first processor opens file if writeable */ 1173 if (type == FILE_MODE_READ) { 1174 MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1175 } else if (type == FILE_MODE_WRITE) { 1176 MPI_File_open(((PetscObject)viewer)->comm,vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1177 } 1178 viewer->format = PETSC_VIEWER_NOFORMAT; 1179 1180 /* 1181 try to open info file: all processors open this file if read only 1182 1183 Below is identical code to the code for Binary above, should be put in seperate routine 1184 */ 1185 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1186 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1187 1188 ierr = PetscStrcpy(infoname,name);CHKERRQ(ierr); 1189 /* remove .gz if it ends library name */ 1190 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1191 if (gz) { 1192 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1193 if (len == 3) { 1194 *gz = 0; 1195 } 1196 } 1197 1198 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1199 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1200 if (type == FILE_MODE_READ) { 1201 ierr = PetscFileRetrieve(((PetscObject)viewer)->comm,iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1202 ierr = PetscOptionsInsertFile(((PetscObject)viewer)->comm,infoname,PETSC_FALSE);CHKERRQ(ierr); 1203 } else { 1204 vbinary->fdes_info = fopen(infoname,"w"); 1205 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1206 } 1207 } 1208 1209 #if defined(PETSC_USE_LOG) 1210 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 1211 #endif 1212 PetscFunctionReturn(0); 1213 } 1214 EXTERN_C_END 1215 1216 EXTERN_C_BEGIN 1217 #undef __FUNCT__ 1218 #define __FUNCT__ "PetscViewerBinarySetMPIIO_Binary" 1219 PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer) 1220 { 1221 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1222 PetscErrorCode ierr; 1223 1224 PetscFunctionBegin; 1225 if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()"); 1226 viewer->ops->destroy = PetscViewerDestroy_MPIIO; 1227 vbinary->MPIIO = PETSC_TRUE; 1228 /* vbinary->skipinfo = PETSC_TRUE; */ 1229 ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);CHKERRQ(ierr); 1230 PetscFunctionReturn(0); 1231 } 1232 EXTERN_C_END 1233 #endif 1234 1235 #undef __FUNCT__ 1236 #define __FUNCT__ "PetscViewerView_Binary" 1237 PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1238 { 1239 PetscErrorCode ierr; 1240 PetscViewer_Binary *binary = (PetscViewer_Binary *)v->data; 1241 1242 PetscFunctionBegin; 1243 if (binary->filename) { 1244 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1245 } 1246 PetscFunctionReturn(0); 1247 } 1248 1249 EXTERN_C_BEGIN 1250 #undef __FUNCT__ 1251 #define __FUNCT__ "PetscViewerCreate_Binary" 1252 PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1253 { 1254 PetscErrorCode ierr; 1255 PetscViewer_Binary *vbinary; 1256 #if defined(PETSC_HAVE_MPIIO) 1257 PetscBool useMPIIO = PETSC_FALSE; 1258 #endif 1259 1260 PetscFunctionBegin; 1261 ierr = PetscNewLog(v,PetscViewer_Binary,&vbinary);CHKERRQ(ierr); 1262 v->data = (void*)vbinary; 1263 v->ops->destroy = PetscViewerDestroy_Binary; 1264 v->ops->view = PetscViewerView_Binary; 1265 v->ops->flush = 0; 1266 v->iformat = 0; 1267 vbinary->fdes_info = 0; 1268 vbinary->fdes = 0; 1269 vbinary->skipinfo = PETSC_FALSE; 1270 vbinary->skipoptions = PETSC_TRUE; 1271 vbinary->skipheader = PETSC_FALSE; 1272 v->ops->getsingleton = PetscViewerGetSingleton_Binary; 1273 v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary; 1274 vbinary->btype = (PetscFileMode) -1; 1275 vbinary->storecompressed = PETSC_FALSE; 1276 vbinary->filename = 0; 1277 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1278 1279 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinaryGetFlowControl_C", 1280 "PetscViewerBinaryGetFlowControl_Binary", 1281 PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1282 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetFlowControl_C", 1283 "PetscViewerBinarySetFlowControl_Binary", 1284 PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1285 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetSkipHeader_C", 1286 "PetscViewerBinarySetSkipHeader_Binary", 1287 PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1288 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C", 1289 "PetscViewerBinaryGetSkipHeader_Binary", 1290 PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1291 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C", 1292 "PetscViewerBinaryGetInfoPointer_Binary", 1293 PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1294 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetName_C", 1295 "PetscViewerFileSetName_Binary", 1296 PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1297 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileSetMode_C", 1298 "PetscViewerFileSetMode_Binary", 1299 PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1300 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetMode_C", 1301 "PetscViewerFileGetMode_Binary", 1302 PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1303 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerFileGetName_C", 1304 "PetscViewerFileGetName_Binary", 1305 PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1306 #if defined(PETSC_HAVE_MPIIO) 1307 ierr = PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscViewerBinarySetMPIIO_C", 1308 "PetscViewerBinarySetMPIIO_Binary", 1309 PetscViewerBinarySetMPIIO_Binary);CHKERRQ(ierr); 1310 1311 ierr = PetscOptionsGetBool(PETSC_NULL,"-viewer_binary_mpiio",&useMPIIO,PETSC_NULL);CHKERRQ(ierr); 1312 if (useMPIIO) { 1313 ierr = PetscViewerBinarySetMPIIO(v);CHKERRQ(ierr); 1314 } 1315 #endif 1316 PetscFunctionReturn(0); 1317 } 1318 EXTERN_C_END 1319 1320 1321 /* ---------------------------------------------------------------------*/ 1322 /* 1323 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1324 is attached to a communicator, in this case the attribute is a PetscViewer. 1325 */ 1326 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1327 1328 #undef __FUNCT__ 1329 #define __FUNCT__ "PETSC_VIEWER_BINARY_" 1330 /*@C 1331 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1332 in a communicator. 1333 1334 Collective on MPI_Comm 1335 1336 Input Parameter: 1337 . comm - the MPI communicator to share the binary PetscViewer 1338 1339 Level: intermediate 1340 1341 Options Database Keys: 1342 + -viewer_binary_filename <name> 1343 . -viewer_binary_skip_info 1344 - -viewer_binary_skip_options 1345 1346 Environmental variables: 1347 - PETSC_VIEWER_BINARY_FILENAME 1348 1349 Notes: 1350 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1351 an error code. The binary PetscViewer is usually used in the form 1352 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1353 1354 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1355 PetscViewerDestroy() 1356 @*/ 1357 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1358 { 1359 PetscErrorCode ierr; 1360 PetscBool flg; 1361 PetscViewer viewer; 1362 char fname[PETSC_MAX_PATH_LEN]; 1363 MPI_Comm ncomm; 1364 1365 PetscFunctionBegin; 1366 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);} 1367 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1368 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1369 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1370 } 1371 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void **)&viewer,(int*)&flg); 1372 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1373 if (!flg) { /* PetscViewer not yet created */ 1374 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg); 1375 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1376 if (!flg) { 1377 ierr = PetscStrcpy(fname,"binaryoutput"); 1378 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1379 } 1380 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1381 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1382 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1383 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1384 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1385 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1386 } 1387 ierr = PetscCommDestroy(&ncomm); 1388 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1389 PetscFunctionReturn(viewer); 1390 } 1391