Actual source code: sysio.c
petsc-3.3-p7 2013-05-11
2: /*
3: This file contains simple binary read/write routines.
4: */
6: #include <petscsys.h>
7: #include <errno.h>
8: #include <fcntl.h>
9: #if defined(PETSC_HAVE_UNISTD_H)
10: #include <unistd.h>
11: #endif
12: #if defined (PETSC_HAVE_IO_H)
13: #include <io.h>
14: #endif
15: #include <petscbt.h>
17: /* --------------------------------------------------------- */
20: /*
21: PetscByteSwapEnum - Swap bytes in a PETSc Enum
23: */
24: PetscErrorCode PetscByteSwapEnum(PetscEnum *buff,PetscInt n)
25: {
26: PetscInt i,j;
27: PetscEnum tmp = ENUM_DUMMY;
28: char *ptr1,*ptr2 = (char*)&tmp;
29:
31: for (j=0; j<n; j++) {
32: ptr1 = (char*)(buff + j);
33: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
34: ptr2[i] = ptr1[sizeof(PetscEnum)-1-i];
35: }
36: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
37: ptr1[i] = ptr2[i];
38: }
39: }
40: return(0);
41: }
45: /*
46: PetscByteSwapBool - Swap bytes in a PETSc Bool
48: */
49: PetscErrorCode PetscByteSwapBool(PetscBool *buff,PetscInt n)
50: {
51: PetscInt i,j;
52: PetscBool tmp = PETSC_FALSE;
53: char *ptr1,*ptr2 = (char*)&tmp;
54:
56: for (j=0; j<n; j++) {
57: ptr1 = (char*)(buff + j);
58: for (i=0; i<(PetscInt)sizeof(PetscBool); i++) {
59: ptr2[i] = ptr1[sizeof(PetscBool)-1-i];
60: }
61: for (i=0; i<(PetscInt)sizeof(PetscBool); i++) {
62: ptr1[i] = ptr2[i];
63: }
64: }
65: return(0);
66: }
70: /*
71: PetscByteSwapInt - Swap bytes in a PETSc integer (which may be 32 or 64 bits)
73: */
74: PetscErrorCode PetscByteSwapInt(PetscInt *buff,PetscInt n)
75: {
76: PetscInt i,j,tmp = 0;
77: char *ptr1,*ptr2 = (char*)&tmp;
78:
80: for (j=0; j<n; j++) {
81: ptr1 = (char*)(buff + j);
82: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
83: ptr2[i] = ptr1[sizeof(PetscInt)-1-i];
84: }
85: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
86: ptr1[i] = ptr2[i];
87: }
88: }
89: return(0);
90: }
91: /* --------------------------------------------------------- */
94: /*
95: PetscByteSwapShort - Swap bytes in a short
96: */
97: PetscErrorCode PetscByteSwapShort(short *buff,PetscInt n)
98: {
99: PetscInt i,j;
100: short tmp;
101: char *ptr1,*ptr2 = (char*)&tmp;
104: for (j=0; j<n; j++) {
105: ptr1 = (char*)(buff + j);
106: for (i=0; i<(PetscInt) sizeof(short); i++) {
107: ptr2[i] = ptr1[sizeof(short)-1-i];
108: }
109: for (i=0; i<(PetscInt) sizeof(short); i++) {
110: ptr1[i] = ptr2[i];
111: }
112: }
113: return(0);
114: }
115: /* --------------------------------------------------------- */
118: /*
119: PetscByteSwapScalar - Swap bytes in a double
120: Complex is dealt with as if array of double twice as long.
121: */
122: PetscErrorCode PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
123: {
124: PetscInt i,j;
125: PetscReal tmp,*buff1 = (PetscReal*)buff;
126: char *ptr1,*ptr2 = (char*)&tmp;
129: #if defined(PETSC_USE_COMPLEX)
130: n *= 2;
131: #endif
132: for (j=0; j<n; j++) {
133: ptr1 = (char*)(buff1 + j);
134: for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
135: ptr2[i] = ptr1[sizeof(PetscReal)-1-i];
136: }
137: for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
138: ptr1[i] = ptr2[i];
139: }
140: }
141: return(0);
142: }
143: /* --------------------------------------------------------- */
146: /*
147: PetscByteSwapDouble - Swap bytes in a double
148: */
149: PetscErrorCode PetscByteSwapDouble(double *buff,PetscInt n)
150: {
151: PetscInt i,j;
152: double tmp,*buff1 = (double*)buff;
153: char *ptr1,*ptr2 = (char*)&tmp;
156: for (j=0; j<n; j++) {
157: ptr1 = (char*)(buff1 + j);
158: for (i=0; i<(PetscInt) sizeof(double); i++) {
159: ptr2[i] = ptr1[sizeof(double)-1-i];
160: }
161: for (i=0; i<(PetscInt) sizeof(double); i++) {
162: ptr1[i] = ptr2[i];
163: }
164: }
165: return(0);
166: }
170: /*
171: PetscByteSwapFloat - Swap bytes in a float
172: */
173: PetscErrorCode PetscByteSwapFloat(float *buff,PetscInt n)
174: {
175: PetscInt i,j;
176: float tmp,*buff1 = (float*)buff;
177: char *ptr1,*ptr2 = (char*)&tmp;
180: for (j=0; j<n; j++) {
181: ptr1 = (char*)(buff1 + j);
182: for (i=0; i<(PetscInt) sizeof(float); i++) {
183: ptr2[i] = ptr1[sizeof(float)-1-i];
184: }
185: for (i=0; i<(PetscInt) sizeof(float); i++) {
186: ptr1[i] = ptr2[i];
187: }
188: }
189: return(0);
190: }
194: PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
195: {
199: if (pdtype == PETSC_INT) {PetscByteSwapInt((PetscInt*)data,count);}
200: else if (pdtype == PETSC_ENUM) {PetscByteSwapEnum((PetscEnum*)data,count);}
201: else if (pdtype == PETSC_BOOL) {PetscByteSwapBool((PetscBool*)data,count);}
202: else if (pdtype == PETSC_SCALAR) {PetscByteSwapScalar((PetscScalar*)data,count);}
203: else if (pdtype == PETSC_DOUBLE) {PetscByteSwapDouble((double*)data,count);}
204: else if (pdtype == PETSC_FLOAT) {PetscByteSwapFloat((float*)data,count);}
205: else if (pdtype == PETSC_SHORT) {PetscByteSwapShort((short*)data,count);}
206: return(0);
207: }
209: /* --------------------------------------------------------- */
212: /*@
213: PetscBinaryRead - Reads from a binary file.
215: Not Collective
217: Input Parameters:
218: + fd - the file
219: . n - the number of items to read
220: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
222: Output Parameters:
223: . p - the buffer
227: Level: developer
229: Notes:
230: PetscBinaryRead() uses byte swapping to work on all machines; the files
231: are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers
232: are converted to the small-endian format when they are read in from the file.
233: When PETSc is ./configure with --with-64bit-indices the integers are written to the
234: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
235: is used.
237: Concepts: files^reading binary
238: Concepts: binary files^reading
240: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
241: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
242: @*/
243: PetscErrorCode PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type)
244: {
245: int wsize,err;
246: size_t m = (size_t) n,maxblock = 65536;
247: char *pp = (char*)p;
248: #if !defined(PETSC_WORDS_BIGENDIAN)
249: PetscErrorCode ierr;
250: void *ptmp = p;
251: #endif
254: if (!n) return(0);
256: if (type == PETSC_INT) m *= sizeof(PetscInt);
257: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
258: else if (type == PETSC_DOUBLE) m *= sizeof(double);
259: else if (type == PETSC_FLOAT) m *= sizeof(float);
260: else if (type == PETSC_SHORT) m *= sizeof(short);
261: else if (type == PETSC_CHAR) m *= sizeof(char);
262: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
263: else if (type == PETSC_BOOL) m *= sizeof(PetscBool);
264: else if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char);
265: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
266:
267: while (m) {
268: wsize = (m < maxblock) ? m : maxblock;
269: err = read(fd,pp,wsize);
270: if (err < 0 && errno == EINTR) continue;
271: if (!err && wsize > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file");
272: if (err < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno);
273: m -= err;
274: pp += err;
275: }
276: #if !defined(PETSC_WORDS_BIGENDIAN)
277: PetscByteSwap(ptmp,type,n);
278: #endif
280: return(0);
281: }
282: /* --------------------------------------------------------- */
285: /*@
286: PetscBinaryWrite - Writes to a binary file.
288: Not Collective
290: Input Parameters:
291: + fd - the file
292: . p - the buffer
293: . n - the number of items to write
294: . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
295: - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise.
297: Level: advanced
299: Notes:
300: PetscBinaryWrite() uses byte swapping to work on all machines; the files
301: are written using big-endian ordering to the file. On small-endian machines the numbers
302: are converted to the big-endian format when they are written to disk.
303: When PETSc is ./configure with --with-64bit-indices the integers are written to the
304: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
305: is used.
307: The Buffer p should be read-write buffer, and not static data.
308: This way, byte-swapping is done in-place, and then the buffer is
309: written to the file.
310:
311: This routine restores the original contents of the buffer, after
312: it is written to the file. This is done by byte-swapping in-place
313: the second time. If the flag istemp is set to PETSC_TRUE, the second
314: byte-swapping operation is not done, thus saving some computation,
315: but the buffer is left corrupted.
317: Because byte-swapping may be done on the values in data it cannot be declared const
319: Concepts: files^writing binary
320: Concepts: binary files^writing
322: .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
323: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
324: @*/
325: PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp)
326: {
327: char *pp = (char*)p;
328: int err,wsize;
329: size_t m = (size_t)n,maxblock=65536;
330: #if !defined(PETSC_WORDS_BIGENDIAN)
332: void *ptmp = p;
333: #endif
336: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
337: if (!n) return(0);
339: if (type == PETSC_INT) m *= sizeof(PetscInt);
340: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
341: else if (type == PETSC_DOUBLE) m *= sizeof(double);
342: else if (type == PETSC_FLOAT) m *= sizeof(float);
343: else if (type == PETSC_SHORT) m *= sizeof(short);
344: else if (type == PETSC_CHAR) m *= sizeof(char);
345: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
346: else if (type == PETSC_BOOL) m *= sizeof(PetscBool);
347: else if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char);
348: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
350: #if !defined(PETSC_WORDS_BIGENDIAN)
351: PetscByteSwap(ptmp,type,n);
352: #endif
354: while (m) {
355: wsize = (m < maxblock) ? m : maxblock;
356: err = write(fd,pp,wsize);
357: if (err < 0 && errno == EINTR) continue;
358: if (err != wsize) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Error writing to file.");
359: m -= wsize;
360: pp += wsize;
361: }
363: #if !defined(PETSC_WORDS_BIGENDIAN)
364: if (!istemp) {
365: PetscByteSwap(ptmp,type,n);
366: }
367: #endif
368: return(0);
369: }
373: /*@C
374: PetscBinaryOpen - Opens a PETSc binary file.
376: Not Collective
378: Input Parameters:
379: + name - filename
380: - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE
382: Output Parameter:
383: . fd - the file
385: Level: advanced
387: Concepts: files^opening binary
388: Concepts: binary files^opening
390: Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in
391: big-endian format. This means the file can be accessed using PetscBinaryOpen() and
392: PetscBinaryRead() and PetscBinaryWrite() on any machine.
394: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(),
395: PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
397: @*/
398: PetscErrorCode PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd)
399: {
401: #if defined(PETSC_HAVE_O_BINARY)
402: if (mode == FILE_MODE_WRITE) {
403: if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
404: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
405: }
406: } else if (mode == FILE_MODE_READ) {
407: if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) {
408: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
409: }
410: } else if (mode == FILE_MODE_APPEND) {
411: if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) {
412: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
413: }
414: #else
415: if (mode == FILE_MODE_WRITE) {
416: if ((*fd = creat(name,0666)) == -1) {
417: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
418: }
419: } else if (mode == FILE_MODE_READ) {
420: if ((*fd = open(name,O_RDONLY,0)) == -1) {
421: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
422: }
423: }
424: else if (mode == FILE_MODE_APPEND) {
425: if ((*fd = open(name,O_WRONLY,0)) == -1) {
426: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
427: }
428: #endif
429: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode");
430: return(0);
431: }
435: /*@
436: PetscBinaryClose - Closes a PETSc binary file.
438: Not Collective
440: Output Parameter:
441: . fd - the file
443: Level: advanced
445: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
446: PetscBinarySynchronizedSeek()
447: @*/
448: PetscErrorCode PetscBinaryClose(int fd)
449: {
451: close(fd);
452: return(0);
453: }
458: /*@
459: PetscBinarySeek - Moves the file pointer on a PETSc binary file.
461: Not Collective
463: Input Parameters:
464: + fd - the file
465: . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
466: etc. in your calculation rather than sizeof() to compute byte lengths.
467: - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file
468: if PETSC_BINARY_SEEK_CUR then off is an offset from the current location
469: if PETSC_BINARY_SEEK_END then off is an offset from the end of file
471: Output Parameter:
472: . offset - new offset in file
474: Level: developer
476: Notes:
477: Integers are stored on the file as 32 long, regardless of whether
478: they are stored in the machine as 32 or 64, this means the same
479: binary file may be read on any machine. Hence you CANNOT use sizeof()
480: to determine the offset or location.
482: Concepts: files^binary seeking
483: Concepts: binary files^seeking
485: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
486: PetscBinarySynchronizedSeek()
487: @*/
488: PetscErrorCode PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
489: {
490: int iwhence = 0;
493: if (whence == PETSC_BINARY_SEEK_SET) {
494: iwhence = SEEK_SET;
495: } else if (whence == PETSC_BINARY_SEEK_CUR) {
496: iwhence = SEEK_CUR;
497: } else if (whence == PETSC_BINARY_SEEK_END) {
498: iwhence = SEEK_END;
499: } else {
500: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location");
501: }
502: #if defined(PETSC_HAVE_LSEEK)
503: *offset = lseek(fd,off,iwhence);
504: #elif defined(PETSC_HAVE__LSEEK)
505: *offset = _lseek(fd,(long)off,iwhence);
506: #else
507: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file");
508: #endif
509: return(0);
510: }
514: /*@C
515: PetscBinarySynchronizedRead - Reads from a binary file.
517: Collective on MPI_Comm
519: Input Parameters:
520: + comm - the MPI communicator
521: . fd - the file
522: . n - the number of items to read
523: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
525: Output Parameters:
526: . p - the buffer
528: Options Database Key:
529: . -binary_longints - indicates the file was generated on a Cray vector
530: machine (not the T3E/D) and the ints are stored as 64 bit
531: quantities, otherwise they are stored as 32 bit
533: Level: developer
535: Notes:
536: Does a PetscBinaryRead() followed by an MPI_Bcast()
538: PetscBinarySynchronizedRead() uses byte swapping to work on all machines.
539: Integers are stored on the file as 32 long, regardless of whether
540: they are stored in the machine as 32 or 64, this means the same
541: binary file may be read on any machine.
543: Concepts: files^synchronized reading of binary files
544: Concepts: binary files^reading, synchronized
546: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(),
547: PetscBinarySynchronizedSeek()
548: @*/
549: PetscErrorCode PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type)
550: {
552: PetscMPIInt rank;
553: MPI_Datatype mtype;
556: MPI_Comm_rank(comm,&rank);
557: if (!rank) {
558: PetscBinaryRead(fd,p,n,type);
559: }
560: PetscDataTypeToMPIDataType(type,&mtype);
561: MPI_Bcast(p,n,mtype,0,comm);
562: return(0);
563: }
567: /*@C
568: PetscBinarySynchronizedWrite - writes to a binary file.
570: Collective on MPI_Comm
572: Input Parameters:
573: + comm - the MPI communicator
574: . fd - the file
575: . n - the number of items to write
576: . p - the buffer
577: . istemp - the buffer may be changed
578: - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
580: Level: developer
582: Notes:
583: Process 0 does a PetscBinaryWrite()
585: PetscBinarySynchronizedWrite() uses byte swapping to work on all machines.
586: Integers are stored on the file as 32 long, regardless of whether
587: they are stored in the machine as 32 or 64, this means the same
588: binary file may be read on any machine.
590: Notes: because byte-swapping may be done on the values in data it cannot be declared const
592: WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0,
593: while PetscSynchronizedFPrintf() has all processes print their strings in order.
595: Concepts: files^synchronized writing of binary files
596: Concepts: binary files^reading, synchronized
598: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(),
599: PetscBinarySynchronizedSeek()
600: @*/
601: PetscErrorCode PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp)
602: {
604: PetscMPIInt rank;
607: MPI_Comm_rank(comm,&rank);
608: if (!rank) {
609: PetscBinaryWrite(fd,p,n,type,istemp);
610: }
611: return(0);
612: }
616: /*@C
617: PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file.
620: Input Parameters:
621: + fd - the file
622: . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file
623: if PETSC_BINARY_SEEK_CUR then size is offset from current location
624: if PETSC_BINARY_SEEK_END then size is offset from end of file
625: - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
626: etc. in your calculation rather than sizeof() to compute byte lengths.
628: Output Parameter:
629: . offset - new offset in file
631: Level: developer
633: Notes:
634: Integers are stored on the file as 32 long, regardless of whether
635: they are stored in the machine as 32 or 64, this means the same
636: binary file may be read on any machine. Hence you CANNOT use sizeof()
637: to determine the offset or location.
639: Concepts: binary files^seeking
640: Concepts: files^seeking in binary
642: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
643: PetscBinarySynchronizedSeek()
644: @*/
645: PetscErrorCode PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
646: {
648: PetscMPIInt rank;
651: MPI_Comm_rank(comm,&rank);
652: if (!rank) {
653: PetscBinarySeek(fd,off,whence,offset);
654: }
655: return(0);
656: }
658: #if defined(PETSC_HAVE_MPIIO)
659: #if !defined(PETSC_WORDS_BIGENDIAN)
661: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
662: EXTERN_C_BEGIN
663: /*
664: MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions.
665: These are set into MPI in PetscInitialize() via MPI_Register_datarep()
667: Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode)
669: The next three routines are not used because MPICH does not support their use
671: */
672: PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state)
673: {
674: MPI_Aint ub;
675: PetscMPIInt ierr;
676:
677: MPI_Type_get_extent(datatype,&ub,file_extent);
678: return ierr;
679: }
681: PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
682: {
683: PetscDataType pdtype;
684: PetscMPIInt ierr;
685: size_t dsize;
686:
687: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
688: PetscDataTypeGetSize(pdtype,&dsize);
690: /* offset is given in units of MPI_Datatype */
691: userbuf = ((char *)userbuf) + dsize*position;
693: PetscMemcpy(userbuf,filebuf,count*dsize);
694: PetscByteSwap(userbuf,pdtype,count);
695: return ierr;
696: }
698: PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
699: {
700: PetscDataType pdtype;
701: PetscMPIInt ierr;
702: size_t dsize;
703:
704: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
705: PetscDataTypeGetSize(pdtype,&dsize);
707: /* offset is given in units of MPI_Datatype */
708: userbuf = ((char *)userbuf) + dsize*position;
710: PetscMemcpy(filebuf,userbuf,count*dsize);
711: PetscByteSwap(filebuf,pdtype,count);
712: return ierr;
713: }
714: EXTERN_C_END
715: #endif
719: PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
720: {
722: PetscDataType pdtype;
725: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
726: PetscByteSwap(data,pdtype,cnt);
727: MPI_File_write_all(fd,data,cnt,dtype,status);
728: PetscByteSwap(data,pdtype,cnt);
729: return(0);
730: }
734: PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
735: {
737: PetscDataType pdtype;
740: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
741: MPI_File_read_all(fd,data,cnt,dtype,status);
742: PetscByteSwap(data,pdtype,cnt);
743: return(0);
744: }
745: #endif
746: #endif