1 #define PETSC_DLL 2 3 /* 4 This file contains simple binary read/write routines. 5 */ 6 7 #include "petsc.h" 8 #include "petscsys.h" /*I "petscsys.h" I*/ 9 10 #include <errno.h> 11 #include <fcntl.h> 12 #if defined(PETSC_HAVE_UNISTD_H) 13 #include <unistd.h> 14 #endif 15 #if defined (PETSC_HAVE_IO_H) 16 #include <io.h> 17 #endif 18 #include "petscbt.h" 19 20 #if !defined(PETSC_WORDS_BIGENDIAN) 21 22 /* --------------------------------------------------------- */ 23 #undef __FUNCT__ 24 #define __FUNCT__ "PetscByteSwapEnum" 25 /* 26 PetscByteSwapEnum - Swap bytes in a PETSc Enum 27 28 */ 29 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapEnum(PetscEnum *buff,PetscInt n) 30 { 31 PetscInt i,j; 32 PetscEnum tmp = 0; 33 PetscEnum *tptr = &tmp; /* Need to access tmp indirectly to get */ 34 char *ptr1,*ptr2 = (char*)&tmp; /* arround the bug in DEC-ALPHA g++ */ 35 36 PetscFunctionBegin; 37 for (j=0; j<n; j++) { 38 ptr1 = (char*)(buff + j); 39 for (i=0; i<(int)sizeof(PetscEnum); i++) { 40 ptr2[i] = ptr1[sizeof(PetscEnum)-1-i]; 41 } 42 buff[j] = *tptr; 43 } 44 PetscFunctionReturn(0); 45 } 46 47 #undef __FUNCT__ 48 #define __FUNCT__ "PetscByteSwapTruth" 49 /* 50 PetscByteSwapTruth - Swap bytes in a PETSc Truth 51 52 */ 53 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapTruth(PetscTruth *buff,PetscInt n) 54 { 55 PetscInt i,j; 56 PetscTruth tmp = 0; 57 PetscTruth *tptr = &tmp; /* Need to access tmp indirectly to get */ 58 char *ptr1,*ptr2 = (char*)&tmp; /* arround the bug in DEC-ALPHA g++ */ 59 60 PetscFunctionBegin; 61 for (j=0; j<n; j++) { 62 ptr1 = (char*)(buff + j); 63 for (i=0; i<(int)sizeof(PetscTruth); i++) { 64 ptr2[i] = ptr1[sizeof(PetscTruth)-1-i]; 65 } 66 buff[j] = *tptr; 67 } 68 PetscFunctionReturn(0); 69 } 70 71 #undef __FUNCT__ 72 #define __FUNCT__ "PetscByteSwapInt" 73 /* 74 PetscByteSwapInt - Swap bytes in a PETSc integer (which may be 32 or 64 bits) 75 76 */ 77 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapInt(PetscInt *buff,PetscInt n) 78 { 79 PetscInt i,j,tmp = 0; 80 PetscInt *tptr = &tmp; /* Need to access tmp indirectly to get */ 81 char *ptr1,*ptr2 = (char*)&tmp; /* arround the bug in DEC-ALPHA g++ */ 82 83 PetscFunctionBegin; 84 for (j=0; j<n; j++) { 85 ptr1 = (char*)(buff + j); 86 for (i=0; i<(int)sizeof(PetscInt); i++) { 87 ptr2[i] = ptr1[sizeof(PetscInt)-1-i]; 88 } 89 buff[j] = *tptr; 90 } 91 PetscFunctionReturn(0); 92 } 93 /* --------------------------------------------------------- */ 94 #undef __FUNCT__ 95 #define __FUNCT__ "PetscByteSwapShort" 96 /* 97 PetscByteSwapShort - Swap bytes in a short 98 */ 99 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapShort(short *buff,PetscInt n) 100 { 101 PetscInt i,j; 102 short tmp; 103 short *tptr = &tmp; /* take care pf bug in DEC-ALPHA g++ */ 104 char *ptr1,*ptr2 = (char*)&tmp; 105 106 PetscFunctionBegin; 107 for (j=0; j<n; j++) { 108 ptr1 = (char*)(buff + j); 109 for (i=0; i<(int) sizeof(short); i++) { 110 ptr2[i] = ptr1[sizeof(int)-1-i]; 111 } 112 buff[j] = *tptr; 113 } 114 PetscFunctionReturn(0); 115 } 116 /* --------------------------------------------------------- */ 117 #undef __FUNCT__ 118 #define __FUNCT__ "PetscByteSwapScalar" 119 /* 120 PetscByteSwapScalar - Swap bytes in a double 121 Complex is dealt with as if array of double twice as long. 122 */ 123 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapScalar(PetscScalar *buff,PetscInt n) 124 { 125 PetscInt i,j; 126 PetscReal tmp,*buff1 = (PetscReal*)buff; 127 PetscReal *tptr = &tmp; /* take care pf bug in DEC-ALPHA g++ */ 128 char *ptr1,*ptr2 = (char*)&tmp; 129 130 PetscFunctionBegin; 131 #if defined(PETSC_USE_COMPLEX) 132 n *= 2; 133 #endif 134 for (j=0; j<n; j++) { 135 ptr1 = (char*)(buff1 + j); 136 for (i=0; i<(int) sizeof(PetscReal); i++) { 137 ptr2[i] = ptr1[sizeof(PetscReal)-1-i]; 138 } 139 buff1[j] = *tptr; 140 } 141 PetscFunctionReturn(0); 142 } 143 /* --------------------------------------------------------- */ 144 #undef __FUNCT__ 145 #define __FUNCT__ "PetscByteSwapDouble" 146 /* 147 PetscByteSwapDouble - Swap bytes in a double 148 */ 149 PetscErrorCode PETSC_DLLEXPORT PetscByteSwapDouble(double *buff,PetscInt n) 150 { 151 PetscInt i,j; 152 double tmp,*buff1 = (double*)buff; 153 double *tptr = &tmp; /* take care pf bug in DEC-ALPHA g++ */ 154 char *ptr1,*ptr2 = (char*)&tmp; 155 156 PetscFunctionBegin; 157 for (j=0; j<n; j++) { 158 ptr1 = (char*)(buff1 + j); 159 for (i=0; i<(int) sizeof(double); i++) { 160 ptr2[i] = ptr1[sizeof(double)-1-i]; 161 } 162 buff1[j] = *tptr; 163 } 164 PetscFunctionReturn(0); 165 } 166 #endif 167 /* --------------------------------------------------------- */ 168 #undef __FUNCT__ 169 #define __FUNCT__ "PetscBinaryRead" 170 /*@ 171 PetscBinaryRead - Reads from a binary file. 172 173 Not Collective 174 175 Input Parameters: 176 + fd - the file 177 . n - the number of items to read 178 - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 179 180 Output Parameters: 181 . p - the buffer 182 183 184 185 Level: developer 186 187 Notes: 188 PetscBinaryRead() uses byte swapping to work on all machines; the files 189 are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers 190 are converted to the small-endian format when they are read in from the file. 191 Integers are stored on the file as 32 bits long, regardless of whether 192 they are stored in the machine as 32 bits or 64 bits, this means the same 193 binary file may be read on any machine. 194 195 Concepts: files^reading binary 196 Concepts: binary files^reading 197 198 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 199 PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 200 @*/ 201 PetscErrorCode PETSC_DLLEXPORT PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type) 202 { 203 int wsize,err; 204 size_t m = (size_t) n,maxblock = 65536; 205 char *pp = (char*)p; 206 #if !defined(PETSC_WORDS_BIGENDIAN) 207 PetscErrorCode ierr; 208 void *ptmp = p; 209 #endif 210 211 PetscFunctionBegin; 212 if (!n) PetscFunctionReturn(0); 213 214 if (type == PETSC_INT) m *= sizeof(PetscInt); 215 else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); 216 else if (type == PETSC_DOUBLE) m *= sizeof(double); 217 else if (type == PETSC_SHORT) m *= sizeof(short); 218 else if (type == PETSC_CHAR) m *= sizeof(char); 219 else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); 220 else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth); 221 else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char); 222 else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 223 224 while (m) { 225 wsize = (m < maxblock) ? m : maxblock; 226 err = read(fd,pp,wsize); 227 if (err < 0 && errno == EINTR) continue; 228 if (!err && wsize > 0) SETERRQ(PETSC_ERR_FILE_READ,"Read past end of file"); 229 if (err < 0) SETERRQ1(PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno); 230 m -= err; 231 pp += err; 232 } 233 #if !defined(PETSC_WORDS_BIGENDIAN) 234 if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt*)ptmp,n);CHKERRQ(ierr);} 235 else if (type == PETSC_ENUM) {ierr = PetscByteSwapEnum((PetscEnum*)ptmp,n);CHKERRQ(ierr);} 236 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapTruth((PetscTruth*)ptmp,n);CHKERRQ(ierr);} 237 else if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 238 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 239 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 240 #endif 241 242 PetscFunctionReturn(0); 243 } 244 /* --------------------------------------------------------- */ 245 #undef __FUNCT__ 246 #define __FUNCT__ "PetscBinaryWrite" 247 /*@ 248 PetscBinaryWrite - Writes to a binary file. 249 250 Not Collective 251 252 Input Parameters: 253 + fd - the file 254 . p - the buffer 255 . n - the number of items to write 256 . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 257 - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise. 258 259 Level: advanced 260 261 Notes: 262 PetscBinaryWrite() uses byte swapping to work on all machines; the files 263 are written using big-endian ordering to the file. On small-endian machines the numbers 264 are converted to the big-endian format when they are written to disk. 265 Integers are stored on the file as 32 bits long, regardless of whether 266 they are stored in the machine as 32 bits or 64 bits, this means the same 267 binary file may be read on any machine. It also means that 64 bit integers larger than 268 roughly 2 billion are TRUNCATED/WRONG when written to the file. 269 270 The Buffer p should be read-write buffer, and not static data. 271 This way, byte-swapping is done in-place, and then the buffer is 272 written to the file. 273 274 This routine restores the original contents of the buffer, after 275 it is written to the file. This is done by byte-swapping in-place 276 the second time. If the flag istemp is set to PETSC_TRUE, the second 277 byte-swapping operation is not done, thus saving some computation, 278 but the buffer corrupted is corrupted. 279 280 Concepts: files^writing binary 281 Concepts: binary files^writing 282 283 .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 284 PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 285 @*/ 286 PetscErrorCode PETSC_DLLEXPORT PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp) 287 { 288 char *pp = (char*)p; 289 int err,wsize; 290 size_t m = (size_t)n,maxblock=65536; 291 #if !defined(PETSC_WORDS_BIGENDIAN) 292 PetscErrorCode ierr; 293 void *ptmp = p; 294 #endif 295 296 PetscFunctionBegin; 297 if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); 298 if (!n) PetscFunctionReturn(0); 299 300 if (type == PETSC_INT) m *= sizeof(PetscInt); 301 else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); 302 else if (type == PETSC_DOUBLE) m *= sizeof(double); 303 else if (type == PETSC_SHORT) m *= sizeof(short); 304 else if (type == PETSC_CHAR) m *= sizeof(char); 305 else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); 306 else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth); 307 else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char); 308 else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 309 310 #if !defined(PETSC_WORDS_BIGENDIAN) 311 if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt*)ptmp,n);CHKERRQ(ierr);} 312 else if (type == PETSC_ENUM) {ierr = PetscByteSwapEnum((PetscEnum*)ptmp,n);CHKERRQ(ierr);} 313 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapTruth((PetscTruth*)ptmp,n);CHKERRQ(ierr);} 314 else if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 315 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 316 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 317 #endif 318 319 while (m) { 320 wsize = (m < maxblock) ? m : maxblock; 321 err = write(fd,pp,wsize); 322 if (err < 0 && errno == EINTR) continue; 323 if (err != wsize) SETERRQ(PETSC_ERR_FILE_WRITE,"Error writing to file."); 324 m -= wsize; 325 pp += wsize; 326 } 327 328 #if !defined(PETSC_WORDS_BIGENDIAN) 329 if (!istemp) { 330 if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt*)ptmp,n);CHKERRQ(ierr);} 331 else if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 332 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 333 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 334 else if (type == PETSC_ENUM) {ierr = PetscByteSwapEnum((PetscEnum*)ptmp,n);CHKERRQ(ierr);} 335 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapTruth((PetscTruth*)ptmp,n);CHKERRQ(ierr);} 336 } 337 #endif 338 PetscFunctionReturn(0); 339 } 340 341 #undef __FUNCT__ 342 #define __FUNCT__ "PetscBinaryOpen" 343 /*@C 344 PetscBinaryOpen - Opens a PETSc binary file. 345 346 Not Collective 347 348 Input Parameters: 349 + name - filename 350 - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE 351 352 Output Parameter: 353 . fd - the file 354 355 Level: advanced 356 357 Concepts: files^opening binary 358 Concepts: binary files^opening 359 360 Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in 361 big-endian format. This means the file can be accessed using PetscBinaryOpen() and 362 PetscBinaryRead() and PetscBinaryWrite() on any machine. 363 364 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(), 365 PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 366 367 @*/ 368 PetscErrorCode PETSC_DLLEXPORT PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd) 369 { 370 PetscFunctionBegin; 371 #if defined(PETSC_HAVE_O_BINARY) 372 if (mode == FILE_MODE_WRITE) { 373 if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) { 374 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 375 } 376 } else if (mode == FILE_MODE_READ) { 377 if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) { 378 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 379 } 380 } else if (mode == FILE_MODE_APPEND) { 381 if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) { 382 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 383 } 384 #else 385 if (mode == FILE_MODE_WRITE) { 386 if ((*fd = creat(name,0666)) == -1) { 387 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 388 } 389 } else if (mode == FILE_MODE_READ) { 390 if ((*fd = open(name,O_RDONLY,0)) == -1) { 391 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 392 } 393 } 394 else if (mode == FILE_MODE_APPEND) { 395 if ((*fd = open(name,O_WRONLY,0)) == -1) { 396 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 397 } 398 #endif 399 } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode"); 400 PetscFunctionReturn(0); 401 } 402 403 #undef __FUNCT__ 404 #define __FUNCT__ "PetscBinaryClose" 405 /*@ 406 PetscBinaryClose - Closes a PETSc binary file. 407 408 Not Collective 409 410 Output Parameter: 411 . fd - the file 412 413 Level: advanced 414 415 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 416 PetscBinarySynchronizedSeek() 417 @*/ 418 PetscErrorCode PETSC_DLLEXPORT PetscBinaryClose(int fd) 419 { 420 PetscFunctionBegin; 421 close(fd); 422 PetscFunctionReturn(0); 423 } 424 425 426 #undef __FUNCT__ 427 #define __FUNCT__ "PetscBinarySeek" 428 /*@ 429 PetscBinarySeek - Moves the file pointer on a PETSc binary file. 430 431 Not Collective 432 433 Input Parameters: 434 + fd - the file 435 . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 436 etc. in your calculation rather than sizeof() to compute byte lengths. 437 - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file 438 if PETSC_BINARY_SEEK_CUR then off is an offset from the current location 439 if PETSC_BINARY_SEEK_END then off is an offset from the end of file 440 441 Output Parameter: 442 . offset - new offset in file 443 444 Level: developer 445 446 Notes: 447 Integers are stored on the file as 32 long, regardless of whether 448 they are stored in the machine as 32 or 64, this means the same 449 binary file may be read on any machine. Hence you CANNOT use sizeof() 450 to determine the offset or location. 451 452 Concepts: files^binary seeking 453 Concepts: binary files^seeking 454 455 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 456 PetscBinarySynchronizedSeek() 457 @*/ 458 PetscErrorCode PETSC_DLLEXPORT PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 459 { 460 int iwhence = 0; 461 462 PetscFunctionBegin; 463 if (whence == PETSC_BINARY_SEEK_SET) { 464 iwhence = SEEK_SET; 465 } else if (whence == PETSC_BINARY_SEEK_CUR) { 466 iwhence = SEEK_CUR; 467 } else if (whence == PETSC_BINARY_SEEK_END) { 468 iwhence = SEEK_END; 469 } else { 470 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location"); 471 } 472 #if defined(PETSC_HAVE_LSEEK) 473 *offset = lseek(fd,off,iwhence); 474 #elif defined(PETSC_HAVE__LSEEK) 475 *offset = _lseek(fd,(long)off,iwhence); 476 #else 477 SETERRQ(PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file"); 478 #endif 479 PetscFunctionReturn(0); 480 } 481 482 #undef __FUNCT__ 483 #define __FUNCT__ "PetscBinarySynchronizedRead" 484 /*@C 485 PetscBinarySynchronizedRead - Reads from a binary file. 486 487 Collective on MPI_Comm 488 489 Input Parameters: 490 + comm - the MPI communicator 491 . fd - the file 492 . n - the number of items to read 493 - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 494 495 Output Parameters: 496 . p - the buffer 497 498 Options Database Key: 499 . -binary_longints - indicates the file was generated on a Cray vector 500 machine (not the T3E/D) and the ints are stored as 64 bit 501 quantities, otherwise they are stored as 32 bit 502 503 Level: developer 504 505 Notes: 506 Does a PetscBinaryRead() followed by an MPI_Bcast() 507 508 PetscBinarySynchronizedRead() uses byte swapping to work on all machines. 509 Integers are stored on the file as 32 long, regardless of whether 510 they are stored in the machine as 32 or 64, this means the same 511 binary file may be read on any machine. 512 513 Concepts: files^synchronized reading of binary files 514 Concepts: binary files^reading, synchronized 515 516 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(), 517 PetscBinarySynchronizedSeek() 518 @*/ 519 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type) 520 { 521 PetscErrorCode ierr; 522 PetscMPIInt rank; 523 MPI_Datatype mtype; 524 525 PetscFunctionBegin; 526 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 527 if (!rank) { 528 ierr = PetscBinaryRead(fd,p,n,type);CHKERRQ(ierr); 529 } 530 ierr = PetscDataTypeToMPIDataType(type,&mtype);CHKERRQ(ierr); 531 ierr = MPI_Bcast(p,n,mtype,0,comm);CHKERRQ(ierr); 532 PetscFunctionReturn(0); 533 } 534 535 #undef __FUNCT__ 536 #define __FUNCT__ "PetscBinarySynchronizedWrite" 537 /*@C 538 PetscBinarySynchronizedWrite - writes to a binary file. 539 540 Collective on MPI_Comm 541 542 Input Parameters: 543 + comm - the MPI communicator 544 . fd - the file 545 . n - the number of items to write 546 . p - the buffer 547 . istemp - the buffer may be changed 548 - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 549 550 Level: developer 551 552 Notes: 553 Process 0 does a PetscBinaryWrite() 554 555 PetscBinarySynchronizedWrite() uses byte swapping to work on all machines. 556 Integers are stored on the file as 32 long, regardless of whether 557 they are stored in the machine as 32 or 64, this means the same 558 binary file may be read on any machine. 559 560 WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0, 561 while PetscSynchronizedFPrintf() has all processes print their strings in order. 562 563 Concepts: files^synchronized writing of binary files 564 Concepts: binary files^reading, synchronized 565 566 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(), 567 PetscBinarySynchronizedSeek() 568 @*/ 569 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp) 570 { 571 PetscErrorCode ierr; 572 PetscMPIInt rank; 573 574 PetscFunctionBegin; 575 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 576 if (!rank) { 577 ierr = PetscBinaryWrite(fd,p,n,type,istemp);CHKERRQ(ierr); 578 } 579 PetscFunctionReturn(0); 580 } 581 582 #undef __FUNCT__ 583 #define __FUNCT__ "PetscBinarySynchronizedSeek" 584 /*@C 585 PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file. 586 587 588 Input Parameters: 589 + fd - the file 590 . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file 591 if PETSC_BINARY_SEEK_CUR then size is offset from current location 592 if PETSC_BINARY_SEEK_END then size is offset from end of file 593 - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 594 etc. in your calculation rather than sizeof() to compute byte lengths. 595 596 Output Parameter: 597 . offset - new offset in file 598 599 Level: developer 600 601 Notes: 602 Integers are stored on the file as 32 long, regardless of whether 603 they are stored in the machine as 32 or 64, this means the same 604 binary file may be read on any machine. Hence you CANNOT use sizeof() 605 to determine the offset or location. 606 607 Concepts: binary files^seeking 608 Concepts: files^seeking in binary 609 610 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 611 PetscBinarySynchronizedSeek() 612 @*/ 613 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 614 { 615 PetscErrorCode ierr; 616 PetscMPIInt rank; 617 618 PetscFunctionBegin; 619 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 620 if (!rank) { 621 ierr = PetscBinarySeek(fd,off,whence,offset);CHKERRQ(ierr); 622 } 623 PetscFunctionReturn(0); 624 } 625 626