Actual source code: memc.c
1: #define PETSC_DLL
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.
53: PETSC_PREFER_COPY_FOR_MEMCPY will cause C code to be used
54: for memory copies on double precision values.
55: PETSC_PREFER_FORTRAN_FORMEMCPY will cause Fortran code to be used
56: for memory copies on double precision values.
58: Note:
59: This routine is analogous to memcpy().
61: Concepts: memory^copying
62: Concepts: copying^memory
63:
64: .seealso: PetscMemmove()
66: @*/
67: PetscErrorCode PETSC_DLLEXPORT PetscMemcpy(void *a,const void *b,size_t n)
68: {
69: unsigned long al = (unsigned long) a,bl = (unsigned long) b;
70: unsigned long nl = (unsigned long) n;
73: if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
74: if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
75: if (a != b) {
76: #if !defined(PETSC_HAVE_CRAY90_POINTER)
77: if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
78: SETERRQ3(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()\n\
79: or make sure your copy regions and lengths are correct. \n\
80: Length (bytes) %ld first address %ld second address %ld",nl,al,bl);
81: }
82: #endif
83: #if (defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) || defined(PETSC_PREFER_COPY_FOR_MEMCPY) || defined(PETSC_PREFER_FORTRAN_FORMEMCPY))
84: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
85: size_t len = n/sizeof(PetscScalar);
86: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
87: PetscBLASInt blen = (PetscBLASInt) len,one = 1;
88: BLAScopy_(&blen,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
89: #elif defined(PETSC_PREFER_FORTRAN_FORMEMCPY)
90: fortrancopy_(&len,(PetscScalar*)b,(PetscScalar*)a);
91: #else
92: size_t i;
93: PetscScalar *x = (PetscScalar*)b, *y = (PetscScalar*)a;
94: for (i=0; i<len; i++) y[i] = x[i];
95: #endif
96: } else {
97: memcpy((char*)(a),(char*)(b),n);
98: }
99: #else
100: memcpy((char*)(a),(char*)(b),n);
101: #endif
102: }
103: return(0);
104: }
108: /*@C
109: PetscBitMemcpy - Copies an amount of data. This can include bit data.
111: Not Collective
113: Input Parameters:
114: + b - pointer to initial memory space
115: . bi - offset of initial memory space (in elementary chunk sizes)
116: . bs - length (in elementary chunk sizes) of space to copy
117: - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
119: Output Parameters:
120: + a - pointer to result memory space
121: - ai - offset of result memory space (in elementary chunk sizes)
123: Level: intermediate
125: Note:
126: This routine is analogous to PetscMemcpy(), except when the data type is
127: PETSC_LOGICAL.
129: Concepts: memory^comparing
130: Concepts: comparing^memory
132: .seealso: PetscMemmove(), PetscMemcpy()
134: @*/
135: PetscErrorCode PETSC_DLLEXPORT PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype)
136: {
137: char *aa = (char *)a,*bb = (char *)b;
138: PetscInt dsize;
142: if (bs > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
143: if (bs > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
144: if (dtype != PETSC_LOGICAL) {
145: PetscDataTypeGetSize(dtype,&dsize);
146: PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
147: } else {
148: PetscBT at = (PetscBT) a;
149: PetscBT bt = (PetscBT) b;
150: PetscInt i;
151: for (i=0; i<bs; i++) {
152: if (PetscBTLookup(bt,bi+i)) {PetscBTSet(at,ai+i);}
153: else {PetscBTClear(at,ai+i);}
154: }
155: }
156: return(0);
157: }
161: /*@C
162: PetscMemzero - Zeros the specified memory.
164: Not Collective
166: Input Parameters:
167: + a - pointer to beginning memory location
168: - n - length (in bytes) of memory to initialize
170: Level: intermediate
172: Compile Option:
173: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
174: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
176: Concepts: memory^zeroing
177: Concepts: zeroing^memory
179: .seealso: PetscMemcpy()
180: @*/
181: PetscErrorCode PETSC_DLLEXPORT PetscMemzero(void *a,size_t n)
182: {
184: if (n > 0) {
185: if (!a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to zero at a null pointer");
186: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
187: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
188: size_t i,len = n/sizeof(PetscScalar);
189: PetscScalar *x = (PetscScalar*)a;
190: for (i=0; i<len; i++) x[i] = 0.0;
191: } else {
192: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
193: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
194: PetscInt len = n/sizeof(PetscScalar);
195: fortranzero_(&len,(PetscScalar*)a);
196: } else {
197: #endif
198: #if defined(PETSC_PREFER_BZERO)
199: bzero((char *)a,n);
200: #else
201: memset((char*)a,0,n);
202: #endif
203: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
204: }
205: #endif
206: }
207: return(0);
208: }
212: /*@C
213: PetscMemcmp - Compares two byte streams in memory.
215: Not Collective
217: Input Parameters:
218: + str1 - Pointer to the first byte stream
219: . str2 - Pointer to the second byte stream
220: - len - The length of the byte stream
221: (both str1 and str2 are assumed to be of length len)
223: Output Parameters:
224: . e - PETSC_TRUE if equal else PETSC_FALSE.
226: Level: intermediate
228: Note:
229: This routine is anologous to memcmp()
230: @*/
231: PetscErrorCode PETSC_DLLEXPORT PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
232: {
233: int r;
236: if (len > 0 && !str1) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
237: if (len > 0 && !str2) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
238: r = memcmp((char *)str1,(char *)str2,len);
239: if (!r) *e = PETSC_TRUE;
240: else *e = PETSC_FALSE;
241: return(0);
242: }
246: /*@C
247: PetscMemmove - Copies n bytes, beginning at location b, to the space
248: beginning at location a. Copying between regions that overlap will
249: take place correctly.
251: Not Collective
253: Input Parameters:
254: + b - pointer to initial memory space
255: - n - length (in bytes) of space to copy
257: Output Parameter:
258: . a - pointer to copy space
260: Level: intermediate
262: Note:
263: This routine is analogous to memmove().
265: Concepts: memory^copying with overlap
266: Concepts: copying^memory with overlap
268: .seealso: PetscMemcpy()
269: @*/
270: PetscErrorCode PETSC_DLLEXPORT PetscMemmove(void *a,void *b,size_t n)
271: {
273: if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to null pointer");
274: if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
275: #if !defined(PETSC_HAVE_MEMMOVE)
276: if (a < b) {
277: if (a <= b - n) {
278: memcpy(a,b,n);
279: } else {
280: memcpy(a,b,(int)(b - a));
281: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
282: }
283: } else {
284: if (b <= a - n) {
285: memcpy(a,b,n);
286: } else {
287: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
288: PetscMemmove(a,b,n - (int)(a - b));
289: }
290: }
291: #else
292: memmove((char*)(a),(char*)(b),n);
293: #endif
294: return(0);
295: }