Actual source code: memc.c

  2: /*
  3:     We define the memory operations here. The reason we just do not use 
  4:   the standard memory routines in the PETSc code is that on some machines 
  5:   they are broken.

  7: */
 8:  #include petsc.h
 9:  #include src/inline/axpy.h

 11: /*
 12:     On the IBM Rs6000 using the Gnu G++ compiler you may have to include 
 13:   <string.h> instead of <memory.h> 
 14: */
 15: #include <memory.h>
 16: #if defined(PETSC_HAVE_STRINGS_H)
 17: #include <strings.h>
 18: #endif
 19: #if defined(PETSC_HAVE_STRING_H)
 20: #include <string.h>
 21: #endif
 22: #if defined(PETSC_HAVE_STDLIB_H)
 23: #include <stdlib.h>
 24: #endif
 25: #include "petscfix.h"
 26:  #include petscbt.h
 27: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
 28:  #include petscblaslapack.h
 29: #endif

 33: /*@C
 34:    PetscMemcpy - Copies n bytes, beginning at location b, to the space
 35:    beginning at location a. The two memory regions CANNOT overlap, use
 36:    PetscMemmove() in that case.

 38:    Not Collective

 40:    Input Parameters:
 41: +  b - pointer to initial memory space
 42: -  n - length (in bytes) of space to copy

 44:    Output Parameter:
 45: .  a - pointer to copy space

 47:    Level: intermediate

 49:    Compile Option:
 50:     PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used 
 51:                                   for memory copies on double precision values.
 52:     PETSC_PREFER_COPY_FOR_MEMCPY will cause C code to be used 
 53:                                   for memory copies on double precision values.
 54:     PETSC_PREFER_FORTRAN_FORMEMCPY will cause Fortran code to be used 
 55:                                   for memory copies on double precision values.

 57:    Note:
 58:    This routine is analogous to memcpy().

 60:   Concepts: memory^copying
 61:   Concepts: copying^memory
 62:   
 63: .seealso: PetscMemmove()

 65: @*/
 66: PetscErrorCode PetscMemcpy(void *a,const void *b,size_t n)
 67: {
 68:   unsigned long al = (unsigned long) a,bl = (unsigned long) b;
 69:   unsigned long nl = (unsigned long) n;

 72:   if (a != b) {
 73: #if !defined(PETSC_HAVE_CRAY90_POINTER)
 74:     if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
 75:       SETERRQ3(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()\n\
 76:               or make sure your copy regions and lengths are correct. \n\
 77:               Length (bytes) %ld first address %ld second address %ld",nl,al,bl);
 78:     }
 79: #endif
 80: #if (defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) || defined(PETSC_PREFER_COPY_FOR_MEMCPY) || defined(PETSC_PREFER_FORTRAN_FORMEMCPY))
 81:    if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
 82:       int len = n/sizeof(PetscScalar);
 83: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
 84:       PetscBLASInt blen = (PetscBLASInt) len,one = 1;
 85:       BLcopy_(&blen,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
 86: #elif defined(PETSC_PREFER_FORTRAN_FORMEMCPY)
 87:       fortrancopy_(&len,(PetscScalar*)b,(PetscScalar*)a);
 88: #else
 89:       int         i;
 90:       PetscScalar *x = (PetscScalar*)b, *y = (PetscScalar*)a;
 91:       for (i=0; i<len; i++) y[i] = x[i];
 92: #endif
 93:     } else {
 94:       memcpy((char*)(a),(char*)(b),n);
 95:     }
 96: #else
 97:     memcpy((char*)(a),(char*)(b),n);
 98: #endif
 99:   }
100:   return(0);
101: }

105: /*@C
106:    PetscBitMemcpy - Copies an amount of data. This can include bit data.

108:    Not Collective

110:    Input Parameters:
111: +  b - pointer to initial memory space
112: .  bi - offset of initial memory space (in elementary chunk sizes)
113: .  bs - length (in elementary chunk sizes) of space to copy
114: -  dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL

116:    Output Parameters:
117: +  a - pointer to result memory space
118: -  ai - offset of result memory space (in elementary chunk sizes)

120:    Level: intermediate

122:    Note:
123:    This routine is analogous to PetscMemcpy(), except when the data type is 
124:    PETSC_LOGICAL.

126:    Concepts: memory^comparing
127:    Concepts: comparing^memory

129: .seealso: PetscMemmove(), PetscMemcpy()

131: @*/
132: PetscErrorCode PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype)
133: {
134:   char           *aa = (char *)a,*bb = (char *)b;
135:   PetscInt       dsize;

139:   if (dtype != PETSC_LOGICAL) {
140:     PetscDataTypeGetSize(dtype,&dsize);
141:     PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
142:   } else {
143:     PetscBT at = (PetscBT) a;
144:     PetscBT bt = (PetscBT) b;
145:     int i;
146:     for (i=0; i<bs; i++) {
147:       if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
148:       else                        PetscBTClear(at,ai+i);
149:     }
150:   }
151:   return(0);
152: }

156: /*@C
157:    PetscMemzero - Zeros the specified memory.

159:    Not Collective

161:    Input Parameters:
162: +  a - pointer to beginning memory location
163: -  n - length (in bytes) of memory to initialize

165:    Level: intermediate

167:    Compile Option:
168:    PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
169:   to be faster than the memset() routine. This flag causes the bzero() routine to be used.

171:    Concepts: memory^zeroing
172:    Concepts: zeroing^memory

174: .seealso: PetscMemcpy()
175: @*/
176: PetscErrorCode PetscMemzero(void *a,size_t n)
177: {
179:   if (n > 0) {
180: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
181:     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
182:       int         i,len = n/sizeof(PetscScalar);
183:       PetscScalar *x = (PetscScalar*)a;
184:       for (i=0; i<len; i++) x[i] = 0.0;
185:     } else {
186: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
187:     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
188:       int len = n/sizeof(PetscScalar);
189:       fortranzero_(&len,(PetscScalar*)a);
190:     } else {
191: #endif
192: #if defined(PETSC_PREFER_BZERO)
193:       bzero((char *)a,n);
194: #else
195:       memset((char*)a,0,n);
196: #endif
197: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
198:     }
199: #endif
200:   }
201:   return(0);
202: }

206: /*@C
207:    PetscMemcmp - Compares two byte streams in memory.

209:    Not Collective

211:    Input Parameters:
212: +  str1 - Pointer to the first byte stream
213: .  str2 - Pointer to the second byte stream
214: -  len  - The length of the byte stream
215:          (both str1 and str2 are assumed to be of length len)

217:    Output Parameters:
218: .   e - PETSC_TRUE if equal else PETSC_FALSE.

220:    Level: intermediate

222:    Note: 
223:    This routine is anologous to memcmp()
224: @*/
225: PetscErrorCode PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
226: {
227:   int r;

230:   r = memcmp((char *)str1,(char *)str2,len);
231:   if (!r) *e = PETSC_TRUE;
232:   else    *e = PETSC_FALSE;
233:   return(0);
234: }

238: /*@C
239:    PetscMemmove - Copies n bytes, beginning at location b, to the space
240:    beginning at location a. Copying  between regions that overlap will
241:    take place correctly.

243:    Not Collective

245:    Input Parameters:
246: +  b - pointer to initial memory space
247: -  n - length (in bytes) of space to copy

249:    Output Parameter:
250: .  a - pointer to copy space

252:    Level: intermediate

254:    Note:
255:    This routine is analogous to memmove().

257:    Contributed by: Matthew Knepley

259:    Concepts: memory^copying with overlap
260:    Concepts: copying^memory with overlap

262: .seealso: PetscMemcpy()
263: @*/
264: PetscErrorCode PetscMemmove(void *a,void *b,size_t n)
265: {
267: #if !defined(PETSC_HAVE_MEMMOVE)
268:   if (a < b) {
269:     if (a <= b - n) {
270:       memcpy(a,b,n);
271:     } else {
272:       memcpy(a,b,(int)(b - a));
273:       PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
274:     }
275:   }  else {
276:     if (b <= a - n) {
277:       memcpy(a,b,n);
278:     } else {
279:       memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
280:       PetscMemmove(a,b,n - (int)(a - b));
281:     }
282:   }
283: #else
284:   memmove((char*)(a),(char*)(b),n);
285: #endif
286:   return(0);
287: }