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 = ENUM_DUMMY; 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<(PetscInt)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 = PETSC_FALSE; 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<(PetscInt)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<(PetscInt)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<(PetscInt) 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<(PetscInt) 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<(PetscInt) 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 When PETSc is config/configure.py with --with-64bit-indices the integers are written to the 192 file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices 193 is used. 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 When PETSc is config/configure.py with --with-64bit-indices the integers are written to the 266 file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices 267 is used. 268 269 The Buffer p should be read-write buffer, and not static data. 270 This way, byte-swapping is done in-place, and then the buffer is 271 written to the file. 272 273 This routine restores the original contents of the buffer, after 274 it is written to the file. This is done by byte-swapping in-place 275 the second time. If the flag istemp is set to PETSC_TRUE, the second 276 byte-swapping operation is not done, thus saving some computation, 277 but the buffer corrupted is corrupted. 278 279 Concepts: files^writing binary 280 Concepts: binary files^writing 281 282 .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 283 PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 284 @*/ 285 PetscErrorCode PETSC_DLLEXPORT PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp) 286 { 287 char *pp = (char*)p; 288 int err,wsize; 289 size_t m = (size_t)n,maxblock=65536; 290 #if !defined(PETSC_WORDS_BIGENDIAN) 291 PetscErrorCode ierr; 292 void *ptmp = p; 293 #endif 294 295 PetscFunctionBegin; 296 if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); 297 if (!n) PetscFunctionReturn(0); 298 299 if (type == PETSC_INT) m *= sizeof(PetscInt); 300 else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); 301 else if (type == PETSC_DOUBLE) m *= sizeof(double); 302 else if (type == PETSC_SHORT) m *= sizeof(short); 303 else if (type == PETSC_CHAR) m *= sizeof(char); 304 else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); 305 else if (type == PETSC_TRUTH) m *= sizeof(PetscTruth); 306 else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char); 307 else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 308 309 #if !defined(PETSC_WORDS_BIGENDIAN) 310 if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt*)ptmp,n);CHKERRQ(ierr);} 311 else if (type == PETSC_ENUM) {ierr = PetscByteSwapEnum((PetscEnum*)ptmp,n);CHKERRQ(ierr);} 312 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapTruth((PetscTruth*)ptmp,n);CHKERRQ(ierr);} 313 else if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 314 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 315 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 316 #endif 317 318 while (m) { 319 wsize = (m < maxblock) ? m : maxblock; 320 err = write(fd,pp,wsize); 321 if (err < 0 && errno == EINTR) continue; 322 if (err != wsize) SETERRQ(PETSC_ERR_FILE_WRITE,"Error writing to file."); 323 m -= wsize; 324 pp += wsize; 325 } 326 327 #if !defined(PETSC_WORDS_BIGENDIAN) 328 if (!istemp) { 329 if (type == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt*)ptmp,n);CHKERRQ(ierr);} 330 else if (type == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)ptmp,n);CHKERRQ(ierr);} 331 else if (type == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)ptmp,n);CHKERRQ(ierr);} 332 else if (type == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)ptmp,n);CHKERRQ(ierr);} 333 else if (type == PETSC_ENUM) {ierr = PetscByteSwapEnum((PetscEnum*)ptmp,n);CHKERRQ(ierr);} 334 else if (type == PETSC_TRUTH) {ierr = PetscByteSwapTruth((PetscTruth*)ptmp,n);CHKERRQ(ierr);} 335 } 336 #endif 337 PetscFunctionReturn(0); 338 } 339 340 #undef __FUNCT__ 341 #define __FUNCT__ "PetscBinaryOpen" 342 /*@C 343 PetscBinaryOpen - Opens a PETSc binary file. 344 345 Not Collective 346 347 Input Parameters: 348 + name - filename 349 - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE 350 351 Output Parameter: 352 . fd - the file 353 354 Level: advanced 355 356 Concepts: files^opening binary 357 Concepts: binary files^opening 358 359 Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in 360 big-endian format. This means the file can be accessed using PetscBinaryOpen() and 361 PetscBinaryRead() and PetscBinaryWrite() on any machine. 362 363 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(), 364 PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 365 366 @*/ 367 PetscErrorCode PETSC_DLLEXPORT PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd) 368 { 369 PetscFunctionBegin; 370 #if defined(PETSC_HAVE_O_BINARY) 371 if (mode == FILE_MODE_WRITE) { 372 if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) { 373 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 374 } 375 } else if (mode == FILE_MODE_READ) { 376 if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) { 377 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 378 } 379 } else if (mode == FILE_MODE_APPEND) { 380 if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) { 381 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 382 } 383 #else 384 if (mode == FILE_MODE_WRITE) { 385 if ((*fd = creat(name,0666)) == -1) { 386 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 387 } 388 } else if (mode == FILE_MODE_READ) { 389 if ((*fd = open(name,O_RDONLY,0)) == -1) { 390 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 391 } 392 } 393 else if (mode == FILE_MODE_APPEND) { 394 if ((*fd = open(name,O_WRONLY,0)) == -1) { 395 SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 396 } 397 #endif 398 } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode"); 399 PetscFunctionReturn(0); 400 } 401 402 #undef __FUNCT__ 403 #define __FUNCT__ "PetscBinaryClose" 404 /*@ 405 PetscBinaryClose - Closes a PETSc binary file. 406 407 Not Collective 408 409 Output Parameter: 410 . fd - the file 411 412 Level: advanced 413 414 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 415 PetscBinarySynchronizedSeek() 416 @*/ 417 PetscErrorCode PETSC_DLLEXPORT PetscBinaryClose(int fd) 418 { 419 PetscFunctionBegin; 420 close(fd); 421 PetscFunctionReturn(0); 422 } 423 424 425 #undef __FUNCT__ 426 #define __FUNCT__ "PetscBinarySeek" 427 /*@ 428 PetscBinarySeek - Moves the file pointer on a PETSc binary file. 429 430 Not Collective 431 432 Input Parameters: 433 + fd - the file 434 . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 435 etc. in your calculation rather than sizeof() to compute byte lengths. 436 - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file 437 if PETSC_BINARY_SEEK_CUR then off is an offset from the current location 438 if PETSC_BINARY_SEEK_END then off is an offset from the end of file 439 440 Output Parameter: 441 . offset - new offset in file 442 443 Level: developer 444 445 Notes: 446 Integers are stored on the file as 32 long, regardless of whether 447 they are stored in the machine as 32 or 64, this means the same 448 binary file may be read on any machine. Hence you CANNOT use sizeof() 449 to determine the offset or location. 450 451 Concepts: files^binary seeking 452 Concepts: binary files^seeking 453 454 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 455 PetscBinarySynchronizedSeek() 456 @*/ 457 PetscErrorCode PETSC_DLLEXPORT PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 458 { 459 int iwhence = 0; 460 461 PetscFunctionBegin; 462 if (whence == PETSC_BINARY_SEEK_SET) { 463 iwhence = SEEK_SET; 464 } else if (whence == PETSC_BINARY_SEEK_CUR) { 465 iwhence = SEEK_CUR; 466 } else if (whence == PETSC_BINARY_SEEK_END) { 467 iwhence = SEEK_END; 468 } else { 469 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location"); 470 } 471 #if defined(PETSC_HAVE_LSEEK) 472 *offset = lseek(fd,off,iwhence); 473 #elif defined(PETSC_HAVE__LSEEK) 474 *offset = _lseek(fd,(long)off,iwhence); 475 #else 476 SETERRQ(PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file"); 477 #endif 478 PetscFunctionReturn(0); 479 } 480 481 #undef __FUNCT__ 482 #define __FUNCT__ "PetscBinarySynchronizedRead" 483 /*@C 484 PetscBinarySynchronizedRead - Reads from a binary file. 485 486 Collective on MPI_Comm 487 488 Input Parameters: 489 + comm - the MPI communicator 490 . fd - the file 491 . n - the number of items to read 492 - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 493 494 Output Parameters: 495 . p - the buffer 496 497 Options Database Key: 498 . -binary_longints - indicates the file was generated on a Cray vector 499 machine (not the T3E/D) and the ints are stored as 64 bit 500 quantities, otherwise they are stored as 32 bit 501 502 Level: developer 503 504 Notes: 505 Does a PetscBinaryRead() followed by an MPI_Bcast() 506 507 PetscBinarySynchronizedRead() uses byte swapping to work on all machines. 508 Integers are stored on the file as 32 long, regardless of whether 509 they are stored in the machine as 32 or 64, this means the same 510 binary file may be read on any machine. 511 512 Concepts: files^synchronized reading of binary files 513 Concepts: binary files^reading, synchronized 514 515 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(), 516 PetscBinarySynchronizedSeek() 517 @*/ 518 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type) 519 { 520 PetscErrorCode ierr; 521 PetscMPIInt rank; 522 MPI_Datatype mtype; 523 524 PetscFunctionBegin; 525 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 526 if (!rank) { 527 ierr = PetscBinaryRead(fd,p,n,type);CHKERRQ(ierr); 528 } 529 ierr = PetscDataTypeToMPIDataType(type,&mtype);CHKERRQ(ierr); 530 ierr = MPI_Bcast(p,n,mtype,0,comm);CHKERRQ(ierr); 531 PetscFunctionReturn(0); 532 } 533 534 #undef __FUNCT__ 535 #define __FUNCT__ "PetscBinarySynchronizedWrite" 536 /*@C 537 PetscBinarySynchronizedWrite - writes to a binary file. 538 539 Collective on MPI_Comm 540 541 Input Parameters: 542 + comm - the MPI communicator 543 . fd - the file 544 . n - the number of items to write 545 . p - the buffer 546 . istemp - the buffer may be changed 547 - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 548 549 Level: developer 550 551 Notes: 552 Process 0 does a PetscBinaryWrite() 553 554 PetscBinarySynchronizedWrite() uses byte swapping to work on all machines. 555 Integers are stored on the file as 32 long, regardless of whether 556 they are stored in the machine as 32 or 64, this means the same 557 binary file may be read on any machine. 558 559 WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0, 560 while PetscSynchronizedFPrintf() has all processes print their strings in order. 561 562 Concepts: files^synchronized writing of binary files 563 Concepts: binary files^reading, synchronized 564 565 .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(), 566 PetscBinarySynchronizedSeek() 567 @*/ 568 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp) 569 { 570 PetscErrorCode ierr; 571 PetscMPIInt rank; 572 573 PetscFunctionBegin; 574 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 575 if (!rank) { 576 ierr = PetscBinaryWrite(fd,p,n,type,istemp);CHKERRQ(ierr); 577 } 578 PetscFunctionReturn(0); 579 } 580 581 #undef __FUNCT__ 582 #define __FUNCT__ "PetscBinarySynchronizedSeek" 583 /*@C 584 PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file. 585 586 587 Input Parameters: 588 + fd - the file 589 . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file 590 if PETSC_BINARY_SEEK_CUR then size is offset from current location 591 if PETSC_BINARY_SEEK_END then size is offset from end of file 592 - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 593 etc. in your calculation rather than sizeof() to compute byte lengths. 594 595 Output Parameter: 596 . offset - new offset in file 597 598 Level: developer 599 600 Notes: 601 Integers are stored on the file as 32 long, regardless of whether 602 they are stored in the machine as 32 or 64, this means the same 603 binary file may be read on any machine. Hence you CANNOT use sizeof() 604 to determine the offset or location. 605 606 Concepts: binary files^seeking 607 Concepts: files^seeking in binary 608 609 .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 610 PetscBinarySynchronizedSeek() 611 @*/ 612 PetscErrorCode PETSC_DLLEXPORT PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 613 { 614 PetscErrorCode ierr; 615 PetscMPIInt rank; 616 617 PetscFunctionBegin; 618 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 619 if (!rank) { 620 ierr = PetscBinarySeek(fd,off,whence,offset);CHKERRQ(ierr); 621 } 622 PetscFunctionReturn(0); 623 } 624 625