Actual source code: memc.c
1: /*$Id: memc.c,v 1.67 2001/03/23 23:20:45 balay 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
26: /*@C
27: PetscMemcpy - Copies n bytes, beginning at location b, to the space
28: beginning at location a. The two memory regions CANNOT overlap, use
29: PetscMemmove() in that case.
31: Not Collective
33: Input Parameters:
34: + b - pointer to initial memory space
35: - n - length (in bytes) of space to copy
37: Output Parameter:
38: . a - pointer to copy space
40: Level: intermediate
42: Compile Option:
43: PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used
44: for memory copies on double precision values.
46: Note:
47: This routine is analogous to memcpy().
49: Concepts: memory^copying
50: Concepts: copying^memory
51:
52: .seealso: PetscMemmove()
54: @*/
55: int PetscMemcpy(void *a,const void *b,int n)
56: {
57: unsigned long al = (unsigned long) a,bl = (unsigned long) b;
58: unsigned long nl = (unsigned long) n;
61: #if !defined(PETSC_HAVE_CRAY90_POINTER)
62: if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
63: SETERRQ(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()n
64: or make sure your copy regions and lengths are correct");
65: }
66: #endif
67: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
68: #if defined(PETSC_HAVE_DOUBLE_ALIGN)
69: if (!(((long) a) % 8) && !(n % 8)) {
70: #else
71: if (!(((long) a) % 4) && !(n % 8)) {
72: #endif
73: int one = 1;
74: dcopy_(&n,(Scalar *)a,&one,(Scalar *)b,&one);
75: } else {
76: memcpy((char*)(a),(char*)(b),n);
77: }
78: #else
79: memcpy((char*)(a),(char*)(b),n);
80: #endif
81: return(0);
82: }
84: /*@C
85: PetscBitMemcpy - Copies an amount of data. This can include bit data.
87: Not Collective
89: Input Parameters:
90: + b - pointer to initial memory space
91: . bi - offset of initial memory space (in elementary chunk sizes)
92: . bs - length (in elementary chunk sizes) of space to copy
93: - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
95: Output Parameters:
96: + a - pointer to result memory space
97: - ai - offset of result memory space (in elementary chunk sizes)
99: Level: intermediate
101: Note:
102: This routine is analogous to PetscMemcpy(), except when the data type is
103: PETSC_LOGICAL.
105: Concepts: memory^comparing
106: Concepts: comparing^memory
108: .seealso: PetscMemmove(), PetscMemcpy()
110: @*/
111: int PetscBitMemcpy(void *a,int ai,const void *b,int bi,int bs,PetscDataType dtype)
112: {
113: char *aa = (char *)a,*bb = (char *)b;
114: int dsize,ierr;
117: if (dtype != PETSC_LOGICAL) {
118: PetscDataTypeGetSize(dtype,&dsize);
119: PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
120: } else {
121: PetscBT at = (PetscBT) a,bt = (PetscBT) b;
122: int i;
123: for (i=0; i<bs; i++) {
124: if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
125: else PetscBTClear(at,ai+i);
126: }
127: }
128: return(0);
129: }
131: /*@C
132: PetscMemzero - Zeros the specified memory.
134: Not Collective
136: Input Parameters:
137: + a - pointer to beginning memory location
138: - n - length (in bytes) of memory to initialize
140: Level: intermediate
142: Compile Option:
143: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
144: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
146: Concepts: memory^zeroing
147: Concepts: zeroing^memory
149: .seealso: PetscMemcpy()
150: @*/
151: int PetscMemzero(void *a,int n)
152: {
154: if (n < 0) SETERRQ(1,"Memory length must be >= 0");
155: if (n > 0) {
156: #if defined(PETSC_PREFER_BZERO)
157: bzero((char *)a,n);
158: #else
159: memset((char*)a,0,n);
160: #endif
161: }
162: return(0);
163: }
165: /*@C
166: PetscMemcmp - Compares two byte streams in memory.
168: Not Collective
170: Input Parameters:
171: + str1 - Pointer to the first byte stream
172: . str2 - Pointer to the second byte stream
173: - len - The length of the byte stream
174: (both str1 and str2 are assumed to be of length len)
176: Output Parameters:
177: . e - PETSC_TRUE if equal else PETSC_FALSE.
179: Level: intermediate
181: Note:
182: This routine is anologous to memcmp()
183: @*/
184: int PetscMemcmp(const void *str1,const void *str2,int len,PetscTruth *e)
185: {
186: int r;
189: r = memcmp((char *)str1,(char *)str2,len);
190: if (!r) *e = PETSC_TRUE;
191: else *e = PETSC_FALSE;
192: return(0);
193: }
195: /*@C
196: PetscMemmove - Copies n bytes, beginning at location b, to the space
197: beginning at location a. Copying between regions that overlap will
198: take place correctly.
200: Not Collective
202: Input Parameters:
203: + b - pointer to initial memory space
204: - n - length (in bytes) of space to copy
206: Output Parameter:
207: . a - pointer to copy space
209: Level: intermediate
211: Note:
212: This routine is analogous to memmove().
214: Contributed by: Matthew Knepley
216: Concepts: memory^copying with overlap
217: Concepts: copying^memory with overlap
219: .seealso: PetscMemcpy()
220: @*/
221: int PetscMemmove(void *a,void *b,int n)
222: {
224: #if !defined(PETSC_HAVE_MEMMOVE)
225: if (a < b) {
226: if (a <= b - n) {
227: memcpy(a,b,n);
228: } else {
229: memcpy(a,b,(int)(b - a));
230: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
231: }
232: } else {
233: if (b <= a - n) {
234: memcpy(a,b,n);
235: } else {
236: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
237: PetscMemmove(a,b,n - (int)(a - b));
238: }
239: }
240: #else
241: memmove((char*)(a),(char*)(b),n);
242: #endif
243: return(0);
244: }