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