1e5c89e4eSSatish Balay 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay This file contains simple binary read/write routines. 4e5c89e4eSSatish Balay */ 5e5c89e4eSSatish Balay 6c6db04a5SJed Brown #include <petscsys.h> 7e5c89e4eSSatish Balay #include <errno.h> 8e5c89e4eSSatish Balay #include <fcntl.h> 9e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H) 10e5c89e4eSSatish Balay #include <unistd.h> 11e5c89e4eSSatish Balay #endif 12e5c89e4eSSatish Balay #if defined(PETSC_HAVE_IO_H) 13e5c89e4eSSatish Balay #include <io.h> 14e5c89e4eSSatish Balay #endif 15c6db04a5SJed Brown #include <petscbt.h> 16e5c89e4eSSatish Balay 17d6a4318aSJed Brown const char *const PetscFileModes[] = {"READ","WRITE","APPEND","UPDATE","APPEND_UPDATE","PetscFileMode","PETSC_FILE_",0}; 18d6a4318aSJed Brown 196de02169SBarry Smith /* --------------------------------------------------------- */ 20e5c89e4eSSatish Balay /* 216de02169SBarry Smith PetscByteSwapEnum - Swap bytes in a PETSc Enum 22e5c89e4eSSatish Balay 23e5c89e4eSSatish Balay */ 247087cfbeSBarry Smith PetscErrorCode PetscByteSwapEnum(PetscEnum *buff,PetscInt n) 25e5c89e4eSSatish Balay { 266de02169SBarry Smith PetscInt i,j; 270b20345dSBarry Smith PetscEnum tmp = ENUM_DUMMY; 28e0890e22SSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 29e5c89e4eSSatish Balay 30e5c89e4eSSatish Balay PetscFunctionBegin; 31e5c89e4eSSatish Balay for (j=0; j<n; j++) { 32e5c89e4eSSatish Balay ptr1 = (char*)(buff + j); 33a297a907SKarl Rupp for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) ptr2[i] = ptr1[sizeof(PetscEnum)-1-i]; 34a297a907SKarl Rupp for (i=0; i<(PetscInt)sizeof(PetscEnum); i++) ptr1[i] = ptr2[i]; 35e5c89e4eSSatish Balay } 36e5c89e4eSSatish Balay PetscFunctionReturn(0); 37e5c89e4eSSatish Balay } 386de02169SBarry Smith 396de02169SBarry Smith /* 40acfcf0e5SJed Brown PetscByteSwapBool - Swap bytes in a PETSc Bool 416de02169SBarry Smith 426de02169SBarry Smith */ 437087cfbeSBarry Smith PetscErrorCode PetscByteSwapBool(PetscBool *buff,PetscInt n) 446de02169SBarry Smith { 456de02169SBarry Smith PetscInt i,j; 46ace3abfcSBarry Smith PetscBool tmp = PETSC_FALSE; 47e0890e22SSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 486de02169SBarry Smith 496de02169SBarry Smith PetscFunctionBegin; 506de02169SBarry Smith for (j=0; j<n; j++) { 516de02169SBarry Smith ptr1 = (char*)(buff + j); 52a297a907SKarl Rupp for (i=0; i<(PetscInt)sizeof(PetscBool); i++) ptr2[i] = ptr1[sizeof(PetscBool)-1-i]; 53a297a907SKarl Rupp for (i=0; i<(PetscInt)sizeof(PetscBool); i++) ptr1[i] = ptr2[i]; 546de02169SBarry Smith } 556de02169SBarry Smith PetscFunctionReturn(0); 566de02169SBarry Smith } 576de02169SBarry Smith 58bd1d2e58SBarry Smith /* 596de02169SBarry Smith PetscByteSwapInt - Swap bytes in a PETSc integer (which may be 32 or 64 bits) 60bd1d2e58SBarry Smith 61bd1d2e58SBarry Smith */ 627087cfbeSBarry Smith PetscErrorCode PetscByteSwapInt(PetscInt *buff,PetscInt n) 63bd1d2e58SBarry Smith { 64bd1d2e58SBarry Smith PetscInt i,j,tmp = 0; 65e0890e22SSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 66bd1d2e58SBarry Smith 67bd1d2e58SBarry Smith PetscFunctionBegin; 68bd1d2e58SBarry Smith for (j=0; j<n; j++) { 69bd1d2e58SBarry Smith ptr1 = (char*)(buff + j); 70a297a907SKarl Rupp for (i=0; i<(PetscInt)sizeof(PetscInt); i++) ptr2[i] = ptr1[sizeof(PetscInt)-1-i]; 71a297a907SKarl Rupp for (i=0; i<(PetscInt)sizeof(PetscInt); i++) ptr1[i] = ptr2[i]; 72bd1d2e58SBarry Smith } 73bd1d2e58SBarry Smith PetscFunctionReturn(0); 74bd1d2e58SBarry Smith } 75bd1d2e58SBarry Smith /* --------------------------------------------------------- */ 76e5c89e4eSSatish Balay /* 77e5c89e4eSSatish Balay PetscByteSwapShort - Swap bytes in a short 78e5c89e4eSSatish Balay */ 797087cfbeSBarry Smith PetscErrorCode PetscByteSwapShort(short *buff,PetscInt n) 80e5c89e4eSSatish Balay { 81e5c89e4eSSatish Balay PetscInt i,j; 82e5c89e4eSSatish Balay short tmp; 83e5c89e4eSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 84e5c89e4eSSatish Balay 85e5c89e4eSSatish Balay PetscFunctionBegin; 86e5c89e4eSSatish Balay for (j=0; j<n; j++) { 87e5c89e4eSSatish Balay ptr1 = (char*)(buff + j); 88a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(short); i++) ptr2[i] = ptr1[sizeof(short)-1-i]; 89a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(short); i++) ptr1[i] = ptr2[i]; 90e5c89e4eSSatish Balay } 91e5c89e4eSSatish Balay PetscFunctionReturn(0); 92e5c89e4eSSatish Balay } 93*972064b6SLisandro Dalcin /* 94*972064b6SLisandro Dalcin PetscByteSwapLong - Swap bytes in a long 95*972064b6SLisandro Dalcin */ 96*972064b6SLisandro Dalcin PetscErrorCode PetscByteSwapLong(long *buff,PetscInt n) 97*972064b6SLisandro Dalcin { 98*972064b6SLisandro Dalcin PetscInt i,j; 99*972064b6SLisandro Dalcin long tmp; 100*972064b6SLisandro Dalcin char *ptr1,*ptr2 = (char*)&tmp; 101*972064b6SLisandro Dalcin 102*972064b6SLisandro Dalcin PetscFunctionBegin; 103*972064b6SLisandro Dalcin for (j=0; j<n; j++) { 104*972064b6SLisandro Dalcin ptr1 = (char*)(buff + j); 105*972064b6SLisandro Dalcin for (i=0; i<(PetscInt) sizeof(long); i++) ptr2[i] = ptr1[sizeof(long)-1-i]; 106*972064b6SLisandro Dalcin for (i=0; i<(PetscInt) sizeof(long); i++) ptr1[i] = ptr2[i]; 107*972064b6SLisandro Dalcin } 108*972064b6SLisandro Dalcin PetscFunctionReturn(0); 109*972064b6SLisandro Dalcin } 110e5c89e4eSSatish Balay /* --------------------------------------------------------- */ 111e5c89e4eSSatish Balay /* 1124caf0332SSatish Balay PetscByteSwapReal - Swap bytes in a PetscReal 1134caf0332SSatish Balay */ 1144caf0332SSatish Balay PetscErrorCode PetscByteSwapReal(PetscReal *buff,PetscInt n) 1154caf0332SSatish Balay { 1164caf0332SSatish Balay PetscInt i,j; 1174caf0332SSatish Balay PetscReal tmp,*buff1 = (PetscReal*)buff; 1184caf0332SSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 1194caf0332SSatish Balay 1204caf0332SSatish Balay PetscFunctionBegin; 1214caf0332SSatish Balay for (j=0; j<n; j++) { 1224caf0332SSatish Balay ptr1 = (char*)(buff1 + j); 1234caf0332SSatish Balay for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i]; 1244caf0332SSatish Balay for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i]; 1254caf0332SSatish Balay } 1264caf0332SSatish Balay PetscFunctionReturn(0); 1274caf0332SSatish Balay } 1284caf0332SSatish Balay /* --------------------------------------------------------- */ 1294caf0332SSatish Balay /* 13041f502e3SPatrick Sanan PetscByteSwapScalar - Swap bytes in a PetscScalar 13141f502e3SPatrick Sanan The complex case is dealt with with an array of PetscReal, twice as long. 132e5c89e4eSSatish Balay */ 1337087cfbeSBarry Smith PetscErrorCode PetscByteSwapScalar(PetscScalar *buff,PetscInt n) 134e5c89e4eSSatish Balay { 135e5c89e4eSSatish Balay PetscInt i,j; 136e5c89e4eSSatish Balay PetscReal tmp,*buff1 = (PetscReal*)buff; 137e5c89e4eSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 138e5c89e4eSSatish Balay 139e5c89e4eSSatish Balay PetscFunctionBegin; 140e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX) 141e5c89e4eSSatish Balay n *= 2; 142e5c89e4eSSatish Balay #endif 143e5c89e4eSSatish Balay for (j=0; j<n; j++) { 144e5c89e4eSSatish Balay ptr1 = (char*)(buff1 + j); 145a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i]; 146a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i]; 147e5c89e4eSSatish Balay } 148e5c89e4eSSatish Balay PetscFunctionReturn(0); 149e5c89e4eSSatish Balay } 150e5c89e4eSSatish Balay /* --------------------------------------------------------- */ 151e5c89e4eSSatish Balay /* 152e5c89e4eSSatish Balay PetscByteSwapDouble - Swap bytes in a double 153e5c89e4eSSatish Balay */ 1547087cfbeSBarry Smith PetscErrorCode PetscByteSwapDouble(double *buff,PetscInt n) 155e5c89e4eSSatish Balay { 156e5c89e4eSSatish Balay PetscInt i,j; 157e5c89e4eSSatish Balay double tmp,*buff1 = (double*)buff; 158e5c89e4eSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 159e5c89e4eSSatish Balay 160e5c89e4eSSatish Balay PetscFunctionBegin; 161e5c89e4eSSatish Balay for (j=0; j<n; j++) { 162e5c89e4eSSatish Balay ptr1 = (char*)(buff1 + j); 163a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(double); i++) ptr2[i] = ptr1[sizeof(double)-1-i]; 164a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(double); i++) ptr1[i] = ptr2[i]; 165e5c89e4eSSatish Balay } 166e5c89e4eSSatish Balay PetscFunctionReturn(0); 167e5c89e4eSSatish Balay } 168e39fd77fSBarry Smith 169e95bf02fSSatish Balay /* 170e95bf02fSSatish Balay PetscByteSwapFloat - Swap bytes in a float 171e95bf02fSSatish Balay */ 172e95bf02fSSatish Balay PetscErrorCode PetscByteSwapFloat(float *buff,PetscInt n) 173e95bf02fSSatish Balay { 174e95bf02fSSatish Balay PetscInt i,j; 175e95bf02fSSatish Balay float tmp,*buff1 = (float*)buff; 176e95bf02fSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 177e95bf02fSSatish Balay 178e95bf02fSSatish Balay PetscFunctionBegin; 179e95bf02fSSatish Balay for (j=0; j<n; j++) { 180e95bf02fSSatish Balay ptr1 = (char*)(buff1 + j); 181a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(float); i++) ptr2[i] = ptr1[sizeof(float)-1-i]; 182a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(float); i++) ptr1[i] = ptr2[i]; 183e95bf02fSSatish Balay } 184e95bf02fSSatish Balay PetscFunctionReturn(0); 185e95bf02fSSatish Balay } 186e95bf02fSSatish Balay 187e39fd77fSBarry Smith PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count) 188e39fd77fSBarry Smith { 189e39fd77fSBarry Smith PetscErrorCode ierr; 190e39fd77fSBarry Smith 191e39fd77fSBarry Smith PetscFunctionBegin; 192e39fd77fSBarry Smith if (pdtype == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt*)data,count);CHKERRQ(ierr);} 193e39fd77fSBarry Smith else if (pdtype == PETSC_ENUM) {ierr = PetscByteSwapEnum((PetscEnum*)data,count);CHKERRQ(ierr);} 194acfcf0e5SJed Brown else if (pdtype == PETSC_BOOL) {ierr = PetscByteSwapBool((PetscBool*)data,count);CHKERRQ(ierr);} 195e39fd77fSBarry Smith else if (pdtype == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)data,count);CHKERRQ(ierr);} 1964caf0332SSatish Balay else if (pdtype == PETSC_REAL) {ierr = PetscByteSwapReal((PetscReal*)data,count);CHKERRQ(ierr);} 197e39fd77fSBarry Smith else if (pdtype == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)data,count);CHKERRQ(ierr);} 198e95bf02fSSatish Balay else if (pdtype == PETSC_FLOAT) {ierr = PetscByteSwapFloat((float*)data,count);CHKERRQ(ierr);} 199e39fd77fSBarry Smith else if (pdtype == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)data,count);CHKERRQ(ierr);} 200*972064b6SLisandro Dalcin else if (pdtype == PETSC_LONG) {ierr = PetscByteSwapLong((long*)data,count);CHKERRQ(ierr);} 201e39fd77fSBarry Smith PetscFunctionReturn(0); 202e39fd77fSBarry Smith } 203e39fd77fSBarry Smith 204e5c89e4eSSatish Balay /* --------------------------------------------------------- */ 205e30d2299SSatish Balay /*@ 206e5c89e4eSSatish Balay PetscBinaryRead - Reads from a binary file. 207e5c89e4eSSatish Balay 208e5c89e4eSSatish Balay Not Collective 209e5c89e4eSSatish Balay 210e5c89e4eSSatish Balay Input Parameters: 211e5c89e4eSSatish Balay + fd - the file 212e5c89e4eSSatish Balay . n - the number of items to read 213e5c89e4eSSatish Balay - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 214e5c89e4eSSatish Balay 215e5c89e4eSSatish Balay Output Parameters: 216e5c89e4eSSatish Balay . p - the buffer 217e5c89e4eSSatish Balay 218e5c89e4eSSatish Balay 219e5c89e4eSSatish Balay 220e5c89e4eSSatish Balay Level: developer 221e5c89e4eSSatish Balay 222e5c89e4eSSatish Balay Notes: 223e5c89e4eSSatish Balay PetscBinaryRead() uses byte swapping to work on all machines; the files 224e5c89e4eSSatish Balay are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers 225e5c89e4eSSatish Balay are converted to the small-endian format when they are read in from the file. 226e2e64c6bSBarry Smith When PETSc is ./configure with --with-64bit-indices the integers are written to the 22754f21887SBarry Smith file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices 22854f21887SBarry Smith is used. 229e5c89e4eSSatish Balay 230e5c89e4eSSatish Balay Concepts: files^reading binary 231e5c89e4eSSatish Balay Concepts: binary files^reading 232e5c89e4eSSatish Balay 2334ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 2344ebed01fSBarry Smith PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 235e5c89e4eSSatish Balay @*/ 2367087cfbeSBarry Smith PetscErrorCode PetscBinaryRead(int fd,void *p,PetscInt n,PetscDataType type) 237e5c89e4eSSatish Balay { 238e5c89e4eSSatish Balay int wsize,err; 239e5c89e4eSSatish Balay size_t m = (size_t) n,maxblock = 65536; 240e5c89e4eSSatish Balay char *pp = (char*)p; 2417a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 242cba51d77SBarry Smith PetscBool readdouble = PETSC_FALSE; 2437a881295SBarry Smith double *ppp; 2447a881295SBarry Smith #endif 2457a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) || defined(PETSC_USE_REAL___FLOAT128) 2466de02169SBarry Smith PetscErrorCode ierr; 2477a881295SBarry Smith #endif 2487a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) 249e5c89e4eSSatish Balay void *ptmp = p; 250e5c89e4eSSatish Balay #endif 25105acbc63SBarry Smith char *fname = NULL; 252e5c89e4eSSatish Balay 253e5c89e4eSSatish Balay PetscFunctionBegin; 2542d53ad75SBarry Smith if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); 255e5c89e4eSSatish Balay if (!n) PetscFunctionReturn(0); 256e5c89e4eSSatish Balay 2572d53ad75SBarry Smith if (type == PETSC_FUNCTION) { 2582d53ad75SBarry Smith m = 64; 2592d53ad75SBarry Smith type = PETSC_CHAR; 26005acbc63SBarry Smith fname = (char*) malloc(m*sizeof(char)); 26105acbc63SBarry Smith if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); 2622d53ad75SBarry Smith pp = (char*)fname; 2632d53ad75SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) 2642d53ad75SBarry Smith ptmp = (void*)fname; 2652d53ad75SBarry Smith #endif 2662d53ad75SBarry Smith } 2672d53ad75SBarry Smith 2686de02169SBarry Smith if (type == PETSC_INT) m *= sizeof(PetscInt); 269e5c89e4eSSatish Balay else if (type == PETSC_SCALAR) m *= sizeof(PetscScalar); 2704caf0332SSatish Balay else if (type == PETSC_REAL) m *= sizeof(PetscReal); 271e5c89e4eSSatish Balay else if (type == PETSC_DOUBLE) m *= sizeof(double); 272e95bf02fSSatish Balay else if (type == PETSC_FLOAT) m *= sizeof(float); 273e5c89e4eSSatish Balay else if (type == PETSC_SHORT) m *= sizeof(short); 274*972064b6SLisandro Dalcin else if (type == PETSC_LONG) m *= sizeof(long); 275e5c89e4eSSatish Balay else if (type == PETSC_CHAR) m *= sizeof(char); 276e5c89e4eSSatish Balay else if (type == PETSC_ENUM) m *= sizeof(PetscEnum); 277ace3abfcSBarry Smith else if (type == PETSC_BOOL) m *= sizeof(PetscBool); 2789f7b6320SBarry Smith else if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char); 279e32f2f54SBarry Smith else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 280e5c89e4eSSatish Balay 2817a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 282c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-binary_read_double",&readdouble,NULL);CHKERRQ(ierr); 2837a881295SBarry Smith /* If using __float128 precision we still read in doubles from file */ 2844caf0332SSatish Balay if ((type == PETSC_SCALAR || type == PETSC_REAL) && readdouble) { 2857a881295SBarry Smith m = m/2; 286785e854fSJed Brown ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr); 2877a881295SBarry Smith pp = (char*)ppp; 2887a881295SBarry Smith } 2897a881295SBarry Smith #endif 2907a881295SBarry Smith 291e5c89e4eSSatish Balay while (m) { 292e5c89e4eSSatish Balay wsize = (m < maxblock) ? m : maxblock; 293e5c89e4eSSatish Balay err = read(fd,pp,wsize); 294e5c89e4eSSatish Balay if (err < 0 && errno == EINTR) continue; 295e32f2f54SBarry Smith if (!err && wsize > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file"); 296e32f2f54SBarry Smith if (err < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno); 297e5c89e4eSSatish Balay m -= err; 298e5c89e4eSSatish Balay pp += err; 299e5c89e4eSSatish Balay } 3007a881295SBarry Smith 3017a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 3024caf0332SSatish Balay if ((type == PETSC_SCALAR || type == PETSC_REAL) && readdouble) { 3037a881295SBarry Smith PetscScalar *pv = (PetscScalar*) p; 3047a881295SBarry Smith PetscInt i; 3057a881295SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) 3067a881295SBarry Smith ierr = PetscByteSwapDouble(ppp,n);CHKERRQ(ierr); 3077a881295SBarry Smith #endif 308a297a907SKarl Rupp for (i=0; i<n; i++) pv[i] = ppp[i]; 3097a881295SBarry Smith ierr = PetscFree(ppp);CHKERRQ(ierr); 3107a881295SBarry Smith PetscFunctionReturn(0); 3117a881295SBarry Smith } 3127a881295SBarry Smith #endif 3137a881295SBarry Smith 314e5c89e4eSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN) 315e39fd77fSBarry Smith ierr = PetscByteSwap(ptmp,type,n);CHKERRQ(ierr); 316e5c89e4eSSatish Balay #endif 317e5c89e4eSSatish Balay 31805acbc63SBarry Smith if (type == PETSC_FUNCTION) { 3192d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 3200298fd71SBarry Smith ierr = PetscDLSym(NULL,fname,(void**)p);CHKERRQ(ierr); 3212d53ad75SBarry Smith #else 3220298fd71SBarry Smith *(void**)p = NULL; 3232d53ad75SBarry Smith #endif 32405acbc63SBarry Smith free(fname); 3252d53ad75SBarry Smith } 326e5c89e4eSSatish Balay PetscFunctionReturn(0); 327e5c89e4eSSatish Balay } 328e5c89e4eSSatish Balay /* --------------------------------------------------------- */ 329e30d2299SSatish Balay /*@ 330e5c89e4eSSatish Balay PetscBinaryWrite - Writes to a binary file. 331e5c89e4eSSatish Balay 332e5c89e4eSSatish Balay Not Collective 333e5c89e4eSSatish Balay 334e5c89e4eSSatish Balay Input Parameters: 335e5c89e4eSSatish Balay + fd - the file 336e5c89e4eSSatish Balay . p - the buffer 337e5c89e4eSSatish Balay . n - the number of items to write 338e5c89e4eSSatish Balay . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 339e5c89e4eSSatish Balay - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise. 340e5c89e4eSSatish Balay 341e5c89e4eSSatish Balay Level: advanced 342e5c89e4eSSatish Balay 343e5c89e4eSSatish Balay Notes: 344e5c89e4eSSatish Balay PetscBinaryWrite() uses byte swapping to work on all machines; the files 345e5c89e4eSSatish Balay are written using big-endian ordering to the file. On small-endian machines the numbers 346e5c89e4eSSatish Balay are converted to the big-endian format when they are written to disk. 347e2e64c6bSBarry Smith When PETSc is ./configure with --with-64bit-indices the integers are written to the 34854f21887SBarry Smith file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices 34954f21887SBarry Smith is used. 350e5c89e4eSSatish Balay 35141f502e3SPatrick Sanan If running with __float128 precision the output is in __float128 unless one uses the -binary_write_double option 3520da86b62SBarry Smith 353e5c89e4eSSatish Balay The Buffer p should be read-write buffer, and not static data. 354e5c89e4eSSatish Balay This way, byte-swapping is done in-place, and then the buffer is 355e5c89e4eSSatish Balay written to the file. 356e5c89e4eSSatish Balay 357e5c89e4eSSatish Balay This routine restores the original contents of the buffer, after 358e5c89e4eSSatish Balay it is written to the file. This is done by byte-swapping in-place 359e5c89e4eSSatish Balay the second time. If the flag istemp is set to PETSC_TRUE, the second 360e5c89e4eSSatish Balay byte-swapping operation is not done, thus saving some computation, 361e5f36e38SBarry Smith but the buffer is left corrupted. 362e5c89e4eSSatish Balay 363300a7f5bSBarry Smith Because byte-swapping may be done on the values in data it cannot be declared const 364300a7f5bSBarry Smith 365e5c89e4eSSatish Balay Concepts: files^writing binary 366e5c89e4eSSatish Balay Concepts: binary files^writing 367e5c89e4eSSatish Balay 3684ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 3694ebed01fSBarry Smith PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 370e5c89e4eSSatish Balay @*/ 3717087cfbeSBarry Smith PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp) 372e5c89e4eSSatish Balay { 373e5c89e4eSSatish Balay char *pp = (char*)p; 374e5c89e4eSSatish Balay int err,wsize; 375e5c89e4eSSatish Balay size_t m = (size_t)n,maxblock=65536; 376e5c89e4eSSatish Balay PetscErrorCode ierr; 377f5351476SHong Zhang #if !defined(PETSC_WORDS_BIGENDIAN) 378e5c89e4eSSatish Balay void *ptmp = p; 379e5c89e4eSSatish Balay #endif 38005acbc63SBarry Smith char *fname = NULL; 3810da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 382df40af56SBarry Smith PetscBool writedouble = PETSC_FALSE; 3830da86b62SBarry Smith double *ppp; 3840da86b62SBarry Smith PetscReal *pv; 3850da86b62SBarry Smith PetscInt i; 3860da86b62SBarry Smith #endif 38741f502e3SPatrick Sanan PetscDataType wtype = type; 388e5c89e4eSSatish Balay 389e5c89e4eSSatish Balay PetscFunctionBegin; 390e32f2f54SBarry Smith if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); 391e5c89e4eSSatish Balay if (!n) PetscFunctionReturn(0); 392e5c89e4eSSatish Balay 3932d53ad75SBarry Smith if (type == PETSC_FUNCTION) { 3942d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 3952d53ad75SBarry Smith const char *fnametmp; 3962d53ad75SBarry Smith #endif 3972d53ad75SBarry Smith m = 64; 398e25ab156SSatish Balay fname = (char*)malloc(m*sizeof(char)); 39905acbc63SBarry Smith if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); 40005acbc63SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 40105acbc63SBarry Smith if (n > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only binary view a single function at a time"); 40205acbc63SBarry Smith ierr = PetscFPTFind(*(void**)p,&fnametmp);CHKERRQ(ierr); 40305acbc63SBarry Smith ierr = PetscStrncpy(fname,fnametmp,m);CHKERRQ(ierr); 40405acbc63SBarry Smith #else 40505acbc63SBarry Smith ierr = PetscStrncpy(fname,"",m);CHKERRQ(ierr); 40605acbc63SBarry Smith #endif 40701963f56SBarry Smith wtype = PETSC_CHAR; 4082d53ad75SBarry Smith pp = (char*)fname; 4092d53ad75SBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) 4102d53ad75SBarry Smith ptmp = (void*)fname; 4112d53ad75SBarry Smith #endif 4122d53ad75SBarry Smith } 4132d53ad75SBarry Smith 4140da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 4150da86b62SBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-binary_write_double",&writedouble,NULL);CHKERRQ(ierr); 4160da86b62SBarry Smith /* If using __float128 precision we still write in doubles to file */ 4174caf0332SSatish Balay if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) { 41841f502e3SPatrick Sanan wtype = PETSC_DOUBLE; 4190da86b62SBarry Smith ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr); 4200da86b62SBarry Smith pv = (PetscReal*)pp; 4210da86b62SBarry Smith for (i=0; i<n; i++) { 4220da86b62SBarry Smith ppp[i] = (double) pv[i]; 4230da86b62SBarry Smith } 4240da86b62SBarry Smith pp = (char*)ppp; 4250da86b62SBarry Smith ptmp = (char*)ppp; 4260da86b62SBarry Smith } 4270da86b62SBarry Smith #endif 4280da86b62SBarry Smith 42941f502e3SPatrick Sanan if (wtype == PETSC_INT) m *= sizeof(PetscInt); 43041f502e3SPatrick Sanan else if (wtype == PETSC_SCALAR) m *= sizeof(PetscScalar); 4314caf0332SSatish Balay else if (wtype == PETSC_REAL) m *= sizeof(PetscReal); 43241f502e3SPatrick Sanan else if (wtype == PETSC_DOUBLE) m *= sizeof(double); 43341f502e3SPatrick Sanan else if (wtype == PETSC_FLOAT) m *= sizeof(float); 43441f502e3SPatrick Sanan else if (wtype == PETSC_SHORT) m *= sizeof(short); 435*972064b6SLisandro Dalcin else if (wtype == PETSC_LONG) m *= sizeof(long); 43641f502e3SPatrick Sanan else if (wtype == PETSC_CHAR) m *= sizeof(char); 43741f502e3SPatrick Sanan else if (wtype == PETSC_ENUM) m *= sizeof(PetscEnum); 43841f502e3SPatrick Sanan else if (wtype == PETSC_BOOL) m *= sizeof(PetscBool); 43941f502e3SPatrick Sanan else if (wtype == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char); 440e32f2f54SBarry Smith else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 441e5c89e4eSSatish Balay 442e5c89e4eSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN) 44341f502e3SPatrick Sanan ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr); 444e5c89e4eSSatish Balay #endif 445e5c89e4eSSatish Balay 446e5c89e4eSSatish Balay while (m) { 447e5c89e4eSSatish Balay wsize = (m < maxblock) ? m : maxblock; 448e5c89e4eSSatish Balay err = write(fd,pp,wsize); 449e5c89e4eSSatish Balay if (err < 0 && errno == EINTR) continue; 45004102261SBarry Smith if (err != wsize) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FILE_WRITE,"Error writing to file total size %d err %d wsize %d",(int)n,(int)err,(int)wsize); 451e5c89e4eSSatish Balay m -= wsize; 452e5c89e4eSSatish Balay pp += wsize; 453e5c89e4eSSatish Balay } 454e5c89e4eSSatish Balay 455b659c0ceSSatish Balay #if !defined(PETSC_WORDS_BIGENDIAN) 456e5c89e4eSSatish Balay if (!istemp) { 45741f502e3SPatrick Sanan ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr); 458e5c89e4eSSatish Balay } 459e5c89e4eSSatish Balay #endif 46005acbc63SBarry Smith if (type == PETSC_FUNCTION) { 46105acbc63SBarry Smith free(fname); 46205acbc63SBarry Smith } 4630da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 4644caf0332SSatish Balay if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) { 4650da86b62SBarry Smith ierr = PetscFree(ppp);CHKERRQ(ierr); 4660da86b62SBarry Smith } 4670da86b62SBarry Smith #endif 468e5c89e4eSSatish Balay PetscFunctionReturn(0); 469e5c89e4eSSatish Balay } 470e5c89e4eSSatish Balay 471e5c89e4eSSatish Balay /*@C 472e5c89e4eSSatish Balay PetscBinaryOpen - Opens a PETSc binary file. 473e5c89e4eSSatish Balay 474e5c89e4eSSatish Balay Not Collective 475e5c89e4eSSatish Balay 476e5c89e4eSSatish Balay Input Parameters: 477e5c89e4eSSatish Balay + name - filename 47845c64e65SBarry Smith - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE 479e5c89e4eSSatish Balay 480e5c89e4eSSatish Balay Output Parameter: 481e5c89e4eSSatish Balay . fd - the file 482e5c89e4eSSatish Balay 483e5c89e4eSSatish Balay Level: advanced 484e5c89e4eSSatish Balay 485e5c89e4eSSatish Balay Concepts: files^opening binary 486e5c89e4eSSatish Balay Concepts: binary files^opening 487e5c89e4eSSatish Balay 48895452b02SPatrick Sanan Notes: 48995452b02SPatrick Sanan Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in 490e5c89e4eSSatish Balay big-endian format. This means the file can be accessed using PetscBinaryOpen() and 491e5c89e4eSSatish Balay PetscBinaryRead() and PetscBinaryWrite() on any machine. 492e5c89e4eSSatish Balay 4934ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(), 4944ebed01fSBarry Smith PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 49545c64e65SBarry Smith 496e5c89e4eSSatish Balay @*/ 4977087cfbeSBarry Smith PetscErrorCode PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd) 498e5c89e4eSSatish Balay { 499e5c89e4eSSatish Balay PetscFunctionBegin; 500e5c89e4eSSatish Balay #if defined(PETSC_HAVE_O_BINARY) 50145c64e65SBarry Smith if (mode == FILE_MODE_WRITE) { 502a297a907SKarl Rupp if ((*fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 50345c64e65SBarry Smith } else if (mode == FILE_MODE_READ) { 504a297a907SKarl Rupp if ((*fd = open(name,O_RDONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 50545c64e65SBarry Smith } else if (mode == FILE_MODE_APPEND) { 506a297a907SKarl Rupp if ((*fd = open(name,O_WRONLY|O_BINARY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 507e5c89e4eSSatish Balay #else 50845c64e65SBarry Smith if (mode == FILE_MODE_WRITE) { 509a297a907SKarl Rupp if ((*fd = creat(name,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 51045c64e65SBarry Smith } else if (mode == FILE_MODE_READ) { 511a297a907SKarl Rupp if ((*fd = open(name,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 512e5c89e4eSSatish Balay } 51345c64e65SBarry Smith else if (mode == FILE_MODE_APPEND) { 514a297a907SKarl Rupp if ((*fd = open(name,O_WRONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 515e5c89e4eSSatish Balay #endif 516e32f2f54SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode"); 517e5c89e4eSSatish Balay PetscFunctionReturn(0); 518e5c89e4eSSatish Balay } 519e5c89e4eSSatish Balay 520e30d2299SSatish Balay /*@ 521e5c89e4eSSatish Balay PetscBinaryClose - Closes a PETSc binary file. 522e5c89e4eSSatish Balay 523e5c89e4eSSatish Balay Not Collective 524e5c89e4eSSatish Balay 525e5c89e4eSSatish Balay Output Parameter: 526e5c89e4eSSatish Balay . fd - the file 527e5c89e4eSSatish Balay 528e5c89e4eSSatish Balay Level: advanced 529e5c89e4eSSatish Balay 5304ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 5314ebed01fSBarry Smith PetscBinarySynchronizedSeek() 532e5c89e4eSSatish Balay @*/ 5337087cfbeSBarry Smith PetscErrorCode PetscBinaryClose(int fd) 534e5c89e4eSSatish Balay { 535e5c89e4eSSatish Balay PetscFunctionBegin; 536e5c89e4eSSatish Balay close(fd); 537e5c89e4eSSatish Balay PetscFunctionReturn(0); 538e5c89e4eSSatish Balay } 539e5c89e4eSSatish Balay 540e5c89e4eSSatish Balay 541e8976759SBarry Smith /*@C 542e5c89e4eSSatish Balay PetscBinarySeek - Moves the file pointer on a PETSc binary file. 543e5c89e4eSSatish Balay 544e5c89e4eSSatish Balay Not Collective 545e5c89e4eSSatish Balay 546e5c89e4eSSatish Balay Input Parameters: 547e5c89e4eSSatish Balay + fd - the file 548ff553b35SMatthew Knepley . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 549e5c89e4eSSatish Balay etc. in your calculation rather than sizeof() to compute byte lengths. 550ff553b35SMatthew Knepley - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file 551ff553b35SMatthew Knepley if PETSC_BINARY_SEEK_CUR then off is an offset from the current location 552ff553b35SMatthew Knepley if PETSC_BINARY_SEEK_END then off is an offset from the end of file 553e5c89e4eSSatish Balay 554e5c89e4eSSatish Balay Output Parameter: 555e5c89e4eSSatish Balay . offset - new offset in file 556e5c89e4eSSatish Balay 557e5c89e4eSSatish Balay Level: developer 558e5c89e4eSSatish Balay 559e5c89e4eSSatish Balay Notes: 560e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 561e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 562e5c89e4eSSatish Balay binary file may be read on any machine. Hence you CANNOT use sizeof() 563e5c89e4eSSatish Balay to determine the offset or location. 564e5c89e4eSSatish Balay 565e5c89e4eSSatish Balay Concepts: files^binary seeking 566e5c89e4eSSatish Balay Concepts: binary files^seeking 567e5c89e4eSSatish Balay 5684ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 5694ebed01fSBarry Smith PetscBinarySynchronizedSeek() 570e5c89e4eSSatish Balay @*/ 5717087cfbeSBarry Smith PetscErrorCode PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 572e5c89e4eSSatish Balay { 573e5c89e4eSSatish Balay int iwhence = 0; 574e5c89e4eSSatish Balay 575e5c89e4eSSatish Balay PetscFunctionBegin; 576a297a907SKarl Rupp if (whence == PETSC_BINARY_SEEK_SET) iwhence = SEEK_SET; 577a297a907SKarl Rupp else if (whence == PETSC_BINARY_SEEK_CUR) iwhence = SEEK_CUR; 578a297a907SKarl Rupp else if (whence == PETSC_BINARY_SEEK_END) iwhence = SEEK_END; 579a297a907SKarl Rupp else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location"); 580e5c89e4eSSatish Balay #if defined(PETSC_HAVE_LSEEK) 581e5c89e4eSSatish Balay *offset = lseek(fd,off,iwhence); 582e5c89e4eSSatish Balay #elif defined(PETSC_HAVE__LSEEK) 583e5c89e4eSSatish Balay *offset = _lseek(fd,(long)off,iwhence); 584e5c89e4eSSatish Balay #else 585e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file"); 586e5c89e4eSSatish Balay #endif 587e5c89e4eSSatish Balay PetscFunctionReturn(0); 588e5c89e4eSSatish Balay } 589e5c89e4eSSatish Balay 590e5c89e4eSSatish Balay /*@C 5911d280d73SBarry Smith PetscBinarySynchronizedRead - Reads from a binary file. 592e5c89e4eSSatish Balay 593e5c89e4eSSatish Balay Collective on MPI_Comm 594e5c89e4eSSatish Balay 595e5c89e4eSSatish Balay Input Parameters: 596e5c89e4eSSatish Balay + comm - the MPI communicator 597e5c89e4eSSatish Balay . fd - the file 598e5c89e4eSSatish Balay . n - the number of items to read 599e5c89e4eSSatish Balay - type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 600e5c89e4eSSatish Balay 601e5c89e4eSSatish Balay Output Parameters: 602e5c89e4eSSatish Balay . p - the buffer 603e5c89e4eSSatish Balay 604e5c89e4eSSatish Balay Level: developer 605e5c89e4eSSatish Balay 606e5c89e4eSSatish Balay Notes: 607e5c89e4eSSatish Balay Does a PetscBinaryRead() followed by an MPI_Bcast() 608e5c89e4eSSatish Balay 6091d280d73SBarry Smith PetscBinarySynchronizedRead() uses byte swapping to work on all machines. 610e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 611e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 612e5c89e4eSSatish Balay binary file may be read on any machine. 613e5c89e4eSSatish Balay 614e5c89e4eSSatish Balay Concepts: files^synchronized reading of binary files 615e5c89e4eSSatish Balay Concepts: binary files^reading, synchronized 616e5c89e4eSSatish Balay 6174ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(), 6184ebed01fSBarry Smith PetscBinarySynchronizedSeek() 619e5c89e4eSSatish Balay @*/ 6207087cfbeSBarry Smith PetscErrorCode PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type) 621e5c89e4eSSatish Balay { 622e1400dc0SSatish Balay PetscErrorCode ierr,ierrp=0; 623e5c89e4eSSatish Balay PetscMPIInt rank; 624e5c89e4eSSatish Balay MPI_Datatype mtype; 62505acbc63SBarry Smith char *fname = NULL; 6260298fd71SBarry Smith void *ptmp = NULL; 627e5c89e4eSSatish Balay 628e5c89e4eSSatish Balay PetscFunctionBegin; 6292d53ad75SBarry Smith if (type == PETSC_FUNCTION) { 6302d53ad75SBarry Smith n = 64; 6312d53ad75SBarry Smith type = PETSC_CHAR; 6322d53ad75SBarry Smith ptmp = p; 633e366c363SBarry Smith fname = (char*)malloc(n*sizeof(char)); 63405acbc63SBarry Smith if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); 6352d53ad75SBarry Smith p = (void*)fname; 6362d53ad75SBarry Smith } 6372d53ad75SBarry Smith 638e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 639e5c89e4eSSatish Balay if (!rank) { 6400090e2cfSJakub Kruzik ierrp = PetscBinaryRead(fd,p,n,type); 641e5c89e4eSSatish Balay } 64247fb9d19SJakub Kruzik ierr = MPI_Bcast(&ierrp,1,MPI_INT,0,comm);CHKERRQ(ierr); 6430090e2cfSJakub Kruzik CHKERRQ(ierrp); 644e5c89e4eSSatish Balay ierr = PetscDataTypeToMPIDataType(type,&mtype);CHKERRQ(ierr); 645e5c89e4eSSatish Balay ierr = MPI_Bcast(p,n,mtype,0,comm);CHKERRQ(ierr); 6462d53ad75SBarry Smith 647e366c363SBarry Smith if (type == PETSC_FUNCTION) { 6482d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 6490298fd71SBarry Smith ierr = PetscDLLibrarySym(PETSC_COMM_SELF,&PetscDLLibrariesLoaded,NULL,fname,(void**)ptmp);CHKERRQ(ierr); 6502d53ad75SBarry Smith #else 6510298fd71SBarry Smith *(void**)ptmp = NULL; 6522d53ad75SBarry Smith #endif 653e366c363SBarry Smith free(fname); 6542d53ad75SBarry Smith } 655e5c89e4eSSatish Balay PetscFunctionReturn(0); 656e5c89e4eSSatish Balay } 657e5c89e4eSSatish Balay 658e5c89e4eSSatish Balay /*@C 6591d280d73SBarry Smith PetscBinarySynchronizedWrite - writes to a binary file. 660e5c89e4eSSatish Balay 661e5c89e4eSSatish Balay Collective on MPI_Comm 662e5c89e4eSSatish Balay 663e5c89e4eSSatish Balay Input Parameters: 664e5c89e4eSSatish Balay + comm - the MPI communicator 665e5c89e4eSSatish Balay . fd - the file 666e5c89e4eSSatish Balay . n - the number of items to write 667e5c89e4eSSatish Balay . p - the buffer 668e5c89e4eSSatish Balay . istemp - the buffer may be changed 669e5c89e4eSSatish Balay - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 670e5c89e4eSSatish Balay 671e5c89e4eSSatish Balay Level: developer 672e5c89e4eSSatish Balay 673e5c89e4eSSatish Balay Notes: 674e5c89e4eSSatish Balay Process 0 does a PetscBinaryWrite() 675e5c89e4eSSatish Balay 6761d280d73SBarry Smith PetscBinarySynchronizedWrite() uses byte swapping to work on all machines. 677e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 678e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 679e5c89e4eSSatish Balay binary file may be read on any machine. 680e5c89e4eSSatish Balay 68195452b02SPatrick Sanan Notes: 68295452b02SPatrick Sanan because byte-swapping may be done on the values in data it cannot be declared const 683300a7f5bSBarry Smith 6841d280d73SBarry Smith WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0, 6851d280d73SBarry Smith while PetscSynchronizedFPrintf() has all processes print their strings in order. 6861d280d73SBarry Smith 687e5c89e4eSSatish Balay Concepts: files^synchronized writing of binary files 688e5c89e4eSSatish Balay Concepts: binary files^reading, synchronized 689e5c89e4eSSatish Balay 6904ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(), 6914ebed01fSBarry Smith PetscBinarySynchronizedSeek() 692e5c89e4eSSatish Balay @*/ 6937087cfbeSBarry Smith PetscErrorCode PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp) 694e5c89e4eSSatish Balay { 695e5c89e4eSSatish Balay PetscErrorCode ierr; 696e5c89e4eSSatish Balay PetscMPIInt rank; 697e5c89e4eSSatish Balay 698e5c89e4eSSatish Balay PetscFunctionBegin; 699e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 700e5c89e4eSSatish Balay if (!rank) { 701e5c89e4eSSatish Balay ierr = PetscBinaryWrite(fd,p,n,type,istemp);CHKERRQ(ierr); 702e5c89e4eSSatish Balay } 703e5c89e4eSSatish Balay PetscFunctionReturn(0); 704e5c89e4eSSatish Balay } 705e5c89e4eSSatish Balay 706e5c89e4eSSatish Balay /*@C 7071d280d73SBarry Smith PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file. 708e5c89e4eSSatish Balay 709e5c89e4eSSatish Balay 710e5c89e4eSSatish Balay Input Parameters: 711e5c89e4eSSatish Balay + fd - the file 712e5c89e4eSSatish Balay . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file 713e5c89e4eSSatish Balay if PETSC_BINARY_SEEK_CUR then size is offset from current location 714e5c89e4eSSatish Balay if PETSC_BINARY_SEEK_END then size is offset from end of file 715e5c89e4eSSatish Balay - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 716e5c89e4eSSatish Balay etc. in your calculation rather than sizeof() to compute byte lengths. 717e5c89e4eSSatish Balay 718e5c89e4eSSatish Balay Output Parameter: 719e5c89e4eSSatish Balay . offset - new offset in file 720e5c89e4eSSatish Balay 721e5c89e4eSSatish Balay Level: developer 722e5c89e4eSSatish Balay 723e5c89e4eSSatish Balay Notes: 724e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 725e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 726e5c89e4eSSatish Balay binary file may be read on any machine. Hence you CANNOT use sizeof() 727e5c89e4eSSatish Balay to determine the offset or location. 728e5c89e4eSSatish Balay 729e5c89e4eSSatish Balay Concepts: binary files^seeking 730e5c89e4eSSatish Balay Concepts: files^seeking in binary 731e5c89e4eSSatish Balay 7324ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 7334ebed01fSBarry Smith PetscBinarySynchronizedSeek() 734e5c89e4eSSatish Balay @*/ 7357087cfbeSBarry Smith PetscErrorCode PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 736e5c89e4eSSatish Balay { 737e5c89e4eSSatish Balay PetscErrorCode ierr; 738e5c89e4eSSatish Balay PetscMPIInt rank; 739e5c89e4eSSatish Balay 740e5c89e4eSSatish Balay PetscFunctionBegin; 741e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 742e5c89e4eSSatish Balay if (!rank) { 743e5c89e4eSSatish Balay ierr = PetscBinarySeek(fd,off,whence,offset);CHKERRQ(ierr); 744e5c89e4eSSatish Balay } 745e5c89e4eSSatish Balay PetscFunctionReturn(0); 746e5c89e4eSSatish Balay } 747e5c89e4eSSatish Balay 7480fc9d207SBarry Smith #if defined(PETSC_HAVE_MPIIO) 749e39fd77fSBarry Smith #if !defined(PETSC_WORDS_BIGENDIAN) 750e39fd77fSBarry Smith 751951e3c8eSBarry Smith #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32) 752e39fd77fSBarry Smith /* 753e39fd77fSBarry Smith MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions. 754e39fd77fSBarry Smith These are set into MPI in PetscInitialize() via MPI_Register_datarep() 755e39fd77fSBarry Smith 756e39fd77fSBarry Smith Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode) 757e39fd77fSBarry Smith 758951e3c8eSBarry Smith The next three routines are not used because MPICH does not support their use 759e39fd77fSBarry Smith 760e39fd77fSBarry Smith */ 7618cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state) 762e39fd77fSBarry Smith { 763e39fd77fSBarry Smith MPI_Aint ub; 764e39fd77fSBarry Smith PetscMPIInt ierr; 765e39fd77fSBarry Smith 766e39fd77fSBarry Smith ierr = MPI_Type_get_extent(datatype,&ub,file_extent); 767e39fd77fSBarry Smith return ierr; 768e39fd77fSBarry Smith } 769e39fd77fSBarry Smith 7708cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state) 771e39fd77fSBarry Smith { 772e39fd77fSBarry Smith PetscDataType pdtype; 773e39fd77fSBarry Smith PetscMPIInt ierr; 774e39fd77fSBarry Smith size_t dsize; 775e39fd77fSBarry Smith 776e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr); 777e39fd77fSBarry Smith ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr); 778e39fd77fSBarry Smith 779e39fd77fSBarry Smith /* offset is given in units of MPI_Datatype */ 780e39fd77fSBarry Smith userbuf = ((char*)userbuf) + dsize*position; 781e39fd77fSBarry Smith 782e39fd77fSBarry Smith ierr = PetscMemcpy(userbuf,filebuf,count*dsize);CHKERRQ(ierr); 783e39fd77fSBarry Smith ierr = PetscByteSwap(userbuf,pdtype,count);CHKERRQ(ierr); 784e39fd77fSBarry Smith return ierr; 785e39fd77fSBarry Smith } 786e39fd77fSBarry Smith 787e39fd77fSBarry Smith PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state) 788e39fd77fSBarry Smith { 789e39fd77fSBarry Smith PetscDataType pdtype; 790e39fd77fSBarry Smith PetscMPIInt ierr; 791e39fd77fSBarry Smith size_t dsize; 792e39fd77fSBarry Smith 793e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr); 794e39fd77fSBarry Smith ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr); 795e39fd77fSBarry Smith 796e39fd77fSBarry Smith /* offset is given in units of MPI_Datatype */ 797e39fd77fSBarry Smith userbuf = ((char*)userbuf) + dsize*position; 798e39fd77fSBarry Smith 799e39fd77fSBarry Smith ierr = PetscMemcpy(filebuf,userbuf,count*dsize);CHKERRQ(ierr); 800e39fd77fSBarry Smith ierr = PetscByteSwap(filebuf,pdtype,count);CHKERRQ(ierr); 801e39fd77fSBarry Smith return ierr; 802e39fd77fSBarry Smith } 803951e3c8eSBarry Smith #endif 804e39fd77fSBarry Smith 805e39fd77fSBarry Smith PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status) 806e39fd77fSBarry Smith { 807e39fd77fSBarry Smith PetscErrorCode ierr; 808e39fd77fSBarry Smith PetscDataType pdtype; 809e39fd77fSBarry Smith 810e39fd77fSBarry Smith PetscFunctionBegin; 811e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr); 812e39fd77fSBarry Smith ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr); 813e39fd77fSBarry Smith ierr = MPI_File_write_all(fd,data,cnt,dtype,status);CHKERRQ(ierr); 814e39fd77fSBarry Smith ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr); 815a6796414SBarry Smith PetscFunctionReturn(0); 816e39fd77fSBarry Smith } 817e39fd77fSBarry Smith 818e39fd77fSBarry Smith PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status) 819e39fd77fSBarry Smith { 820e39fd77fSBarry Smith PetscErrorCode ierr; 821e39fd77fSBarry Smith PetscDataType pdtype; 822e39fd77fSBarry Smith 823e39fd77fSBarry Smith PetscFunctionBegin; 824e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr); 825e39fd77fSBarry Smith ierr = MPI_File_read_all(fd,data,cnt,dtype,status);CHKERRQ(ierr); 826e39fd77fSBarry Smith ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr); 827a6796414SBarry Smith PetscFunctionReturn(0); 828e39fd77fSBarry Smith } 829e39fd77fSBarry Smith #endif 830951e3c8eSBarry Smith #endif 831