Actual source code: sysio.c

  1: #define PETSC_DLL

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

 7:  #include petscsys.h
  8: #include <errno.h>
  9: #include <fcntl.h>
 10: #if defined(PETSC_HAVE_UNISTD_H)
 11: #include <unistd.h>
 12: #endif
 13: #if defined (PETSC_HAVE_IO_H)
 14: #include <io.h>
 15: #endif
 16:  #include petscbt.h

 18: #if !defined(PETSC_WORDS_BIGENDIAN)

 20: /* --------------------------------------------------------- */
 23: /*
 24:   PetscByteSwapEnum - Swap bytes in a  PETSc Enum

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

 48: /*
 49:   PetscByteSwapTruth - Swap bytes in a  PETSc Truth

 51: */
 52: PetscErrorCode  PetscByteSwapTruth(PetscTruth *buff,PetscInt n)
 53: {
 54:   PetscInt    i,j;
 55:   PetscTruth  tmp = PETSC_FALSE;
 56:   char        *ptr1,*ptr2 = (char*)&tmp;
 57: 
 59:   for (j=0; j<n; j++) {
 60:     ptr1 = (char*)(buff + j);
 61:     for (i=0; i<(PetscInt)sizeof(PetscTruth); i++) {
 62:       ptr2[i] = ptr1[sizeof(PetscTruth)-1-i];
 63:     }
 64:     for (i=0; i<(PetscInt)sizeof(PetscTruth); i++) {
 65:       ptr1[i] = ptr2[i];
 66:     }
 67:   }
 68:   return(0);
 69: }

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

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

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:     for (i=0; i<(PetscInt) sizeof(short); i++) {
113:       ptr1[i] = ptr2[i];
114:     }
115:   }
116:   return(0);
117: }
118: /* --------------------------------------------------------- */
121: /*
122:   PetscByteSwapScalar - Swap bytes in a double
123:   Complex is dealt with as if array of double twice as long.
124: */
125: PetscErrorCode  PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
126: {
127:   PetscInt  i,j;
128:   PetscReal tmp,*buff1 = (PetscReal*)buff;
129:   char      *ptr1,*ptr2 = (char*)&tmp;

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

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

173: PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
174: {

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

187: #endif
188: /* --------------------------------------------------------- */
191: /*@
192:    PetscBinaryRead - Reads from a binary file.

194:    Not Collective

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

201:    Output Parameters:
202: .  p - the buffer



206:    Level: developer

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

216:    Concepts: files^reading binary
217:    Concepts: binary files^reading

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

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

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

258:   return(0);
259: }
260: /* --------------------------------------------------------- */
263: /*@
264:    PetscBinaryWrite - Writes to a binary file.

266:    Not Collective

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

275:    Level: advanced

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

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

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

297:    Concepts: files^writing binary
298:    Concepts: binary files^writing

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

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

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

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

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

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

350: /*@C
351:    PetscBinaryOpen - Opens a PETSc binary file.

353:    Not Collective

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

359:    Output Parameter:
360: .  fd - the file

362:    Level: advanced

364:   Concepts: files^opening binary
365:   Concepts: binary files^opening

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

371: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(), 
372:           PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()

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

412: /*@
413:    PetscBinaryClose - Closes a PETSc binary file.

415:    Not Collective

417:    Output Parameter:
418: .  fd - the file

420:    Level: advanced

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


435: /*@
436:    PetscBinarySeek - Moves the file pointer on a PETSc binary file.

438:    Not Collective

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

448:    Output Parameter:
449: .   offset - new offset in file

451:    Level: developer

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

459:    Concepts: files^binary seeking
460:    Concepts: binary files^seeking

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

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

491: /*@C
492:    PetscBinarySynchronizedRead - Reads from a binary file.

494:    Collective on MPI_Comm

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

502:    Output Parameters:
503: .  p - the buffer

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

510:    Level: developer

512:    Notes: 
513:    Does a PetscBinaryRead() followed by an MPI_Bcast()

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

520:    Concepts: files^synchronized reading of binary files
521:    Concepts: binary files^reading, synchronized

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

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

544: /*@C
545:    PetscBinarySynchronizedWrite - writes to a binary file.

547:    Collective on MPI_Comm

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

557:    Level: developer

559:    Notes: 
560:    Process 0 does a PetscBinaryWrite()

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

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

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

572:    Concepts: files^synchronized writing of binary files
573:    Concepts: binary files^reading, synchronized

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

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

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


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

605:    Output Parameter:
606: .   offset - new offset in file

608:    Level: developer

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

616:    Concepts: binary files^seeking
617:    Concepts: files^seeking in binary 

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

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

635: #if defined(PETSC_HAVE_MPIIO)
636: #if !defined(PETSC_WORDS_BIGENDIAN)

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

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

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

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

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

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

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

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

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

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

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

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

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

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