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 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) *gz = 0; 1125 } 1126 1127 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1128 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1129 if (type == FILE_MODE_READ) { 1130 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1131 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1132 } else { 1133 vbinary->fdes_info = fopen(infoname,"w"); 1134 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1135 } 1136 } 1137 1138 #if defined(PETSC_USE_LOG) 1139 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 1140 #endif 1141 PetscFunctionReturn(0); 1142 } 1143 1144 #if defined(PETSC_HAVE_MPIIO) 1145 #undef __FUNCT__ 1146 #define __FUNCT__ "PetscViewerFileSetName_MPIIO" 1147 PetscErrorCode PetscViewerFileSetName_MPIIO(PetscViewer viewer,const char name[]) 1148 { 1149 PetscMPIInt rank; 1150 PetscErrorCode ierr; 1151 size_t len; 1152 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1153 char *gz; 1154 PetscBool found; 1155 PetscFileMode type = vbinary->btype; 1156 1157 PetscFunctionBegin; 1158 if (type == (PetscFileMode) -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode() before PetscViewerFileSetName()"); 1159 ierr = PetscViewerFileClose_MPIIO(viewer);CHKERRQ(ierr); 1160 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_info",&vbinary->skipinfo,NULL);CHKERRQ(ierr); 1161 ierr = PetscOptionsGetBool(((PetscObject)viewer)->prefix,"-viewer_binary_skip_options",&vbinary->skipoptions,NULL);CHKERRQ(ierr); 1162 1163 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr); 1164 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr); 1165 1166 vbinary->storecompressed = PETSC_FALSE; 1167 1168 /* only first processor opens file if writeable */ 1169 if (type == FILE_MODE_READ) { 1170 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1171 } else if (type == FILE_MODE_WRITE) { 1172 MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr); 1173 } 1174 1175 /* 1176 try to open info file: all processors open this file if read only 1177 1178 Below is identical code to the code for Binary above, should be put in seperate routine 1179 */ 1180 if (!vbinary->skipinfo && (!rank || type == FILE_MODE_READ)) { 1181 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN]; 1182 1183 ierr = PetscStrcpy(infoname,name);CHKERRQ(ierr); 1184 /* remove .gz if it ends library name */ 1185 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr); 1186 if (gz) { 1187 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr); 1188 if (len == 3) *gz = 0; 1189 } 1190 1191 ierr = PetscStrcat(infoname,".info");CHKERRQ(ierr); 1192 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr); 1193 if (type == FILE_MODE_READ) { 1194 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr); 1195 ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),infoname,PETSC_FALSE);CHKERRQ(ierr); 1196 } else { 1197 vbinary->fdes_info = fopen(infoname,"w"); 1198 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname); 1199 } 1200 } 1201 1202 #if defined(PETSC_USE_LOG) 1203 PetscLogObjectState((PetscObject)viewer,"File: %s",name); 1204 #endif 1205 PetscFunctionReturn(0); 1206 } 1207 1208 #undef __FUNCT__ 1209 #define __FUNCT__ "PetscViewerBinarySetMPIIO_Binary" 1210 PetscErrorCode PetscViewerBinarySetMPIIO_Binary(PetscViewer viewer) 1211 { 1212 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data; 1213 PetscErrorCode ierr; 1214 1215 PetscFunctionBegin; 1216 if (vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call before calling PetscViewerFileSetName()"); 1217 viewer->ops->destroy = PetscViewerDestroy_MPIIO; 1218 vbinary->MPIIO = PETSC_TRUE; 1219 /* vbinary->skipinfo = PETSC_TRUE; */ 1220 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_MPIIO",PetscViewerFileSetName_MPIIO);CHKERRQ(ierr); 1221 PetscFunctionReturn(0); 1222 } 1223 #endif 1224 1225 #undef __FUNCT__ 1226 #define __FUNCT__ "PetscViewerView_Binary" 1227 PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer) 1228 { 1229 PetscErrorCode ierr; 1230 PetscViewer_Binary *binary = (PetscViewer_Binary*)v->data; 1231 1232 PetscFunctionBegin; 1233 if (binary->filename) { 1234 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",binary->filename);CHKERRQ(ierr); 1235 } 1236 PetscFunctionReturn(0); 1237 } 1238 1239 #undef __FUNCT__ 1240 #define __FUNCT__ "PetscViewerCreate_Binary" 1241 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v) 1242 { 1243 PetscErrorCode ierr; 1244 PetscViewer_Binary *vbinary; 1245 #if defined(PETSC_HAVE_MPIIO) 1246 PetscBool useMPIIO = PETSC_FALSE; 1247 #endif 1248 1249 PetscFunctionBegin; 1250 ierr = PetscNewLog(v,PetscViewer_Binary,&vbinary);CHKERRQ(ierr); 1251 v->data = (void*)vbinary; 1252 v->ops->destroy = PetscViewerDestroy_Binary; 1253 v->ops->view = PetscViewerView_Binary; 1254 v->ops->flush = 0; 1255 vbinary->fdes_info = 0; 1256 vbinary->fdes = 0; 1257 vbinary->skipinfo = PETSC_FALSE; 1258 vbinary->skipoptions = PETSC_TRUE; 1259 vbinary->skipheader = PETSC_FALSE; 1260 v->ops->getsingleton = PetscViewerGetSingleton_Binary; 1261 v->ops->restoresingleton = PetscViewerRestoreSingleton_Binary; 1262 vbinary->btype = (PetscFileMode) -1; 1263 vbinary->storecompressed = PETSC_FALSE; 1264 vbinary->filename = 0; 1265 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */ 1266 1267 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C","PetscViewerBinaryGetFlowControl_Binary",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr); 1268 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C","PetscViewerBinarySetFlowControl_Binary",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr); 1269 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C","PetscViewerBinarySetSkipHeader_Binary",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr); 1270 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C","PetscViewerBinaryGetSkipHeader_Binary",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr); 1271 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C","PetscViewerBinaryGetInfoPointer_Binary",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr); 1272 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C","PetscViewerFileSetName_Binary",PetscViewerFileSetName_Binary);CHKERRQ(ierr); 1273 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_Binary",PetscViewerFileSetMode_Binary);CHKERRQ(ierr); 1274 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_Binary",PetscViewerFileGetMode_Binary);CHKERRQ(ierr); 1275 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C","PetscViewerFileGetName_Binary",PetscViewerFileGetName_Binary);CHKERRQ(ierr); 1276 #if defined(PETSC_HAVE_MPIIO) 1277 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetMPIIO_C","PetscViewerBinarySetMPIIO_Binary",PetscViewerBinarySetMPIIO_Binary);CHKERRQ(ierr); 1278 1279 ierr = PetscOptionsGetBool(NULL,"-viewer_binary_mpiio",&useMPIIO,NULL);CHKERRQ(ierr); 1280 if (useMPIIO) { 1281 ierr = PetscViewerBinarySetMPIIO(v);CHKERRQ(ierr); 1282 } 1283 #endif 1284 PetscFunctionReturn(0); 1285 } 1286 1287 /* ---------------------------------------------------------------------*/ 1288 /* 1289 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that 1290 is attached to a communicator, in this case the attribute is a PetscViewer. 1291 */ 1292 static int Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID; 1293 1294 #undef __FUNCT__ 1295 #define __FUNCT__ "PETSC_VIEWER_BINARY_" 1296 /*@C 1297 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors 1298 in a communicator. 1299 1300 Collective on MPI_Comm 1301 1302 Input Parameter: 1303 . comm - the MPI communicator to share the binary PetscViewer 1304 1305 Level: intermediate 1306 1307 Options Database Keys: 1308 + -viewer_binary_filename <name> 1309 . -viewer_binary_skip_info 1310 - -viewer_binary_skip_options 1311 1312 Environmental variables: 1313 - PETSC_VIEWER_BINARY_FILENAME 1314 1315 Notes: 1316 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return 1317 an error code. The binary PetscViewer is usually used in the form 1318 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm)); 1319 1320 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(), 1321 PetscViewerDestroy() 1322 @*/ 1323 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm) 1324 { 1325 PetscErrorCode ierr; 1326 PetscBool flg; 1327 PetscViewer viewer; 1328 char fname[PETSC_MAX_PATH_LEN]; 1329 MPI_Comm ncomm; 1330 1331 PetscFunctionBegin; 1332 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);} 1333 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) { 1334 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,0); 1335 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1336 } 1337 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg); 1338 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1339 if (!flg) { /* PetscViewer not yet created */ 1340 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&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) { 1343 ierr = PetscStrcpy(fname,"binaryoutput"); 1344 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1345 } 1346 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer); 1347 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1348 ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 1349 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1350 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer); 1351 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1352 } 1353 ierr = PetscCommDestroy(&ncomm); 1354 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 1355 PetscFunctionReturn(viewer); 1356 } 1357