Actual source code: memc.c
1: /*$Id: memc.c,v 1.69 2001/09/07 20:08:33 bsmith Exp $*/
2: /*
3: We define the memory operations here. The reason we just do not use
4: the standard memory routines in the PETSc code is that on some machines
5: they are broken.
7: */
8: #include petsc.h
9: /*
10: On the IBM Rs6000 using the Gnu G++ compiler you may have to include
11: <string.h> instead of <memory.h>
12: */
13: #include <memory.h>
14: #if defined(PETSC_HAVE_STRINGS_H)
15: #include <strings.h>
16: #endif
17: #if defined(PETSC_HAVE_STRING_H)
18: #include <string.h>
19: #endif
20: #if defined(PETSC_HAVE_STDLIB_H)
21: #include <stdlib.h>
22: #endif
23: #include "petscfix.h"
24: #include petscbt.h
25: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
26: #include petscblaslapack.h
27: #endif
29: /*@C
30: PetscMemcpy - Copies n bytes, beginning at location b, to the space
31: beginning at location a. The two memory regions CANNOT overlap, use
32: PetscMemmove() in that case.
34: Not Collective
36: Input Parameters:
37: + b - pointer to initial memory space
38: - n - length (in bytes) of space to copy
40: Output Parameter:
41: . a - pointer to copy space
43: Level: intermediate
45: Compile Option:
46: PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used
47: for memory copies on double precision values.
49: Note:
50: This routine is analogous to memcpy().
52: Concepts: memory^copying
53: Concepts: copying^memory
54:
55: .seealso: PetscMemmove()
57: @*/
58: int PetscMemcpy(void *a,const void *b,int n)
59: {
60: unsigned long al = (unsigned long) a,bl = (unsigned long) b;
61: unsigned long nl = (unsigned long) n;
64: if (a != b) {
65: #if !defined(PETSC_HAVE_CRAY90_POINTER)
66: if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
67: SETERRQ(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()n
68: or make sure your copy regions and lengths are correct");
69: }
70: #endif
71: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) && !defined(PETSC_USE_COMPLEX)
72: # if defined(HAVE_DOUBLE_ALIGN)
73: if (!(((long) a) % 8) && !(n % 8)) {
74: # else
75: if (!(((long) a) % 4) && !(n % 8)) {
76: #endif
77: int one = 1;
78: int len = n/sizeof(PetscScalar);
79: BLcopy_(&len,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
80: } else {
81: memcpy((char*)(a),(char*)(b),n);
82: }
83: #else
84: memcpy((char*)(a),(char*)(b),n);
85: #endif
86: }
87: return(0);
88: }
90: /*@C
91: PetscBitMemcpy - Copies an amount of data. This can include bit data.
93: Not Collective
95: Input Parameters:
96: + b - pointer to initial memory space
97: . bi - offset of initial memory space (in elementary chunk sizes)
98: . bs - length (in elementary chunk sizes) of space to copy
99: - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
101: Output Parameters:
102: + a - pointer to result memory space
103: - ai - offset of result memory space (in elementary chunk sizes)
105: Level: intermediate
107: Note:
108: This routine is analogous to PetscMemcpy(), except when the data type is
109: PETSC_LOGICAL.
111: Concepts: memory^comparing
112: Concepts: comparing^memory
114: .seealso: PetscMemmove(), PetscMemcpy()
116: @*/
117: int PetscBitMemcpy(void *a,int ai,const void *b,int bi,int bs,PetscDataType dtype)
118: {
119: char *aa = (char *)a,*bb = (char *)b;
120: int dsize,ierr;
123: if (dtype != PETSC_LOGICAL) {
124: PetscDataTypeGetSize(dtype,&dsize);
125: PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
126: } else {
127: PetscBT at = (PetscBT) a,bt = (PetscBT) b;
128: int i;
129: for (i=0; i<bs; i++) {
130: if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
131: else PetscBTClear(at,ai+i);
132: }
133: }
134: return(0);
135: }
137: /*@C
138: PetscMemzero - Zeros the specified memory.
140: Not Collective
142: Input Parameters:
143: + a - pointer to beginning memory location
144: - n - length (in bytes) of memory to initialize
146: Level: intermediate
148: Compile Option:
149: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
150: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
152: Concepts: memory^zeroing
153: Concepts: zeroing^memory
155: .seealso: PetscMemcpy()
156: @*/
157: int PetscMemzero(void *a,int n)
158: {
160: if (n < 0) SETERRQ(1,"Memory length must be >= 0");
161: if (n > 0) {
162: #if defined(PETSC_PREFER_BZERO)
163: bzero((char *)a,n);
164: #else
165: memset((char*)a,0,n);
166: #endif
167: }
168: return(0);
169: }
171: /*@C
172: PetscMemcmp - Compares two byte streams in memory.
174: Not Collective
176: Input Parameters:
177: + str1 - Pointer to the first byte stream
178: . str2 - Pointer to the second byte stream
179: - len - The length of the byte stream
180: (both str1 and str2 are assumed to be of length len)
182: Output Parameters:
183: . e - PETSC_TRUE if equal else PETSC_FALSE.
185: Level: intermediate
187: Note:
188: This routine is anologous to memcmp()
189: @*/
190: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
191: {
192: int r;
195: r = memcmp((char *)str1,(char *)str2,len);
196: if (!r) *e = PETSC_TRUE;
197: else *e = PETSC_FALSE;
198: return(0);
199: }
201: /*@C
202: PetscMemmove - Copies n bytes, beginning at location b, to the space
203: beginning at location a. Copying between regions that overlap will
204: take place correctly.
206: Not Collective
208: Input Parameters:
209: + b - pointer to initial memory space
210: - n - length (in bytes) of space to copy
212: Output Parameter:
213: . a - pointer to copy space
215: Level: intermediate
217: Note:
218: This routine is analogous to memmove().
220: Contributed by: Matthew Knepley
222: Concepts: memory^copying with overlap
223: Concepts: copying^memory with overlap
225: .seealso: PetscMemcpy()
226: @*/
227: int PetscMemmove(void *a,void *b,int n)
228: {
230: #if !defined(PETSC_HAVE_MEMMOVE)
231: if (a < b) {
232: if (a <= b - n) {
233: memcpy(a,b,n);
234: } else {
235: memcpy(a,b,(int)(b - a));
236: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
237: }
238: } else {
239: if (b <= a - n) {
240: memcpy(a,b,n);
241: } else {
242: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
243: PetscMemmove(a,b,n - (int)(a - b));
244: }
245: }
246: #else
247: memmove((char*)(a),(char*)(b),n);
248: #endif
249: return(0);
250: }