Actual source code: memc.c
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: #include src/inline/axpy.h
11: /*
12: On the IBM Rs6000 using the Gnu G++ compiler you may have to include
13: <string.h> instead of <memory.h>
14: */
15: #include <memory.h>
16: #if defined(PETSC_HAVE_STRINGS_H)
17: #include <strings.h>
18: #endif
19: #if defined(PETSC_HAVE_STRING_H)
20: #include <string.h>
21: #endif
22: #if defined(PETSC_HAVE_STDLIB_H)
23: #include <stdlib.h>
24: #endif
25: #include "petscfix.h"
26: #include petscbt.h
27: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
28: #include petscblaslapack.h
29: #endif
33: /*@C
34: PetscMemcpy - Copies n bytes, beginning at location b, to the space
35: beginning at location a. The two memory regions CANNOT overlap, use
36: PetscMemmove() in that case.
38: Not Collective
40: Input Parameters:
41: + b - pointer to initial memory space
42: - n - length (in bytes) of space to copy
44: Output Parameter:
45: . a - pointer to copy space
47: Level: intermediate
49: Compile Option:
50: PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used
51: for memory copies on double precision values.
52: PETSC_PREFER_COPY_FOR_MEMCPY will cause C code to be used
53: for memory copies on double precision values.
54: PETSC_PREFER_FORTRAN_FORMEMCPY will cause Fortran code to be used
55: for memory copies on double precision values.
57: Note:
58: This routine is analogous to memcpy().
60: Concepts: memory^copying
61: Concepts: copying^memory
62:
63: .seealso: PetscMemmove()
65: @*/
66: PetscErrorCode PetscMemcpy(void *a,const void *b,size_t n)
67: {
68: unsigned long al = (unsigned long) a,bl = (unsigned long) b;
69: unsigned long nl = (unsigned long) n;
72: if (a != b) {
73: #if !defined(PETSC_HAVE_CRAY90_POINTER)
74: if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
75: SETERRQ3(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()\n\
76: or make sure your copy regions and lengths are correct. \n\
77: Length (bytes) %ld first address %ld second address %ld",nl,al,bl);
78: }
79: #endif
80: #if (defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) || defined(PETSC_PREFER_COPY_FOR_MEMCPY) || defined(PETSC_PREFER_FORTRAN_FORMEMCPY))
81: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
82: int len = n/sizeof(PetscScalar);
83: #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
84: PetscBLASInt blen = (PetscBLASInt) len,one = 1;
85: BLcopy_(&blen,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
86: #elif defined(PETSC_PREFER_FORTRAN_FORMEMCPY)
87: fortrancopy_(&len,(PetscScalar*)b,(PetscScalar*)a);
88: #else
89: int i;
90: PetscScalar *x = (PetscScalar*)b, *y = (PetscScalar*)a;
91: for (i=0; i<len; i++) y[i] = x[i];
92: #endif
93: } else {
94: memcpy((char*)(a),(char*)(b),n);
95: }
96: #else
97: memcpy((char*)(a),(char*)(b),n);
98: #endif
99: }
100: return(0);
101: }
105: /*@C
106: PetscBitMemcpy - Copies an amount of data. This can include bit data.
108: Not Collective
110: Input Parameters:
111: + b - pointer to initial memory space
112: . bi - offset of initial memory space (in elementary chunk sizes)
113: . bs - length (in elementary chunk sizes) of space to copy
114: - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
116: Output Parameters:
117: + a - pointer to result memory space
118: - ai - offset of result memory space (in elementary chunk sizes)
120: Level: intermediate
122: Note:
123: This routine is analogous to PetscMemcpy(), except when the data type is
124: PETSC_LOGICAL.
126: Concepts: memory^comparing
127: Concepts: comparing^memory
129: .seealso: PetscMemmove(), PetscMemcpy()
131: @*/
132: PetscErrorCode PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype)
133: {
134: char *aa = (char *)a,*bb = (char *)b;
135: PetscInt dsize;
139: if (dtype != PETSC_LOGICAL) {
140: PetscDataTypeGetSize(dtype,&dsize);
141: PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
142: } else {
143: PetscBT at = (PetscBT) a;
144: PetscBT bt = (PetscBT) b;
145: int i;
146: for (i=0; i<bs; i++) {
147: if (PetscBTLookup(bt,bi+i)) PetscBTSet(at,ai+i);
148: else PetscBTClear(at,ai+i);
149: }
150: }
151: return(0);
152: }
156: /*@C
157: PetscMemzero - Zeros the specified memory.
159: Not Collective
161: Input Parameters:
162: + a - pointer to beginning memory location
163: - n - length (in bytes) of memory to initialize
165: Level: intermediate
167: Compile Option:
168: PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
169: to be faster than the memset() routine. This flag causes the bzero() routine to be used.
171: Concepts: memory^zeroing
172: Concepts: zeroing^memory
174: .seealso: PetscMemcpy()
175: @*/
176: PetscErrorCode PetscMemzero(void *a,size_t n)
177: {
179: if (n > 0) {
180: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
181: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
182: int i,len = n/sizeof(PetscScalar);
183: PetscScalar *x = (PetscScalar*)a;
184: for (i=0; i<len; i++) x[i] = 0.0;
185: } else {
186: #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
187: if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
188: int len = n/sizeof(PetscScalar);
189: fortranzero_(&len,(PetscScalar*)a);
190: } else {
191: #endif
192: #if defined(PETSC_PREFER_BZERO)
193: bzero((char *)a,n);
194: #else
195: memset((char*)a,0,n);
196: #endif
197: #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
198: }
199: #endif
200: }
201: return(0);
202: }
206: /*@C
207: PetscMemcmp - Compares two byte streams in memory.
209: Not Collective
211: Input Parameters:
212: + str1 - Pointer to the first byte stream
213: . str2 - Pointer to the second byte stream
214: - len - The length of the byte stream
215: (both str1 and str2 are assumed to be of length len)
217: Output Parameters:
218: . e - PETSC_TRUE if equal else PETSC_FALSE.
220: Level: intermediate
222: Note:
223: This routine is anologous to memcmp()
224: @*/
225: PetscErrorCode PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
226: {
227: int r;
230: r = memcmp((char *)str1,(char *)str2,len);
231: if (!r) *e = PETSC_TRUE;
232: else *e = PETSC_FALSE;
233: return(0);
234: }
238: /*@C
239: PetscMemmove - Copies n bytes, beginning at location b, to the space
240: beginning at location a. Copying between regions that overlap will
241: take place correctly.
243: Not Collective
245: Input Parameters:
246: + b - pointer to initial memory space
247: - n - length (in bytes) of space to copy
249: Output Parameter:
250: . a - pointer to copy space
252: Level: intermediate
254: Note:
255: This routine is analogous to memmove().
257: Contributed by: Matthew Knepley
259: Concepts: memory^copying with overlap
260: Concepts: copying^memory with overlap
262: .seealso: PetscMemcpy()
263: @*/
264: PetscErrorCode PetscMemmove(void *a,void *b,size_t n)
265: {
267: #if !defined(PETSC_HAVE_MEMMOVE)
268: if (a < b) {
269: if (a <= b - n) {
270: memcpy(a,b,n);
271: } else {
272: memcpy(a,b,(int)(b - a));
273: PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
274: }
275: } else {
276: if (b <= a - n) {
277: memcpy(a,b,n);
278: } else {
279: memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
280: PetscMemmove(a,b,n - (int)(a - b));
281: }
282: }
283: #else
284: memmove((char*)(a),(char*)(b),n);
285: #endif
286: return(0);
287: }