1 #define PETSC_DLL 2 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. 7 8 */ 9 #include "petsc.h" /*I "petsc.h" I*/ 10 #include "src/inline/axpy.h" 11 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 31 32 #undef __FUNCT__ 33 #define __FUNCT__ "PetscMemcpy" 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. 38 39 Not Collective 40 41 Input Parameters: 42 + b - pointer to initial memory space 43 - n - length (in bytes) of space to copy 44 45 Output Parameter: 46 . a - pointer to copy space 47 48 Level: intermediate 49 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. 57 58 Note: 59 This routine is analogous to memcpy(). 60 61 Concepts: memory^copying 62 Concepts: copying^memory 63 64 .seealso: PetscMemmove() 65 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; 71 72 PetscFunctionBegin; 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 PetscFunctionReturn(0); 106 } 107 108 #undef __FUNCT__ 109 #define __FUNCT__ "PetscBitMemcpy" 110 /*@C 111 PetscBitMemcpy - Copies an amount of data. This can include bit data. 112 113 Not Collective 114 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 120 121 Output Parameters: 122 + a - pointer to result memory space 123 - ai - offset of result memory space (in elementary chunk sizes) 124 125 Level: intermediate 126 127 Note: 128 This routine is analogous to PetscMemcpy(), except when the data type is 129 PETSC_LOGICAL. 130 131 Concepts: memory^comparing 132 Concepts: comparing^memory 133 134 .seealso: PetscMemmove(), PetscMemcpy() 135 136 @*/ 137 PetscErrorCode PETSC_DLLEXPORT PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype) 138 { 139 char *aa = (char *)a,*bb = (char *)b; 140 size_t dsize; 141 PetscErrorCode ierr; 142 143 PetscFunctionBegin; 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 ierr = PetscDataTypeGetSize(dtype,&dsize);CHKERRQ(ierr); 148 ierr = PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);CHKERRQ(ierr); 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)) {ierr = PetscBTSet(at,ai+i);CHKERRQ(ierr);} 155 else {ierr = PetscBTClear(at,ai+i);CHKERRQ(ierr);} 156 } 157 } 158 PetscFunctionReturn(0); 159 } 160 161 #undef __FUNCT__ 162 #define __FUNCT__ "PetscMemzero" 163 /*@ 164 PetscMemzero - Zeros the specified memory. 165 166 Not Collective 167 168 Input Parameters: 169 + a - pointer to beginning memory location 170 - n - length (in bytes) of memory to initialize 171 172 Level: intermediate 173 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. 177 178 Concepts: memory^zeroing 179 Concepts: zeroing^memory 180 181 .seealso: PetscMemcpy() 182 @*/ 183 PetscErrorCode PETSC_DLLEXPORT PetscMemzero(void *a,size_t n) 184 { 185 PetscFunctionBegin; 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 PetscFunctionReturn(0); 212 } 213 214 #undef __FUNCT__ 215 #define __FUNCT__ "PetscMemcmp" 216 /*@ 217 PetscMemcmp - Compares two byte streams in memory. 218 219 Not Collective 220 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) 226 227 Output Parameters: 228 . e - PETSC_TRUE if equal else PETSC_FALSE. 229 230 Level: intermediate 231 232 Note: 233 This routine is anologous to memcmp() 234 @*/ 235 PetscErrorCode PETSC_DLLEXPORT PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e) 236 { 237 int r; 238 239 PetscFunctionBegin; 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 PetscFunctionReturn(0); 246 } 247 248 #undef __FUNCT__ 249 #define __FUNCT__ "PetscMemmove" 250 /*@ 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. 254 255 Not Collective 256 257 Input Parameters: 258 + b - pointer to initial memory space 259 - n - length (in bytes) of space to copy 260 261 Output Parameter: 262 . a - pointer to copy space 263 264 Level: intermediate 265 266 Note: 267 This routine is analogous to memmove(). 268 269 Concepts: memory^copying with overlap 270 Concepts: copying^memory with overlap 271 272 .seealso: PetscMemcpy() 273 @*/ 274 PetscErrorCode PETSC_DLLEXPORT PetscMemmove(void *a,void *b,size_t n) 275 { 276 PetscFunctionBegin; 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 PetscFunctionReturn(0); 299 } 300 301 302 303 304