Actual source code: memc.c

  1: #define PETSC_DLL

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

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

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

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

 39:    Not Collective

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

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

 48:    Level: intermediate

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

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

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

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

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

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

111:    Not Collective

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

119:    Output Parameters:
120: +  a - pointer to result memory space
121: -  ai - offset of result memory space (in elementary chunk sizes)

123:    Level: intermediate

125:    Note:
126:    This routine is analogous to PetscMemcpy(), except when the data type is 
127:    PETSC_LOGICAL.

129:    Concepts: memory^comparing
130:    Concepts: comparing^memory

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

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

142:   if (bs > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
143:   if (bs > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
144:   if (dtype != PETSC_LOGICAL) {
145:     PetscDataTypeGetSize(dtype,&dsize);
146:     PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
147:   } else {
148:     PetscBT  at = (PetscBT) a;
149:     PetscBT  bt = (PetscBT) b;
150:     PetscInt i;
151:     for (i=0; i<bs; i++) {
152:       if (PetscBTLookup(bt,bi+i)) {PetscBTSet(at,ai+i);}
153:       else                        {PetscBTClear(at,ai+i);}
154:     }
155:   }
156:   return(0);
157: }

161: /*@C
162:    PetscMemzero - Zeros the specified memory.

164:    Not Collective

166:    Input Parameters:
167: +  a - pointer to beginning memory location
168: -  n - length (in bytes) of memory to initialize

170:    Level: intermediate

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

176:    Concepts: memory^zeroing
177:    Concepts: zeroing^memory

179: .seealso: PetscMemcpy()
180: @*/
181: PetscErrorCode PETSC_DLLEXPORT PetscMemzero(void *a,size_t n)
182: {
184:   if (n > 0) {
185:     if (!a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to zero at a null pointer");
186: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
187:     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
188:       size_t      i,len = n/sizeof(PetscScalar);
189:       PetscScalar *x = (PetscScalar*)a;
190:       for (i=0; i<len; i++) x[i] = 0.0;
191:     } else {
192: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
193:     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
194:       PetscInt len = n/sizeof(PetscScalar);
195:       fortranzero_(&len,(PetscScalar*)a);
196:     } else {
197: #endif
198: #if defined(PETSC_PREFER_BZERO)
199:       bzero((char *)a,n);
200: #else
201:       memset((char*)a,0,n);
202: #endif
203: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
204:     }
205: #endif
206:   }
207:   return(0);
208: }

212: /*@C
213:    PetscMemcmp - Compares two byte streams in memory.

215:    Not Collective

217:    Input Parameters:
218: +  str1 - Pointer to the first byte stream
219: .  str2 - Pointer to the second byte stream
220: -  len  - The length of the byte stream
221:          (both str1 and str2 are assumed to be of length len)

223:    Output Parameters:
224: .   e - PETSC_TRUE if equal else PETSC_FALSE.

226:    Level: intermediate

228:    Note: 
229:    This routine is anologous to memcmp()
230: @*/
231: PetscErrorCode PETSC_DLLEXPORT PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
232: {
233:   int r;

236:   if (len > 0 && !str1) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
237:   if (len > 0 && !str2) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
238:   r = memcmp((char *)str1,(char *)str2,len);
239:   if (!r) *e = PETSC_TRUE;
240:   else    *e = PETSC_FALSE;
241:   return(0);
242: }

246: /*@C
247:    PetscMemmove - Copies n bytes, beginning at location b, to the space
248:    beginning at location a. Copying  between regions that overlap will
249:    take place correctly.

251:    Not Collective

253:    Input Parameters:
254: +  b - pointer to initial memory space
255: -  n - length (in bytes) of space to copy

257:    Output Parameter:
258: .  a - pointer to copy space

260:    Level: intermediate

262:    Note:
263:    This routine is analogous to memmove().

265:    Concepts: memory^copying with overlap
266:    Concepts: copying^memory with overlap

268: .seealso: PetscMemcpy()
269: @*/
270: PetscErrorCode PETSC_DLLEXPORT PetscMemmove(void *a,void *b,size_t n)
271: {
273:   if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to null pointer");
274:   if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
275: #if !defined(PETSC_HAVE_MEMMOVE)
276:   if (a < b) {
277:     if (a <= b - n) {
278:       memcpy(a,b,n);
279:     } else {
280:       memcpy(a,b,(int)(b - a));
281:       PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
282:     }
283:   }  else {
284:     if (b <= a - n) {
285:       memcpy(a,b,n);
286:     } else {
287:       memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
288:       PetscMemmove(a,b,n - (int)(a - b));
289:     }
290:   }
291: #else
292:   memmove((char*)(a),(char*)(b),n);
293: #endif
294:   return(0);
295: }