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
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: SETERRQ3(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()\n\
73: or make sure your copy regions and lengths are correct. \n\
74: Length (bytes) %ld first address %ld second address %ld",nl,al,bl);
75: }
76: #endif
77: #if (defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) || defined(PETSC_PREFER_COPY_FOR_MEMCPY) || defined(PETSC_PREFER_FORTRAN_FORMEMCPY))
78: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
79: int len = n/sizeof(PetscScalar);
80: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
81: int one = 1;
82: BLcopy_(&len,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
83: #elif defined(PETSC_PREFER_FORTRAN_FORMEMCPY)
84: fortrancopy_(&len,(PetscScalar*)b,(PetscScalar*)a);
85: #else
86: int i;
87: PetscScalar *x = (PetscScalar*)b, *y = (PetscScalar*)a;
88: for (i=0; i<len; i++) y[i] = x[i];
89: #endif
90: } else {
91: memcpy((char*)(a),(char*)(b),n);
92: }
93: #else
94: memcpy((char*)(a),(char*)(b),n);
95: #endif
96: }
97: return(0);
98: }
102: /*@C
103: PetscBitMemcpy - Copies an amount of data. This can include bit data.
105: Not Collective
107: Input Parameters:
108: + b - pointer to initial memory space
109: . bi - offset of initial memory space (in elementary chunk sizes)
110: . bs - length (in elementary chunk sizes) of space to copy
111: - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
113: Output Parameters:
114: + a - pointer to result memory space
115: - ai - offset of result memory space (in elementary chunk sizes)
117: Level: intermediate
119: Note:
120: This routine is analogous to PetscMemcpy(), except when the data type is
121: PETSC_LOGICAL.
123: Concepts: memory^comparing
124: Concepts: comparing^memory
126: .seealso: PetscMemmove(), PetscMemcpy()
128: @*/
129: int PetscBitMemcpy(void *a,int ai,const void *b,int bi,int bs,PetscDataType dtype)
130: {
131: char *aa = (char *)a,*bb = (char *)b;
132: int dsize,ierr;
135: if (dtype != PETSC_LOGICAL) {
136: PetscDataTypeGetSize(dtype,&dsize);
137: PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
138: } else {
139: PetscBT at = (PetscBT) a,bt = (PetscBT) b;
140: int i;
141: for (i=0; i<bs; i++) {
142: if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
143: else PetscBTClear(at,ai+i);
144: }
145: }
146: return(0);
147: }
151: /*@C
152: PetscMemzero - Zeros the specified memory.
154: Not Collective
156: Input Parameters:
157: + a - pointer to beginning memory location
158: - n - length (in bytes) of memory to initialize
160: Level: intermediate
162: Compile Option:
163: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
164: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
166: Concepts: memory^zeroing
167: Concepts: zeroing^memory
169: .seealso: PetscMemcpy()
170: @*/
171: int PetscMemzero(void *a,int n)
172: {
174: if (n < 0) SETERRQ(1,"Memory length must be >= 0");
175: if (n > 0) {
176: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
177: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
178: int i,len = n/sizeof(PetscScalar);
179: PetscScalar *x = (PetscScalar*)a;
180: for (i=0; i<len; i++) x[i] = 0.0;
181: } else {
182: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
183: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
184: int len = n/sizeof(PetscScalar);
185: fortranzero_(&len,(PetscScalar*)a);
186: } else {
187: #endif
188: #if defined(PETSC_PREFER_BZERO)
189: bzero((char *)a,n);
190: #else
191: memset((char*)a,0,n);
192: #endif
193: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
194: }
195: #endif
196: }
197: return(0);
198: }
202: /*@C
203: PetscMemcmp - Compares two byte streams in memory.
205: Not Collective
207: Input Parameters:
208: + str1 - Pointer to the first byte stream
209: . str2 - Pointer to the second byte stream
210: - len - The length of the byte stream
211: (both str1 and str2 are assumed to be of length len)
213: Output Parameters:
214: . e - PETSC_TRUE if equal else PETSC_FALSE.
216: Level: intermediate
218: Note:
219: This routine is anologous to memcmp()
220: @*/
221: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
222: {
223: int r;
226: r = memcmp((char *)str1,(char *)str2,len);
227: if (!r) *e = PETSC_TRUE;
228: else *e = PETSC_FALSE;
229: return(0);
230: }
234: /*@C
235: PetscMemmove - Copies n bytes, beginning at location b, to the space
236: beginning at location a. Copying between regions that overlap will
237: take place correctly.
239: Not Collective
241: Input Parameters:
242: + b - pointer to initial memory space
243: - n - length (in bytes) of space to copy
245: Output Parameter:
246: . a - pointer to copy space
248: Level: intermediate
250: Note:
251: This routine is analogous to memmove().
253: Contributed by: Matthew Knepley
255: Concepts: memory^copying with overlap
256: Concepts: copying^memory with overlap
258: .seealso: PetscMemcpy()
259: @*/
260: int PetscMemmove(void *a,void *b,int n)
261: {
263: #if !defined(PETSC_HAVE_MEMMOVE)
264: if (a < b) {
265: if (a <= b - n) {
266: memcpy(a,b,n);
267: } else {
268: memcpy(a,b,(int)(b - a));
269: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
270: }
271: } else {
272: if (b <= a - n) {
273: memcpy(a,b,n);
274: } else {
275: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
276: PetscMemmove(a,b,n - (int)(a - b));
277: }
278: }
279: #else
280: memmove((char*)(a),(char*)(b),n);
281: #endif
282: return(0);
283: }