hp2FEM  0.1
src/metis-5.0/libmetis/macros.h
00001 /*
00002  * Copyright 1997, Regents of the University of Minnesota
00003  *
00004  * macros.h
00005  *
00006  * This file contains macros used in multilevel
00007  *
00008  * Started 9/25/94
00009  * George
00010  *
00011  * $Id: macros.h 10060 2011-06-02 18:56:30Z karypis $
00012  *
00013  */
00014 
00015 #ifndef _LIBMETIS_MACROS_H_
00016 #define _LIBMETIS_MACROS_H_
00017 
00018 /*************************************************************************
00019 * The following macro returns a random number in the specified range
00020 **************************************************************************/
00021 #define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b)))
00022 #define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b)))
00023 #define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b)))
00024 
00025 //#define icopy(n, a, b) (idx_t *)memcpy((void *)(b), (void *)(a), sizeof(idx_t)*(n)) 
00026 
00027 #define HASHFCT(key, size) ((key)%(size))
00028 #define SWAP gk_SWAP
00029 
00030 /* gets the appropriate option value */
00031 #define GETOPTION(options, idx, defval) \
00032             ((options) == NULL || (options)[idx] == -1 ? defval : (options)[idx]) 
00033 
00034 /* converts a user provided ufactor into a real ubfactor */
00035 #define I2RUBFACTOR(ufactor) (1.0+0.001*(ufactor))
00036 
00037 /* set/reset the current workspace core */
00038 #define WCOREPUSH    wspacepush(ctrl)
00039 #define WCOREPOP     wspacepop(ctrl)
00040 
00041 
00042 
00043 /*************************************************************************
00044 * These macros insert and remove nodes from a Direct Access list 
00045 **************************************************************************/
00046 #define ListInsert(n, lind, lptr, i) \
00047    do { \
00048      ASSERT(lptr[i] == -1); \
00049      lind[n] = i; \
00050      lptr[i] = (n)++;\
00051    } while(0) 
00052 
00053 #define ListDelete(n, lind, lptr, i) \
00054    do { \
00055      ASSERT(lptr[i] != -1); \
00056      lind[lptr[i]] = lind[--(n)]; \
00057      lptr[lind[n]] = lptr[i]; \
00058      lptr[i] = -1; \
00059    } while(0) 
00060 
00061 
00062 /*************************************************************************
00063 * These macros insert and remove nodes from the boundary list
00064 **************************************************************************/
00065 #define BNDInsert(nbnd, bndind, bndptr, vtx) \
00066   ListInsert(nbnd, bndind, bndptr, vtx)
00067 
00068 #define BNDDelete(nbnd, bndind, bndptr, vtx) \
00069   ListDelete(nbnd, bndind, bndptr, vtx)
00070 
00071 
00072 /*************************************************************************
00073 * These macros deal with id/ed updating during k-way refinement
00074 **************************************************************************/
00075 #define UpdateMovedVertexInfoAndBND(i, from, k, to, myrinfo, mynbrs, where, \
00076             nbnd, bndptr, bndind, bndtype) \
00077    do { \
00078      where[i] = to; \
00079      myrinfo->ed += myrinfo->id-mynbrs[k].ed; \
00080      SWAP(myrinfo->id, mynbrs[k].ed, j); \
00081      if (mynbrs[k].ed == 0) \
00082        mynbrs[k] = mynbrs[--myrinfo->nnbrs]; \
00083      else \
00084        mynbrs[k].pid = from; \
00085      \
00086      /* Update the boundary information. Both deletion and addition is \
00087         allowed as this routine can be used for moving arbitrary nodes. */ \
00088      if (bndtype == BNDTYPE_REFINE) { \
00089        if (bndptr[i] != -1 && myrinfo->ed - myrinfo->id < 0) \
00090          BNDDelete(nbnd, bndind, bndptr, i); \
00091        if (bndptr[i] == -1 && myrinfo->ed - myrinfo->id >= 0) \
00092          BNDInsert(nbnd, bndind, bndptr, i); \
00093      } \
00094      else { \
00095        if (bndptr[i] != -1 && myrinfo->ed <= 0) \
00096          BNDDelete(nbnd, bndind, bndptr, i); \
00097        if (bndptr[i] == -1 && myrinfo->ed > 0) \
00098          BNDInsert(nbnd, bndind, bndptr, i); \
00099      } \
00100    } while(0) 
00101 
00102 
00103 #define UpdateAdjacentVertexInfoAndBND(ctrl, vid, adjlen, me, from, to, \
00104             myrinfo, ewgt, nbnd, bndptr, bndind, bndtype) \
00105    do { \
00106      idx_t k; \
00107      cnbr_t *mynbrs; \
00108      \
00109      if (myrinfo->inbr == -1) { \
00110        myrinfo->inbr  = cnbrpoolGetNext(ctrl, adjlen+1); \
00111        myrinfo->nnbrs = 0; \
00112      } \
00113      ASSERT(CheckRInfo(ctrl, myrinfo)); \
00114      \
00115      mynbrs = ctrl->cnbrpool + myrinfo->inbr; \
00116      \
00117      /* Update global ID/ED and boundary */ \
00118      if (me == from) { \
00119        INC_DEC(myrinfo->ed, myrinfo->id, (ewgt)); \
00120        if (bndtype == BNDTYPE_REFINE) { \
00121          if (myrinfo->ed-myrinfo->id >= 0 && bndptr[(vid)] == -1) \
00122            BNDInsert(nbnd, bndind, bndptr, (vid)); \
00123        } \
00124        else { \
00125          if (myrinfo->ed > 0 && bndptr[(vid)] == -1) \
00126            BNDInsert(nbnd, bndind, bndptr, (vid)); \
00127        } \
00128      } \
00129      else if (me == to) { \
00130        INC_DEC(myrinfo->id, myrinfo->ed, (ewgt)); \
00131        if (bndtype == BNDTYPE_REFINE) { \
00132          if (myrinfo->ed-myrinfo->id < 0 && bndptr[(vid)] != -1) \
00133            BNDDelete(nbnd, bndind, bndptr, (vid)); \
00134        } \
00135        else { \
00136          if (myrinfo->ed <= 0 && bndptr[(vid)] != -1) \
00137            BNDDelete(nbnd, bndind, bndptr, (vid)); \
00138        } \
00139      } \
00140      \
00141      /* Remove contribution from the .ed of 'from' */ \
00142      if (me != from) { \
00143        for (k=0; k<myrinfo->nnbrs; k++) { \
00144          if (mynbrs[k].pid == from) { \
00145            if (mynbrs[k].ed == (ewgt)) \
00146              mynbrs[k] = mynbrs[--myrinfo->nnbrs]; \
00147            else \
00148              mynbrs[k].ed -= (ewgt); \
00149            break; \
00150          } \
00151        } \
00152      } \
00153      \
00154      /* Add contribution to the .ed of 'to' */ \
00155      if (me != to) { \
00156        for (k=0; k<myrinfo->nnbrs; k++) { \
00157          if (mynbrs[k].pid == to) { \
00158            mynbrs[k].ed += (ewgt); \
00159            break; \
00160          } \
00161        } \
00162        if (k == myrinfo->nnbrs) { \
00163          mynbrs[k].pid  = to; \
00164          mynbrs[k].ed   = (ewgt); \
00165          myrinfo->nnbrs++; \
00166        } \
00167      } \
00168      \
00169      ASSERT(CheckRInfo(ctrl, myrinfo));\
00170    } while(0) 
00171 
00172 
00173 #define UpdateQueueInfo(queue, vstatus, vid, me, from, to, myrinfo, oldnnbrs, \
00174             nupd, updptr, updind, bndtype) \
00175    do { \
00176      real_t rgain; \
00177      \
00178      if (me == to || me == from || oldnnbrs != myrinfo->nnbrs) {  \
00179        rgain = (myrinfo->nnbrs > 0 ?  \
00180                 1.0*myrinfo->ed/sqrt(myrinfo->nnbrs) : 0.0) - myrinfo->id; \
00181    \
00182        if (bndtype == BNDTYPE_REFINE) { \
00183          if (vstatus[(vid)] == VPQSTATUS_PRESENT) { \
00184            if (myrinfo->ed-myrinfo->id >= 0) \
00185              rpqUpdate(queue, (vid), rgain); \
00186            else { \
00187              rpqDelete(queue, (vid)); \
00188              vstatus[(vid)] = VPQSTATUS_NOTPRESENT; \
00189              ListDelete(nupd, updind, updptr, (vid)); \
00190            } \
00191          } \
00192          else if (vstatus[(vid)] == VPQSTATUS_NOTPRESENT && myrinfo->ed-myrinfo->id >= 0) { \
00193            rpqInsert(queue, (vid), rgain); \
00194            vstatus[(vid)] = VPQSTATUS_PRESENT; \
00195            ListInsert(nupd, updind, updptr, (vid)); \
00196          } \
00197        } \
00198        else { \
00199          if (vstatus[(vid)] == VPQSTATUS_PRESENT) { \
00200            if (myrinfo->ed > 0) \
00201              rpqUpdate(queue, (vid), rgain); \
00202            else { \
00203              rpqDelete(queue, (vid)); \
00204              vstatus[(vid)] = VPQSTATUS_NOTPRESENT; \
00205              ListDelete(nupd, updind, updptr, (vid)); \
00206            } \
00207          } \
00208          else if (vstatus[(vid)] == VPQSTATUS_NOTPRESENT && myrinfo->ed > 0) { \
00209            rpqInsert(queue, (vid), rgain); \
00210            vstatus[(vid)] = VPQSTATUS_PRESENT; \
00211            ListInsert(nupd, updind, updptr, (vid)); \
00212          } \
00213        } \
00214      } \
00215    } while(0) 
00216 
00217 
00218 
00219 /*************************************************************************/
00222 /*************************************************************************/
00223 #define SelectSafeTargetSubdomains(myrinfo, mynbrs, nads, adids, maxndoms, safetos, vtmp) \
00224   do { \
00225     idx_t j, k, l, nadd, to; \
00226     for (j=0; j<myrinfo->nnbrs; j++) { \
00227       safetos[to = mynbrs[j].pid] = 0; \
00228       \
00229       /* uncompress the connectivity info for the 'to' subdomain */ \
00230       for (k=0; k<nads[to]; k++) \
00231         vtmp[adids[to][k]] = 1; \
00232       \
00233       for (nadd=0, k=0; k<myrinfo->nnbrs; k++) { \
00234         if (k == j) \
00235           continue; \
00236         \
00237         l = mynbrs[k].pid; \
00238         if (vtmp[l] == 0) { \
00239           if (nads[l] > maxndoms-1) { \
00240             nadd = maxndoms; \
00241             break; \
00242           } \
00243           nadd++; \
00244         } \
00245       } \
00246       if (nads[to]+nadd <= maxndoms) \
00247         safetos[to] = 1; \
00248       if (nadd == 0) \
00249         safetos[to] = 2; \
00250       \
00251       /* cleanup the connectivity info due to the 'to' subdomain */ \
00252       for (k=0; k<nads[to]; k++) \
00253         vtmp[adids[to][k]] = 0; \
00254     } \
00255   } while (0)
00256 
00257 
00258 #endif
 All Classes Files Functions Variables Typedefs Friends Defines