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: /*@
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 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: #elif defined(PETSC_HAVE__INTEL_FAST_MEMCPY)
100: _intel_fast_memcpy((char*)(a),(char*)(b),n);
101: #else
102: memcpy((char*)(a),(char*)(b),n);
103: #endif
104: }
105: return(0);
106: }
110: /*@C
111: PetscBitMemcpy - Copies an amount of data. This can include bit data.
113: Not Collective
115: Input Parameters:
116: + b - pointer to initial memory space
117: . bi - offset of initial memory space (in elementary chunk sizes)
118: . bs - length (in elementary chunk sizes) of space to copy
119: - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
121: Output Parameters:
122: + a - pointer to result memory space
123: - ai - offset of result memory space (in elementary chunk sizes)
125: Level: intermediate
127: Note:
128: This routine is analogous to PetscMemcpy(), except when the data type is
129: PETSC_LOGICAL.
131: Concepts: memory^comparing
132: Concepts: comparing^memory
134: .seealso: PetscMemmove(), PetscMemcpy()
136: @*/
137: PetscErrorCode PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype)
138: {
139: char *aa = (char *)a,*bb = (char *)b;
140: PetscInt dsize;
144: if (bs > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
145: if (bs > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
146: if (dtype != PETSC_LOGICAL) {
147: PetscDataTypeGetSize(dtype,&dsize);
148: PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
149: } else {
150: PetscBT at = (PetscBT) a;
151: PetscBT bt = (PetscBT) b;
152: PetscInt i;
153: for (i=0; i<bs; i++) {
154: if (PetscBTLookup(bt,bi+i)) {PetscBTSet(at,ai+i);}
155: else {PetscBTClear(at,ai+i);}
156: }
157: }
158: return(0);
159: }
163: /*@
164: PetscMemzero - Zeros the specified memory.
166: Not Collective
168: Input Parameters:
169: + a - pointer to beginning memory location
170: - n - length (in bytes) of memory to initialize
172: Level: intermediate
174: Compile Option:
175: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
176: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
178: Concepts: memory^zeroing
179: Concepts: zeroing^memory
181: .seealso: PetscMemcpy()
182: @*/
183: PetscErrorCode PetscMemzero(void *a,size_t n)
184: {
186: if (n > 0) {
187: if (!a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to zero at a null pointer");
188: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
189: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
190: size_t i,len = n/sizeof(PetscScalar);
191: PetscScalar *x = (PetscScalar*)a;
192: for (i=0; i<len; i++) x[i] = 0.0;
193: } else {
194: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
195: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
196: PetscInt len = n/sizeof(PetscScalar);
197: fortranzero_(&len,(PetscScalar*)a);
198: } else {
199: #endif
200: #if defined(PETSC_PREFER_BZERO)
201: bzero((char *)a,n);
202: #elif defined (PETSC_HAVE__INTEL_FAST_MEMSET)
203: _intel_fast_memset((char*)a,0,n);
204: #else
205: memset((char*)a,0,n);
206: #endif
207: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
208: }
209: #endif
210: }
211: return(0);
212: }
216: /*@C
217: PetscMemcmp - Compares two byte streams in memory.
219: Not Collective
221: Input Parameters:
222: + str1 - Pointer to the first byte stream
223: . str2 - Pointer to the second byte stream
224: - len - The length of the byte stream
225: (both str1 and str2 are assumed to be of length len)
227: Output Parameters:
228: . e - PETSC_TRUE if equal else PETSC_FALSE.
230: Level: intermediate
232: Note:
233: This routine is anologous to memcmp()
234: @*/
235: PetscErrorCode PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
236: {
237: int r;
240: if (len > 0 && !str1) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
241: if (len > 0 && !str2) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
242: r = memcmp((char *)str1,(char *)str2,len);
243: if (!r) *e = PETSC_TRUE;
244: else *e = PETSC_FALSE;
245: return(0);
246: }
250: /*@C
251: PetscMemmove - Copies n bytes, beginning at location b, to the space
252: beginning at location a. Copying between regions that overlap will
253: take place correctly.
255: Not Collective
257: Input Parameters:
258: + b - pointer to initial memory space
259: - n - length (in bytes) of space to copy
261: Output Parameter:
262: . a - pointer to copy space
264: Level: intermediate
266: Note:
267: This routine is analogous to memmove().
269: Concepts: memory^copying with overlap
270: Concepts: copying^memory with overlap
272: .seealso: PetscMemcpy()
273: @*/
274: PetscErrorCode PetscMemmove(void *a,void *b,size_t n)
275: {
277: if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to null pointer");
278: if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
279: #if !defined(PETSC_HAVE_MEMMOVE)
280: if (a < b) {
281: if (a <= b - n) {
282: memcpy(a,b,n);
283: } else {
284: memcpy(a,b,(int)(b - a));
285: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
286: }
287: } else {
288: if (b <= a - n) {
289: memcpy(a,b,n);
290: } else {
291: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
292: PetscMemmove(a,b,n - (int)(a - b));
293: }
294: }
295: #else
296: memmove((char*)(a),(char*)(b),n);
297: #endif
298: return(0);
299: }