xref: /petsc/src/sys/utils/memc.c (revision 300a7f5b1a2fd87c9550c4ae2ba6f40f37aef7e5)
1e5c89e4eSSatish Balay #define PETSC_DLL
2e5c89e4eSSatish Balay 
3e5c89e4eSSatish Balay /*
4e5c89e4eSSatish Balay     We define the memory operations here. The reason we just do not use
5e5c89e4eSSatish Balay   the standard memory routines in the PETSc code is that on some machines
6e5c89e4eSSatish Balay   they are broken.
7e5c89e4eSSatish Balay 
8e5c89e4eSSatish Balay */
9e5c89e4eSSatish Balay #include "petsc.h"        /*I  "petsc.h"   I*/
10e5c89e4eSSatish Balay #include "src/inline/axpy.h"
11e5c89e4eSSatish Balay 
12e5c89e4eSSatish Balay /*
13e5c89e4eSSatish Balay     On the IBM Rs6000 using the Gnu G++ compiler you may have to include
14e5c89e4eSSatish Balay   <string.h> instead of <memory.h>
15e5c89e4eSSatish Balay */
16d8ff6ed1SSatish Balay #if defined(PETSC_HAVE_MEMORY_H)
17e5c89e4eSSatish Balay #include <memory.h>
18d8ff6ed1SSatish Balay #endif
19e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STRINGS_H)
20e5c89e4eSSatish Balay #include <strings.h>
21e5c89e4eSSatish Balay #endif
22e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STRING_H)
23e5c89e4eSSatish Balay #include <string.h>
24e5c89e4eSSatish Balay #endif
25e5c89e4eSSatish Balay #if defined(PETSC_HAVE_STDLIB_H)
26e5c89e4eSSatish Balay #include <stdlib.h>
27e5c89e4eSSatish Balay #endif
28e5c89e4eSSatish Balay #include "petscfix.h"
29e5c89e4eSSatish Balay #include "petscbt.h"
30e5c89e4eSSatish Balay #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
31e5c89e4eSSatish Balay #include "petscblaslapack.h"
32e5c89e4eSSatish Balay #endif
33e5c89e4eSSatish Balay 
34e5c89e4eSSatish Balay #undef __FUNCT__
35e5c89e4eSSatish Balay #define __FUNCT__ "PetscMemcpy"
36e30d2299SSatish Balay /*@
37e5c89e4eSSatish Balay    PetscMemcpy - Copies n bytes, beginning at location b, to the space
38e5c89e4eSSatish Balay    beginning at location a. The two memory regions CANNOT overlap, use
39e5c89e4eSSatish Balay    PetscMemmove() in that case.
40e5c89e4eSSatish Balay 
41e5c89e4eSSatish Balay    Not Collective
42e5c89e4eSSatish Balay 
43e5c89e4eSSatish Balay    Input Parameters:
44e5c89e4eSSatish Balay +  b - pointer to initial memory space
45e5c89e4eSSatish Balay -  n - length (in bytes) of space to copy
46e5c89e4eSSatish Balay 
47e5c89e4eSSatish Balay    Output Parameter:
48e5c89e4eSSatish Balay .  a - pointer to copy space
49e5c89e4eSSatish Balay 
50e5c89e4eSSatish Balay    Level: intermediate
51e5c89e4eSSatish Balay 
52e5c89e4eSSatish Balay    Compile Option:
53e5c89e4eSSatish Balay     PETSC_PREFER_DCOPY_FOR_MEMCPY will cause the BLAS dcopy() routine to be used
54e5c89e4eSSatish Balay                                   for memory copies on double precision values.
55e5c89e4eSSatish Balay     PETSC_PREFER_COPY_FOR_MEMCPY will cause C code to be used
56e5c89e4eSSatish Balay                                   for memory copies on double precision values.
57e5c89e4eSSatish Balay     PETSC_PREFER_FORTRAN_FORMEMCPY will cause Fortran code to be used
58e5c89e4eSSatish Balay                                   for memory copies on double precision values.
59e5c89e4eSSatish Balay 
60e5c89e4eSSatish Balay    Note:
61e5c89e4eSSatish Balay    This routine is analogous to memcpy().
62e5c89e4eSSatish Balay 
63e5c89e4eSSatish Balay   Concepts: memory^copying
64e5c89e4eSSatish Balay   Concepts: copying^memory
65e5c89e4eSSatish Balay 
66e5c89e4eSSatish Balay .seealso: PetscMemmove()
67e5c89e4eSSatish Balay 
68e5c89e4eSSatish Balay @*/
69e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscMemcpy(void *a,const void *b,size_t n)
70e5c89e4eSSatish Balay {
71e5c89e4eSSatish Balay   unsigned long al = (unsigned long) a,bl = (unsigned long) b;
72e5c89e4eSSatish Balay   unsigned long nl = (unsigned long) n;
73e5c89e4eSSatish Balay 
74e5c89e4eSSatish Balay   PetscFunctionBegin;
75e5c89e4eSSatish Balay   if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
76e5c89e4eSSatish Balay   if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
77e5c89e4eSSatish Balay   if (a != b) {
78e5c89e4eSSatish Balay #if !defined(PETSC_HAVE_CRAY90_POINTER)
79e5c89e4eSSatish Balay     if ((al > bl && (al - bl) < nl) || (bl - al) < nl) {
80e5c89e4eSSatish Balay       SETERRQ3(PETSC_ERR_ARG_INCOMP,"Memory regions overlap: either use PetscMemmov()\n\
81e5c89e4eSSatish Balay               or make sure your copy regions and lengths are correct. \n\
82e5c89e4eSSatish Balay               Length (bytes) %ld first address %ld second address %ld",nl,al,bl);
83e5c89e4eSSatish Balay     }
84e5c89e4eSSatish Balay #endif
85e5c89e4eSSatish Balay #if (defined(PETSC_PREFER_DCOPY_FOR_MEMCPY) || defined(PETSC_PREFER_COPY_FOR_MEMCPY) || defined(PETSC_PREFER_FORTRAN_FORMEMCPY))
86e5c89e4eSSatish Balay    if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
87e5c89e4eSSatish Balay       size_t len = n/sizeof(PetscScalar);
88e5c89e4eSSatish Balay #if defined(PETSC_PREFER_DCOPY_FOR_MEMCPY)
890805154bSBarry Smith       PetscBLASInt one = 1,blen = PetscBLASIntCast(len);
90e5c89e4eSSatish Balay       BLAScopy_(&blen,(PetscScalar *)b,&one,(PetscScalar *)a,&one);
91e5c89e4eSSatish Balay #elif defined(PETSC_PREFER_FORTRAN_FORMEMCPY)
92e5c89e4eSSatish Balay       fortrancopy_(&len,(PetscScalar*)b,(PetscScalar*)a);
93e5c89e4eSSatish Balay #else
94e5c89e4eSSatish Balay       size_t      i;
95e5c89e4eSSatish Balay       PetscScalar *x = (PetscScalar*)b, *y = (PetscScalar*)a;
96e5c89e4eSSatish Balay       for (i=0; i<len; i++) y[i] = x[i];
97e5c89e4eSSatish Balay #endif
98e5c89e4eSSatish Balay     } else {
99e5c89e4eSSatish Balay       memcpy((char*)(a),(char*)(b),n);
100e5c89e4eSSatish Balay     }
1011b54b3b6SSatish Balay #elif defined(PETSC_HAVE__INTEL_FAST_MEMCPY)
1021b54b3b6SSatish Balay     _intel_fast_memcpy((char*)(a),(char*)(b),n);
103e5c89e4eSSatish Balay #else
104e5c89e4eSSatish Balay     memcpy((char*)(a),(char*)(b),n);
105e5c89e4eSSatish Balay #endif
106e5c89e4eSSatish Balay   }
107e5c89e4eSSatish Balay   PetscFunctionReturn(0);
108e5c89e4eSSatish Balay }
109e5c89e4eSSatish Balay 
110e5c89e4eSSatish Balay #undef __FUNCT__
111e5c89e4eSSatish Balay #define __FUNCT__ "PetscBitMemcpy"
112e5c89e4eSSatish Balay /*@C
113e5c89e4eSSatish Balay    PetscBitMemcpy - Copies an amount of data. This can include bit data.
114e5c89e4eSSatish Balay 
115e5c89e4eSSatish Balay    Not Collective
116e5c89e4eSSatish Balay 
117e5c89e4eSSatish Balay    Input Parameters:
118e5c89e4eSSatish Balay +  b - pointer to initial memory space
119e5c89e4eSSatish Balay .  bi - offset of initial memory space (in elementary chunk sizes)
120e5c89e4eSSatish Balay .  bs - length (in elementary chunk sizes) of space to copy
121e5c89e4eSSatish Balay -  dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL
122e5c89e4eSSatish Balay 
123e5c89e4eSSatish Balay    Output Parameters:
124e5c89e4eSSatish Balay +  a - pointer to result memory space
125e5c89e4eSSatish Balay -  ai - offset of result memory space (in elementary chunk sizes)
126e5c89e4eSSatish Balay 
127e5c89e4eSSatish Balay    Level: intermediate
128e5c89e4eSSatish Balay 
129e5c89e4eSSatish Balay    Note:
130e5c89e4eSSatish Balay    This routine is analogous to PetscMemcpy(), except when the data type is
131e5c89e4eSSatish Balay    PETSC_LOGICAL.
132e5c89e4eSSatish Balay 
133e5c89e4eSSatish Balay    Concepts: memory^comparing
134e5c89e4eSSatish Balay    Concepts: comparing^memory
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay .seealso: PetscMemmove(), PetscMemcpy()
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay @*/
139e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype)
140e5c89e4eSSatish Balay {
141e5c89e4eSSatish Balay   char           *aa = (char *)a,*bb = (char *)b;
1422ad021e3SSatish Balay   size_t         dsize;
143e5c89e4eSSatish Balay   PetscErrorCode ierr;
144e5c89e4eSSatish Balay 
145e5c89e4eSSatish Balay   PetscFunctionBegin;
146e5c89e4eSSatish Balay   if (bs > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
147e5c89e4eSSatish Balay   if (bs > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer");
148e5c89e4eSSatish Balay   if (dtype != PETSC_LOGICAL) {
149e5c89e4eSSatish Balay     ierr = PetscDataTypeGetSize(dtype,&dsize);CHKERRQ(ierr);
150e5c89e4eSSatish Balay     ierr = PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);CHKERRQ(ierr);
151e5c89e4eSSatish Balay   } else {
152e5c89e4eSSatish Balay     PetscBT  at = (PetscBT) a;
153e5c89e4eSSatish Balay     PetscBT  bt = (PetscBT) b;
154e5c89e4eSSatish Balay     PetscInt i;
155e5c89e4eSSatish Balay     for (i=0; i<bs; i++) {
156e5c89e4eSSatish Balay       if (PetscBTLookup(bt,bi+i)) {ierr = PetscBTSet(at,ai+i);CHKERRQ(ierr);}
157e5c89e4eSSatish Balay       else                        {ierr = PetscBTClear(at,ai+i);CHKERRQ(ierr);}
158e5c89e4eSSatish Balay     }
159e5c89e4eSSatish Balay   }
160e5c89e4eSSatish Balay   PetscFunctionReturn(0);
161e5c89e4eSSatish Balay }
162e5c89e4eSSatish Balay 
163e5c89e4eSSatish Balay #undef __FUNCT__
164e5c89e4eSSatish Balay #define __FUNCT__ "PetscMemzero"
165e30d2299SSatish Balay /*@
166e5c89e4eSSatish Balay    PetscMemzero - Zeros the specified memory.
167e5c89e4eSSatish Balay 
168e5c89e4eSSatish Balay    Not Collective
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay    Input Parameters:
171e5c89e4eSSatish Balay +  a - pointer to beginning memory location
172e5c89e4eSSatish Balay -  n - length (in bytes) of memory to initialize
173e5c89e4eSSatish Balay 
174e5c89e4eSSatish Balay    Level: intermediate
175e5c89e4eSSatish Balay 
176e5c89e4eSSatish Balay    Compile Option:
177e5c89e4eSSatish Balay    PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens
178e5c89e4eSSatish Balay   to be faster than the memset() routine. This flag causes the bzero() routine to be used.
179e5c89e4eSSatish Balay 
180e5c89e4eSSatish Balay    Concepts: memory^zeroing
181e5c89e4eSSatish Balay    Concepts: zeroing^memory
182e5c89e4eSSatish Balay 
183e5c89e4eSSatish Balay .seealso: PetscMemcpy()
184e5c89e4eSSatish Balay @*/
185e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscMemzero(void *a,size_t n)
186e5c89e4eSSatish Balay {
187e5c89e4eSSatish Balay   PetscFunctionBegin;
188e5c89e4eSSatish Balay   if (n > 0) {
189e5c89e4eSSatish Balay     if (!a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to zero at a null pointer");
190e5c89e4eSSatish Balay #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO)
191e5c89e4eSSatish Balay     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
192e5c89e4eSSatish Balay       size_t      i,len = n/sizeof(PetscScalar);
193e5c89e4eSSatish Balay       PetscScalar *x = (PetscScalar*)a;
194e5c89e4eSSatish Balay       for (i=0; i<len; i++) x[i] = 0.0;
195e5c89e4eSSatish Balay     } else {
196e5c89e4eSSatish Balay #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
197e5c89e4eSSatish Balay     if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) {
198e5c89e4eSSatish Balay       PetscInt len = n/sizeof(PetscScalar);
199e5c89e4eSSatish Balay       fortranzero_(&len,(PetscScalar*)a);
200e5c89e4eSSatish Balay     } else {
201e5c89e4eSSatish Balay #endif
202e5c89e4eSSatish Balay #if defined(PETSC_PREFER_BZERO)
203e5c89e4eSSatish Balay       bzero((char *)a,n);
2041b54b3b6SSatish Balay #elif defined (PETSC_HAVE__INTEL_FAST_MEMSET)
2051b54b3b6SSatish Balay       _intel_fast_memset((char*)a,0,n);
206e5c89e4eSSatish Balay #else
207e5c89e4eSSatish Balay       memset((char*)a,0,n);
208e5c89e4eSSatish Balay #endif
209e5c89e4eSSatish Balay #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO)
210e5c89e4eSSatish Balay     }
211e5c89e4eSSatish Balay #endif
212e5c89e4eSSatish Balay   }
213e5c89e4eSSatish Balay   PetscFunctionReturn(0);
214e5c89e4eSSatish Balay }
215e5c89e4eSSatish Balay 
216e5c89e4eSSatish Balay #undef __FUNCT__
217e5c89e4eSSatish Balay #define __FUNCT__ "PetscMemcmp"
2184610e317SSatish Balay /*@
219e5c89e4eSSatish Balay    PetscMemcmp - Compares two byte streams in memory.
220e5c89e4eSSatish Balay 
221e5c89e4eSSatish Balay    Not Collective
222e5c89e4eSSatish Balay 
223e5c89e4eSSatish Balay    Input Parameters:
224e5c89e4eSSatish Balay +  str1 - Pointer to the first byte stream
225e5c89e4eSSatish Balay .  str2 - Pointer to the second byte stream
226e5c89e4eSSatish Balay -  len  - The length of the byte stream
227e5c89e4eSSatish Balay          (both str1 and str2 are assumed to be of length len)
228e5c89e4eSSatish Balay 
229e5c89e4eSSatish Balay    Output Parameters:
230e5c89e4eSSatish Balay .   e - PETSC_TRUE if equal else PETSC_FALSE.
231e5c89e4eSSatish Balay 
232e5c89e4eSSatish Balay    Level: intermediate
233e5c89e4eSSatish Balay 
234e5c89e4eSSatish Balay    Note:
235e5c89e4eSSatish Balay    This routine is anologous to memcmp()
236e5c89e4eSSatish Balay @*/
237e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e)
238e5c89e4eSSatish Balay {
239e5c89e4eSSatish Balay   int r;
240e5c89e4eSSatish Balay 
241e5c89e4eSSatish Balay   PetscFunctionBegin;
242e5c89e4eSSatish Balay   if (len > 0 && !str1) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
243e5c89e4eSSatish Balay   if (len > 0 && !str2) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer");
244e5c89e4eSSatish Balay   r = memcmp((char *)str1,(char *)str2,len);
245e5c89e4eSSatish Balay   if (!r) *e = PETSC_TRUE;
246e5c89e4eSSatish Balay   else    *e = PETSC_FALSE;
247e5c89e4eSSatish Balay   PetscFunctionReturn(0);
248e5c89e4eSSatish Balay }
249e5c89e4eSSatish Balay 
250e5c89e4eSSatish Balay #undef __FUNCT__
251e5c89e4eSSatish Balay #define __FUNCT__ "PetscMemmove"
2524610e317SSatish Balay /*@
253e5c89e4eSSatish Balay    PetscMemmove - Copies n bytes, beginning at location b, to the space
254e5c89e4eSSatish Balay    beginning at location a. Copying  between regions that overlap will
255e5c89e4eSSatish Balay    take place correctly.
256e5c89e4eSSatish Balay 
257e5c89e4eSSatish Balay    Not Collective
258e5c89e4eSSatish Balay 
259e5c89e4eSSatish Balay    Input Parameters:
260e5c89e4eSSatish Balay +  b - pointer to initial memory space
261e5c89e4eSSatish Balay -  n - length (in bytes) of space to copy
262e5c89e4eSSatish Balay 
263e5c89e4eSSatish Balay    Output Parameter:
264e5c89e4eSSatish Balay .  a - pointer to copy space
265e5c89e4eSSatish Balay 
266e5c89e4eSSatish Balay    Level: intermediate
267e5c89e4eSSatish Balay 
268e5c89e4eSSatish Balay    Note:
269e5c89e4eSSatish Balay    This routine is analogous to memmove().
270e5c89e4eSSatish Balay 
271*300a7f5bSBarry Smith    Since b can overlap with a, b cannot be declared as const
272*300a7f5bSBarry Smith 
273e5c89e4eSSatish Balay    Concepts: memory^copying with overlap
274e5c89e4eSSatish Balay    Concepts: copying^memory with overlap
275e5c89e4eSSatish Balay 
276e5c89e4eSSatish Balay .seealso: PetscMemcpy()
277e5c89e4eSSatish Balay @*/
278e5c89e4eSSatish Balay PetscErrorCode PETSC_DLLEXPORT PetscMemmove(void *a,void *b,size_t n)
279e5c89e4eSSatish Balay {
280e5c89e4eSSatish Balay   PetscFunctionBegin;
281e5c89e4eSSatish Balay   if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to null pointer");
282e5c89e4eSSatish Balay   if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer");
283e5c89e4eSSatish Balay #if !defined(PETSC_HAVE_MEMMOVE)
284e5c89e4eSSatish Balay   if (a < b) {
285e5c89e4eSSatish Balay     if (a <= b - n) {
286e5c89e4eSSatish Balay       memcpy(a,b,n);
287e5c89e4eSSatish Balay     } else {
288e5c89e4eSSatish Balay       memcpy(a,b,(int)(b - a));
289e5c89e4eSSatish Balay       PetscMemmove(b,b + (int)(b - a),n - (int)(b - a));
290e5c89e4eSSatish Balay     }
291e5c89e4eSSatish Balay   }  else {
292e5c89e4eSSatish Balay     if (b <= a - n) {
293e5c89e4eSSatish Balay       memcpy(a,b,n);
294e5c89e4eSSatish Balay     } else {
295e5c89e4eSSatish Balay       memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b));
296e5c89e4eSSatish Balay       PetscMemmove(a,b,n - (int)(a - b));
297e5c89e4eSSatish Balay     }
298e5c89e4eSSatish Balay   }
299e5c89e4eSSatish Balay #else
300e5c89e4eSSatish Balay   memmove((char*)(a),(char*)(b),n);
301e5c89e4eSSatish Balay #endif
302e5c89e4eSSatish Balay   PetscFunctionReturn(0);
303e5c89e4eSSatish Balay }
304e5c89e4eSSatish Balay 
305e5c89e4eSSatish Balay 
306e5c89e4eSSatish Balay 
307e5c89e4eSSatish Balay 
308