Actual source code: memc.c

      1: #define PETSC_DLL

      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.

      8: */
     9:  #include petsc.h
     10:  #include src/inline/axpy.h

     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

     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.

     39:    Not Collective

     41:    Input Parameters:
     42: +  b - pointer to initial memory space
     43: -  n - length (in bytes) of space to copy

     45:    Output Parameter:
     46: .  a - pointer to copy space

     48:    Level: intermediate

     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.

     58:    Note:
     59:    This routine is analogous to memcpy().

     61:   Concepts: memory^copying
     62:   Concepts: copying^memory
     63:
     64: .seealso: PetscMemmove()

     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;

     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:   return(0);
    104: }

    108: /*@C
    109:    PetscBitMemcpy - Copies an amount of data. This can include bit data.

    111:    Not Collective

    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

    119:    Output Parameters:
    120: +  a - pointer to result memory space
    121: -  ai - offset of result memory space (in elementary chunk sizes)

    123:    Level: intermediate

    125:    Note:
    126:    This routine is analogous to PetscMemcpy(), except when the data type is
    127:    PETSC_LOGICAL.

    129:    Concepts: memory^comparing
    130:    Concepts: comparing^memory

    132: .seealso: PetscMemmove(), PetscMemcpy()

    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;

    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:     PetscDataTypeGetSize(dtype,&dsize);
    146:     PetscMemcpy(aa+ai*dsize,bb+bi*dsize,bs*dsize);
    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)) {PetscBTSet(at,ai+i);}
    153:       else                        {PetscBTClear(at,ai+i);}
    154:     }
    155:   }
    156:   return(0);
    157: }

    161: /*@C
    162:    PetscMemzero - Zeros the specified memory.

    164:    Not Collective

    166:    Input Parameters:
    167: +  a - pointer to beginning memory location
    168: -  n - length (in bytes) of memory to initialize

    170:    Level: intermediate

    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.

    176:    Concepts: memory^zeroing
    177:    Concepts: zeroing^memory

    179: .seealso: PetscMemcpy()
    180: @*/
    181: PetscErrorCode PETSC_DLLEXPORT PetscMemzero(void *a,size_t n)
    182: {
    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:   return(0);
    208: }

    212: /*@C
    213:    PetscMemcmp - Compares two byte streams in memory.

    215:    Not Collective

    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)

    223:    Output Parameters:
    224: .   e - PETSC_TRUE if equal else PETSC_FALSE.

    226:    Level: intermediate

    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;

    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:   return(0);
    242: }

    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.

    251:    Not Collective

    253:    Input Parameters:
    254: +  b - pointer to initial memory space
    255: -  n - length (in bytes) of space to copy

    257:    Output Parameter:
    258: .  a - pointer to copy space

    260:    Level: intermediate

    262:    Note:
    263:    This routine is analogous to memmove().

    265:    Concepts: memory^copying with overlap
    266:    Concepts: copying^memory with overlap

    268: .seealso: PetscMemcpy()
    269: @*/
    270: PetscErrorCode PETSC_DLLEXPORT PetscMemmove(void *a,void *b,size_t n)
    271: {
    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:   return(0);
    295: }