Actual source code: sysio.c

  1: #define PETSC_DLL

  3: /* 
  4:    This file contains simple binary read/write routines.
  5:  */

 7:  #include petsc.h
 8:  #include petscsys.h

 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

 20: #if !defined(PETSC_WORDS_BIGENDIAN)

 22: /* --------------------------------------------------------- */
 25: /*
 26:   PetscByteSwapEnum - Swap bytes in a  PETSc Enum

 28: */
 29: PetscErrorCode  PetscByteSwapEnum(PetscEnum *buff,PetscInt n)
 30: {
 31:   PetscInt   i,j;
 32:   PetscEnum   tmp = ENUM_DUMMY;
 33:   char       *ptr1,*ptr2 = (char*)&tmp;
 34: 
 36:   for (j=0; j<n; j++) {
 37:     ptr1 = (char*)(buff + j);
 38:     for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
 39:       ptr2[i] = ptr1[sizeof(PetscEnum)-1-i];
 40:     }
 41:     for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
 42:       ptr1[i] = ptr2[i];
 43:     }
 44:   }
 45:   return(0);
 46: }

 50: /*
 51:   PetscByteSwapTruth - Swap bytes in a  PETSc Truth

 53: */
 54: PetscErrorCode  PetscByteSwapTruth(PetscTruth *buff,PetscInt n)
 55: {
 56:   PetscInt    i,j;
 57:   PetscTruth  tmp = PETSC_FALSE;
 58:   char        *ptr1,*ptr2 = (char*)&tmp;
 59: 
 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:     for (i=0; i<(PetscInt)sizeof(PetscTruth); i++) {
 67:       ptr1[i] = ptr2[i];
 68:     }
 69:   }
 70:   return(0);
 71: }

 75: /*
 76:   PetscByteSwapInt - Swap bytes in a  PETSc integer (which may be 32 or 64 bits) 

 78: */
 79: PetscErrorCode  PetscByteSwapInt(PetscInt *buff,PetscInt n)
 80: {
 81:   PetscInt  i,j,tmp = 0;
 82:   char       *ptr1,*ptr2 = (char*)&tmp;
 83: 
 85:   for (j=0; j<n; j++) {
 86:     ptr1 = (char*)(buff + j);
 87:     for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
 88:       ptr2[i] = ptr1[sizeof(PetscInt)-1-i];
 89:     }
 90:     for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
 91:       ptr1[i] = ptr2[i];
 92:     }
 93:   }
 94:   return(0);
 95: }
 96: /* --------------------------------------------------------- */
 99: /*
100:   PetscByteSwapShort - Swap bytes in a short
101: */
102: PetscErrorCode  PetscByteSwapShort(short *buff,PetscInt n)
103: {
104:   PetscInt   i,j;
105:   short      tmp;
106:   char       *ptr1,*ptr2 = (char*)&tmp;

109:   for (j=0; j<n; j++) {
110:     ptr1 = (char*)(buff + j);
111:     for (i=0; i<(PetscInt) sizeof(short); i++) {
112:       ptr2[i] = ptr1[sizeof(int)-1-i];
113:     }
114:     for (i=0; i<(PetscInt) sizeof(short); i++) {
115:       ptr1[i] = ptr2[i];
116:     }
117:   }
118:   return(0);
119: }
120: /* --------------------------------------------------------- */
123: /*
124:   PetscByteSwapScalar - Swap bytes in a double
125:   Complex is dealt with as if array of double twice as long.
126: */
127: PetscErrorCode  PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
128: {
129:   PetscInt  i,j;
130:   PetscReal tmp,*buff1 = (PetscReal*)buff;
131:   char      *ptr1,*ptr2 = (char*)&tmp;

134: #if defined(PETSC_USE_COMPLEX)
135:   n *= 2;
136: #endif
137:   for (j=0; j<n; j++) {
138:     ptr1 = (char*)(buff1 + j);
139:     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
140:       ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
141:     }
142:     for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
143:       ptr1[i] = ptr2[i];
144:     }
145:   }
146:   return(0);
147: }
148: /* --------------------------------------------------------- */
151: /*
152:   PetscByteSwapDouble - Swap bytes in a double
153: */
154: PetscErrorCode  PetscByteSwapDouble(double *buff,PetscInt n)
155: {
156:   PetscInt i,j;
157:   double   tmp,*buff1 = (double*)buff;
158:   char     *ptr1,*ptr2 = (char*)&tmp;

161:   for (j=0; j<n; j++) {
162:     ptr1 = (char*)(buff1 + j);
163:     for (i=0; i<(PetscInt) sizeof(double); i++) {
164:       ptr2[i] = ptr1[sizeof(double)-1-i];
165:     }
166:     for (i=0; i<(PetscInt) sizeof(double); i++) {
167:       ptr1[i] = ptr2[i];
168:     }
169:   }
170:   return(0);
171: }

175: PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
176: {

180:   if      (pdtype == PETSC_INT)    {PetscByteSwapInt((PetscInt*)data,count);}
181:   else if (pdtype == PETSC_ENUM)   {PetscByteSwapEnum((PetscEnum*)data,count);}
182:   else if (pdtype == PETSC_TRUTH)  {PetscByteSwapTruth((PetscTruth*)data,count);}
183:   else if (pdtype == PETSC_SCALAR) {PetscByteSwapScalar((PetscScalar*)data,count);}
184:   else if (pdtype == PETSC_DOUBLE) {PetscByteSwapDouble((double*)data,count);}
185:   else if (pdtype == PETSC_SHORT)  {PetscByteSwapShort((short*)data,count);}
186:   return(0);
187: }

189: #endif
190: /* --------------------------------------------------------- */
193: /*@
194:    PetscBinaryRead - Reads from a binary file.

196:    Not Collective

198:    Input Parameters:
199: +  fd - the file
200: .  n  - the number of items to read 
201: -  type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)

203:    Output Parameters:
204: .  p - the buffer



208:    Level: developer

210:    Notes: 
211:    PetscBinaryRead() uses byte swapping to work on all machines; the files
212:    are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers
213:    are converted to the small-endian format when they are read in from the file.
214:    When PETSc is config/configure.py with --with-64bit-indices the integers are written to the
215:    file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
216:    is used.

218:    Concepts: files^reading binary
219:    Concepts: binary files^reading

221: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
222:           PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
223: @*/
224: PetscErrorCode  PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type)
225: {
226:   int               wsize,err;
227:   size_t            m = (size_t) n,maxblock = 65536;
228:   char              *pp = (char*)p;
229: #if !defined(PETSC_WORDS_BIGENDIAN)
230:   PetscErrorCode    ierr;
231:   void              *ptmp = p;
232: #endif

235:   if (!n) return(0);

237:   if (type == PETSC_INT)          m *= sizeof(PetscInt);
238:   else if (type == PETSC_SCALAR)  m *= sizeof(PetscScalar);
239:   else if (type == PETSC_DOUBLE)  m *= sizeof(double);
240:   else if (type == PETSC_SHORT)   m *= sizeof(short);
241:   else if (type == PETSC_CHAR)    m *= sizeof(char);
242:   else if (type == PETSC_ENUM)    m *= sizeof(PetscEnum);
243:   else if (type == PETSC_TRUTH)   m *= sizeof(PetscTruth);
244:   else if (type == PETSC_LOGICAL) m  = PetscBTLength(m)*sizeof(char);
245:   else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
246: 
247:   while (m) {
248:     wsize = (m < maxblock) ? m : maxblock;
249:     err = read(fd,pp,wsize);
250:     if (err < 0 && errno == EINTR) continue;
251:     if (!err && wsize > 0) SETERRQ(PETSC_ERR_FILE_READ,"Read past end of file");
252:     if (err < 0) SETERRQ1(PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno);
253:     m  -= err;
254:     pp += err;
255:   }
256: #if !defined(PETSC_WORDS_BIGENDIAN)
257:   PetscByteSwap(ptmp,type,n);
258: #endif

260:   return(0);
261: }
262: /* --------------------------------------------------------- */
265: /*@
266:    PetscBinaryWrite - Writes to a binary file.

268:    Not Collective

270:    Input Parameters:
271: +  fd     - the file
272: .  p      - the buffer
273: .  n      - the number of items to write
274: .  type   - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
275: -  istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise.

277:    Level: advanced

279:    Notes: 
280:    PetscBinaryWrite() uses byte swapping to work on all machines; the files
281:    are written using big-endian ordering to the file. On small-endian machines the numbers
282:    are converted to the big-endian format when they are written to disk.
283:    When PETSc is config/configure.py with --with-64bit-indices the integers are written to the
284:    file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
285:    is used.

287:    The Buffer p should be read-write buffer, and not static data.
288:    This way, byte-swapping is done in-place, and then the buffer is
289:    written to the file.
290:    
291:    This routine restores the original contents of the buffer, after 
292:    it is written to the file. This is done by byte-swapping in-place 
293:    the second time. If the flag istemp is set to PETSC_TRUE, the second
294:    byte-swapping operation is not done, thus saving some computation,
295:    but the buffer corrupted is corrupted.

297:    Because byte-swapping may be done on the values in data it cannot be declared const

299:    Concepts: files^writing binary
300:    Concepts: binary files^writing

302: .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 
303:           PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
304: @*/
305: PetscErrorCode  PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp)
306: {
307:   char           *pp = (char*)p;
308:   int            err,wsize;
309:   size_t         m = (size_t)n,maxblock=65536;
310: #if !defined(PETSC_WORDS_BIGENDIAN)
312:   void           *ptmp = p;
313: #endif

316:   if (n < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
317:   if (!n) return(0);

319:   if (type == PETSC_INT)          m *= sizeof(PetscInt);
320:   else if (type == PETSC_SCALAR)  m *= sizeof(PetscScalar);
321:   else if (type == PETSC_DOUBLE)  m *= sizeof(double);
322:   else if (type == PETSC_SHORT)   m *= sizeof(short);
323:   else if (type == PETSC_CHAR)    m *= sizeof(char);
324:   else if (type == PETSC_ENUM)    m *= sizeof(PetscEnum);
325:   else if (type == PETSC_TRUTH)   m *= sizeof(PetscTruth);
326:   else if (type == PETSC_LOGICAL) m = PetscBTLength(m)*sizeof(char);
327:   else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");

329: #if !defined(PETSC_WORDS_BIGENDIAN)
330:   PetscByteSwap(ptmp,type,n);
331: #endif

333:   while (m) {
334:     wsize = (m < maxblock) ? m : maxblock;
335:     err = write(fd,pp,wsize);
336:     if (err < 0 && errno == EINTR) continue;
337:     if (err != wsize) SETERRQ(PETSC_ERR_FILE_WRITE,"Error writing to file.");
338:     m -= wsize;
339:     pp += wsize;
340:   }

342: #if !defined(PETSC_WORDS_BIGENDIAN)
343:   if (!istemp) {
344:     PetscByteSwap(ptmp,type,n);
345:   }
346: #endif
347:   return(0);
348: }

352: /*@C
353:    PetscBinaryOpen - Opens a PETSc binary file.

355:    Not Collective

357:    Input Parameters:
358: +  name - filename
359: -  type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE

361:    Output Parameter:
362: .  fd - the file

364:    Level: advanced

366:   Concepts: files^opening binary
367:   Concepts: binary files^opening

369:    Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in
370:    big-endian format. This means the file can be accessed using PetscBinaryOpen() and
371:    PetscBinaryRead() and PetscBinaryWrite() on any machine.

373: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(), 
374:           PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()

376: @*/
377: PetscErrorCode  PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd)
378: {
380: #if defined(PETSC_HAVE_O_BINARY) 
381:   if (mode == FILE_MODE_WRITE) {
382:     if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
383:       SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
384:     }
385:   } else if (mode == FILE_MODE_READ) {
386:     if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) {
387:       SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
388:     }
389:   } else if (mode == FILE_MODE_APPEND) {
390:     if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) {
391:       SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
392:     }
393: #else
394:   if (mode == FILE_MODE_WRITE) {
395:     if ((*fd = creat(name,0666)) == -1) {
396:       SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
397:     }
398:   } else if (mode == FILE_MODE_READ) {
399:     if ((*fd = open(name,O_RDONLY,0)) == -1) {
400:       SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
401:     }
402:   }
403:   else if (mode == FILE_MODE_APPEND) {
404:     if ((*fd = open(name,O_WRONLY,0)) == -1) {
405:       SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
406:     }
407: #endif
408:   } else SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode");
409:   return(0);
410: }

414: /*@
415:    PetscBinaryClose - Closes a PETSc binary file.

417:    Not Collective

419:    Output Parameter:
420: .  fd - the file

422:    Level: advanced

424: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
425:           PetscBinarySynchronizedSeek()
426: @*/
427: PetscErrorCode  PetscBinaryClose(int fd)
428: {
430:   close(fd);
431:   return(0);
432: }


437: /*@
438:    PetscBinarySeek - Moves the file pointer on a PETSc binary file.

440:    Not Collective

442:    Input Parameters:
443: +  fd - the file
444: .  off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
445:             etc. in your calculation rather than sizeof() to compute byte lengths.
446: -  whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file
447:             if PETSC_BINARY_SEEK_CUR then off is an offset from the current location
448:             if PETSC_BINARY_SEEK_END then off is an offset from the end of file

450:    Output Parameter:
451: .   offset - new offset in file

453:    Level: developer

455:    Notes: 
456:    Integers are stored on the file as 32 long, regardless of whether
457:    they are stored in the machine as 32 or 64, this means the same
458:    binary file may be read on any machine. Hence you CANNOT use sizeof()
459:    to determine the offset or location.

461:    Concepts: files^binary seeking
462:    Concepts: binary files^seeking

464: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
465:           PetscBinarySynchronizedSeek()
466: @*/
467: PetscErrorCode  PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
468: {
469:   int iwhence = 0;

472:   if (whence == PETSC_BINARY_SEEK_SET) {
473:     iwhence = SEEK_SET;
474:   } else if (whence == PETSC_BINARY_SEEK_CUR) {
475:     iwhence = SEEK_CUR;
476:   } else if (whence == PETSC_BINARY_SEEK_END) {
477:     iwhence = SEEK_END;
478:   } else {
479:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location");
480:   }
481: #if defined(PETSC_HAVE_LSEEK)
482:   *offset = lseek(fd,off,iwhence);
483: #elif defined(PETSC_HAVE__LSEEK)
484:   *offset = _lseek(fd,(long)off,iwhence);
485: #else
486:   SETERRQ(PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file");
487: #endif
488:   return(0);
489: }

493: /*@C
494:    PetscBinarySynchronizedRead - Reads from a binary file.

496:    Collective on MPI_Comm

498:    Input Parameters:
499: +  comm - the MPI communicator 
500: .  fd - the file
501: .  n  - the number of items to read 
502: -  type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)

504:    Output Parameters:
505: .  p - the buffer

507:    Options Database Key:
508: .   -binary_longints - indicates the file was generated on a Cray vector 
509:          machine (not the T3E/D) and the ints are stored as 64 bit 
510:          quantities, otherwise they are stored as 32 bit

512:    Level: developer

514:    Notes: 
515:    Does a PetscBinaryRead() followed by an MPI_Bcast()

517:    PetscBinarySynchronizedRead() uses byte swapping to work on all machines.
518:    Integers are stored on the file as 32 long, regardless of whether
519:    they are stored in the machine as 32 or 64, this means the same
520:    binary file may be read on any machine.

522:    Concepts: files^synchronized reading of binary files
523:    Concepts: binary files^reading, synchronized

525: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(), 
526:           PetscBinarySynchronizedSeek()
527: @*/
528: PetscErrorCode  PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type)
529: {
531:   PetscMPIInt    rank;
532:   MPI_Datatype   mtype;

535:   MPI_Comm_rank(comm,&rank);
536:   if (!rank) {
537:     PetscBinaryRead(fd,p,n,type);
538:   }
539:   PetscDataTypeToMPIDataType(type,&mtype);
540:   MPI_Bcast(p,n,mtype,0,comm);
541:   return(0);
542: }

546: /*@C
547:    PetscBinarySynchronizedWrite - writes to a binary file.

549:    Collective on MPI_Comm

551:    Input Parameters:
552: +  comm - the MPI communicator 
553: .  fd - the file
554: .  n  - the number of items to write
555: .  p - the buffer
556: .  istemp - the buffer may be changed
557: -  type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)

559:    Level: developer

561:    Notes: 
562:    Process 0 does a PetscBinaryWrite()

564:    PetscBinarySynchronizedWrite() uses byte swapping to work on all machines.
565:    Integers are stored on the file as 32 long, regardless of whether
566:    they are stored in the machine as 32 or 64, this means the same
567:    binary file may be read on any machine.

569:    Notes: because byte-swapping may be done on the values in data it cannot be declared const

571:    WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0,
572:    while PetscSynchronizedFPrintf() has all processes print their strings in order.

574:    Concepts: files^synchronized writing of binary files
575:    Concepts: binary files^reading, synchronized

577: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(),
578:           PetscBinarySynchronizedSeek()
579: @*/
580: PetscErrorCode  PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscTruth istemp)
581: {
583:   PetscMPIInt    rank;

586:   MPI_Comm_rank(comm,&rank);
587:   if (!rank) {
588:     PetscBinaryWrite(fd,p,n,type,istemp);
589:   }
590:   return(0);
591: }

595: /*@C
596:    PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file.


599:    Input Parameters:
600: +  fd - the file
601: .  whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file
602:             if PETSC_BINARY_SEEK_CUR then size is offset from current location
603:             if PETSC_BINARY_SEEK_END then size is offset from end of file
604: -  off    - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
605:             etc. in your calculation rather than sizeof() to compute byte lengths.

607:    Output Parameter:
608: .   offset - new offset in file

610:    Level: developer

612:    Notes: 
613:    Integers are stored on the file as 32 long, regardless of whether
614:    they are stored in the machine as 32 or 64, this means the same
615:    binary file may be read on any machine. Hence you CANNOT use sizeof()
616:    to determine the offset or location.

618:    Concepts: binary files^seeking
619:    Concepts: files^seeking in binary 

621: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
622:           PetscBinarySynchronizedSeek()
623: @*/
624: PetscErrorCode  PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
625: {
627:   PetscMPIInt    rank;

630:   MPI_Comm_rank(comm,&rank);
631:   if (!rank) {
632:     PetscBinarySeek(fd,off,whence,offset);
633:   }
634:   return(0);
635: }

637: #if defined(PETSC_HAVE_MPIIO)
638: #if !defined(PETSC_WORDS_BIGENDIAN)

640: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
642: /*
643:       MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions.
644:     These are set into MPI in PetscInitialize() via MPI_Register_datarep()

646:     Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode)

648:     The next three routines are not used because MPICH does not support their use

650: */
651: PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state)
652: {
653:   MPI_Aint    ub;
654:   PetscMPIInt ierr;
655: 
656:   MPI_Type_get_extent(datatype,&ub,file_extent);
657:   return ierr;
658: }

660: PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
661: {
662:   PetscDataType pdtype;
663:   PetscMPIInt   ierr;
664:   size_t        dsize;
665: 
666:   PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
667:   PetscDataTypeGetSize(pdtype,&dsize);

669:   /* offset is given in units of MPI_Datatype */
670:   userbuf = ((char *)userbuf) + dsize*position;

672:   PetscMemcpy(userbuf,filebuf,count*dsize);
673:   PetscByteSwap(userbuf,pdtype,count);
674:   return ierr;
675: }

677: PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
678: {
679:   PetscDataType pdtype;
680:   PetscMPIInt   ierr;
681:   size_t        dsize;
682: 
683:   PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
684:   PetscDataTypeGetSize(pdtype,&dsize);

686:   /* offset is given in units of MPI_Datatype */
687:   userbuf = ((char *)userbuf) + dsize*position;

689:   PetscMemcpy(filebuf,userbuf,count*dsize);
690:   PetscByteSwap(filebuf,pdtype,count);
691:   return ierr;
692: }
694: #endif

696: PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
697: {
699:   PetscDataType  pdtype;

702:   PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
703:   PetscByteSwap(data,pdtype,cnt);
704:   MPI_File_write_all(fd,data,cnt,dtype,status);
705:   PetscByteSwap(data,pdtype,cnt);
706:   return(0);
707: }

709: PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
710: {
712:   PetscDataType  pdtype;

715:   PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
716:   MPI_File_read_all(fd,data,cnt,dtype,status);
717:   PetscByteSwap(data,pdtype,cnt);
718:   return(0);
719: }
720: #endif
721: #endif