Actual source code: memc.c

  1: /*$Id: memc.c,v 1.69 2001/09/07 20:08:33 bsmith Exp $*/

  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

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

 37:    Not Collective

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

 43:    Output Parameter:
 44: .  a - pointer to copy space

 46:    Level: intermediate

 48:    Compile Option:
 49:     PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used 
 50:    for memory copies on double precision values.

 52:    Note:
 53:    This routine is analogous to memcpy().

 55:   Concepts: memory^copying
 56:   Concepts: copying^memory
 57:   
 58: .seealso: PetscMemmove()

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

 67:   if (a != b) {
 68: #if !defined(PETSC_HAVE_CRAY90_POINTER)
 69:     if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
 70:       SETERRQ(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()n
 71:               or make sure your copy regions and lengths are correct");
 72:     }
 73: #endif
 74: #if (defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) || defined(PETSC_PREFER_COPY_FOR_MEMCPY) || defined(PETSC_PREFER_FORTRAN_FORMEMCPY))
 75:    if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
 76:       int len = n/sizeof(PetscScalar);
 77: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
 78:       int one = 1;
 79:       BLcopy_(&len,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
 80: #elif defined(PETSC_PREFER_FORTRAN_FORMEMCPY)
 81:       fortrancopy_(&len,(PetscScalar*)b,(PetscScalar*)a);
 82: #else
 83:       int         i;
 84:       PetscScalar *x = (PetscScalar*)b, *y = (PetscScalar*)a;
 85:       for (i=0; i<len; i++) y[i] = x[i];
 86: #endif
 87:     } else {
 88:       memcpy((char*)(a),(char*)(b),n);
 89:     }
 90: #else
 91:     memcpy((char*)(a),(char*)(b),n);
 92: #endif
 93:   }
 94:   return(0);
 95: }

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

100:    Not Collective

102:    Input Parameters:
103: +  b - pointer to initial memory space
104: .  bi - offset of initial memory space (in elementary chunk sizes)
105: .  bs - length (in elementary chunk sizes) of space to copy
106: -  dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL

108:    Output Parameters:
109: +  a - pointer to result memory space
110: -  ai - offset of result memory space (in elementary chunk sizes)

112:    Level: intermediate

114:    Note:
115:    This routine is analogous to PetscMemcpy(), except when the data type is 
116:    PETSC_LOGICAL.

118:    Concepts: memory^comparing
119:    Concepts: comparing^memory

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

123: @*/
124: int PetscBitMemcpy(void *a,int ai,const void *b,int bi,int bs,PetscDataType dtype)
125: {
126:   char *aa = (char *)a,*bb = (char *)b;
127:   int  dsize,ierr;

130:   if (dtype != PETSC_LOGICAL) {
131:     PetscDataTypeGetSize(dtype,&dsize);
132:     PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
133:   } else {
134:     PetscBT at = (PetscBT) a,bt = (PetscBT) b;
135:     int i;
136:     for (i=0; i<bs; i++) {
137:       if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
138:       else                        PetscBTClear(at,ai+i);
139:     }
140:   }
141:   return(0);
142: }

144: /*@C
145:    PetscMemzero - Zeros the specified memory.

147:    Not Collective

149:    Input Parameters:
150: +  a - pointer to beginning memory location
151: -  n - length (in bytes) of memory to initialize

153:    Level: intermediate

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

159:    Concepts: memory^zeroing
160:    Concepts: zeroing^memory

162: .seealso: PetscMemcpy()
163: @*/
164: int PetscMemzero(void *a,int n)
165: {
167:   if (n < 0) SETERRQ(1,"Memory length must be >= 0");
168:   if (n > 0) {
169: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
170:     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
171:       int         i,len = n/sizeof(PetscScalar);
172:       PetscScalar *x = (PetscScalar*)a;
173:       for (i=0; i<len; i++) x[i] = 0.0;
174:     } else {
175: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
176:     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
177:       int len = n/sizeof(PetscScalar);
178:       fortranzero_(&len,(PetscScalar*)a);
179:     } else {
180: #endif
181: #if defined(PETSC_PREFER_BZERO)
182:       bzero((char *)a,n);
183: #else
184:       memset((char*)a,0,n);
185: #endif
186: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
187:     }
188: #endif
189:   }
190:   return(0);
191: }

193: /*@C
194:    PetscMemcmp - Compares two byte streams in memory.

196:    Not Collective

198:    Input Parameters:
199: +  str1 - Pointer to the first byte stream
200: .  str2 - Pointer to the second byte stream
201: -  len  - The length of the byte stream
202:          (both str1 and str2 are assumed to be of length len)

204:    Output Parameters:
205: .   e - PETSC_TRUE if equal else PETSC_FALSE.

207:    Level: intermediate

209:    Note: 
210:    This routine is anologous to memcmp()
211: @*/
212: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
213: {
214:   int r;

217:   r = memcmp((char *)str1,(char *)str2,len);
218:   if (!r) *e = PETSC_TRUE;
219:   else    *e = PETSC_FALSE;
220:   return(0);
221: }

223: /*@C
224:    PetscMemmove - Copies n bytes, beginning at location b, to the space
225:    beginning at location a. Copying  between regions that overlap will
226:    take place correctly.

228:    Not Collective

230:    Input Parameters:
231: +  b - pointer to initial memory space
232: -  n - length (in bytes) of space to copy

234:    Output Parameter:
235: .  a - pointer to copy space

237:    Level: intermediate

239:    Note:
240:    This routine is analogous to memmove().

242:    Contributed by: Matthew Knepley

244:    Concepts: memory^copying with overlap
245:    Concepts: copying^memory with overlap

247: .seealso: PetscMemcpy()
248: @*/
249: int PetscMemmove(void *a,void *b,int n)
250: {
252: #if !defined(PETSC_HAVE_MEMMOVE)
253:   if (a < b) {
254:     if (a <= b - n) {
255:       memcpy(a,b,n);
256:     } else {
257:       memcpy(a,b,(int)(b - a));
258:       PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
259:     }
260:   }  else {
261:     if (b <= a - n) {
262:       memcpy(a,b,n);
263:     } else {
264:       memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
265:       PetscMemmove(a,b,n - (int)(a - b));
266:     }
267:   }
268: #else
269:   memmove((char*)(a),(char*)(b),n);
270: #endif
271:   return(0);
272: }