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