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: /*@
 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  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: #elif defined(PETSC_HAVE__INTEL_FAST_MEMCPY)
100:     _intel_fast_memcpy((char*)(a),(char*)(b),n);
101: #else
102:     memcpy((char*)(a),(char*)(b),n);
103: #endif
104:   }
105:   return(0);
106: }

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

113:    Not Collective

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

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

125:    Level: intermediate

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

131:    Concepts: memory^comparing
132:    Concepts: comparing^memory

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

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

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

163: /*@
164:    PetscMemzero - Zeros the specified memory.

166:    Not Collective

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

172:    Level: intermediate

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

178:    Concepts: memory^zeroing
179:    Concepts: zeroing^memory

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

216: /*@C
217:    PetscMemcmp - Compares two byte streams in memory.

219:    Not Collective

221:    Input Parameters:
222: +  str1 - Pointer to the first byte stream
223: .  str2 - Pointer to the second byte stream
224: -  len  - The length of the byte stream
225:          (both str1 and str2 are assumed to be of length len)

227:    Output Parameters:
228: .   e - PETSC_TRUE if equal else PETSC_FALSE.

230:    Level: intermediate

232:    Note: 
233:    This routine is anologous to memcmp()
234: @*/
235: PetscErrorCode  PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
236: {
237:   int r;

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

250: /*@C
251:    PetscMemmove - Copies n bytes, beginning at location b, to the space
252:    beginning at location a. Copying  between regions that overlap will
253:    take place correctly.

255:    Not Collective

257:    Input Parameters:
258: +  b - pointer to initial memory space
259: -  n - length (in bytes) of space to copy

261:    Output Parameter:
262: .  a - pointer to copy space

264:    Level: intermediate

266:    Note:
267:    This routine is analogous to memmove().

269:    Concepts: memory^copying with overlap
270:    Concepts: copying^memory with overlap

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