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 } 759e3e4c22SLisandro Dalcin 769e3e4c22SLisandro Dalcin /* 779e3e4c22SLisandro Dalcin PetscByteSwapInt64 - Swap bytes in a PETSc integer (64 bits) 789e3e4c22SLisandro Dalcin 799e3e4c22SLisandro Dalcin */ 809e3e4c22SLisandro Dalcin PetscErrorCode PetscByteSwapInt64(PetscInt64 *buff,PetscInt n) 819e3e4c22SLisandro Dalcin { 829e3e4c22SLisandro Dalcin PetscInt i,j; 839e3e4c22SLisandro Dalcin PetscInt64 tmp = 0; 849e3e4c22SLisandro Dalcin char *ptr1,*ptr2 = (char*)&tmp; 859e3e4c22SLisandro Dalcin 869e3e4c22SLisandro Dalcin PetscFunctionBegin; 879e3e4c22SLisandro Dalcin for (j=0; j<n; j++) { 889e3e4c22SLisandro Dalcin ptr1 = (char*)(buff + j); 899e3e4c22SLisandro Dalcin for (i=0; i<(PetscInt)sizeof(PetscInt64); i++) ptr2[i] = ptr1[sizeof(PetscInt64)-1-i]; 909e3e4c22SLisandro Dalcin for (i=0; i<(PetscInt)sizeof(PetscInt64); i++) ptr1[i] = ptr2[i]; 919e3e4c22SLisandro Dalcin } 929e3e4c22SLisandro Dalcin PetscFunctionReturn(0); 939e3e4c22SLisandro Dalcin } 949e3e4c22SLisandro Dalcin 95bd1d2e58SBarry Smith /* --------------------------------------------------------- */ 96e5c89e4eSSatish Balay /* 97e5c89e4eSSatish Balay PetscByteSwapShort - Swap bytes in a short 98e5c89e4eSSatish Balay */ 997087cfbeSBarry Smith PetscErrorCode PetscByteSwapShort(short *buff,PetscInt n) 100e5c89e4eSSatish Balay { 101e5c89e4eSSatish Balay PetscInt i,j; 102e5c89e4eSSatish Balay short tmp; 103e5c89e4eSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 104e5c89e4eSSatish Balay 105e5c89e4eSSatish Balay PetscFunctionBegin; 106e5c89e4eSSatish Balay for (j=0; j<n; j++) { 107e5c89e4eSSatish Balay ptr1 = (char*)(buff + j); 108a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(short); i++) ptr2[i] = ptr1[sizeof(short)-1-i]; 109a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(short); i++) ptr1[i] = ptr2[i]; 110e5c89e4eSSatish Balay } 111e5c89e4eSSatish Balay PetscFunctionReturn(0); 112e5c89e4eSSatish Balay } 113972064b6SLisandro Dalcin /* 114972064b6SLisandro Dalcin PetscByteSwapLong - Swap bytes in a long 115972064b6SLisandro Dalcin */ 116972064b6SLisandro Dalcin PetscErrorCode PetscByteSwapLong(long *buff,PetscInt n) 117972064b6SLisandro Dalcin { 118972064b6SLisandro Dalcin PetscInt i,j; 119972064b6SLisandro Dalcin long tmp; 120972064b6SLisandro Dalcin char *ptr1,*ptr2 = (char*)&tmp; 121972064b6SLisandro Dalcin 122972064b6SLisandro Dalcin PetscFunctionBegin; 123972064b6SLisandro Dalcin for (j=0; j<n; j++) { 124972064b6SLisandro Dalcin ptr1 = (char*)(buff + j); 125972064b6SLisandro Dalcin for (i=0; i<(PetscInt) sizeof(long); i++) ptr2[i] = ptr1[sizeof(long)-1-i]; 126972064b6SLisandro Dalcin for (i=0; i<(PetscInt) sizeof(long); i++) ptr1[i] = ptr2[i]; 127972064b6SLisandro Dalcin } 128972064b6SLisandro Dalcin PetscFunctionReturn(0); 129972064b6SLisandro Dalcin } 130e5c89e4eSSatish Balay /* --------------------------------------------------------- */ 131e5c89e4eSSatish Balay /* 1324caf0332SSatish Balay PetscByteSwapReal - Swap bytes in a PetscReal 1334caf0332SSatish Balay */ 1344caf0332SSatish Balay PetscErrorCode PetscByteSwapReal(PetscReal *buff,PetscInt n) 1354caf0332SSatish Balay { 1364caf0332SSatish Balay PetscInt i,j; 1374caf0332SSatish Balay PetscReal tmp,*buff1 = (PetscReal*)buff; 1384caf0332SSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 1394caf0332SSatish Balay 1404caf0332SSatish Balay PetscFunctionBegin; 1414caf0332SSatish Balay for (j=0; j<n; j++) { 1424caf0332SSatish Balay ptr1 = (char*)(buff1 + j); 1434caf0332SSatish Balay for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i]; 1444caf0332SSatish Balay for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i]; 1454caf0332SSatish Balay } 1464caf0332SSatish Balay PetscFunctionReturn(0); 1474caf0332SSatish Balay } 1484caf0332SSatish Balay /* --------------------------------------------------------- */ 1494caf0332SSatish Balay /* 15041f502e3SPatrick Sanan PetscByteSwapScalar - Swap bytes in a PetscScalar 15141f502e3SPatrick Sanan The complex case is dealt with with an array of PetscReal, twice as long. 152e5c89e4eSSatish Balay */ 1537087cfbeSBarry Smith PetscErrorCode PetscByteSwapScalar(PetscScalar *buff,PetscInt n) 154e5c89e4eSSatish Balay { 155e5c89e4eSSatish Balay PetscInt i,j; 156e5c89e4eSSatish Balay PetscReal tmp,*buff1 = (PetscReal*)buff; 157e5c89e4eSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 158e5c89e4eSSatish Balay 159e5c89e4eSSatish Balay PetscFunctionBegin; 160e5c89e4eSSatish Balay #if defined(PETSC_USE_COMPLEX) 161e5c89e4eSSatish Balay n *= 2; 162e5c89e4eSSatish Balay #endif 163e5c89e4eSSatish Balay for (j=0; j<n; j++) { 164e5c89e4eSSatish Balay ptr1 = (char*)(buff1 + j); 165a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr2[i] = ptr1[sizeof(PetscReal)-1-i]; 166a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(PetscReal); i++) ptr1[i] = ptr2[i]; 167e5c89e4eSSatish Balay } 168e5c89e4eSSatish Balay PetscFunctionReturn(0); 169e5c89e4eSSatish Balay } 170e5c89e4eSSatish Balay /* --------------------------------------------------------- */ 171e5c89e4eSSatish Balay /* 172e5c89e4eSSatish Balay PetscByteSwapDouble - Swap bytes in a double 173e5c89e4eSSatish Balay */ 1747087cfbeSBarry Smith PetscErrorCode PetscByteSwapDouble(double *buff,PetscInt n) 175e5c89e4eSSatish Balay { 176e5c89e4eSSatish Balay PetscInt i,j; 177e5c89e4eSSatish Balay double tmp,*buff1 = (double*)buff; 178e5c89e4eSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 179e5c89e4eSSatish Balay 180e5c89e4eSSatish Balay PetscFunctionBegin; 181e5c89e4eSSatish Balay for (j=0; j<n; j++) { 182e5c89e4eSSatish Balay ptr1 = (char*)(buff1 + j); 183a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(double); i++) ptr2[i] = ptr1[sizeof(double)-1-i]; 184a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(double); i++) ptr1[i] = ptr2[i]; 185e5c89e4eSSatish Balay } 186e5c89e4eSSatish Balay PetscFunctionReturn(0); 187e5c89e4eSSatish Balay } 188e39fd77fSBarry Smith 189e95bf02fSSatish Balay /* 190e95bf02fSSatish Balay PetscByteSwapFloat - Swap bytes in a float 191e95bf02fSSatish Balay */ 192e95bf02fSSatish Balay PetscErrorCode PetscByteSwapFloat(float *buff,PetscInt n) 193e95bf02fSSatish Balay { 194e95bf02fSSatish Balay PetscInt i,j; 195e95bf02fSSatish Balay float tmp,*buff1 = (float*)buff; 196e95bf02fSSatish Balay char *ptr1,*ptr2 = (char*)&tmp; 197e95bf02fSSatish Balay 198e95bf02fSSatish Balay PetscFunctionBegin; 199e95bf02fSSatish Balay for (j=0; j<n; j++) { 200e95bf02fSSatish Balay ptr1 = (char*)(buff1 + j); 201a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(float); i++) ptr2[i] = ptr1[sizeof(float)-1-i]; 202a297a907SKarl Rupp for (i=0; i<(PetscInt) sizeof(float); i++) ptr1[i] = ptr2[i]; 203e95bf02fSSatish Balay } 204e95bf02fSSatish Balay PetscFunctionReturn(0); 205e95bf02fSSatish Balay } 206e95bf02fSSatish Balay 207e39fd77fSBarry Smith PetscErrorCode PetscByteSwap(void *data,PetscDataType pdtype,PetscInt count) 208e39fd77fSBarry Smith { 209e39fd77fSBarry Smith PetscErrorCode ierr; 210e39fd77fSBarry Smith 211e39fd77fSBarry Smith PetscFunctionBegin; 212e39fd77fSBarry Smith if (pdtype == PETSC_INT) {ierr = PetscByteSwapInt((PetscInt*)data,count);CHKERRQ(ierr);} 213e39fd77fSBarry Smith else if (pdtype == PETSC_ENUM) {ierr = PetscByteSwapEnum((PetscEnum*)data,count);CHKERRQ(ierr);} 214acfcf0e5SJed Brown else if (pdtype == PETSC_BOOL) {ierr = PetscByteSwapBool((PetscBool*)data,count);CHKERRQ(ierr);} 215e39fd77fSBarry Smith else if (pdtype == PETSC_SCALAR) {ierr = PetscByteSwapScalar((PetscScalar*)data,count);CHKERRQ(ierr);} 2164caf0332SSatish Balay else if (pdtype == PETSC_REAL) {ierr = PetscByteSwapReal((PetscReal*)data,count);CHKERRQ(ierr);} 2179860990eSLisandro Dalcin else if (pdtype == PETSC_COMPLEX){ierr = PetscByteSwapReal((PetscReal*)data,2*count);CHKERRQ(ierr);} 2189e3e4c22SLisandro Dalcin else if (pdtype == PETSC_INT64) {ierr = PetscByteSwapInt64((PetscInt64*)data,count);CHKERRQ(ierr);} 219e39fd77fSBarry Smith else if (pdtype == PETSC_DOUBLE) {ierr = PetscByteSwapDouble((double*)data,count);CHKERRQ(ierr);} 220e95bf02fSSatish Balay else if (pdtype == PETSC_FLOAT) {ierr = PetscByteSwapFloat((float*)data,count);CHKERRQ(ierr);} 221e39fd77fSBarry Smith else if (pdtype == PETSC_SHORT) {ierr = PetscByteSwapShort((short*)data,count);CHKERRQ(ierr);} 222972064b6SLisandro Dalcin else if (pdtype == PETSC_LONG) {ierr = PetscByteSwapLong((long*)data,count);CHKERRQ(ierr);} 223e39fd77fSBarry Smith PetscFunctionReturn(0); 224e39fd77fSBarry Smith } 225e39fd77fSBarry Smith 2269860990eSLisandro Dalcin /*@C 227e5c89e4eSSatish Balay PetscBinaryRead - Reads from a binary file. 228e5c89e4eSSatish Balay 229e5c89e4eSSatish Balay Not Collective 230e5c89e4eSSatish Balay 231e5c89e4eSSatish Balay Input Parameters: 2329860990eSLisandro Dalcin + fd - the file descriptor 2339860990eSLisandro Dalcin . num - the maximum number of items to read 2349860990eSLisandro Dalcin - type - the type of items to read (PETSC_INT, PETSC_REAL, PETSC_SCALAR, etc.) 235e5c89e4eSSatish Balay 236e5c89e4eSSatish Balay Output Parameters: 2379860990eSLisandro Dalcin + data - the buffer 2389860990eSLisandro Dalcin - count - the number of items read, optional 239e5c89e4eSSatish Balay 240e5c89e4eSSatish Balay 241e5c89e4eSSatish Balay 242e5c89e4eSSatish Balay Level: developer 243e5c89e4eSSatish Balay 244e5c89e4eSSatish Balay Notes: 2459860990eSLisandro Dalcin If count is not provided and the number of items read is less than 2469860990eSLisandro Dalcin the maximum number of items to read, then this routine errors. 2479860990eSLisandro Dalcin 248e5c89e4eSSatish Balay PetscBinaryRead() uses byte swapping to work on all machines; the files 249e5c89e4eSSatish Balay are written to file ALWAYS using big-endian ordering. On small-endian machines the numbers 250e5c89e4eSSatish Balay are converted to the small-endian format when they are read in from the file. 251e2e64c6bSBarry Smith When PETSc is ./configure with --with-64bit-indices the integers are written to the 25254f21887SBarry Smith file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices 25354f21887SBarry Smith is used. 254e5c89e4eSSatish Balay 255e5c89e4eSSatish Balay Concepts: files^reading binary 256e5c89e4eSSatish Balay Concepts: binary files^reading 257e5c89e4eSSatish Balay 2584ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 2594ebed01fSBarry Smith PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 260e5c89e4eSSatish Balay @*/ 2619860990eSLisandro Dalcin PetscErrorCode PetscBinaryRead(int fd,void *data,PetscInt num,PetscInt *count,PetscDataType type) 262e5c89e4eSSatish Balay { 2639860990eSLisandro Dalcin size_t typesize, m = (size_t) num, n = 0, maxblock = 65536; 2649860990eSLisandro Dalcin char *p = (char*)data; 2657a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 266cba51d77SBarry Smith PetscBool readdouble = PETSC_FALSE; 2679860990eSLisandro Dalcin double *pdouble; 2687a881295SBarry Smith #endif 2699860990eSLisandro Dalcin void *ptmp = data; 27005acbc63SBarry Smith char *fname = NULL; 2719860990eSLisandro Dalcin PetscErrorCode ierr; 272e5c89e4eSSatish Balay 273e5c89e4eSSatish Balay PetscFunctionBegin; 2749860990eSLisandro Dalcin if (count) *count = 0; 2759860990eSLisandro Dalcin if (num < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to read a negative amount of data %D",num); 2769860990eSLisandro Dalcin if (!num) PetscFunctionReturn(0); 277e5c89e4eSSatish Balay 2782d53ad75SBarry Smith if (type == PETSC_FUNCTION) { 2792d53ad75SBarry Smith m = 64; 2802d53ad75SBarry Smith type = PETSC_CHAR; 28105acbc63SBarry Smith fname = (char*)malloc(m*sizeof(char)); 2829860990eSLisandro Dalcin p = (char*)fname; 2832d53ad75SBarry Smith ptmp = (void*)fname; 2849860990eSLisandro Dalcin if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); 2852d53ad75SBarry Smith } 2869860990eSLisandro Dalcin if (type == PETSC_BIT_LOGICAL) m = PetscBTLength(m); 2872d53ad75SBarry Smith 2889860990eSLisandro Dalcin ierr = PetscDataTypeGetSize(type,&typesize);CHKERRQ(ierr); 289e5c89e4eSSatish Balay 2907a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 291c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-binary_read_double",&readdouble,NULL);CHKERRQ(ierr); 2927a881295SBarry Smith /* If using __float128 precision we still read in doubles from file */ 2939860990eSLisandro Dalcin if ((type == PETSC_REAL || type == PETSC_COMPLEX) && readdouble) { 2949860990eSLisandro Dalcin PetscInt cnt = num * ((type == PETSC_REAL) ? 1 : 2); 2959860990eSLisandro Dalcin ierr = PetscMalloc1(cnt,&pdouble);CHKERRQ(ierr); 2969860990eSLisandro Dalcin p = (char*)pdouble; 2979860990eSLisandro Dalcin typesize /= 2; 2987a881295SBarry Smith } 2997a881295SBarry Smith #endif 3007a881295SBarry Smith 3019860990eSLisandro Dalcin m *= typesize; 3029860990eSLisandro Dalcin 303e5c89e4eSSatish Balay while (m) { 3049860990eSLisandro Dalcin size_t len = (m < maxblock) ? m : maxblock; 3059860990eSLisandro Dalcin int ret = (int)read(fd,p,len); 3069860990eSLisandro Dalcin if (ret < 0 && errno == EINTR) continue; 3079860990eSLisandro Dalcin if (!ret && len > 0) break; /* Proxy for EOF */ 3089860990eSLisandro Dalcin if (ret < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Error reading from file, errno %d",errno); 3099860990eSLisandro Dalcin m -= ret; 3109860990eSLisandro Dalcin p += ret; 3119860990eSLisandro Dalcin n += ret; 312e5c89e4eSSatish Balay } 3139860990eSLisandro Dalcin if (m && !count) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Read past end of file"); 3149860990eSLisandro Dalcin 3159860990eSLisandro Dalcin num = (PetscInt)(n/typesize); /* Should we require `n % typesize == 0` ? */ 3169860990eSLisandro Dalcin if (count) *count = num; /* TODO: This is most likely wrong for PETSC_BIT_LOGICAL */ 3177a881295SBarry Smith 3187a881295SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 3199860990eSLisandro Dalcin if ((type == PETSC_REAL || type == PETSC_COMPLEX) && readdouble) { 3209860990eSLisandro Dalcin PetscInt i, cnt = num * ((type == PETSC_REAL) ? 1 : 2); 3219860990eSLisandro Dalcin PetscReal *preal = (PetscReal*)data; 322*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwapDouble(pdouble,cnt);CHKERRQ(ierr);} 3239860990eSLisandro Dalcin for (i=0; i<cnt; i++) preal[i] = pdouble[i]; 3249860990eSLisandro Dalcin ierr = PetscFree(pdouble);CHKERRQ(ierr); 3257a881295SBarry Smith PetscFunctionReturn(0); 3267a881295SBarry Smith } 3277a881295SBarry Smith #endif 3287a881295SBarry Smith 329*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(ptmp,type,num);CHKERRQ(ierr);} 330e5c89e4eSSatish Balay 33105acbc63SBarry Smith if (type == PETSC_FUNCTION) { 3322d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 3339860990eSLisandro Dalcin ierr = PetscDLSym(NULL,fname,(void**)data);CHKERRQ(ierr); 3342d53ad75SBarry Smith #else 3359860990eSLisandro Dalcin *(void**)data = NULL; 3362d53ad75SBarry Smith #endif 33705acbc63SBarry Smith free(fname); 3382d53ad75SBarry Smith } 339e5c89e4eSSatish Balay PetscFunctionReturn(0); 340e5c89e4eSSatish Balay } 3419860990eSLisandro Dalcin 342e30d2299SSatish Balay /*@ 343e5c89e4eSSatish Balay PetscBinaryWrite - Writes to a binary file. 344e5c89e4eSSatish Balay 345e5c89e4eSSatish Balay Not Collective 346e5c89e4eSSatish Balay 347e5c89e4eSSatish Balay Input Parameters: 348e5c89e4eSSatish Balay + fd - the file 349e5c89e4eSSatish Balay . p - the buffer 350e5c89e4eSSatish Balay . n - the number of items to write 351e5c89e4eSSatish Balay . type - the type of items to read (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 352e5c89e4eSSatish Balay - istemp - PETSC_FALSE if buffer data should be preserved, PETSC_TRUE otherwise. 353e5c89e4eSSatish Balay 354e5c89e4eSSatish Balay Level: advanced 355e5c89e4eSSatish Balay 356e5c89e4eSSatish Balay Notes: 357e5c89e4eSSatish Balay PetscBinaryWrite() uses byte swapping to work on all machines; the files 358e5c89e4eSSatish Balay are written using big-endian ordering to the file. On small-endian machines the numbers 359e5c89e4eSSatish Balay are converted to the big-endian format when they are written to disk. 360e2e64c6bSBarry Smith When PETSc is ./configure with --with-64bit-indices the integers are written to the 36154f21887SBarry Smith file as 64 bit integers, this means they can only be read back in when the option --with-64bit-indices 36254f21887SBarry Smith is used. 363e5c89e4eSSatish Balay 36441f502e3SPatrick Sanan If running with __float128 precision the output is in __float128 unless one uses the -binary_write_double option 3650da86b62SBarry Smith 366e5c89e4eSSatish Balay The Buffer p should be read-write buffer, and not static data. 367e5c89e4eSSatish Balay This way, byte-swapping is done in-place, and then the buffer is 368e5c89e4eSSatish Balay written to the file. 369e5c89e4eSSatish Balay 370e5c89e4eSSatish Balay This routine restores the original contents of the buffer, after 371e5c89e4eSSatish Balay it is written to the file. This is done by byte-swapping in-place 372e5c89e4eSSatish Balay the second time. If the flag istemp is set to PETSC_TRUE, the second 373e5c89e4eSSatish Balay byte-swapping operation is not done, thus saving some computation, 374e5f36e38SBarry Smith but the buffer is left corrupted. 375e5c89e4eSSatish Balay 376300a7f5bSBarry Smith Because byte-swapping may be done on the values in data it cannot be declared const 377300a7f5bSBarry Smith 378e5c89e4eSSatish Balay Concepts: files^writing binary 379e5c89e4eSSatish Balay Concepts: binary files^writing 380e5c89e4eSSatish Balay 3814ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryOpen(), PetscBinaryClose(), PetscViewerBinaryGetDescriptor(), PetscBinarySynchronizedWrite(), 3824ebed01fSBarry Smith PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 383e5c89e4eSSatish Balay @*/ 3847087cfbeSBarry Smith PetscErrorCode PetscBinaryWrite(int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp) 385e5c89e4eSSatish Balay { 386e5c89e4eSSatish Balay char *pp = (char*)p; 387e5c89e4eSSatish Balay int err,wsize; 388e5c89e4eSSatish Balay size_t m = (size_t)n,maxblock=65536; 389e5c89e4eSSatish Balay PetscErrorCode ierr; 390e5c89e4eSSatish Balay void *ptmp = p; 39105acbc63SBarry Smith char *fname = NULL; 3920da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 393df40af56SBarry Smith PetscBool writedouble = PETSC_FALSE; 3940da86b62SBarry Smith double *ppp; 3950da86b62SBarry Smith PetscReal *pv; 3960da86b62SBarry Smith PetscInt i; 3970da86b62SBarry Smith #endif 39841f502e3SPatrick Sanan PetscDataType wtype = type; 399e5c89e4eSSatish Balay 400e5c89e4eSSatish Balay PetscFunctionBegin; 401e32f2f54SBarry Smith if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to write a negative amount of data %D",n); 402e5c89e4eSSatish Balay if (!n) PetscFunctionReturn(0); 403e5c89e4eSSatish Balay 4042d53ad75SBarry Smith if (type == PETSC_FUNCTION) { 4052d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 4062d53ad75SBarry Smith const char *fnametmp; 4072d53ad75SBarry Smith #endif 4082d53ad75SBarry Smith m = 64; 409e25ab156SSatish Balay fname = (char*)malloc(m*sizeof(char)); 41005acbc63SBarry Smith if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); 41105acbc63SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 41205acbc63SBarry Smith if (n > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can only binary view a single function at a time"); 41305acbc63SBarry Smith ierr = PetscFPTFind(*(void**)p,&fnametmp);CHKERRQ(ierr); 41405acbc63SBarry Smith ierr = PetscStrncpy(fname,fnametmp,m);CHKERRQ(ierr); 41505acbc63SBarry Smith #else 41605acbc63SBarry Smith ierr = PetscStrncpy(fname,"",m);CHKERRQ(ierr); 41705acbc63SBarry Smith #endif 41801963f56SBarry Smith wtype = PETSC_CHAR; 4192d53ad75SBarry Smith pp = (char*)fname; 4202d53ad75SBarry Smith ptmp = (void*)fname; 4212d53ad75SBarry Smith } 4222d53ad75SBarry Smith 4230da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 4240da86b62SBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-binary_write_double",&writedouble,NULL);CHKERRQ(ierr); 4250da86b62SBarry Smith /* If using __float128 precision we still write in doubles to file */ 4264caf0332SSatish Balay if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) { 42741f502e3SPatrick Sanan wtype = PETSC_DOUBLE; 4280da86b62SBarry Smith ierr = PetscMalloc1(n,&ppp);CHKERRQ(ierr); 4290da86b62SBarry Smith pv = (PetscReal*)pp; 4300da86b62SBarry Smith for (i=0; i<n; i++) { 4310da86b62SBarry Smith ppp[i] = (double) pv[i]; 4320da86b62SBarry Smith } 4330da86b62SBarry Smith pp = (char*)ppp; 4340da86b62SBarry Smith ptmp = (char*)ppp; 4350da86b62SBarry Smith } 4360da86b62SBarry Smith #endif 4370da86b62SBarry Smith 43841f502e3SPatrick Sanan if (wtype == PETSC_INT) m *= sizeof(PetscInt); 43941f502e3SPatrick Sanan else if (wtype == PETSC_SCALAR) m *= sizeof(PetscScalar); 4404caf0332SSatish Balay else if (wtype == PETSC_REAL) m *= sizeof(PetscReal); 44141f502e3SPatrick Sanan else if (wtype == PETSC_DOUBLE) m *= sizeof(double); 44241f502e3SPatrick Sanan else if (wtype == PETSC_FLOAT) m *= sizeof(float); 44341f502e3SPatrick Sanan else if (wtype == PETSC_SHORT) m *= sizeof(short); 444972064b6SLisandro Dalcin else if (wtype == PETSC_LONG) m *= sizeof(long); 44541f502e3SPatrick Sanan else if (wtype == PETSC_CHAR) m *= sizeof(char); 44641f502e3SPatrick Sanan else if (wtype == PETSC_ENUM) m *= sizeof(PetscEnum); 44741f502e3SPatrick Sanan else if (wtype == PETSC_BOOL) m *= sizeof(PetscBool); 4489e3e4c22SLisandro Dalcin else if (wtype == PETSC_INT64) m *= sizeof(PetscInt64); 44941f502e3SPatrick Sanan else if (wtype == PETSC_BIT_LOGICAL) m = PetscBTLength(m)*sizeof(char); 450e32f2f54SBarry Smith else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown type"); 451e5c89e4eSSatish Balay 452*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);} 453e5c89e4eSSatish Balay 454e5c89e4eSSatish Balay while (m) { 455e5c89e4eSSatish Balay wsize = (m < maxblock) ? m : maxblock; 456e5c89e4eSSatish Balay err = write(fd,pp,wsize); 457e5c89e4eSSatish Balay if (err < 0 && errno == EINTR) continue; 45804102261SBarry 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); 459e5c89e4eSSatish Balay m -= wsize; 460e5c89e4eSSatish Balay pp += wsize; 461e5c89e4eSSatish Balay } 462e5c89e4eSSatish Balay 463e5c89e4eSSatish Balay if (!istemp) { 464*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(ptmp,wtype,n);CHKERRQ(ierr);} 465e5c89e4eSSatish Balay } 46605acbc63SBarry Smith if (type == PETSC_FUNCTION) { 46705acbc63SBarry Smith free(fname); 46805acbc63SBarry Smith } 4690da86b62SBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 4704caf0332SSatish Balay if ((type == PETSC_SCALAR || type == PETSC_REAL) && writedouble) { 4710da86b62SBarry Smith ierr = PetscFree(ppp);CHKERRQ(ierr); 4720da86b62SBarry Smith } 4730da86b62SBarry Smith #endif 474e5c89e4eSSatish Balay PetscFunctionReturn(0); 475e5c89e4eSSatish Balay } 476e5c89e4eSSatish Balay 477e5c89e4eSSatish Balay /*@C 478e5c89e4eSSatish Balay PetscBinaryOpen - Opens a PETSc binary file. 479e5c89e4eSSatish Balay 480e5c89e4eSSatish Balay Not Collective 481e5c89e4eSSatish Balay 482e5c89e4eSSatish Balay Input Parameters: 483e5c89e4eSSatish Balay + name - filename 48445c64e65SBarry Smith - type - type of binary file, one of FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_WRITE 485e5c89e4eSSatish Balay 486e5c89e4eSSatish Balay Output Parameter: 487e5c89e4eSSatish Balay . fd - the file 488e5c89e4eSSatish Balay 489e5c89e4eSSatish Balay Level: advanced 490e5c89e4eSSatish Balay 491e5c89e4eSSatish Balay Concepts: files^opening binary 492e5c89e4eSSatish Balay Concepts: binary files^opening 493e5c89e4eSSatish Balay 49495452b02SPatrick Sanan Notes: 49595452b02SPatrick Sanan Files access with PetscBinaryRead() and PetscBinaryWrite() are ALWAYS written in 496e5c89e4eSSatish Balay big-endian format. This means the file can be accessed using PetscBinaryOpen() and 497e5c89e4eSSatish Balay PetscBinaryRead() and PetscBinaryWrite() on any machine. 498e5c89e4eSSatish Balay 4994ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscFileMode, PetscViewerFileSetMode(), PetscViewerBinaryGetDescriptor(), 5004ebed01fSBarry Smith PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), PetscBinarySynchronizedSeek() 50145c64e65SBarry Smith 502e5c89e4eSSatish Balay @*/ 5037087cfbeSBarry Smith PetscErrorCode PetscBinaryOpen(const char name[],PetscFileMode mode,int *fd) 504e5c89e4eSSatish Balay { 505e5c89e4eSSatish Balay PetscFunctionBegin; 506e5c89e4eSSatish Balay #if defined(PETSC_HAVE_O_BINARY) 50745c64e65SBarry Smith if (mode == FILE_MODE_WRITE) { 508a297a907SKarl 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); 50945c64e65SBarry Smith } else if (mode == FILE_MODE_READ) { 510a297a907SKarl 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); 51145c64e65SBarry Smith } else if (mode == FILE_MODE_APPEND) { 512a297a907SKarl 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); 513e5c89e4eSSatish Balay #else 51445c64e65SBarry Smith if (mode == FILE_MODE_WRITE) { 515a297a907SKarl Rupp if ((*fd = creat(name,0666)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot create file for writing: %s",name); 51645c64e65SBarry Smith } else if (mode == FILE_MODE_READ) { 517a297a907SKarl Rupp if ((*fd = open(name,O_RDONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for reading: %s",name); 518e5c89e4eSSatish Balay } 51945c64e65SBarry Smith else if (mode == FILE_MODE_APPEND) { 520a297a907SKarl Rupp if ((*fd = open(name,O_WRONLY,0)) == -1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open file for writing: %s",name); 521e5c89e4eSSatish Balay #endif 522e32f2f54SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown file mode"); 523e5c89e4eSSatish Balay PetscFunctionReturn(0); 524e5c89e4eSSatish Balay } 525e5c89e4eSSatish Balay 526e30d2299SSatish Balay /*@ 527e5c89e4eSSatish Balay PetscBinaryClose - Closes a PETSc binary file. 528e5c89e4eSSatish Balay 529e5c89e4eSSatish Balay Not Collective 530e5c89e4eSSatish Balay 531e5c89e4eSSatish Balay Output Parameter: 532e5c89e4eSSatish Balay . fd - the file 533e5c89e4eSSatish Balay 534e5c89e4eSSatish Balay Level: advanced 535e5c89e4eSSatish Balay 5364ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 5374ebed01fSBarry Smith PetscBinarySynchronizedSeek() 538e5c89e4eSSatish Balay @*/ 5397087cfbeSBarry Smith PetscErrorCode PetscBinaryClose(int fd) 540e5c89e4eSSatish Balay { 541e5c89e4eSSatish Balay PetscFunctionBegin; 542e5c89e4eSSatish Balay close(fd); 543e5c89e4eSSatish Balay PetscFunctionReturn(0); 544e5c89e4eSSatish Balay } 545e5c89e4eSSatish Balay 546e5c89e4eSSatish Balay 547e8976759SBarry Smith /*@C 548e5c89e4eSSatish Balay PetscBinarySeek - Moves the file pointer on a PETSc binary file. 549e5c89e4eSSatish Balay 550e5c89e4eSSatish Balay Not Collective 551e5c89e4eSSatish Balay 552e5c89e4eSSatish Balay Input Parameters: 553e5c89e4eSSatish Balay + fd - the file 554ff553b35SMatthew Knepley . off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 555e5c89e4eSSatish Balay etc. in your calculation rather than sizeof() to compute byte lengths. 556ff553b35SMatthew Knepley - whence - if PETSC_BINARY_SEEK_SET then off is an absolute location in the file 557ff553b35SMatthew Knepley if PETSC_BINARY_SEEK_CUR then off is an offset from the current location 558ff553b35SMatthew Knepley if PETSC_BINARY_SEEK_END then off is an offset from the end of file 559e5c89e4eSSatish Balay 560e5c89e4eSSatish Balay Output Parameter: 561e5c89e4eSSatish Balay . offset - new offset in file 562e5c89e4eSSatish Balay 563e5c89e4eSSatish Balay Level: developer 564e5c89e4eSSatish Balay 565e5c89e4eSSatish Balay Notes: 566e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 567e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 568e5c89e4eSSatish Balay binary file may be read on any machine. Hence you CANNOT use sizeof() 569e5c89e4eSSatish Balay to determine the offset or location. 570e5c89e4eSSatish Balay 571e5c89e4eSSatish Balay Concepts: files^binary seeking 572e5c89e4eSSatish Balay Concepts: binary files^seeking 573e5c89e4eSSatish Balay 5744ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 5754ebed01fSBarry Smith PetscBinarySynchronizedSeek() 576e5c89e4eSSatish Balay @*/ 5777087cfbeSBarry Smith PetscErrorCode PetscBinarySeek(int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 578e5c89e4eSSatish Balay { 579e5c89e4eSSatish Balay int iwhence = 0; 580e5c89e4eSSatish Balay 581e5c89e4eSSatish Balay PetscFunctionBegin; 582a297a907SKarl Rupp if (whence == PETSC_BINARY_SEEK_SET) iwhence = SEEK_SET; 583a297a907SKarl Rupp else if (whence == PETSC_BINARY_SEEK_CUR) iwhence = SEEK_CUR; 584a297a907SKarl Rupp else if (whence == PETSC_BINARY_SEEK_END) iwhence = SEEK_END; 585a297a907SKarl Rupp else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown seek location"); 586e5c89e4eSSatish Balay #if defined(PETSC_HAVE_LSEEK) 587e5c89e4eSSatish Balay *offset = lseek(fd,off,iwhence); 588e5c89e4eSSatish Balay #elif defined(PETSC_HAVE__LSEEK) 589e5c89e4eSSatish Balay *offset = _lseek(fd,(long)off,iwhence); 590e5c89e4eSSatish Balay #else 591e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"System does not have a way of seeking on a file"); 592e5c89e4eSSatish Balay #endif 593e5c89e4eSSatish Balay PetscFunctionReturn(0); 594e5c89e4eSSatish Balay } 595e5c89e4eSSatish Balay 596e5c89e4eSSatish Balay /*@C 5971d280d73SBarry Smith PetscBinarySynchronizedRead - Reads from a binary file. 598e5c89e4eSSatish Balay 599e5c89e4eSSatish Balay Collective on MPI_Comm 600e5c89e4eSSatish Balay 601e5c89e4eSSatish Balay Input Parameters: 602e5c89e4eSSatish Balay + comm - the MPI communicator 6039860990eSLisandro Dalcin . fd - the file descriptor 6049860990eSLisandro Dalcin . num - the maximum number of items to read 6059860990eSLisandro Dalcin - type - the type of items to read (PETSC_INT, PETSC_REAL, PETSC_SCALAR, etc.) 606e5c89e4eSSatish Balay 607e5c89e4eSSatish Balay Output Parameters: 6089860990eSLisandro Dalcin + data - the buffer 6099860990eSLisandro Dalcin - count - the number of items read, optional 610e5c89e4eSSatish Balay 611e5c89e4eSSatish Balay Level: developer 612e5c89e4eSSatish Balay 613e5c89e4eSSatish Balay Notes: 614e5c89e4eSSatish Balay Does a PetscBinaryRead() followed by an MPI_Bcast() 615e5c89e4eSSatish Balay 6169860990eSLisandro Dalcin If count is not provided and the number of items read is less than 6179860990eSLisandro Dalcin the maximum number of items to read, then this routine errors. 6189860990eSLisandro Dalcin 6191d280d73SBarry Smith PetscBinarySynchronizedRead() uses byte swapping to work on all machines. 620e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 621e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 622e5c89e4eSSatish Balay binary file may be read on any machine. 623e5c89e4eSSatish Balay 624e5c89e4eSSatish Balay Concepts: files^synchronized reading of binary files 625e5c89e4eSSatish Balay Concepts: binary files^reading, synchronized 626e5c89e4eSSatish Balay 6274ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedWrite(), 6284ebed01fSBarry Smith PetscBinarySynchronizedSeek() 629e5c89e4eSSatish Balay @*/ 6309860990eSLisandro Dalcin PetscErrorCode PetscBinarySynchronizedRead(MPI_Comm comm,int fd,void *data,PetscInt num,PetscInt *count,PetscDataType type) 631e5c89e4eSSatish Balay { 6329860990eSLisandro Dalcin PetscErrorCode ierr; 633e5c89e4eSSatish Balay PetscMPIInt rank; 634e5c89e4eSSatish Balay MPI_Datatype mtype; 6359860990eSLisandro Dalcin PetscInt ibuf[2] = {0, 0}; 63605acbc63SBarry Smith char *fname = NULL; 6379860990eSLisandro Dalcin void *fptr = NULL; 638e5c89e4eSSatish Balay 639e5c89e4eSSatish Balay PetscFunctionBegin; 6402d53ad75SBarry Smith if (type == PETSC_FUNCTION) { 6419860990eSLisandro Dalcin num = 64; 6422d53ad75SBarry Smith type = PETSC_CHAR; 6439860990eSLisandro Dalcin fname = (char*)malloc(num*sizeof(char)); 6449860990eSLisandro Dalcin fptr = data; 6459860990eSLisandro Dalcin data = (void*)fname; 64605acbc63SBarry Smith if (!fname) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Cannot allocate space for function name"); 6472d53ad75SBarry Smith } 6482d53ad75SBarry Smith 649e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 650e5c89e4eSSatish Balay if (!rank) { 6519860990eSLisandro Dalcin ibuf[0] = PetscBinaryRead(fd,data,num,count?&ibuf[1]:NULL,type); 652e5c89e4eSSatish Balay } 6539860990eSLisandro Dalcin ierr = MPI_Bcast(ibuf,2,MPIU_INT,0,comm);CHKERRQ(ierr); 6549860990eSLisandro Dalcin ierr = (PetscErrorCode)ibuf[0];CHKERRQ(ierr); 655e5c89e4eSSatish Balay ierr = PetscDataTypeToMPIDataType(type,&mtype);CHKERRQ(ierr); 6569860990eSLisandro Dalcin ierr = MPI_Bcast(data,count?ibuf[1]:num,mtype,0,comm);CHKERRQ(ierr); 6579860990eSLisandro Dalcin if (count) *count = ibuf[1]; 6582d53ad75SBarry Smith 659e366c363SBarry Smith if (type == PETSC_FUNCTION) { 6602d53ad75SBarry Smith #if defined(PETSC_SERIALIZE_FUNCTIONS) 6619860990eSLisandro Dalcin ierr = PetscDLLibrarySym(PETSC_COMM_SELF,&PetscDLLibrariesLoaded,NULL,fname,(void**)fptr);CHKERRQ(ierr); 6622d53ad75SBarry Smith #else 6639860990eSLisandro Dalcin *(void**)fptr = NULL; 6642d53ad75SBarry Smith #endif 665e366c363SBarry Smith free(fname); 6662d53ad75SBarry Smith } 667e5c89e4eSSatish Balay PetscFunctionReturn(0); 668e5c89e4eSSatish Balay } 669e5c89e4eSSatish Balay 670e5c89e4eSSatish Balay /*@C 6711d280d73SBarry Smith PetscBinarySynchronizedWrite - writes to a binary file. 672e5c89e4eSSatish Balay 673e5c89e4eSSatish Balay Collective on MPI_Comm 674e5c89e4eSSatish Balay 675e5c89e4eSSatish Balay Input Parameters: 676e5c89e4eSSatish Balay + comm - the MPI communicator 677e5c89e4eSSatish Balay . fd - the file 678e5c89e4eSSatish Balay . n - the number of items to write 679e5c89e4eSSatish Balay . p - the buffer 680e5c89e4eSSatish Balay . istemp - the buffer may be changed 681e5c89e4eSSatish Balay - type - the type of items to write (PETSC_INT, PETSC_DOUBLE or PETSC_SCALAR) 682e5c89e4eSSatish Balay 683e5c89e4eSSatish Balay Level: developer 684e5c89e4eSSatish Balay 685e5c89e4eSSatish Balay Notes: 686e5c89e4eSSatish Balay Process 0 does a PetscBinaryWrite() 687e5c89e4eSSatish Balay 6881d280d73SBarry Smith PetscBinarySynchronizedWrite() uses byte swapping to work on all machines. 689e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 690e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 691e5c89e4eSSatish Balay binary file may be read on any machine. 692e5c89e4eSSatish Balay 69395452b02SPatrick Sanan Notes: 69495452b02SPatrick Sanan because byte-swapping may be done on the values in data it cannot be declared const 695300a7f5bSBarry Smith 6961d280d73SBarry Smith WARNING: This is NOT like PetscSynchronizedFPrintf()! This routine ignores calls on all but process 0, 6971d280d73SBarry Smith while PetscSynchronizedFPrintf() has all processes print their strings in order. 6981d280d73SBarry Smith 699e5c89e4eSSatish Balay Concepts: files^synchronized writing of binary files 700e5c89e4eSSatish Balay Concepts: binary files^reading, synchronized 701e5c89e4eSSatish Balay 7024ebed01fSBarry Smith .seealso: PetscBinaryWrite(), PetscBinaryOpen(), PetscBinaryClose(), PetscBinaryRead(), PetscBinarySynchronizedRead(), 7034ebed01fSBarry Smith PetscBinarySynchronizedSeek() 704e5c89e4eSSatish Balay @*/ 7057087cfbeSBarry Smith PetscErrorCode PetscBinarySynchronizedWrite(MPI_Comm comm,int fd,void *p,PetscInt n,PetscDataType type,PetscBool istemp) 706e5c89e4eSSatish Balay { 707e5c89e4eSSatish Balay PetscErrorCode ierr; 708e5c89e4eSSatish Balay PetscMPIInt rank; 709e5c89e4eSSatish Balay 710e5c89e4eSSatish Balay PetscFunctionBegin; 711e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 712e5c89e4eSSatish Balay if (!rank) { 713e5c89e4eSSatish Balay ierr = PetscBinaryWrite(fd,p,n,type,istemp);CHKERRQ(ierr); 714e5c89e4eSSatish Balay } 715e5c89e4eSSatish Balay PetscFunctionReturn(0); 716e5c89e4eSSatish Balay } 717e5c89e4eSSatish Balay 718e5c89e4eSSatish Balay /*@C 7191d280d73SBarry Smith PetscBinarySynchronizedSeek - Moves the file pointer on a PETSc binary file. 720e5c89e4eSSatish Balay 721e5c89e4eSSatish Balay 722e5c89e4eSSatish Balay Input Parameters: 723e5c89e4eSSatish Balay + fd - the file 724e5c89e4eSSatish Balay . whence - if PETSC_BINARY_SEEK_SET then size is an absolute location in the file 725e5c89e4eSSatish Balay if PETSC_BINARY_SEEK_CUR then size is offset from current location 726e5c89e4eSSatish Balay if PETSC_BINARY_SEEK_END then size is offset from end of file 727e5c89e4eSSatish Balay - off - number of bytes to move. Use PETSC_BINARY_INT_SIZE, PETSC_BINARY_SCALAR_SIZE, 728e5c89e4eSSatish Balay etc. in your calculation rather than sizeof() to compute byte lengths. 729e5c89e4eSSatish Balay 730e5c89e4eSSatish Balay Output Parameter: 731e5c89e4eSSatish Balay . offset - new offset in file 732e5c89e4eSSatish Balay 733e5c89e4eSSatish Balay Level: developer 734e5c89e4eSSatish Balay 735e5c89e4eSSatish Balay Notes: 736e5c89e4eSSatish Balay Integers are stored on the file as 32 long, regardless of whether 737e5c89e4eSSatish Balay they are stored in the machine as 32 or 64, this means the same 738e5c89e4eSSatish Balay binary file may be read on any machine. Hence you CANNOT use sizeof() 739e5c89e4eSSatish Balay to determine the offset or location. 740e5c89e4eSSatish Balay 741e5c89e4eSSatish Balay Concepts: binary files^seeking 742e5c89e4eSSatish Balay Concepts: files^seeking in binary 743e5c89e4eSSatish Balay 7444ebed01fSBarry Smith .seealso: PetscBinaryRead(), PetscBinaryWrite(), PetscBinaryOpen(), PetscBinarySynchronizedWrite(), PetscBinarySynchronizedRead(), 7454ebed01fSBarry Smith PetscBinarySynchronizedSeek() 746e5c89e4eSSatish Balay @*/ 7477087cfbeSBarry Smith PetscErrorCode PetscBinarySynchronizedSeek(MPI_Comm comm,int fd,off_t off,PetscBinarySeekType whence,off_t *offset) 748e5c89e4eSSatish Balay { 749e5c89e4eSSatish Balay PetscErrorCode ierr; 750e5c89e4eSSatish Balay PetscMPIInt rank; 751e5c89e4eSSatish Balay 752e5c89e4eSSatish Balay PetscFunctionBegin; 753e5c89e4eSSatish Balay ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 754e5c89e4eSSatish Balay if (!rank) { 755e5c89e4eSSatish Balay ierr = PetscBinarySeek(fd,off,whence,offset);CHKERRQ(ierr); 756e5c89e4eSSatish Balay } 757e5c89e4eSSatish Balay PetscFunctionReturn(0); 758e5c89e4eSSatish Balay } 759e5c89e4eSSatish Balay 7600fc9d207SBarry Smith #if defined(PETSC_HAVE_MPIIO) 761e39fd77fSBarry Smith 762951e3c8eSBarry Smith #if defined(PETSC_USE_PETSC_MPI_EXTERNAL32) 763e39fd77fSBarry Smith /* 764e39fd77fSBarry Smith MPICH does not provide the external32 representation for MPI_File_set_view() so we need to provide the functions. 765e39fd77fSBarry Smith These are set into MPI in PetscInitialize() via MPI_Register_datarep() 766e39fd77fSBarry Smith 767e39fd77fSBarry Smith Note I use PetscMPIInt for the MPI error codes since that is what MPI uses (instead of the standard PetscErrorCode) 768e39fd77fSBarry Smith 769951e3c8eSBarry Smith The next three routines are not used because MPICH does not support their use 770e39fd77fSBarry Smith 771e39fd77fSBarry Smith */ 7728cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_extent_fn(MPI_Datatype datatype,MPI_Aint *file_extent,void *extra_state) 773e39fd77fSBarry Smith { 774e39fd77fSBarry Smith MPI_Aint ub; 775e39fd77fSBarry Smith PetscMPIInt ierr; 776e39fd77fSBarry Smith 777e39fd77fSBarry Smith ierr = MPI_Type_get_extent(datatype,&ub,file_extent); 778e39fd77fSBarry Smith return ierr; 779e39fd77fSBarry Smith } 780e39fd77fSBarry Smith 7818cc058d9SJed Brown PETSC_EXTERN PetscMPIInt PetscDataRep_read_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state) 782e39fd77fSBarry Smith { 783e39fd77fSBarry Smith PetscDataType pdtype; 784e39fd77fSBarry Smith PetscMPIInt ierr; 785e39fd77fSBarry Smith size_t dsize; 786e39fd77fSBarry Smith 787e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr); 788e39fd77fSBarry Smith ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr); 789e39fd77fSBarry Smith 790e39fd77fSBarry Smith /* offset is given in units of MPI_Datatype */ 791e39fd77fSBarry Smith userbuf = ((char*)userbuf) + dsize*position; 792e39fd77fSBarry Smith 793e39fd77fSBarry Smith ierr = PetscMemcpy(userbuf,filebuf,count*dsize);CHKERRQ(ierr); 794*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(userbuf,pdtype,count);CHKERRQ(ierr);} 795e39fd77fSBarry Smith return ierr; 796e39fd77fSBarry Smith } 797e39fd77fSBarry Smith 798e39fd77fSBarry Smith PetscMPIInt PetscDataRep_write_conv_fn(void *userbuf, MPI_Datatype datatype,PetscMPIInt count,void *filebuf, MPI_Offset position,void *extra_state) 799e39fd77fSBarry Smith { 800e39fd77fSBarry Smith PetscDataType pdtype; 801e39fd77fSBarry Smith PetscMPIInt ierr; 802e39fd77fSBarry Smith size_t dsize; 803e39fd77fSBarry Smith 804e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(datatype,&pdtype);CHKERRQ(ierr); 805e39fd77fSBarry Smith ierr = PetscDataTypeGetSize(pdtype,&dsize);CHKERRQ(ierr); 806e39fd77fSBarry Smith 807e39fd77fSBarry Smith /* offset is given in units of MPI_Datatype */ 808e39fd77fSBarry Smith userbuf = ((char*)userbuf) + dsize*position; 809e39fd77fSBarry Smith 810e39fd77fSBarry Smith ierr = PetscMemcpy(filebuf,userbuf,count*dsize);CHKERRQ(ierr); 811*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(filebuf,pdtype,count);CHKERRQ(ierr);} 812e39fd77fSBarry Smith return ierr; 813e39fd77fSBarry Smith } 814951e3c8eSBarry Smith #endif 815e39fd77fSBarry Smith 816e39fd77fSBarry Smith PetscErrorCode MPIU_File_write_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status) 817e39fd77fSBarry Smith { 818e39fd77fSBarry Smith PetscDataType pdtype; 819*30815ce0SLisandro Dalcin PetscErrorCode ierr; 820*30815ce0SLisandro Dalcin 821e39fd77fSBarry Smith 822e39fd77fSBarry Smith PetscFunctionBegin; 823e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr); 824*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);} 825e39fd77fSBarry Smith ierr = MPI_File_write_all(fd,data,cnt,dtype,status);CHKERRQ(ierr); 826*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);} 827a6796414SBarry Smith PetscFunctionReturn(0); 828e39fd77fSBarry Smith } 829e39fd77fSBarry Smith 830e39fd77fSBarry Smith PetscErrorCode MPIU_File_read_all(MPI_File fd,void *data,PetscMPIInt cnt,MPI_Datatype dtype,MPI_Status *status) 831e39fd77fSBarry Smith { 832e39fd77fSBarry Smith PetscDataType pdtype; 833*30815ce0SLisandro Dalcin PetscErrorCode ierr; 834e39fd77fSBarry Smith 835e39fd77fSBarry Smith PetscFunctionBegin; 836e39fd77fSBarry Smith ierr = PetscMPIDataTypeToPetscDataType(dtype,&pdtype);CHKERRQ(ierr); 837e39fd77fSBarry Smith ierr = MPI_File_read_all(fd,data,cnt,dtype,status);CHKERRQ(ierr); 838*30815ce0SLisandro Dalcin if (!PetscBinaryBigEndian()) {ierr = PetscByteSwap(data,pdtype,cnt);CHKERRQ(ierr);} 839a6796414SBarry Smith PetscFunctionReturn(0); 840e39fd77fSBarry Smith } 841*30815ce0SLisandro Dalcin 842951e3c8eSBarry Smith #endif 843