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: #undef __FUNCT__  
 34: /*@C
 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.

 54:    Note:
 55:    This routine is analogous to memcpy().

 57:   Concepts: memory^copying
 58:   Concepts: copying^memory
 59:   
 60: .seealso: PetscMemmove()

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

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

 99: #undef __FUNCT__  
101: /*@C
102:    PetscBitMemcpy - Copies an amount of data. This can include bit data.

104:    Not Collective

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

112:    Output Parameters:
113: +  a - pointer to result memory space
114: -  ai - offset of result memory space (in elementary chunk sizes)

116:    Level: intermediate

118:    Note:
119:    This routine is analogous to PetscMemcpy(), except when the data type is 
120:    PETSC_LOGICAL.

122:    Concepts: memory^comparing
123:    Concepts: comparing^memory

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

127: @*/
128: int PetscBitMemcpy(void *a,int ai,const void *b,int bi,int bs,PetscDataType dtype)
129: {
130:   char *aa = (char *)a,*bb = (char *)b;
131:   int  dsize,ierr;

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

148: #undef __FUNCT__  
150: /*@C
151:    PetscMemzero - Zeros the specified memory.

153:    Not Collective

155:    Input Parameters:
156: +  a - pointer to beginning memory location
157: -  n - length (in bytes) of memory to initialize

159:    Level: intermediate

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

165:    Concepts: memory^zeroing
166:    Concepts: zeroing^memory

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

199: #undef __FUNCT__  
201: /*@C
202:    PetscMemcmp - Compares two byte streams in memory.

204:    Not Collective

206:    Input Parameters:
207: +  str1 - Pointer to the first byte stream
208: .  str2 - Pointer to the second byte stream
209: -  len  - The length of the byte stream
210:          (both str1 and str2 are assumed to be of length len)

212:    Output Parameters:
213: .   e - PETSC_TRUE if equal else PETSC_FALSE.

215:    Level: intermediate

217:    Note: 
218:    This routine is anologous to memcmp()
219: @*/
220: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
221: {
222:   int r;

225:   r = memcmp((char *)str1,(char *)str2,len);
226:   if (!r) *e = PETSC_TRUE;
227:   else    *e = PETSC_FALSE;
228:   return(0);
229: }

231: #undef __FUNCT__  
233: /*@C
234:    PetscMemmove - Copies n bytes, beginning at location b, to the space
235:    beginning at location a. Copying  between regions that overlap will
236:    take place correctly.

238:    Not Collective

240:    Input Parameters:
241: +  b - pointer to initial memory space
242: -  n - length (in bytes) of space to copy

244:    Output Parameter:
245: .  a - pointer to copy space

247:    Level: intermediate

249:    Note:
250:    This routine is analogous to memmove().

252:    Contributed by: Matthew Knepley

254:    Concepts: memory^copying with overlap
255:    Concepts: copying^memory with overlap

257: .seealso: PetscMemcpy()
258: @*/
259: int PetscMemmove(void *a,void *b,int n)
260: {
262: #if !defined(PETSC_HAVE_MEMMOVE)
263:   if (a < b) {
264:     if (a <= b - n) {
265:       memcpy(a,b,n);
266:     } else {
267:       memcpy(a,b,(int)(b - a));
268:       PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
269:     }
270:   }  else {
271:     if (b <= a - n) {
272:       memcpy(a,b,n);
273:     } else {
274:       memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
275:       PetscMemmove(a,b,n - (int)(a - b));
276:     }
277:   }
278: #else
279:   memmove((char*)(a),(char*)(b),n);
280: #endif
281:   return(0);
282: }