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 /*@C 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 #else 100 memcpy((char*)(a),(char*)(b),n); 101 #endif 102 } 103 PetscFunctionReturn(0); 104 } 105 106 #undef __FUNCT__ 107 #define __FUNCT__ "PetscBitMemcpy" 108 /*@C 109 PetscBitMemcpy - Copies an amount of data. This can include bit data. 110 111 Not Collective 112 113 Input Parameters: 114 + b - pointer to initial memory space 115 . bi - offset of initial memory space (in elementary chunk sizes) 116 . bs - length (in elementary chunk sizes) of space to copy 117 - dtype - datatype, for example, PETSC_INT, PETSC_DOUBLE, PETSC_LOGICAL 118 119 Output Parameters: 120 + a - pointer to result memory space 121 - ai - offset of result memory space (in elementary chunk sizes) 122 123 Level: intermediate 124 125 Note: 126 This routine is analogous to PetscMemcpy(), except when the data type is 127 PETSC_LOGICAL. 128 129 Concepts: memory^comparing 130 Concepts: comparing^memory 131 132 .seealso: PetscMemmove(), PetscMemcpy() 133 134 @*/ 135 PetscErrorCode PETSC_DLLEXPORT PetscBitMemcpy(void *a,PetscInt ai,const void *b,PetscInt bi,PetscInt bs,PetscDataType dtype) 136 { 137 char *aa = (char *)a,*bb = (char *)b; 138 PetscInt dsize; 139 PetscErrorCode ierr; 140 141 PetscFunctionBegin; 142 if (bs > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer"); 143 if (bs > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to a null pointer"); 144 if (dtype != PETSC_LOGICAL) { 145 ierr = PetscDataTypeGetSize(dtype,&dsize);CHKERRQ(ierr); 146 ierr = PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);CHKERRQ(ierr); 147 } else { 148 PetscBT at = (PetscBT) a; 149 PetscBT bt = (PetscBT) b; 150 PetscInt i; 151 for (i=0; i<bs; i++) { 152 if (PetscBTLookup(bt,bi+i)) {ierr = PetscBTSet(at,ai+i);CHKERRQ(ierr);} 153 else {ierr = PetscBTClear(at,ai+i);CHKERRQ(ierr);} 154 } 155 } 156 PetscFunctionReturn(0); 157 } 158 159 #undef __FUNCT__ 160 #define __FUNCT__ "PetscMemzero" 161 /*@C 162 PetscMemzero - Zeros the specified memory. 163 164 Not Collective 165 166 Input Parameters: 167 + a - pointer to beginning memory location 168 - n - length (in bytes) of memory to initialize 169 170 Level: intermediate 171 172 Compile Option: 173 PETSC_PREFER_BZERO - on certain machines (the IBM RS6000) the bzero() routine happens 174 to be faster than the memset() routine. This flag causes the bzero() routine to be used. 175 176 Concepts: memory^zeroing 177 Concepts: zeroing^memory 178 179 .seealso: PetscMemcpy() 180 @*/ 181 PetscErrorCode PETSC_DLLEXPORT PetscMemzero(void *a,size_t n) 182 { 183 PetscFunctionBegin; 184 if (n > 0) { 185 if (!a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to zero at a null pointer"); 186 #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) 187 if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) { 188 size_t i,len = n/sizeof(PetscScalar); 189 PetscScalar *x = (PetscScalar*)a; 190 for (i=0; i<len; i++) x[i] = 0.0; 191 } else { 192 #elif defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO) 193 if (!(((long) a) % sizeof(PetscScalar)) && !(n % sizeof(PetscScalar))) { 194 PetscInt len = n/sizeof(PetscScalar); 195 fortranzero_(&len,(PetscScalar*)a); 196 } else { 197 #endif 198 #if defined(PETSC_PREFER_BZERO) 199 bzero((char *)a,n); 200 #else 201 memset((char*)a,0,n); 202 #endif 203 #if defined(PETSC_PREFER_ZERO_FOR_MEMZERO) || defined(PETSC_PREFER_FORTRAN_FOR_MEMZERO) 204 } 205 #endif 206 } 207 PetscFunctionReturn(0); 208 } 209 210 #undef __FUNCT__ 211 #define __FUNCT__ "PetscMemcmp" 212 /*@C 213 PetscMemcmp - Compares two byte streams in memory. 214 215 Not Collective 216 217 Input Parameters: 218 + str1 - Pointer to the first byte stream 219 . str2 - Pointer to the second byte stream 220 - len - The length of the byte stream 221 (both str1 and str2 are assumed to be of length len) 222 223 Output Parameters: 224 . e - PETSC_TRUE if equal else PETSC_FALSE. 225 226 Level: intermediate 227 228 Note: 229 This routine is anologous to memcmp() 230 @*/ 231 PetscErrorCode PETSC_DLLEXPORT PetscMemcmp(const void *str1,const void *str2,size_t len,PetscTruth *e) 232 { 233 int r; 234 235 PetscFunctionBegin; 236 if (len > 0 && !str1) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer"); 237 if (len > 0 && !str2) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to compare at a null pointer"); 238 r = memcmp((char *)str1,(char *)str2,len); 239 if (!r) *e = PETSC_TRUE; 240 else *e = PETSC_FALSE; 241 PetscFunctionReturn(0); 242 } 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "PetscMemmove" 246 /*@C 247 PetscMemmove - Copies n bytes, beginning at location b, to the space 248 beginning at location a. Copying between regions that overlap will 249 take place correctly. 250 251 Not Collective 252 253 Input Parameters: 254 + b - pointer to initial memory space 255 - n - length (in bytes) of space to copy 256 257 Output Parameter: 258 . a - pointer to copy space 259 260 Level: intermediate 261 262 Note: 263 This routine is analogous to memmove(). 264 265 Concepts: memory^copying with overlap 266 Concepts: copying^memory with overlap 267 268 .seealso: PetscMemcpy() 269 @*/ 270 PetscErrorCode PETSC_DLLEXPORT PetscMemmove(void *a,void *b,size_t n) 271 { 272 PetscFunctionBegin; 273 if (n > 0 && !a) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy to null pointer"); 274 if (n > 0 && !b) SETERRQ(PETSC_ERR_ARG_NULL,"Trying to copy from a null pointer"); 275 #if !defined(PETSC_HAVE_MEMMOVE) 276 if (a < b) { 277 if (a <= b - n) { 278 memcpy(a,b,n); 279 } else { 280 memcpy(a,b,(int)(b - a)); 281 PetscMemmove(b,b + (int)(b - a),n - (int)(b - a)); 282 } 283 } else { 284 if (b <= a - n) { 285 memcpy(a,b,n); 286 } else { 287 memcpy(b + n,b + (n - (int)(a - b)),(int)(a - b)); 288 PetscMemmove(a,b,n - (int)(a - b)); 289 } 290 } 291 #else 292 memmove((char*)(a),(char*)(b),n); 293 #endif 294 PetscFunctionReturn(0); 295 } 296 297 298 299 300