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: }