Actual source code: memc.c

  1: /*$Id: memc.c,v 1.69 2001/09/07 20:08:33 bsmith Exp $*/
  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: /*
 10:     On the IBM Rs6000 using the Gnu G++ compiler you may have to include 
 11:   <string.h> instead of <memory.h> 
 12: */
 13: #include <memory.h>
 14: #if defined(PETSC_HAVE_STRINGS_H)
 15: #include <strings.h>
 16: #endif
 17: #if defined(PETSC_HAVE_STRING_H)
 18: #include <string.h>
 19: #endif
 20: #if defined(PETSC_HAVE_STDLIB_H)
 21: #include <stdlib.h>
 22: #endif
 23: #include "petscfix.h"
 24:  #include petscbt.h
 25: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
 26:  #include petscblaslapack.h
 27: #endif

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

 34:    Not Collective

 36:    Input Parameters:
 37: +  b - pointer to initial memory space
 38: -  n - length (in bytes) of space to copy

 40:    Output Parameter:
 41: .  a - pointer to copy space

 43:    Level: intermediate

 45:    Compile Option:
 46:     PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used 
 47:    for memory copies on double precision values.

 49:    Note:
 50:    This routine is analogous to memcpy().

 52:   Concepts: memory^copying
 53:   Concepts: copying^memory
 54:   
 55: .seealso: PetscMemmove()

 57: @*/
 58: int PetscMemcpy(void *a,const void *b,int n)
 59: {
 60:   unsigned long al = (unsigned long) a,bl = (unsigned long) b;
 61:   unsigned long nl = (unsigned long) n;

 64:   if (a != b) {
 65: #if !defined(PETSC_HAVE_CRAY90_POINTER)
 66:     if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
 67:       SETERRQ(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()n
 68:               or make sure your copy regions and lengths are correct");
 69:     }
 70: #endif
 71: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) && !defined(PETSC_USE_COMPLEX)
 72: #  if defined(HAVE_DOUBLE_ALIGN)
 73:     if (!(((long) a) % 8) && !(n % 8)) {
 74: #  else
 75:     if (!(((long) a) % 4) && !(n % 8)) {
 76: #endif
 77:       int one = 1;
 78:       int len = n/sizeof(PetscScalar);
 79:       BLcopy_(&len,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
 80:     } else {
 81:       memcpy((char*)(a),(char*)(b),n);
 82:     }
 83: #else
 84:     memcpy((char*)(a),(char*)(b),n);
 85: #endif
 86:   }
 87:   return(0);
 88: }

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

 93:    Not Collective

 95:    Input Parameters:
 96: +  b - pointer to initial memory space
 97: .  bi - offset of initial memory space (in elementary chunk sizes)
 98: .  bs - length (in elementary chunk sizes) of space to copy
 99: -  dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL

101:    Output Parameters:
102: +  a - pointer to result memory space
103: -  ai - offset of result memory space (in elementary chunk sizes)

105:    Level: intermediate

107:    Note:
108:    This routine is analogous to PetscMemcpy(), except when the data type is 
109:    PETSC_LOGICAL.

111:    Concepts: memory^comparing
112:    Concepts: comparing^memory

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

116: @*/
117: int PetscBitMemcpy(void *a,int ai,const void *b,int bi,int bs,PetscDataType dtype)
118: {
119:   char *aa = (char *)a,*bb = (char *)b;
120:   int  dsize,ierr;

123:   if (dtype != PETSC_LOGICAL) {
124:     PetscDataTypeGetSize(dtype,&dsize);
125:     PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
126:   } else {
127:     PetscBT at = (PetscBT) a,bt = (PetscBT) b;
128:     int i;
129:     for (i=0; i<bs; i++) {
130:       if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
131:       else                        PetscBTClear(at,ai+i);
132:     }
133:   }
134:   return(0);
135: }

137: /*@C
138:    PetscMemzero - Zeros the specified memory.

140:    Not Collective

142:    Input Parameters:
143: +  a - pointer to beginning memory location
144: -  n - length (in bytes) of memory to initialize

146:    Level: intermediate

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

152:    Concepts: memory^zeroing
153:    Concepts: zeroing^memory

155: .seealso: PetscMemcpy()
156: @*/
157: int PetscMemzero(void *a,int n)
158: {
160:   if (n < 0) SETERRQ(1,"Memory length must be >= 0");
161:   if (n > 0) {
162: #if defined(PETSC_PREFER_BZERO)
163:     bzero((char *)a,n);
164: #else
165:     memset((char*)a,0,n);
166: #endif
167:   }
168:   return(0);
169: }

171: /*@C
172:    PetscMemcmp - Compares two byte streams in memory.

174:    Not Collective

176:    Input Parameters:
177: +  str1 - Pointer to the first byte stream
178: .  str2 - Pointer to the second byte stream
179: -  len  - The length of the byte stream
180:          (both str1 and str2 are assumed to be of length len)

182:    Output Parameters:
183: .   e - PETSC_TRUE if equal else PETSC_FALSE.

185:    Level: intermediate

187:    Note: 
188:    This routine is anologous to memcmp()
189: @*/
190: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
191: {
192:   int r;

195:   r = memcmp((char *)str1,(char *)str2,len);
196:   if (!r) *e = PETSC_TRUE;
197:   else    *e = PETSC_FALSE;
198:   return(0);
199: }

201: /*@C
202:    PetscMemmove - Copies n bytes, beginning at location b, to the space
203:    beginning at location a. Copying  between regions that overlap will
204:    take place correctly.

206:    Not Collective

208:    Input Parameters:
209: +  b - pointer to initial memory space
210: -  n - length (in bytes) of space to copy

212:    Output Parameter:
213: .  a - pointer to copy space

215:    Level: intermediate

217:    Note:
218:    This routine is analogous to memmove().

220:    Contributed by: Matthew Knepley

222:    Concepts: memory^copying with overlap
223:    Concepts: copying^memory with overlap

225: .seealso: PetscMemcpy()
226: @*/
227: int PetscMemmove(void *a,void *b,int n)
228: {
230: #if !defined(PETSC_HAVE_MEMMOVE)
231:   if (a < b) {
232:     if (a <= b - n) {
233:       memcpy(a,b,n);
234:     } else {
235:       memcpy(a,b,(int)(b - a));
236:       PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
237:     }
238:   }  else {
239:     if (b <= a - n) {
240:       memcpy(a,b,n);
241:     } else {
242:       memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
243:       PetscMemmove(a,b,n - (int)(a - b));
244:     }
245:   }
246: #else
247:   memmove((char*)(a),(char*)(b),n);
248: #endif
249:   return(0);
250: }