Actual source code: memc.c

  1: /*$Id: memc.c,v 1.67 2001/03/23 23:20:45 balay 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"        /*I  "petsc.h"   I*/
  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"

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

 31:    Not Collective

 33:    Input Parameters:
 34: +  b - pointer to initial memory space
 35: -  n - length (in bytes) of space to copy

 37:    Output Parameter:
 38: .  a - pointer to copy space

 40:    Level: intermediate

 42:    Compile Option:
 43:     PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used 
 44:    for memory copies on double precision values.

 46:    Note:
 47:    This routine is analogous to memcpy().

 49:   Concepts: memory^copying
 50:   Concepts: copying^memory
 51:   
 52: .seealso: PetscMemmove()

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

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

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

 87:    Not Collective

 89:    Input Parameters:
 90: +  b - pointer to initial memory space
 91: .  bi - offset of initial memory space (in elementary chunk sizes)
 92: .  bs - length (in elementary chunk sizes) of space to copy
 93: -  dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL

 95:    Output Parameters:
 96: +  a - pointer to result memory space
 97: -  ai - offset of result memory space (in elementary chunk sizes)

 99:    Level: intermediate

101:    Note:
102:    This routine is analogous to PetscMemcpy(), except when the data type is 
103:    PETSC_LOGICAL.

105:    Concepts: memory^comparing
106:    Concepts: comparing^memory

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

110: @*/
111: int PetscBitMemcpy(void *a,int ai,const void *b,int bi,int bs,PetscDataType dtype)
112: {
113:   char *aa = (char *)a,*bb = (char *)b;
114:   int  dsize,ierr;

117:   if (dtype != PETSC_LOGICAL) {
118:     PetscDataTypeGetSize(dtype,&dsize);
119:     PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
120:   } else {
121:     PetscBT at = (PetscBT) a,bt = (PetscBT) b;
122:     int i;
123:     for (i=0; i<bs; i++) {
124:       if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
125:       else                        PetscBTClear(at,ai+i);
126:     }
127:   }
128:   return(0);
129: }

131: /*@C
132:    PetscMemzero - Zeros the specified memory.

134:    Not Collective

136:    Input Parameters:
137: +  a - pointer to beginning memory location
138: -  n - length (in bytes) of memory to initialize

140:    Level: intermediate

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

146:    Concepts: memory^zeroing
147:    Concepts: zeroing^memory

149: .seealso: PetscMemcpy()
150: @*/
151: int PetscMemzero(void *a,int n)
152: {
154:   if (n < 0) SETERRQ(1,"Memory length must be >= 0");
155:   if (n > 0) {
156: #if defined(PETSC_PREFER_BZERO)
157:     bzero((char *)a,n);
158: #else
159:     memset((char*)a,0,n);
160: #endif
161:   }
162:   return(0);
163: }

165: /*@C
166:    PetscMemcmp - Compares two byte streams in memory.

168:    Not Collective

170:    Input Parameters:
171: +  str1 - Pointer to the first byte stream
172: .  str2 - Pointer to the second byte stream
173: -  len  - The length of the byte stream
174:          (both str1 and str2 are assumed to be of length len)

176:    Output Parameters:
177: .   e - PETSC_TRUE if equal else PETSC_FALSE.

179:    Level: intermediate

181:    Note: 
182:    This routine is anologous to memcmp()
183: @*/
184: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
185: {
186:   int r;

189:   r = memcmp((char *)str1,(char *)str2,len);
190:   if (!r) *e = PETSC_TRUE;
191:   else    *e = PETSC_FALSE;
192:   return(0);
193: }

195: /*@C
196:    PetscMemmove - Copies n bytes, beginning at location b, to the space
197:    beginning at location a. Copying  between regions that overlap will
198:    take place correctly.

200:    Not Collective

202:    Input Parameters:
203: +  b - pointer to initial memory space
204: -  n - length (in bytes) of space to copy

206:    Output Parameter:
207: .  a - pointer to copy space

209:    Level: intermediate

211:    Note:
212:    This routine is analogous to memmove().

214:    Contributed by: Matthew Knepley

216:    Concepts: memory^copying with overlap
217:    Concepts: copying^memory with overlap

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