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: #if defined(PETSC_HAVE_MEMORY_H)
 17: #include <memory.h>
 18: #endif
 19: #if defined(PETSC_HAVE_STRINGS_H)
 20: #include <strings.h>
 21: #endif
 22: #if defined(PETSC_HAVE_STRING_H)
 23: #include <string.h>
 24: #endif
 25: #if defined(PETSC_HAVE_STDLIB_H)
 26: #include <stdlib.h>
 27: #endif
 28: #include "petscfix.h"
 29:  #include petscbt.h
 30: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
 31:  #include petscblaslapack.h
 32: #endif

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

 41:    Not Collective

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

 47:    Output Parameter:
 48: .  a - pointer to copy space

 50:    Level: intermediate

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

 60:    Note:
 61:    This routine is analogous to memcpy().

 63:   Concepts: memory^copying
 64:   Concepts: copying^memory
 65:   
 66: .seealso: PetscMemmove()

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

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

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

115:    Not Collective

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

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

127:    Level: intermediate

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

133:    Concepts: memory^comparing
134:    Concepts: comparing^memory

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

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

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

165: /*@
166:    PetscMemzero - Zeros the specified memory.

168:    Not Collective

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

174:    Level: intermediate

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

180:    Concepts: memory^zeroing
181:    Concepts: zeroing^memory

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

218: /*@
219:    PetscMemcmp - Compares two byte streams in memory.

221:    Not Collective

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

229:    Output Parameters:
230: .   e - PETSC_TRUE if equal else PETSC_FALSE.

232:    Level: intermediate

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

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

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

257:    Not Collective

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

263:    Output Parameter:
264: .  a - pointer to copy space

266:    Level: intermediate

268:    Note:
269:    This routine is analogous to memmove().

271:    Since b can overlap with a, b cannot be declared as const

273:    Concepts: memory^copying with overlap
274:    Concepts: copying^memory with overlap

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