Actual source code: sysio.c
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: #if !defined(PETSC_WORDS_BIGENDIAN)
19: /* --------------------------------------------------------- */
22: /*
23: PetscByteSwapEnum - Swap bytes in a PETSc Enum
25: */
26: PetscErrorCode PetscByteSwapEnum(PetscEnum *buff,PetscInt n)
27: {
28: PetscInt i,j;
29: PetscEnum tmp = ENUM_DUMMY;
30: char *ptr1,*ptr2 = (char*)&tmp;
31:
33: for (j=0; j<n; j++) {
34: ptr1 = (char*)(buff + j);
35: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
36: ptr2[i] = ptr1[sizeof(PetscEnum)-1-i];
37: }
38: for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) {
39: ptr1[i] = ptr2[i];
40: }
41: }
42: return(0);
43: }
47: /*
48: PetscByteSwapBool - Swap bytes in a PETSc Bool
50: */
51: PetscErrorCode PetscByteSwapBool(PetscBool *buff,PetscInt n)
52: {
53: PetscInt i,j;
54: PetscBool tmp = PETSC_FALSE;
55: char *ptr1,*ptr2 = (char*)&tmp;
56:
58: for (j=0; j<n; j++) {
59: ptr1 = (char*)(buff + j);
60: for (i=0; i<(PetscInt)sizeof(PetscBool); i++) {
61: ptr2[i] = ptr1[sizeof(PetscBool)-1-i];
62: }
63: for (i=0; i<(PetscInt)sizeof(PetscBool); i++) {
64: ptr1[i] = ptr2[i];
65: }
66: }
67: return(0);
68: }
72: /*
73: PetscByteSwapInt - Swap bytes in a PETSc integer (which may be 32 or 64 bits)
75: */
76: PetscErrorCode PetscByteSwapInt(PetscInt *buff,PetscInt n)
77: {
78: PetscInt i,j,tmp = 0;
79: char *ptr1,*ptr2 = (char*)&tmp;
80:
82: for (j=0; j<n; j++) {
83: ptr1 = (char*)(buff + j);
84: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
85: ptr2[i] = ptr1[sizeof(PetscInt)-1-i];
86: }
87: for (i=0; i<(PetscInt)sizeof(PetscInt); i++) {
88: ptr1[i] = ptr2[i];
89: }
90: }
91: return(0);
92: }
93: /* --------------------------------------------------------- */
96: /*
97: PetscByteSwapShort - Swap bytes in a short
98: */
99: PetscErrorCode PetscByteSwapShort(short *buff,PetscInt n)
100: {
101: PetscInt i,j;
102: short tmp;
103: char *ptr1,*ptr2 = (char*)&tmp;
106: for (j=0; j<n; j++) {
107: ptr1 = (char*)(buff + j);
108: for (i=0; i<(PetscInt) sizeof(short); i++) {
109: ptr2[i] = ptr1[sizeof(short)-1-i];
110: }
111: for (i=0; i<(PetscInt) sizeof(short); i++) {
112: ptr1[i] = ptr2[i];
113: }
114: }
115: return(0);
116: }
117: /* --------------------------------------------------------- */
120: /*
121: PetscByteSwapScalar - Swap bytes in a double
122: Complex is dealt with as if array of double twice as long.
123: */
124: PetscErrorCode PetscByteSwapScalar(PetscScalar *buff,PetscInt n)
125: {
126: PetscInt i,j;
127: PetscReal tmp,*buff1 = (PetscReal*)buff;
128: char *ptr1,*ptr2 = (char*)&tmp;
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: for (i=0; i<(PetscInt) sizeof(PetscReal); i++) {
140: ptr1[i] = ptr2[i];
141: }
142: }
143: return(0);
144: }
145: /* --------------------------------------------------------- */
148: /*
149: PetscByteSwapDouble - Swap bytes in a double
150: */
151: PetscErrorCode PetscByteSwapDouble(double *buff,PetscInt n)
152: {
153: PetscInt i,j;
154: double tmp,*buff1 = (double*)buff;
155: char *ptr1,*ptr2 = (char*)&tmp;
158: for (j=0; j<n; j++) {
159: ptr1 = (char*)(buff1 + j);
160: for (i=0; i<(PetscInt) sizeof(double); i++) {
161: ptr2[i] = ptr1[sizeof(double)-1-i];
162: }
163: for (i=0; i<(PetscInt) sizeof(double); i++) {
164: ptr1[i] = ptr2[i];
165: }
166: }
167: return(0);
168: }
172: /*
173: PetscByteSwapFloat - Swap bytes in a float
174: */
175: PetscErrorCode PetscByteSwapFloat(float *buff,PetscInt n)
176: {
177: PetscInt i,j;
178: float tmp,*buff1 = (float*)buff;
179: char *ptr1,*ptr2 = (char*)&tmp;
182: for (j=0; j<n; j++) {
183: ptr1 = (char*)(buff1 + j);
184: for (i=0; i<(PetscInt) sizeof(float); i++) {
185: ptr2[i] = ptr1[sizeof(float)-1-i];
186: }
187: for (i=0; i<(PetscInt) sizeof(float); i++) {
188: ptr1[i] = ptr2[i];
189: }
190: }
191: return(0);
192: }
196: PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count)
197: {
201: if (pdtype == PETSC_INT) {PetscByteSwapInt((PetscInt*)data,count);}
202: else if (pdtype == PETSC_ENUM) {PetscByteSwapEnum((PetscEnum*)data,count);}
203: else if (pdtype == PETSC_BOOL) {PetscByteSwapBool((PetscBool*)data,count);}
204: else if (pdtype == PETSC_SCALAR) {PetscByteSwapScalar((PetscScalar*)data,count);}
205: else if (pdtype == PETSC_DOUBLE) {PetscByteSwapDouble((double*)data,count);}
206: else if (pdtype == PETSC_FLOAT) {PetscByteSwapFloat((float*)data,count);}
207: else if (pdtype == PETSC_SHORT) {PetscByteSwapShort((short*)data,count);}
208: return(0);
209: }
211: #endif
212: /* --------------------------------------------------------- */
215: /*@
216: PetscBinaryRead - Reads from a binary file.
218: Not Collective
220: Input Parameters:
221: + fd - the file
222: . n - the number of items to read
223: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
225: Output Parameters:
226: . p - the buffer
230: Level: developer
232: Notes:
233: PetscBinaryRead() uses byte swapping to work on all machines; the files
234: are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers
235: are converted to the small-endian format when they are read in from the file.
236: When PETSc is ./configure with --with-64bit-indices the integers are written to the
237: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
238: is used.
240: Concepts: files^reading binary
241: Concepts: binary files^reading
243: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
244: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
245: @*/
246: PetscErrorCode PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type)
247: {
248: int wsize,err;
249: size_t m = (size_t) n,maxblock = 65536;
250: char *pp = (char*)p;
251: #if !defined(PETSC_WORDS_BIGENDIAN)
252: PetscErrorCode ierr;
253: void *ptmp = p;
254: #endif
257: if (!n) return(0);
259: if (type == PETSC_INT) m *= sizeof(PetscInt);
260: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
261: else if (type == PETSC_DOUBLE) m *= sizeof(double);
262: else if (type == PETSC_FLOAT) m *= sizeof(float);
263: else if (type == PETSC_SHORT) m *= sizeof(short);
264: else if (type == PETSC_CHAR) m *= sizeof(char);
265: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
266: else if (type == PETSC_BOOL) m *= sizeof(PetscBool);
267: else if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char);
268: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
269:
270: while (m) {
271: wsize = (m < maxblock) ? m : maxblock;
272: err = read(fd,pp,wsize);
273: if (err < 0 && errno == EINTR) continue;
274: if (!err && wsize > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file");
275: if (err < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno);
276: m -= err;
277: pp += err;
278: }
279: #if !defined(PETSC_WORDS_BIGENDIAN)
280: PetscByteSwap(ptmp,type,n);
281: #endif
283: return(0);
284: }
285: /* --------------------------------------------------------- */
288: /*@
289: PetscBinaryWrite - Writes to a binary file.
291: Not Collective
293: Input Parameters:
294: + fd - the file
295: . p - the buffer
296: . n - the number of items to write
297: . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
298: - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise.
300: Level: advanced
302: Notes:
303: PetscBinaryWrite() uses byte swapping to work on all machines; the files
304: are written using big-endian ordering to the file. On small-endian machines the numbers
305: are converted to the big-endian format when they are written to disk.
306: When PETSc is ./configure with --with-64bit-indices the integers are written to the
307: file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices
308: is used.
310: The Buffer p should be read-write buffer, and not static data.
311: This way, byte-swapping is done in-place, and then the buffer is
312: written to the file.
313:
314: This routine restores the original contents of the buffer, after
315: it is written to the file. This is done by byte-swapping in-place
316: the second time. If the flag istemp is set to PETSC_TRUE, the second
317: byte-swapping operation is not done, thus saving some computation,
318: but the buffer corrupted is corrupted.
320: Because byte-swapping may be done on the values in data it cannot be declared const
322: Concepts: files^writing binary
323: Concepts: binary files^writing
325: .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(),
326: PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
327: @*/
328: PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp)
329: {
330: char *pp = (char*)p;
331: int err,wsize;
332: size_t m = (size_t)n,maxblock=65536;
333: #if !defined(PETSC_WORDS_BIGENDIAN)
335: void *ptmp = p;
336: #endif
339: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n);
340: if (!n) return(0);
342: if (type == PETSC_INT) m *= sizeof(PetscInt);
343: else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar);
344: else if (type == PETSC_DOUBLE) m *= sizeof(double);
345: else if (type == PETSC_FLOAT) m *= sizeof(float);
346: else if (type == PETSC_SHORT) m *= sizeof(short);
347: else if (type == PETSC_CHAR) m *= sizeof(char);
348: else if (type == PETSC_ENUM) m *= sizeof(PetscEnum);
349: else if (type == PETSC_BOOL) m *= sizeof(PetscBool);
350: else if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char);
351: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type");
353: #if !defined(PETSC_WORDS_BIGENDIAN)
354: PetscByteSwap(ptmp,type,n);
355: #endif
357: while (m) {
358: wsize = (m < maxblock) ? m : maxblock;
359: err = write(fd,pp,wsize);
360: if (err < 0 && errno == EINTR) continue;
361: if (err != wsize) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Error writing to file.");
362: m -= wsize;
363: pp += wsize;
364: }
366: #if !defined(PETSC_WORDS_BIGENDIAN)
367: if (!istemp) {
368: PetscByteSwap(ptmp,type,n);
369: }
370: #endif
371: return(0);
372: }
376: /*@C
377: PetscBinaryOpen - Opens a PETSc binary file.
379: Not Collective
381: Input Parameters:
382: + name - filename
383: - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE
385: Output Parameter:
386: . fd - the file
388: Level: advanced
390: Concepts: files^opening binary
391: Concepts: binary files^opening
393: Notes: Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in
394: big-endian format. This means the file can be accessed using PetscBinaryOpen() and
395: PetscBinaryRead() and PetscBinaryWrite() on any machine.
397: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(),
398: PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek()
400: @*/
401: PetscErrorCode PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd)
402: {
404: #if defined(PETSC_HAVE_O_BINARY)
405: if (mode == FILE_MODE_WRITE) {
406: if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) {
407: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
408: }
409: } else if (mode == FILE_MODE_READ) {
410: if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) {
411: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
412: }
413: } else if (mode == FILE_MODE_APPEND) {
414: if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) {
415: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
416: }
417: #else
418: if (mode == FILE_MODE_WRITE) {
419: if ((*fd = creat(name,0666)) == -1) {
420: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name);
421: }
422: } else if (mode == FILE_MODE_READ) {
423: if ((*fd = open(name,O_RDONLY,0)) == -1) {
424: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name);
425: }
426: }
427: else if (mode == FILE_MODE_APPEND) {
428: if ((*fd = open(name,O_WRONLY,0)) == -1) {
429: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name);
430: }
431: #endif
432: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode");
433: return(0);
434: }
438: /*@
439: PetscBinaryClose - Closes a PETSc binary file.
441: Not Collective
443: Output Parameter:
444: . fd - the file
446: Level: advanced
448: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
449: PetscBinarySynchronizedSeek()
450: @*/
451: PetscErrorCode PetscBinaryClose(int fd)
452: {
454: close(fd);
455: return(0);
456: }
461: /*@
462: PetscBinarySeek - Moves the file pointer on a PETSc binary file.
464: Not Collective
466: Input Parameters:
467: + fd - the file
468: . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
469: etc. in your calculation rather than sizeof() to compute byte lengths.
470: - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file
471: if PETSC_BINARY_SEEK_CUR then off is an offset from the current location
472: if PETSC_BINARY_SEEK_END then off is an offset from the end of file
474: Output Parameter:
475: . offset - new offset in file
477: Level: developer
479: Notes:
480: Integers are stored on the file as 32 long, regardless of whether
481: they are stored in the machine as 32 or 64, this means the same
482: binary file may be read on any machine. Hence you CANNOT use sizeof()
483: to determine the offset or location.
485: Concepts: files^binary seeking
486: Concepts: binary files^seeking
488: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
489: PetscBinarySynchronizedSeek()
490: @*/
491: PetscErrorCode PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
492: {
493: int iwhence = 0;
496: if (whence == PETSC_BINARY_SEEK_SET) {
497: iwhence = SEEK_SET;
498: } else if (whence == PETSC_BINARY_SEEK_CUR) {
499: iwhence = SEEK_CUR;
500: } else if (whence == PETSC_BINARY_SEEK_END) {
501: iwhence = SEEK_END;
502: } else {
503: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location");
504: }
505: #if defined(PETSC_HAVE_LSEEK)
506: *offset = lseek(fd,off,iwhence);
507: #elif defined(PETSC_HAVE__LSEEK)
508: *offset = _lseek(fd,(long)off,iwhence);
509: #else
510: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file");
511: #endif
512: return(0);
513: }
517: /*@C
518: PetscBinarySynchronizedRead - Reads from a binary file.
520: Collective on MPI_Comm
522: Input Parameters:
523: + comm - the MPI communicator
524: . fd - the file
525: . n - the number of items to read
526: - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
528: Output Parameters:
529: . p - the buffer
531: Options Database Key:
532: . -binary_longints - indicates the file was generated on a Cray vector
533: machine (not the T3E/D) and the ints are stored as 64 bit
534: quantities, otherwise they are stored as 32 bit
536: Level: developer
538: Notes:
539: Does a PetscBinaryRead() followed by an MPI_Bcast()
541: PetscBinarySynchronizedRead() uses byte swapping to work on all machines.
542: Integers are stored on the file as 32 long, regardless of whether
543: they are stored in the machine as 32 or 64, this means the same
544: binary file may be read on any machine.
546: Concepts: files^synchronized reading of binary files
547: Concepts: binary files^reading, synchronized
549: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(),
550: PetscBinarySynchronizedSeek()
551: @*/
552: PetscErrorCode PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type)
553: {
555: PetscMPIInt rank;
556: MPI_Datatype mtype;
559: MPI_Comm_rank(comm,&rank);
560: if (!rank) {
561: PetscBinaryRead(fd,p,n,type);
562: }
563: PetscDataTypeToMPIDataType(type,&mtype);
564: MPI_Bcast(p,n,mtype,0,comm);
565: return(0);
566: }
570: /*@C
571: PetscBinarySynchronizedWrite - writes to a binary file.
573: Collective on MPI_Comm
575: Input Parameters:
576: + comm - the MPI communicator
577: . fd - the file
578: . n - the number of items to write
579: . p - the buffer
580: . istemp - the buffer may be changed
581: - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR)
583: Level: developer
585: Notes:
586: Process 0 does a PetscBinaryWrite()
588: PetscBinarySynchronizedWrite() uses byte swapping to work on all machines.
589: Integers are stored on the file as 32 long, regardless of whether
590: they are stored in the machine as 32 or 64, this means the same
591: binary file may be read on any machine.
593: Notes: because byte-swapping may be done on the values in data it cannot be declared const
595: WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0,
596: while PetscSynchronizedFPrintf() has all processes print their strings in order.
598: Concepts: files^synchronized writing of binary files
599: Concepts: binary files^reading, synchronized
601: .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(),
602: PetscBinarySynchronizedSeek()
603: @*/
604: PetscErrorCode PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp)
605: {
607: PetscMPIInt rank;
610: MPI_Comm_rank(comm,&rank);
611: if (!rank) {
612: PetscBinaryWrite(fd,p,n,type,istemp);
613: }
614: return(0);
615: }
619: /*@C
620: PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file.
623: Input Parameters:
624: + fd - the file
625: . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file
626: if PETSC_BINARY_SEEK_CUR then size is offset from current location
627: if PETSC_BINARY_SEEK_END then size is offset from end of file
628: - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE,
629: etc. in your calculation rather than sizeof() to compute byte lengths.
631: Output Parameter:
632: . offset - new offset in file
634: Level: developer
636: Notes:
637: Integers are stored on the file as 32 long, regardless of whether
638: they are stored in the machine as 32 or 64, this means the same
639: binary file may be read on any machine. Hence you CANNOT use sizeof()
640: to determine the offset or location.
642: Concepts: binary files^seeking
643: Concepts: files^seeking in binary
645: .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(),
646: PetscBinarySynchronizedSeek()
647: @*/
648: PetscErrorCode PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset)
649: {
651: PetscMPIInt rank;
654: MPI_Comm_rank(comm,&rank);
655: if (!rank) {
656: PetscBinarySeek(fd,off,whence,offset);
657: }
658: return(0);
659: }
661: #if defined(PETSC_HAVE_MPIIO)
662: #if !defined(PETSC_WORDS_BIGENDIAN)
664: #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32)
666: /*
667: MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions.
668: These are set into MPI in PetscInitialize() via MPI_Register_datarep()
670: Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode)
672: The next three routines are not used because MPICH does not support their use
674: */
675: PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state)
676: {
677: MPI_Aint ub;
678: PetscMPIInt ierr;
679:
680: MPI_Type_get_extent(datatype,&ub,file_extent);
681: return ierr;
682: }
684: PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
685: {
686: PetscDataType pdtype;
687: PetscMPIInt ierr;
688: size_t dsize;
689:
690: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
691: PetscDataTypeGetSize(pdtype,&dsize);
693: /* offset is given in units of MPI_Datatype */
694: userbuf = ((char *)userbuf) + dsize*position;
696: PetscMemcpy(userbuf,filebuf,count*dsize);
697: PetscByteSwap(userbuf,pdtype,count);
698: return ierr;
699: }
701: PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state)
702: {
703: PetscDataType pdtype;
704: PetscMPIInt ierr;
705: size_t dsize;
706:
707: PetscMPIDataTypeToPetscDataType(datatype,&pdtype);
708: PetscDataTypeGetSize(pdtype,&dsize);
710: /* offset is given in units of MPI_Datatype */
711: userbuf = ((char *)userbuf) + dsize*position;
713: PetscMemcpy(filebuf,userbuf,count*dsize);
714: PetscByteSwap(filebuf,pdtype,count);
715: return ierr;
716: }
718: #endif
722: PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
723: {
725: PetscDataType pdtype;
728: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
729: PetscByteSwap(data,pdtype,cnt);
730: MPI_File_write_all(fd,data,cnt,dtype,status);
731: PetscByteSwap(data,pdtype,cnt);
732: return(0);
733: }
737: PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status)
738: {
740: PetscDataType pdtype;
743: PetscMPIDataTypeToPetscDataType(dtype,&pdtype);
744: MPI_File_read_all(fd,data,cnt,dtype,status);
745: PetscByteSwap(data,pdtype,cnt);
746: return(0);
747: }
748: #endif
749: #endif