00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef _LIBMETIS_MACROS_H_
00016 #define _LIBMETIS_MACROS_H_
00017
00018
00019
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
00026
00027 #define HASHFCT(key, size) ((key)%(size))
00028 #define SWAP gk_SWAP
00029
00030
00031 #define GETOPTION(options, idx, defval) \
00032 ((options) == NULL || (options)[idx] == -1 ? defval : (options)[idx])
00033
00034
00035 #define I2RUBFACTOR(ufactor) (1.0+0.001*(ufactor))
00036
00037
00038 #define WCOREPUSH wspacepush(ctrl)
00039 #define WCOREPOP wspacepop(ctrl)
00040
00041
00042
00043
00044
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
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
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
00087 \
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 \
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 \
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 \
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 \
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 \
00252 for (k=0; k<nads[to]; k++) \
00253 vtmp[adids[to][k]] = 0; \
00254 } \
00255 } while (0)
00256
00257
00258 #endif