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 #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 33 34 #undef __FUNCT__ 35 #define __FUNCT__ "PetscMemcpy" 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. 40 41 Not Collective 42 43 Input Parameters: 44 + b - pointer to initial memory space 45 - n - length (in bytes) of space to copy 46 47 Output Parameter: 48 . a - pointer to copy space 49 50 Level: intermediate 51 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. 59 60 Note: 61 This routine is analogous to memcpy(). 62 63 Concepts: memory^copying 64 Concepts: copying^memory 65 66 .seealso: PetscMemmove() 67 68 @*/ 69 PetscErrorCode PETSC_DLLEXPORT 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; 73 74 PetscFunctionBegin; 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 PetscFunctionReturn(0); 108 } 109 110 #undef __FUNCT__ 111 #define __FUNCT__ "PetscBitMemcpy" 112 /*@C 113 PetscBitMemcpy - Copies an amount of data. This can include bit data. 114 115 Not Collective 116 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 122 123 Output Parameters: 124 + a - pointer to result memory space 125 - ai - offset of result memory space (in elementary chunk sizes) 126 127 Level: intermediate 128 129 Note: 130 This routine is analogous to PetscMemcpy(), except when the data type is 131 PETSC_LOGICAL. 132 133 Concepts: memory^comparing 134 Concepts: comparing^memory 135 136 .seealso: PetscMemmove(), PetscMemcpy() 137 138 @*/ 139 PetscErrorCode PETSC_DLLEXPORT 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; 143 PetscErrorCode ierr; 144 145 PetscFunctionBegin; 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 ierr = PetscDataTypeGetSize(dtype,&dsize);CHKERRQ(ierr); 150 ierr = PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);CHKERRQ(ierr); 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)) {ierr = PetscBTSet(at,ai+i);CHKERRQ(ierr);} 157 else {ierr = PetscBTClear(at,ai+i);CHKERRQ(ierr);} 158 } 159 } 160 PetscFunctionReturn(0); 161 } 162 163 #undef __FUNCT__ 164 #define __FUNCT__ "PetscMemzero" 165 /*@ 166 PetscMemzero - Zeros the specified memory. 167 168 Not Collective 169 170 Input Parameters: 171 + a - pointer to beginning memory location 172 - n - length (in bytes) of memory to initialize 173 174 Level: intermediate 175 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. 179 180 Concepts: memory^zeroing 181 Concepts: zeroing^memory 182 183 .seealso: PetscMemcpy() 184 @*/ 185 PetscErrorCode PETSC_DLLEXPORT PetscMemzero(void *a,size_t n) 186 { 187 PetscFunctionBegin; 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 PetscFunctionReturn(0); 214 } 215 216 #undef __FUNCT__ 217 #define __FUNCT__ "PetscMemcmp" 218 /*@ 219 PetscMemcmp - Compares two byte streams in memory. 220 221 Not Collective 222 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) 228 229 Output Parameters: 230 . e - PETSC_TRUE if equal else PETSC_FALSE. 231 232 Level: intermediate 233 234 Note: 235 This routine is anologous to memcmp() 236 @*/ 237 PetscErrorCode PETSC_DLLEXPORT PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e) 238 { 239 int r; 240 241 PetscFunctionBegin; 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 PetscFunctionReturn(0); 248 } 249 250 #undef __FUNCT__ 251 #define __FUNCT__ "PetscMemmove" 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. 256 257 Not Collective 258 259 Input Parameters: 260 + b - pointer to initial memory space 261 - n - length (in bytes) of space to copy 262 263 Output Parameter: 264 . a - pointer to copy space 265 266 Level: intermediate 267 268 Note: 269 This routine is analogous to memmove(). 270 271 Concepts: memory^copying with overlap 272 Concepts: copying^memory with overlap 273 274 .seealso: PetscMemcpy() 275 @*/ 276 PetscErrorCode PETSC_DLLEXPORT PetscMemmove(void *a,void *b,size_t n) 277 { 278 PetscFunctionBegin; 279 if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to null pointer"); 280 if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer"); 281 #if !defined(PETSC_HAVE_MEMMOVE) 282 if (a < b) { 283 if (a <= b - n) { 284 memcpy(a,b,n); 285 } else { 286 memcpy(a,b,(int)(b - a)); 287 PetscMemmove(b,b + (int)(b - a),n - (int)(b - a)); 288 } 289 } else { 290 if (b <= a - n) { 291 memcpy(a,b,n); 292 } else { 293 memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b)); 294 PetscMemmove(a,b,n - (int)(a - b)); 295 } 296 } 297 #else 298 memmove((char*)(a),(char*)(b),n); 299 #endif 300 PetscFunctionReturn(0); 301 } 302 303 304 305 306