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;
140: PetscBT bt = (PetscBT) b;
141: int i;
142: for (i=0; i<bs; i++) {
143: if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
144: else PetscBTClear(at,ai+i);
145: }
146: }
147: return(0);
148: }
152: /*@C
153: PetscMemzero - Zeros the specified memory.
155: Not Collective
157: Input Parameters:
158: + a - pointer to beginning memory location
159: - n - length (in bytes) of memory to initialize
161: Level: intermediate
163: Compile Option:
164: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
165: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
167: Concepts: memory^zeroing
168: Concepts: zeroing^memory
170: .seealso: PetscMemcpy()
171: @*/
172: int PetscMemzero(void *a,int n)
173: {
175: if (n < 0) SETERRQ(1,"Memory length must be >= 0");
176: if (n > 0) {
177: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
178: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
179: int i,len = n/sizeof(PetscScalar);
180: PetscScalar *x = (PetscScalar*)a;
181: for (i=0; i<len; i++) x[i] = 0.0;
182: } else {
183: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
184: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
185: int len = n/sizeof(PetscScalar);
186: fortranzero_(&len,(PetscScalar*)a);
187: } else {
188: #endif
189: #if defined(PETSC_PREFER_BZERO)
190: bzero((char *)a,n);
191: #else
192: memset((char*)a,0,n);
193: #endif
194: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
195: }
196: #endif
197: }
198: return(0);
199: }
203: /*@C
204: PetscMemcmp - Compares two byte streams in memory.
206: Not Collective
208: Input Parameters:
209: + str1 - Pointer to the first byte stream
210: . str2 - Pointer to the second byte stream
211: - len - The length of the byte stream
212: (both str1 and str2 are assumed to be of length len)
214: Output Parameters:
215: . e - PETSC_TRUE if equal else PETSC_FALSE.
217: Level: intermediate
219: Note:
220: This routine is anologous to memcmp()
221: @*/
222: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
223: {
224: int r;
227: r = memcmp((char *)str1,(char *)str2,len);
228: if (!r) *e = PETSC_TRUE;
229: else *e = PETSC_FALSE;
230: return(0);
231: }
235: /*@C
236: PetscMemmove - Copies n bytes, beginning at location b, to the space
237: beginning at location a. Copying between regions that overlap will
238: take place correctly.
240: Not Collective
242: Input Parameters:
243: + b - pointer to initial memory space
244: - n - length (in bytes) of space to copy
246: Output Parameter:
247: . a - pointer to copy space
249: Level: intermediate
251: Note:
252: This routine is analogous to memmove().
254: Contributed by: Matthew Knepley
256: Concepts: memory^copying with overlap
257: Concepts: copying^memory with overlap
259: .seealso: PetscMemcpy()
260: @*/
261: int PetscMemmove(void *a,void *b,int n)
262: {
264: #if !defined(PETSC_HAVE_MEMMOVE)
265: if (a < b) {
266: if (a <= b - n) {
267: memcpy(a,b,n);
268: } else {
269: memcpy(a,b,(int)(b - a));
270: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
271: }
272: } else {
273: if (b <= a - n) {
274: memcpy(a,b,n);
275: } else {
276: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
277: PetscMemmove(a,b,n - (int)(a - b));
278: }
279: }
280: #else
281: memmove((char*)(a),(char*)(b),n);
282: #endif
283: return(0);
284: }