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: #if defined(PETSC_HAVE_MEMORY_H)
17: #include <memory.h>
18: #endif
19: #if defined(PETSC_HAVE_STRINGS_H)
20: #include <strings.h>
21: #endif
22: #if defined(PETSC_HAVE_STRING_H)
23: #include <string.h>
24: #endif
25: #if defined(PETSC_HAVE_STDLIB_H)
26: #include <stdlib.h>
27: #endif
28: #include "petscfix.h"
29: #include petscbt.h
30: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
31: #include petscblaslapack.h
32: #endif
36: /*@
37: PetscMemcpy - Copies n bytes, beginning at location b, to the space
38: beginning at location a. The two memory regions CANNOT overlap, use
39: PetscMemmove() in that case.
41: Not Collective
43: Input Parameters:
44: + b - pointer to initial memory space
45: - n - length (in bytes) of space to copy
47: Output Parameter:
48: . a - pointer to copy space
50: Level: intermediate
52: Compile Option:
53: PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used
54: for memory copies on double precision values.
55: PETSC_PREFER_COPY_FOR_MEMCPY will cause C code to be used
56: for memory copies on double precision values.
57: PETSC_PREFER_FORTRAN_FORMEMCPY will cause Fortran code to be used
58: for memory copies on double precision values.
60: Note:
61: This routine is analogous to memcpy().
63: Concepts: memory^copying
64: Concepts: copying^memory
65:
66: .seealso: PetscMemmove()
68: @*/
69: PetscErrorCode PetscMemcpy(void *a,const void *b,size_t n)
70: {
71: unsigned long al = (unsigned long) a,bl = (unsigned long) b;
72: unsigned long nl = (unsigned long) n;
75: if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
76: if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
77: if (a != b) {
78: #if !defined(PETSC_HAVE_CRAY90_POINTER)
79: if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
80: SETERRQ3(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()\n\
81: or make sure your copy regions and lengths are correct. \n\
82: Length (bytes) %ld first address %ld second address %ld",nl,al,bl);
83: }
84: #endif
85: #if (defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) || defined(PETSC_PREFER_COPY_FOR_MEMCPY) || defined(PETSC_PREFER_FORTRAN_FORMEMCPY))
86: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
87: size_t len = n/sizeof(PetscScalar);
88: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
89: PetscBLASInt one = 1,blen = PetscBLASIntCast(len);
90: BLAScopy_(&blen,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
91: #elif defined(PETSC_PREFER_FORTRAN_FORMEMCPY)
92: fortrancopy_(&len,(PetscScalar*)b,(PetscScalar*)a);
93: #else
94: size_t i;
95: PetscScalar *x = (PetscScalar*)b, *y = (PetscScalar*)a;
96: for (i=0; i<len; i++) y[i] = x[i];
97: #endif
98: } else {
99: memcpy((char*)(a),(char*)(b),n);
100: }
101: #elif defined(PETSC_HAVE__INTEL_FAST_MEMCPY)
102: _intel_fast_memcpy((char*)(a),(char*)(b),n);
103: #else
104: memcpy((char*)(a),(char*)(b),n);
105: #endif
106: }
107: return(0);
108: }
112: /*@C
113: PetscBitMemcpy - Copies an amount of data. This can include bit data.
115: Not Collective
117: Input Parameters:
118: + b - pointer to initial memory space
119: . bi - offset of initial memory space (in elementary chunk sizes)
120: . bs - length (in elementary chunk sizes) of space to copy
121: - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
123: Output Parameters:
124: + a - pointer to result memory space
125: - ai - offset of result memory space (in elementary chunk sizes)
127: Level: intermediate
129: Note:
130: This routine is analogous to PetscMemcpy(), except when the data type is
131: PETSC_LOGICAL.
133: Concepts: memory^comparing
134: Concepts: comparing^memory
136: .seealso: PetscMemmove(), PetscMemcpy()
138: @*/
139: PetscErrorCode PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype)
140: {
141: char *aa = (char *)a,*bb = (char *)b;
142: size_t dsize;
146: if (bs > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
147: if (bs > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
148: if (dtype != PETSC_LOGICAL) {
149: PetscDataTypeGetSize(dtype,&dsize);
150: PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
151: } else {
152: PetscBT at = (PetscBT) a;
153: PetscBT bt = (PetscBT) b;
154: PetscInt i;
155: for (i=0; i<bs; i++) {
156: if (PetscBTLookup(bt,bi+i)) {PetscBTSet(at,ai+i);}
157: else {PetscBTClear(at,ai+i);}
158: }
159: }
160: return(0);
161: }
165: /*@
166: PetscMemzero - Zeros the specified memory.
168: Not Collective
170: Input Parameters:
171: + a - pointer to beginning memory location
172: - n - length (in bytes) of memory to initialize
174: Level: intermediate
176: Compile Option:
177: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
178: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
180: Concepts: memory^zeroing
181: Concepts: zeroing^memory
183: .seealso: PetscMemcpy()
184: @*/
185: PetscErrorCode PetscMemzero(void *a,size_t n)
186: {
188: if (n > 0) {
189: if (!a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to zero at a null pointer");
190: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
191: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
192: size_t i,len = n/sizeof(PetscScalar);
193: PetscScalar *x = (PetscScalar*)a;
194: for (i=0; i<len; i++) x[i] = 0.0;
195: } else {
196: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
197: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
198: PetscInt len = n/sizeof(PetscScalar);
199: fortranzero_(&len,(PetscScalar*)a);
200: } else {
201: #endif
202: #if defined(PETSC_PREFER_BZERO)
203: bzero((char *)a,n);
204: #elif defined (PETSC_HAVE__INTEL_FAST_MEMSET)
205: _intel_fast_memset((char*)a,0,n);
206: #else
207: memset((char*)a,0,n);
208: #endif
209: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
210: }
211: #endif
212: }
213: return(0);
214: }
218: /*@
219: PetscMemcmp - Compares two byte streams in memory.
221: Not Collective
223: Input Parameters:
224: + str1 - Pointer to the first byte stream
225: . str2 - Pointer to the second byte stream
226: - len - The length of the byte stream
227: (both str1 and str2 are assumed to be of length len)
229: Output Parameters:
230: . e - PETSC_TRUE if equal else PETSC_FALSE.
232: Level: intermediate
234: Note:
235: This routine is anologous to memcmp()
236: @*/
237: PetscErrorCode PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
238: {
239: int r;
242: if (len > 0 && !str1) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
243: if (len > 0 && !str2) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
244: r = memcmp((char *)str1,(char *)str2,len);
245: if (!r) *e = PETSC_TRUE;
246: else *e = PETSC_FALSE;
247: return(0);
248: }
252: /*@
253: PetscMemmove - Copies n bytes, beginning at location b, to the space
254: beginning at location a. Copying between regions that overlap will
255: take place correctly.
257: Not Collective
259: Input Parameters:
260: + b - pointer to initial memory space
261: - n - length (in bytes) of space to copy
263: Output Parameter:
264: . a - pointer to copy space
266: Level: intermediate
268: Note:
269: This routine is analogous to memmove().
271: Since b can overlap with a, b cannot be declared as const
273: Concepts: memory^copying with overlap
274: Concepts: copying^memory with overlap
276: .seealso: PetscMemcpy()
277: @*/
278: PetscErrorCode PetscMemmove(void *a,void *b,size_t n)
279: {
281: if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to null pointer");
282: if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
283: #if !defined(PETSC_HAVE_MEMMOVE)
284: if (a < b) {
285: if (a <= b - n) {
286: memcpy(a,b,n);
287: } else {
288: memcpy(a,b,(int)(b - a));
289: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
290: }
291: } else {
292: if (b <= a - n) {
293: memcpy(a,b,n);
294: } else {
295: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
296: PetscMemmove(a,b,n - (int)(a - b));
297: }
298: }
299: #else
300: memmove((char*)(a),(char*)(b),n);
301: #endif
302: return(0);
303: }