int BEND1::run() { for (int i = 0; i < framesToRun(); i++) { if (--branch <= 0) { if (amptable) aamp = tablei(currentFrame(), amptable, amptabs) * amp; float freq = diff * tablei(currentFrame(), glissf, tags) + freq0; sset(SR, freq, tf0, tfN, strumq1); branch = reset; } float a = strum(d, strumq1); float b = dist(dgain*a); d = fbgain*delay(b, dq); float out[2]; out[0] = (cleanlevel*a + distlevel*b) * aamp; if (outputChannels() == 2) { /* split stereo files between the channels */ out[1] = (1.0 - spread) * out[0]; out[0] *= spread; } rtaddout(out); increment(); } return framesToRun(); }
int START::init(double p[], int n_args) { float outskip = p[0]; float dur = p[1]; float pitch = p[2]; float fdecay = p[3]; float nydecay = p[4]; float amp = p[5]; int squish = (int)p[6]; spread = p[7]; deleteflag = (int)p[8]; if (rtsetoutput(outskip, dur, this) == -1) return DONT_SCHEDULE; strumq1 = new strumq; curstrumq[0] = strumq1; float freq = cpspch(pitch); sset(SR, freq, fdecay, nydecay, strumq1); randfill(amp, squish, strumq1); amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } else { rtcmix_advise("START", "Setting phrase curve to all 1's."); aamp = 1.0; } skip = (int)(SR / (float)resetval); return nSamps(); }
/************************************************************************* * This function computes the load for each subdomain **************************************************************************/ void ComputeLoad(GraphType *graph, int nparts, floattype *load, floattype *tpwgts, int index) { int i; int nvtxs, ncon; idxtype *where; floattype *nvwgt; nvtxs = graph->nvtxs; ncon = graph->ncon; where = graph->where; nvwgt = graph->nvwgt; sset(nparts, 0.0, load); for (i=0; i<nvtxs; i++) load[where[i]] += nvwgt[i*ncon+index]; ASSERTS(fabs(ssum(nparts, load)-1.0) < 0.001); for (i=0; i<nparts; i++) { load[i] -= tpwgts[i*ncon+index]; } return; }
/************************************************************************* * The following function allocates and sets an array of floattypes **************************************************************************/ floattype *fsmalloc(int n, floattype fval, char *msg) { if (n == 0) return NULL; return sset(n, fval, (floattype *)GKmalloc(sizeof(floattype)*n, msg)); }
SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMember, const SkFontStyle& fontstyle) const { SkString familyName; SkFontStyleSet_DirectWrite sset( this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get() ); return sset.matchStyle(fontstyle); }
int BEND1::init(double p[], int n_args) { // p0 = start; p1 = dur; p2 = pitch0 (oct.pc); p3 = pitch1 (oct.pc) // p4 = gliss function #; p5 = fundamental decay time // p6 = nyquist decay time; p7 = distortion gain; p8 = feedback gain // p9 = feedback pitch (oct.pc); p10 = clean signal level // p11 = distortion signal level; p12 = amp; p13 = update gliss nsamples // p14 = stereo spread [optional] float dur = p[1]; if (rtsetoutput(p[0], dur, this) == -1) return DONT_SCHEDULE; strumq1 = curstrumq[0]; freq0 = cpspch(p[2]); diff = cpspch(p[3]) - freq0; tf0 = p[5]; tfN = p[6]; sset(SR, freq0, tf0, tfN, strumq1); dq = curdelayq; delayset(SR, cpspch(p[9]), dq); amp = p[12]; amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, dur, amplen, amptabs); } else { rtcmix_advise("BEND1", "Setting phrase curve to all 1's."); aamp = amp; } glissf = floc((int)p[4]); if (glissf) { int leng = fsize((int)p[4]); tableset(SR, p[1],leng,tags); } else return die("BEND1", "You haven't made the glissando function (table %d).", (int)p[4]); dgain = p[7]; fbgain = p[8]/dgain; cleanlevel = p[10]; distlevel = p[11]; reset = (int)p[13]; if (reset == 0) reset = 100; spread = p[14]; d = 0.0; return nSamps(); }
/************************************************************************* * This function computes the initial id/ed **************************************************************************/ void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph) { int i, j, /*k, l,*/ nvtxs, ncon, nbnd, mincut; idxtype *xadj, *adjncy, *adjwgt; float *nvwgt, *npwgts; idxtype *id, *ed, *where; idxtype *bndptr, *bndind; int me/*, other*/; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; npwgts = sset(2*ncon, 0.0, graph->npwgts); id = idxset(nvtxs, 0, graph->id); ed = idxset(nvtxs, 0, graph->ed); bndptr = idxset(nvtxs, -1, graph->bndptr); bndind = graph->bndind; /*------------------------------------------------------------ / Compute now the id/ed degrees /------------------------------------------------------------*/ nbnd = mincut = 0; for (i=0; i<nvtxs; i++) { ASSERT(where[i] >= 0 && where[i] <= 1); me = where[i]; saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); for (j=xadj[i]; j<xadj[i+1]; j++) { if (me == where[adjncy[j]]) id[i] += adjwgt[j]; else ed[i] += adjwgt[j]; } if (ed[i] > 0 || xadj[i] == xadj[i+1]) { mincut += ed[i]; bndptr[i] = nbnd; bndind[nbnd++] = i; } } graph->mincut = mincut/2; graph->nbnd = nbnd; }
/************************************************************************* * This function computes the initial id/ed **************************************************************************/ void Mc_Serial_Compute2WayPartitionParams(GraphType *graph) { int i, j, me, nvtxs, ncon, nbnd, mincut; idxtype *xadj, *adjncy, *adjwgt; float *nvwgt, *npwgts; idxtype *id, *ed, *where; idxtype *bndptr, *bndind; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; npwgts = sset(2*ncon, 0.0, graph->gnpwgts); id = idxset(nvtxs, 0, graph->sendind); ed = idxset(nvtxs, 0, graph->recvind); bndptr = idxset(nvtxs, -1, graph->sendptr); bndind = graph->recvptr; /*------------------------------------------------------------ / Compute now the id/ed degrees /------------------------------------------------------------*/ nbnd = mincut = 0; for (i=0; i<nvtxs; i++) { me = where[i]; saxpy2(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); for (j=xadj[i]; j<xadj[i+1]; j++) { if (me == where[adjncy[j]]) id[i] += adjwgt[j]; else ed[i] += adjwgt[j]; } if (ed[i] > 0 || xadj[i] == xadj[i+1]) { mincut += ed[i]; bndptr[i] = nbnd; bndind[nbnd++] = i; } } graph->mincut = mincut/2; graph->gnvtxs = nbnd; }
Ostrum::Ostrum(float srate, float freq, int squish, float fundDecayTime, float nyquistDecayTime) : _srate(srate), _funddcy(fundDecayTime), _nyqdcy(nyquistDecayTime), _dcz1(0.0f) { // Size strum array so that it will work with freqs as low as kMinFreq. -JGG _dlen = int((1.0 / kMinFreq * _srate) + 0.5); _d = new float [_dlen]; _maxfreq = _srate * 0.333333f; // Prevent _d underflow. -JGG sset(freq, fundDecayTime, nyquistDecayTime); // Init this outside of sset, which may be called to change freq. -JGG _p = _n; randfill(); squisher(squish); }
/************************************************************************* * This function computes the balance of the partitioning **************************************************************************/ void Moc_ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec) { int i, j, nvtxs, ncon; float *kpwgts, *nvwgt; float balance; nvtxs = graph->nvtxs; ncon = graph->ncon; nvwgt = graph->nvwgt; kpwgts = fmalloc(nparts, "ComputePartitionInfo: kpwgts"); for (j=0; j<ncon; j++) { sset(nparts, 0.0, kpwgts); for (i=0; i<graph->nvtxs; i++) kpwgts[where[i]] += nvwgt[i*ncon+j]; ubvec[j] = (float)nparts*kpwgts[samax(nparts, kpwgts)]/ssum(nparts, kpwgts); } free(kpwgts); }
int VSTART1::run() { for (int i = 0; i < framesToRun(); i++) { if (--branch1 <= 0) { vsi = (( (rrand()+1.0)/2.0) * vsidiff) + vsibot; branch1 = (int)((float)vlen/vsi); } if (--branch2 <= 0) { if (amptable) aamp = tablei(currentFrame(), amptable, amptabs) * amp; float vamp = tablei(currentFrame(), eloc, tab) * vdepth; float freqch = oscili(vamp,vsi,vloc,vlen,&vphase); sset(SR, freq+freqch, tf0, tfN, strumq1); branch2 = reset; vphase += (float)branch2 * vsi; while (vphase >= (float) vlen) vphase -= (float) vlen; } float a = strum(d, strumq1); float b = dist(dgain*a); d = fbgain*delay(b, dq); float out[2]; out[0] = (cleanlevel*a + distlevel*b) * aamp; if (outputChannels() == 2) { /* split stereo files between the channels */ out[1] = (1.0 - spread) * out[0]; out[0] *= spread; } rtaddout(out); increment(); } return framesToRun(); }
SkTypeface* onMatchFamilyStyle(const char familyName[], const SkFontStyle& fontStyle) const override { SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); return sset->matchStyle(fontStyle); }
int VSTART1::init(double p[], int n_args) { // p0 = start; p1 = dur; p2 = pitch (oct.pc); p3 = fundamental decay time // p4 = nyquist decay time; p5 = distortion gain; p6 = feedback gain // p7 = feedback pitch (oct.pc); p8 = clean signal level // p9 = distortion signal level; p10 = amp; p11 = squish // p12 = low vibrato freq range; p13 = hi vibrato freq range // p14 = vibrato freq depth (expressed in cps); p15 = random seed value // p16 = pitch update (default 200/sec) // p17 = stereo spread [optional] // p18 = flag for deleting pluck arrays (used by FRET, BEND, etc.) [optional] // assumes makegen 1 is the amplitude envelope, makegen 2 is the vibrato // function, and makegen 3 is the vibrato amplitude envelope if (rtsetoutput(p[0], p[1], this) == -1) return DONT_SCHEDULE; strumq1 = new StrumQueue; strumq1->ref(); curstrumq[0] = strumq1; freq = cpspch(p[2]); tf0 = p[3]; tfN = p[4]; sset(SR, freq, tf0, tfN, strumq1); randfill(1.0, (int)p[11], strumq1); dq = new DelayQueue; dq->ref(); curdelayq = dq; delayset(SR, cpspch(p[7]), dq); delayclean(dq); amp = p[10]; amptable = floc(1); if (amptable) { int amplen = fsize(1); tableset(SR, p[1], amplen, amptabs); } else { rtcmix_advise("VSTART1", "Setting phrase curve to all 1's."); aamp = amp; } vloc = floc(2); if (vloc == NULL) return die("VSTART1", "You need to store a vibrato function in gen num. 2."); vlen = fsize(2); vsibot = p[12] * (float)vlen/SR; vsidiff = vsibot - (p[13] * (float)vlen/SR); srrand((int)p[15]); vsi = ((rrand()+1.0)/2.0) * vsidiff; vsi += vsibot; vphase = 0.0; eloc = floc(3); if (eloc == NULL) return die("VSTART1", "You need to store a vibrato amp. envelope in gen num. 3."); int elen = fsize(3); tableset(SR, p[1], elen, tab); dgain = p[5]; fbgain = p[6]/dgain; cleanlevel = p[8]; distlevel = p[9]; vdepth = p[14]; reset = (int)p[16]; if (reset == 0) reset = 200; spread = p[17]; deleteflag = (int)p[18]; d = 0.0; return nSamps(); }
/************************************************************************* * This function performs k-way refinement **************************************************************************/ void Moc_KWayFM(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) { int h, i, ii, iii, j, k, c; int pass, nvtxs, nedges, ncon; int nmoves, nmoved, nswaps, nzgswaps; /* int gnswaps, gnzgswaps; */ int me, firstvtx, lastvtx, yourlastvtx; int from, to = -1, oldto, oldcut, mydomain, yourdomain, imbalanced, overweight; int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; int nlupd, nsupd, nnbrs, nchanged; idxtype *xadj, *ladjncy, *adjwgt, *vtxdist; idxtype *where, *tmp_where, *moved; floattype *lnpwgts, *gnpwgts, *ognpwgts, *pgnpwgts, *movewgts, *overfill; idxtype *update, *supdate, *rupdate, *pe_updates; idxtype *changed, *perm, *pperm, *htable; idxtype *peind, *recvptr, *sendptr; KeyValueType *swchanges, *rwchanges; RInfoType *rinfo, *myrinfo, *tmp_myrinfo, *tmp_rinfo; EdgeType *tmp_edegrees, *my_edegrees, *your_edegrees; floattype lbvec[MAXNCON], *nvwgt, *badmaxpwgt, *ubvec, *tpwgts, lbavg, ubavg; int *nupds_pe; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); /*************************/ /* set up common aliases */ /*************************/ nvtxs = graph->nvtxs; nedges = graph->nedges; ncon = graph->ncon; vtxdist = graph->vtxdist; xadj = graph->xadj; ladjncy = graph->adjncy; adjwgt = graph->adjwgt; firstvtx = vtxdist[mype]; lastvtx = vtxdist[mype+1]; where = graph->where; rinfo = graph->rinfo; lnpwgts = graph->lnpwgts; gnpwgts = graph->gnpwgts; ubvec = ctrl->ubvec; tpwgts = ctrl->tpwgts; nnbrs = graph->nnbrs; peind = graph->peind; recvptr = graph->recvptr; sendptr = graph->sendptr; changed = idxmalloc(nvtxs, "KWR: changed"); rwchanges = wspace->pairs; swchanges = rwchanges + recvptr[nnbrs]; /************************************/ /* set up important data structures */ /************************************/ perm = idxmalloc(nvtxs, "KWR: perm"); pperm = idxmalloc(nparts, "KWR: pperm"); update = idxmalloc(nvtxs, "KWR: update"); supdate = wspace->indices; rupdate = supdate + recvptr[nnbrs]; nupds_pe = imalloc(npes, "KWR: nupds_pe"); htable = idxsmalloc(nvtxs+graph->nrecv, 0, "KWR: lhtable"); badmaxpwgt = fmalloc(nparts*ncon, "badmaxpwgt"); for (i=0; i<nparts; i++) { for (h=0; h<ncon; h++) { badmaxpwgt[i*ncon+h] = ubvec[h]*tpwgts[i*ncon+h]; } } movewgts = fmalloc(nparts*ncon, "KWR: movewgts"); ognpwgts = fmalloc(nparts*ncon, "KWR: ognpwgts"); pgnpwgts = fmalloc(nparts*ncon, "KWR: pgnpwgts"); overfill = fmalloc(nparts*ncon, "KWR: overfill"); moved = idxmalloc(nvtxs, "KWR: moved"); tmp_where = idxmalloc(nvtxs+graph->nrecv, "KWR: tmp_where"); tmp_rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "KWR: tmp_rinfo"); tmp_edegrees = (EdgeType *)GKmalloc(sizeof(EdgeType)*nedges, "KWR: tmp_edegrees"); idxcopy(nvtxs+graph->nrecv, where, tmp_where); for (i=0; i<nvtxs; i++) { tmp_rinfo[i].id = rinfo[i].id; tmp_rinfo[i].ed = rinfo[i].ed; tmp_rinfo[i].ndegrees = rinfo[i].ndegrees; tmp_rinfo[i].degrees = tmp_edegrees+xadj[i]; for (j=0; j<rinfo[i].ndegrees; j++) { tmp_rinfo[i].degrees[j].edge = rinfo[i].degrees[j].edge; tmp_rinfo[i].degrees[j].ewgt = rinfo[i].degrees[j].ewgt; } } nswaps = nzgswaps = 0; /*********************************************************/ /* perform a small number of passes through the vertices */ /*********************************************************/ for (pass=0; pass<npasses; pass++) { if (mype == 0) RandomPermute(nparts, pperm, 1); MPI_Bcast((void *)pperm, nparts, IDX_DATATYPE, 0, ctrl->comm); FastRandomPermute(nvtxs, perm, 1); oldcut = graph->mincut; /* check to see if the partitioning is imbalanced */ Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); ubavg = savg(ncon, ubvec); lbavg = savg(ncon, lbvec); imbalanced = (lbavg > ubavg) ? 1 : 0; for (c=0; c<2; c++) { scopy(ncon*nparts, gnpwgts, ognpwgts); sset(ncon*nparts, 0.0, movewgts); nmoved = 0; /**********************************************/ /* PASS ONE -- record stats for desired moves */ /**********************************************/ for (iii=0; iii<nvtxs; iii++) { i = perm[iii]; from = tmp_where[i]; nvwgt = graph->nvwgt+i*ncon; for (h=0; h<ncon; h++) if (fabs(nvwgt[h]-gnpwgts[from*ncon+h]) < SMALLFLOAT) break; if (h < ncon) { continue; } /* check for a potential improvement */ if (tmp_rinfo[i].ed >= tmp_rinfo[i].id) { my_edegrees = tmp_rinfo[i].degrees; for (k=0; k<tmp_rinfo[i].ndegrees; k++) { to = my_edegrees[k].edge; if (ProperSide(c, pperm[from], pperm[to])) { for (h=0; h<ncon; h++) if (gnpwgts[to*ncon+h]+nvwgt[h] > badmaxpwgt[to*ncon+h] && nvwgt[h] > 0.0) break; if (h == ncon) break; } } oldto = to; /* check if a subdomain was found that fits */ if (k < tmp_rinfo[i].ndegrees) { for (j=k+1; j<tmp_rinfo[i].ndegrees; j++) { to = my_edegrees[j].edge; if (ProperSide(c, pperm[from], pperm[to])) { for (h=0; h<ncon; h++) if (gnpwgts[to*ncon+h]+nvwgt[h] > badmaxpwgt[to*ncon+h] && nvwgt[h] > 0.0) break; if (h == ncon) { if (my_edegrees[j].ewgt > my_edegrees[k].ewgt || (my_edegrees[j].ewgt == my_edegrees[k].ewgt && IsHBalanceBetterTT(ncon,gnpwgts+oldto*ncon,gnpwgts+to*ncon,nvwgt,ubvec))){ k = j; oldto = my_edegrees[k].edge; } } } } to = oldto; if (my_edegrees[k].ewgt > tmp_rinfo[i].id || (my_edegrees[k].ewgt == tmp_rinfo[i].id && (imbalanced || graph->level > 3 || iii % 8 == 0) && IsHBalanceBetterFT(ncon,gnpwgts+from*ncon,gnpwgts+to*ncon,nvwgt,ubvec))){ /****************************************/ /* Update tmp arrays of the moved vertex */ /****************************************/ tmp_where[i] = to; moved[nmoved++] = i; for (h=0; h<ncon; h++) { lnpwgts[to*ncon+h] += nvwgt[h]; lnpwgts[from*ncon+h] -= nvwgt[h]; gnpwgts[to*ncon+h] += nvwgt[h]; gnpwgts[from*ncon+h] -= nvwgt[h]; movewgts[to*ncon+h] += nvwgt[h]; movewgts[from*ncon+h] -= nvwgt[h]; } tmp_rinfo[i].ed += tmp_rinfo[i].id-my_edegrees[k].ewgt; SWAP(tmp_rinfo[i].id, my_edegrees[k].ewgt, j); if (my_edegrees[k].ewgt == 0) { tmp_rinfo[i].ndegrees--; my_edegrees[k].edge = my_edegrees[tmp_rinfo[i].ndegrees].edge; my_edegrees[k].ewgt = my_edegrees[tmp_rinfo[i].ndegrees].ewgt; } else { my_edegrees[k].edge = from; } /* Update the degrees of adjacent vertices */ for (j=xadj[i]; j<xadj[i+1]; j++) { /* no need to bother about vertices on different pe's */ if (ladjncy[j] >= nvtxs) continue; me = ladjncy[j]; mydomain = tmp_where[me]; myrinfo = tmp_rinfo+me; your_edegrees = myrinfo->degrees; if (mydomain == from) { INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); } else { if (mydomain == to) { INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); } } /* Remove contribution from the .ed of 'from' */ if (mydomain != from) { for (k=0; k<myrinfo->ndegrees; k++) { if (your_edegrees[k].edge == from) { if (your_edegrees[k].ewgt == adjwgt[j]) { myrinfo->ndegrees--; your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge; your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt; } else { your_edegrees[k].ewgt -= adjwgt[j]; } break; } } } /* Add contribution to the .ed of 'to' */ if (mydomain != to) { for (k=0; k<myrinfo->ndegrees; k++) { if (your_edegrees[k].edge == to) { your_edegrees[k].ewgt += adjwgt[j]; break; } } if (k == myrinfo->ndegrees) { your_edegrees[myrinfo->ndegrees].edge = to; your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; } } } } } } } /******************************************/ /* Let processors know the subdomain wgts */ /* if all proposed moves commit. */ /******************************************/ MPI_Allreduce((void *)lnpwgts, (void *)pgnpwgts, nparts*ncon, MPI_DOUBLE, MPI_SUM, ctrl->comm); /**************************/ /* compute overfill array */ /**************************/ overweight = 0; for (j=0; j<nparts; j++) { for (h=0; h<ncon; h++) { if (pgnpwgts[j*ncon+h] > ognpwgts[j*ncon+h]) { overfill[j*ncon+h] = (pgnpwgts[j*ncon+h]-badmaxpwgt[j*ncon+h]) / (pgnpwgts[j*ncon+h]-ognpwgts[j*ncon+h]); } else { overfill[j*ncon+h] = 0.0; } overfill[j*ncon+h] = amax(overfill[j*ncon+h], 0.0); overfill[j*ncon+h] *= movewgts[j*ncon+h]; if (overfill[j*ncon+h] > 0.0) overweight = 1; ASSERTP(ctrl, ognpwgts[j*ncon+h] <= badmaxpwgt[j*ncon+h] || pgnpwgts[j*ncon+h] <= ognpwgts[j*ncon+h], (ctrl, "%.4f %.4f %.4f\n", ognpwgts[j*ncon+h], badmaxpwgt[j*ncon+h], pgnpwgts[j*ncon+h])); } } /****************************************************/ /* select moves to undo according to overfill array */ /****************************************************/ if (overweight == 1) { for (iii=0; iii<nmoved; iii++) { i = moved[iii]; oldto = tmp_where[i]; nvwgt = graph->nvwgt+i*ncon; my_edegrees = tmp_rinfo[i].degrees; for (k=0; k<tmp_rinfo[i].ndegrees; k++) if (my_edegrees[k].edge == where[i]) break; for (h=0; h<ncon; h++) if (nvwgt[h] > 0.0 && overfill[oldto*ncon+h] > nvwgt[h]/4.0) break; /**********************************/ /* nullify this move if necessary */ /**********************************/ if (k != tmp_rinfo[i].ndegrees && h != ncon) { moved[iii] = -1; from = oldto; to = where[i]; for (h=0; h<ncon; h++) { overfill[oldto*ncon+h] = amax(overfill[oldto*ncon+h]-nvwgt[h], 0.0); } tmp_where[i] = to; tmp_rinfo[i].ed += tmp_rinfo[i].id-my_edegrees[k].ewgt; SWAP(tmp_rinfo[i].id, my_edegrees[k].ewgt, j); if (my_edegrees[k].ewgt == 0) { tmp_rinfo[i].ndegrees--; my_edegrees[k].edge = my_edegrees[tmp_rinfo[i].ndegrees].edge; my_edegrees[k].ewgt = my_edegrees[tmp_rinfo[i].ndegrees].ewgt; } else { my_edegrees[k].edge = from; } for (h=0; h<ncon; h++) { lnpwgts[to*ncon+h] += nvwgt[h]; lnpwgts[from*ncon+h] -= nvwgt[h]; } /* Update the degrees of adjacent vertices */ for (j=xadj[i]; j<xadj[i+1]; j++) { /* no need to bother about vertices on different pe's */ if (ladjncy[j] >= nvtxs) continue; me = ladjncy[j]; mydomain = tmp_where[me]; myrinfo = tmp_rinfo+me; your_edegrees = myrinfo->degrees; if (mydomain == from) { INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); } else { if (mydomain == to) { INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); } } /* Remove contribution from the .ed of 'from' */ if (mydomain != from) { for (k=0; k<myrinfo->ndegrees; k++) { if (your_edegrees[k].edge == from) { if (your_edegrees[k].ewgt == adjwgt[j]) { myrinfo->ndegrees--; your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge; your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt; } else { your_edegrees[k].ewgt -= adjwgt[j]; } break; } } } /* Add contribution to the .ed of 'to' */ if (mydomain != to) { for (k=0; k<myrinfo->ndegrees; k++) { if (your_edegrees[k].edge == to) { your_edegrees[k].ewgt += adjwgt[j]; break; } } if (k == myrinfo->ndegrees) { your_edegrees[myrinfo->ndegrees].edge = to; your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; } } } } } } /*************************************************/ /* PASS TWO -- commit the remainder of the moves */ /*************************************************/ nlupd = nsupd = nmoves = nchanged = 0; for (iii=0; iii<nmoved; iii++) { i = moved[iii]; if (i == -1) continue; where[i] = tmp_where[i]; /* Make sure to update the vertex information */ if (htable[i] == 0) { /* make sure you do the update */ htable[i] = 1; update[nlupd++] = i; } /* Put the vertices adjacent to i into the update array */ for (j=xadj[i]; j<xadj[i+1]; j++) { k = ladjncy[j]; if (htable[k] == 0) { htable[k] = 1; if (k<nvtxs) update[nlupd++] = k; else supdate[nsupd++] = k; } } nmoves++; nswaps++; /* check number of zero-gain moves */ for (k=0; k<rinfo[i].ndegrees; k++) if (rinfo[i].degrees[k].edge == to) break; if (rinfo[i].id == rinfo[i].degrees[k].ewgt) nzgswaps++; if (graph->pexadj[i+1]-graph->pexadj[i] > 0) changed[nchanged++] = i; } /* Tell interested pe's the new where[] info for the interface vertices */ CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, swchanges, rwchanges, wspace->pv4); IFSET(ctrl->dbglvl, DBG_RMOVEINFO, rprintf(ctrl, "\t[%d %d], [%.4f], [%d %d %d]\n", pass, c, badmaxpwgt[0], GlobalSESum(ctrl, nmoves), GlobalSESum(ctrl, nsupd), GlobalSESum(ctrl, nlupd))); /*------------------------------------------------------------- / Time to communicate with processors to send the vertices / whose degrees need to be update. /-------------------------------------------------------------*/ /* Issue the receives first */ for (i=0; i<nnbrs; i++) { MPI_Irecv((void *)(rupdate+sendptr[i]), sendptr[i+1]-sendptr[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); } /* Issue the sends next. This needs some preporcessing */ for (i=0; i<nsupd; i++) { htable[supdate[i]] = 0; supdate[i] = graph->imap[supdate[i]]; } iidxsort(nsupd, supdate); for (j=i=0; i<nnbrs; i++) { yourlastvtx = vtxdist[peind[i]+1]; for (k=j; k<nsupd && supdate[k] < yourlastvtx; k++); MPI_Isend((void *)(supdate+j), k-j, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); j = k; } /* OK, now get into the loop waiting for the send/recv operations to finish */ MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); for (i=0; i<nnbrs; i++) MPI_Get_count(ctrl->statuses+i, IDX_DATATYPE, nupds_pe+i); MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); /*------------------------------------------------------------- / Place the recieved to-be updated vertices into update[] /-------------------------------------------------------------*/ for (i=0; i<nnbrs; i++) { pe_updates = rupdate+sendptr[i]; for (j=0; j<nupds_pe[i]; j++) { k = pe_updates[j]; if (htable[k-firstvtx] == 0) { htable[k-firstvtx] = 1; update[nlupd++] = k-firstvtx; } } } /*------------------------------------------------------------- / Update the rinfo of the vertices in the update[] array /-------------------------------------------------------------*/ for (ii=0; ii<nlupd; ii++) { i = update[ii]; ASSERT(ctrl, htable[i] == 1); htable[i] = 0; mydomain = where[i]; myrinfo = rinfo+i; tmp_myrinfo = tmp_rinfo+i; my_edegrees = myrinfo->degrees; your_edegrees = tmp_myrinfo->degrees; graph->lmincut -= myrinfo->ed; myrinfo->ndegrees = 0; myrinfo->id = 0; myrinfo->ed = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { yourdomain = where[ladjncy[j]]; if (mydomain != yourdomain) { myrinfo->ed += adjwgt[j]; for (k=0; k<myrinfo->ndegrees; k++) { if (my_edegrees[k].edge == yourdomain) { my_edegrees[k].ewgt += adjwgt[j]; your_edegrees[k].ewgt += adjwgt[j]; break; } } if (k == myrinfo->ndegrees) { my_edegrees[k].edge = yourdomain; my_edegrees[k].ewgt = adjwgt[j]; your_edegrees[k].edge = yourdomain; your_edegrees[k].ewgt = adjwgt[j]; myrinfo->ndegrees++; } ASSERT(ctrl, myrinfo->ndegrees <= xadj[i+1]-xadj[i]); ASSERT(ctrl, tmp_myrinfo->ndegrees <= xadj[i+1]-xadj[i]); } else { myrinfo->id += adjwgt[j]; } } graph->lmincut += myrinfo->ed; tmp_myrinfo->id = myrinfo->id; tmp_myrinfo->ed = myrinfo->ed; tmp_myrinfo->ndegrees = myrinfo->ndegrees; } /* finally, sum-up the partition weights */ MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon, MPI_DOUBLE, MPI_SUM, ctrl->comm); } graph->mincut = GlobalSESum(ctrl, graph->lmincut)/2; if (graph->mincut == oldcut) break; } /* gnswaps = GlobalSESum(ctrl, nswaps); gnzgswaps = GlobalSESum(ctrl, nzgswaps); if (mype == 0) printf("niters: %d, nswaps: %d, nzgswaps: %d\n", pass+1, gnswaps, gnzgswaps); */ GKfree((void **)&badmaxpwgt, (void **)&update, (void **)&nupds_pe, (void **)&htable, LTERM); GKfree((void **)&changed, (void **)&pperm, (void **)&perm, (void **)&moved, LTERM); GKfree((void **)&pgnpwgts, (void **)&ognpwgts, (void **)&overfill, (void **)&movewgts, LTERM); GKfree((void **)&tmp_where, (void **)&tmp_rinfo, (void **)&tmp_edegrees, LTERM); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); }
/************************************************************************* * This function performs an edge-based FM refinement **************************************************************************/ int BalanceMyLink(CtrlType *ctrl, GraphType *graph, idxtype *home, int me, int you, float *flows, float maxdiff, float *diff_cost, float *diff_lbavg, float avgvwgt) { int h, i, ii, j, k; int nvtxs, ncon; int nqueues, minval, maxval, higain, vtx, edge, totalv; int from, to, qnum, index, nchanges, cut, tmp; int pass, nswaps, nmoves, multiplier; idxtype *xadj, *vsize, *adjncy, *adjwgt, *where, *ed, *id; idxtype *hval, *nvpq, *inq, *map, *rmap, *ptr, *myqueue, *changes; float *nvwgt, lbvec[MAXNCON], pwgts[MAXNCON*2], tpwgts[MAXNCON*2], my_wgt[MAXNCON]; float newgain, oldgain = 0.0; float lbavg, bestflow, mycost; float ipc_factor, redist_factor, ftmp; FPQueueType *queues; int mype; MPI_Comm_rank(MPI_COMM_WORLD, &mype); nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; vsize = graph->vsize; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; ipc_factor = ctrl->ipc_factor; redist_factor = ctrl->redist_factor; hval = idxmalloc(nvtxs*7, "hval"); id = hval + nvtxs; ed = hval + nvtxs*2; map = hval + nvtxs*3; rmap = hval + nvtxs*4; myqueue = hval + nvtxs*5; changes = hval + nvtxs*6; sset(ncon*2, 0.0, pwgts); for (h=0; h<ncon; h++) { tpwgts[h] = -1.0 * flows[h]; tpwgts[ncon+h] = flows[h]; } for (i=0; i<nvtxs; i++) { if (where[i] == me) { for (h=0; h<ncon; h++) { tpwgts[h] += nvwgt[i*ncon+h]; pwgts[h] += nvwgt[i*ncon+h]; } } else { ASSERTS(where[i] == you); for (h=0; h<ncon; h++) { tpwgts[ncon+h] += nvwgt[i*ncon+h]; pwgts[ncon+h] += nvwgt[i*ncon+h]; } } } /* we don't want any tpwgts to be less than zero */ for (h=0; h<ncon; h++) { if (tpwgts[h] < 0.0) { tpwgts[ncon+h] += tpwgts[h]; tpwgts[h] = 0.0; } if (tpwgts[ncon+h] < 0.0) { tpwgts[h] += tpwgts[ncon+h]; tpwgts[ncon+h] = 0.0; } } /*******************************/ /* insert vertices into queues */ /*******************************/ minval = maxval = 0; multiplier = 1; for (i=0; i<ncon; i++) { multiplier *= (i+1); maxval += i*multiplier; minval += (ncon-1-i)*multiplier; } nqueues = maxval-minval+1; nvpq = idxsmalloc(nqueues, 0, "nvpq"); ptr = idxmalloc(nqueues+1, "ptr"); inq = idxmalloc(nqueues*2, "inq"); queues = (FPQueueType *)(GKmalloc(sizeof(FPQueueType)*nqueues*2, "queues")); for (i=0; i<nvtxs; i++) hval[i] = Moc_HashVwgts(ncon, nvwgt+i*ncon) - minval; for (i=0; i<nvtxs; i++) nvpq[hval[i]]++; ptr[0] = 0; for (i=0; i<nqueues; i++) ptr[i+1] = ptr[i] + nvpq[i]; for (i=0; i<nvtxs; i++) { map[i] = ptr[hval[i]]; rmap[ptr[hval[i]]++] = i; } for (i=nqueues-1; i>0; i--) ptr[i] = ptr[i-1]; ptr[0] = 0; /* initialize queues */ for (i=0; i<nqueues; i++) if (nvpq[i] > 0) { FPQueueInit(queues+i, nvpq[i]); FPQueueInit(queues+i+nqueues, nvpq[i]); } /* compute internal/external degrees */ idxset(nvtxs, 0, id); idxset(nvtxs, 0, ed); for (j=0; j<nvtxs; j++) for (k=xadj[j]; k<xadj[j+1]; k++) if (where[adjncy[k]] == where[j]) id[j] += adjwgt[k]; else ed[j] += adjwgt[k]; nswaps = 0; for (pass=0; pass<N_MOC_BAL_PASSES; pass++) { idxset(nvtxs, -1, myqueue); idxset(nqueues*2, 0, inq); /* insert vertices into correct queues */ for (j=0; j<nvtxs; j++) { index = (where[j] == me) ? 0 : nqueues; newgain = ipc_factor*(float)(ed[j]-id[j]); if (home[j] == me || home[j] == you) { if (where[j] == home[j]) newgain -= redist_factor*(float)vsize[j]; else newgain += redist_factor*(float)vsize[j]; } FPQueueInsert(queues+hval[j]+index, map[j]-ptr[hval[j]], newgain); myqueue[j] = (where[j] == me) ? 0 : 1; inq[hval[j]+index]++; } /* bestflow = sfavg(ncon, flows); */ for (j=0, h=0; h<ncon; h++) if (fabs(flows[h]) > fabs(flows[j])) j = h; bestflow = fabs(flows[j]); nchanges = nmoves = 0; for (ii=0; ii<nvtxs/2; ii++) { from = -1; Moc_DynamicSelectQueue(nqueues, ncon, me, you, inq, flows, &from, &qnum, minval, avgvwgt, maxdiff); /* can't find a vertex in one subdomain, try the other */ if (from != -1 && qnum == -1) { from = (from == me) ? you : me; if (from == me) { for (j=0; j<ncon; j++) if (flows[j] > avgvwgt) break; } else { for (j=0; j<ncon; j++) if (flows[j] < -1.0*avgvwgt) break; } if (j != ncon) Moc_DynamicSelectQueue(nqueues, ncon, me, you, inq, flows, &from, &qnum, minval, avgvwgt, maxdiff); } if (qnum == -1) break; to = (from == me) ? you : me; index = (from == me) ? 0 : nqueues; higain = FPQueueGetMax(queues+qnum+index); inq[qnum+index]--; ASSERTS(higain != -1); /*****************/ /* make the swap */ /*****************/ vtx = rmap[higain+ptr[qnum]]; myqueue[vtx] = -1; where[vtx] = to; nswaps++; nmoves++; /* update the flows */ for (j=0; j<ncon; j++) flows[j] += (to == me) ? nvwgt[vtx*ncon+j] : -1.0*nvwgt[vtx*ncon+j]; /* ftmp = sfavg(ncon, flows); */ for (j=0, h=0; h<ncon; h++) if (fabs(flows[h]) > fabs(flows[j])) j = h; ftmp = fabs(flows[j]); if (ftmp < bestflow) { bestflow = ftmp; nchanges = 0; } else { changes[nchanges++] = vtx; } SWAP(id[vtx], ed[vtx], tmp); for (j=xadj[vtx]; j<xadj[vtx+1]; j++) { edge = adjncy[j]; /* must compute oldgain before changing id/ed */ if (myqueue[edge] != -1) { oldgain = ipc_factor*(float)(ed[edge]-id[edge]); if (home[edge] == me || home[edge] == you) { if (where[edge] == home[edge]) oldgain -= redist_factor*(float)vsize[edge]; else oldgain += redist_factor*(float)vsize[edge]; } } tmp = (to == where[edge] ? adjwgt[j] : -adjwgt[j]); INC_DEC(id[edge], ed[edge], tmp); if (myqueue[edge] != -1) { newgain = ipc_factor*(float)(ed[edge]-id[edge]); if (home[edge] == me || home[edge] == you) { if (where[edge] == home[edge]) newgain -= redist_factor*(float)vsize[edge]; else newgain += redist_factor*(float)vsize[edge]; } FPQueueUpdate(queues+hval[edge]+(nqueues*myqueue[edge]), map[edge]-ptr[hval[edge]], oldgain, newgain); } } } /****************************/ /* now go back to best flow */ /****************************/ nswaps -= nchanges; nmoves -= nchanges; for (i=0; i<nchanges; i++) { vtx = changes[i]; from = where[vtx]; where[vtx] = to = (from == me) ? you : me; SWAP(id[vtx], ed[vtx], tmp); for (j=xadj[vtx]; j<xadj[vtx+1]; j++) { edge = adjncy[j]; tmp = (to == where[edge] ? adjwgt[j] : -adjwgt[j]); INC_DEC(id[edge], ed[edge], tmp); } } for (i=0; i<nqueues; i++) { if (nvpq[i] > 0) { FPQueueReset(queues+i); FPQueueReset(queues+i+nqueues); } } if (nmoves == 0) break; } /***************************/ /* compute 2-way imbalance */ /***************************/ sset(ncon, 0.0, my_wgt); for (i=0; i<nvtxs; i++) if (where[i] == me) for (h=0; h<ncon; h++) my_wgt[h] += nvwgt[i*ncon+h]; for (i=0; i<ncon; i++) { ftmp = (pwgts[i]+pwgts[ncon+i])/2.0; if (ftmp != 0.0) lbvec[i] = fabs(my_wgt[i]-tpwgts[i]) / ftmp; else lbvec[i] = 0.0; } lbavg = savg(ncon, lbvec); *diff_lbavg = lbavg; /****************/ /* compute cost */ /****************/ cut = totalv = 0; for (i=0; i<nvtxs; i++) { if (where[i] != home[i]) totalv += vsize[i]; for (j=xadj[i]; j<xadj[i+1]; j++) if (where[adjncy[j]] != where[i]) cut += adjwgt[j]; } cut /= 2; mycost = cut*ipc_factor + totalv*redist_factor; *diff_cost = mycost; /* free memory */ for (i=0; i<nqueues; i++) if (nvpq[i] > 0) { FPQueueFree(queues+i); FPQueueFree(queues+i+nqueues); } GKfree((void **)&hval, (void **)&nvpq, (void **)&ptr, (void **)&inq, (void **)&queues, LTERM); return nswaps; }
/************************************************************************* * This function computes the initial id/ed **************************************************************************/ void Moc_ComputePartitionParams(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int h, i, j, k; int nvtxs, ncon; int firstvtx, lastvtx; idxtype *xadj, *ladjncy, *adjwgt, *vtxdist; floattype *lnpwgts, *gnpwgts; idxtype *where, *swhere, *rwhere; RInfoType *rinfo, *myrinfo; EdgeType *edegrees; int me, other; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayInitTmr)); nvtxs = graph->nvtxs; ncon = graph->ncon; vtxdist = graph->vtxdist; xadj = graph->xadj; ladjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; rinfo = graph->rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "CPP: rinfo"); lnpwgts = graph->lnpwgts = fmalloc(ctrl->nparts*ncon, "CPP: lnpwgts"); gnpwgts = graph->gnpwgts = fmalloc(ctrl->nparts*ncon, "CPP: gnpwgts"); sset(ctrl->nparts*ncon, 0, lnpwgts); firstvtx = vtxdist[ctrl->mype]; lastvtx = vtxdist[ctrl->mype+1]; /*------------------------------------------------------------ / Send/Receive the where information of interface vertices /------------------------------------------------------------*/ swhere = wspace->indices; rwhere = where + nvtxs; CommInterfaceData(ctrl, graph, where, swhere, rwhere); #ifdef DEBUG_COMPUTEPPARAM PrintVector(ctrl, nvtxs, firstvtx, where, "where"); #endif ASSERT(ctrl, wspace->nlarge >= xadj[nvtxs]); /*------------------------------------------------------------ / Compute now the id/ed degrees /------------------------------------------------------------*/ graph->lmincut = 0; for (i=0; i<nvtxs; i++) { me = where[i]; myrinfo = rinfo+i; for (h=0; h<ncon; h++) lnpwgts[me*ncon+h] += graph->nvwgt[i*ncon+h]; myrinfo->degrees = wspace->degrees + xadj[i]; myrinfo->ndegrees = myrinfo->id = myrinfo->ed = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { if (me == where[ladjncy[j]]) myrinfo->id += adjwgt[j]; else myrinfo->ed += adjwgt[j]; } if (myrinfo->ed > 0) { /* Time to do some serious work */ graph->lmincut += myrinfo->ed; edegrees = myrinfo->degrees; for (j=xadj[i]; j<xadj[i+1]; j++) { other = where[ladjncy[j]]; if (me != other) { for (k=0; k<myrinfo->ndegrees; k++) { if (edegrees[k].edge == other) { edegrees[k].ewgt += adjwgt[j]; break; } } if (k == myrinfo->ndegrees) { edegrees[k].edge = other; edegrees[k].ewgt = adjwgt[j]; myrinfo->ndegrees++; } ASSERT(ctrl, myrinfo->ndegrees <= xadj[i+1]-xadj[i]); } } } } #ifdef DEBUG_COMPUTEPPARAM PrintVector(ctrl, ctrl->nparts*ncon, 0, lnpwgts, "lnpwgts"); #endif /* Finally, sum-up the partition weights */ MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, ctrl->nparts*ncon, MPI_DOUBLE, MPI_SUM, ctrl->comm); graph->mincut = GlobalSESum(ctrl, graph->lmincut)/2; #ifdef DEBUG_COMPUTEPPARAM PrintVector(ctrl, ctrl->nparts*ncon, 0, gnpwgts, "gnpwgts"); #endif IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayInitTmr)); }
/************************************************************************* * This function computes the initial id/ed **************************************************************************/ void MocComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) { int i, j, k, l, nvtxs, ncon, nbnd, mincut, me, other; idxtype *xadj, *adjncy, *adjwgt, *where, *bndind, *bndptr; RInfoType *rinfo, *myrinfo; EDegreeType *myedegrees; float *nvwgt, *npwgts; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; npwgts = sset(ncon*nparts, 0.0, graph->npwgts); bndind = graph->bndind; bndptr = idxset(nvtxs, -1, graph->bndptr); rinfo = graph->rinfo; /*------------------------------------------------------------ / Compute now the id/ed degrees /------------------------------------------------------------*/ ctrl->wspace.cdegree = 0; nbnd = mincut = 0; for (i=0; i<nvtxs; i++) { me = where[i]; saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); myrinfo = rinfo+i; myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; myrinfo->edegrees = NULL; for (j=xadj[i]; j<xadj[i+1]; j++) { if (me != where[adjncy[j]]) myrinfo->ed += adjwgt[j]; } myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed; if (myrinfo->ed > 0) mincut += myrinfo->ed; if (myrinfo->ed-myrinfo->id >= 0) BNDInsert(nbnd, bndind, bndptr, i); /* Time to compute the particular external degrees */ if (myrinfo->ed > 0) { myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; for (j=xadj[i]; j<xadj[i+1]; j++) { other = where[adjncy[j]]; if (me != other) { for (k=0; k<myrinfo->ndegrees; k++) { if (myedegrees[k].pid == other) { myedegrees[k].ed += adjwgt[j]; break; } } if (k == myrinfo->ndegrees) { myedegrees[myrinfo->ndegrees].pid = other; myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; } } } ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]); } } graph->mincut = mincut/2; graph->nbnd = nbnd; }
SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[], const SkFontStyle& fontstyle) const { sk_sp<SkFontStyleSet> sset(this->matchFamily(familyName)); return sset->matchStyle(fontstyle); }
/************************************************************************* * This function computes the initial id/ed **************************************************************************/ void Mc_ComputeSerialPartitionParams(GraphType *graph, int nparts, EdgeType *degrees) { int i, j, k; int nvtxs, nedges, ncon, mincut, me, other; idxtype *xadj, *adjncy, *adjwgt, *where; RInfoType *rinfo, *myrinfo; EdgeType *mydegrees; float *nvwgt, *npwgts; int mype; MPI_Comm_rank(MPI_COMM_WORLD, &mype); nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; rinfo = graph->rinfo; npwgts = sset(ncon*nparts, 0.0, graph->gnpwgts); /*------------------------------------------------------------ / Compute now the id/ed degrees /------------------------------------------------------------*/ nedges = mincut = 0; for (i=0; i<nvtxs; i++) { me = where[i]; saxpy2(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); myrinfo = rinfo+i; myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; myrinfo->degrees = degrees + nedges; nedges += xadj[i+1]-xadj[i]; for (j=xadj[i]; j<xadj[i+1]; j++) { if (me == where[adjncy[j]]) { myrinfo->id += adjwgt[j]; } else { myrinfo->ed += adjwgt[j]; } } mincut += myrinfo->ed; /* Time to compute the particular external degrees */ if (myrinfo->ed > 0) { mydegrees = myrinfo->degrees; for (j=xadj[i]; j<xadj[i+1]; j++) { other = where[adjncy[j]]; if (me != other) { for (k=0; k<myrinfo->ndegrees; k++) { if (mydegrees[k].edge == other) { mydegrees[k].ewgt += adjwgt[j]; break; } } if (k == myrinfo->ndegrees) { mydegrees[myrinfo->ndegrees].edge = other; mydegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; } } } } } graph->mincut = mincut/2; return; }
int main() { std::vector<boost::dynamic_bitset<> > temp; std::vector<boost::dynamic_bitset<> > temp_search; for( int i = 0; i < 1024; i++ ) { temp.push_back(boost::dynamic_bitset<>()); for( int j = 0; j < 1024; j++ ) { int b = rand() >= RAND_MAX / 2; temp.back().push_back(b); } } temp_search = temp; std::random_shuffle( temp_search.begin(), temp_search.end()); for( int i = 0; i < 1024; i++ ) { temp_search.push_back(boost::dynamic_bitset<>()); for( int j = 0; j < 1024; j++ ) { int b = rand() >= RAND_MAX / 2; temp_search.back().push_back(b); } } // temp_search = temp; size_t found_vec = 0; size_t found_set = 0; ivy_mike::perf_timer pt; std::vector<boost::dynamic_bitset<> > svec = temp; std::sort(svec.begin(), svec.end()); pt.add_int(); for( int i = 0; i < 1000; ++i ) { for( std::vector< boost::dynamic_bitset< long unsigned int > >::iterator it = temp_search.begin(); it != temp_search.end(); ++it ) { bool found = std::binary_search( svec.begin(), svec.end(), *it ); if( found ) { found_vec++; } } } pt.add_int(); std::tr1::unordered_set<boost::dynamic_bitset<>, bitset_hash> sset( temp.begin(), temp.end() ); pt.add_int(); for( int i = 0; i < 1000; ++i ) { for( std::vector< boost::dynamic_bitset< long unsigned int > >::iterator it = temp_search.begin(); it != temp_search.end(); ++it ) { bool found = sset.find(*it) != sset.end(); if( found ) { found_set++; } } } pt.add_int(); pt.print(); std::cout << svec.size() << " " << sset.size() << "\n"; std::cout << found_vec << " " << found_set << "\n"; }
/*********************************************************************************** * This function is the testing routine for the adaptive multilevel partitioning code. * It computes a partition from scratch, it then moves the graph and changes some * of the vertex weights and then call the adaptive code. ************************************************************************************/ void TestParMetis_V3(char *filename, MPI_Comm comm) { int ncon, nparts, npes, mype, opt2, realcut; GraphType graph, mgraph; idxtype *part, *mpart, *savepart, *order, *sizes; int numflag=0, wgtflag=0, options[10], edgecut, ndims; float ipc2redist, *xyz, *tpwgts = NULL, ubvec[MAXNCON]; MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &mype); ndims = 2; ParallelReadGraph(&graph, filename, comm); xyz = ReadTestCoordinates(&graph, filename, 2, comm); MPI_Barrier(comm); part = idxmalloc(graph.nvtxs, "TestParMetis_V3: part"); tpwgts = fmalloc(MAXNCON*npes*2, "TestParMetis_V3: tpwgts"); sset(MAXNCON, 1.05, ubvec); graph.vwgt = idxsmalloc(graph.nvtxs*5, 1, "TestParMetis_V3: vwgt"); /*====================================================================== / ParMETIS_V3_PartKway /=======================================================================*/ options[0] = 1; options[1] = 3; options[2] = 1; wgtflag = 2; numflag = 0; edgecut = 0; for (nparts=2*npes; nparts>=npes/2 && nparts > 0; nparts = nparts/2) { for (ncon=1; ncon<=5; ncon+=2) { if (ncon > 1 && nparts > 1) Mc_AdaptGraph(&graph, part, ncon, nparts, comm); else idxset(graph.nvtxs, 1, graph.vwgt); for (opt2=1; opt2<=2; opt2++) { options[2] = opt2; sset(nparts*ncon, 1.0/(float)nparts, tpwgts); if (mype == 0) printf("\nTesting ParMETIS_V3_PartKway with options[1-2] = {%d %d}, Ncon: %d, Nparts: %d\n", options[1], options[2], ncon, nparts); ParMETIS_V3_PartKway(graph.vtxdist, graph.xadj, graph.adjncy, graph.vwgt, NULL, &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &comm); if (mype == 0) { printf("ParMETIS_V3_PartKway reported a cut of %d\n", edgecut); } } } } /*====================================================================== / ParMETIS_V3_PartGeomKway /=======================================================================*/ options[0] = 1; options[1] = 3; wgtflag = 2; numflag = 0; for (nparts=2*npes; nparts>=npes/2 && nparts > 0; nparts = nparts/2) { for (ncon=1; ncon<=5; ncon+=2) { if (ncon > 1) Mc_AdaptGraph(&graph, part, ncon, nparts, comm); else idxset(graph.nvtxs, 1, graph.vwgt); for (opt2=1; opt2<=2; opt2++) { options[2] = opt2; sset(nparts*ncon, 1.0/(float)nparts, tpwgts); if (mype == 0) printf("\nTesting ParMETIS_V3_PartGeomKway with options[1-2] = {%d %d}, Ncon: %d, Nparts: %d\n", options[1], options[2], ncon, nparts); ParMETIS_V3_PartGeomKway(graph.vtxdist, graph.xadj, graph.adjncy, graph.vwgt, NULL, &wgtflag, &numflag, &ndims, xyz, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &comm); if (mype == 0) { printf("ParMETIS_V3_PartGeomKway reported a cut of %d\n", edgecut); } } } } /*====================================================================== / ParMETIS_V3_PartGeom /=======================================================================*/ wgtflag = 0; numflag = 0; if (mype == 0) printf("\nTesting ParMETIS_V3_PartGeom\n"); /* ParMETIS_V3_PartGeom(graph.vtxdist, &ndims, xyz, part, &comm); */ if (mype == 0) printf("ParMETIS_V3_PartGeom partition complete\n"); /* realcut = ComputeRealCut(graph.vtxdist, part, filename, comm); if (mype == 0) printf("ParMETIS_V3_PartGeom reported a cut of %d\n", realcut); */ /*====================================================================== / ParMETIS_V3_RefineKway /=======================================================================*/ options[0] = 1; options[1] = 3; options[2] = 1; options[3] = COUPLED; nparts = npes; wgtflag = 0; numflag = 0; ncon = 1; sset(nparts*ncon, 1.0/(float)nparts, tpwgts); if (mype == 0) printf("\nTesting ParMETIS_V3_RefineKway with default options (before move)\n"); ParMETIS_V3_RefineKway(graph.vtxdist, graph.xadj, graph.adjncy, NULL, NULL, &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &comm); MALLOC_CHECK(NULL); if (mype == 0) { printf("ParMETIS_V3_RefineKway reported a cut of %d\n", edgecut); } MALLOC_CHECK(NULL); /* Compute a good partition and move the graph. Do so quietly! */ options[0] = 0; nparts = npes; wgtflag = 0; numflag = 0; ncon = 1; sset(nparts*ncon, 1.0/(float)nparts, tpwgts); ParMETIS_V3_PartKway(graph.vtxdist, graph.xadj, graph.adjncy, NULL, NULL, &wgtflag, &numflag, &ncon, &npes, tpwgts, ubvec, options, &edgecut, part, &comm); TestMoveGraph(&graph, &mgraph, part, comm); GKfree((void *)&(graph.vwgt), LTERM); mpart = idxsmalloc(mgraph.nvtxs, mype, "TestParMetis_V3: mpart"); savepart = idxmalloc(mgraph.nvtxs, "TestParMetis_V3: savepart"); MALLOC_CHECK(NULL); /*====================================================================== / ParMETIS_V3_RefineKway /=======================================================================*/ options[0] = 1; options[1] = 3; options[3] = COUPLED; nparts = npes; wgtflag = 0; numflag = 0; for (ncon=1; ncon<=5; ncon+=2) { for (opt2=1; opt2<=2; opt2++) { options[2] = opt2; sset(nparts*ncon, 1.0/(float)nparts, tpwgts); if (mype == 0) printf("\nTesting ParMETIS_V3_RefineKway with options[1-3] = {%d %d %d}, Ncon: %d, Nparts: %d\n", options[1], options[2], options[3], ncon, nparts); ParMETIS_V3_RefineKway(mgraph.vtxdist, mgraph.xadj, mgraph.adjncy, NULL, NULL, &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, mpart, &comm); if (mype == 0) { printf("ParMETIS_V3_RefineKway reported a cut of %d\n", edgecut); } } } /*====================================================================== / ParMETIS_V3_AdaptiveRepart /=======================================================================*/ mgraph.vwgt = idxsmalloc(mgraph.nvtxs*5, 1, "TestParMetis_V3: mgraph.vwgt"); mgraph.vsize = idxsmalloc(mgraph.nvtxs, 1, "TestParMetis_V3: mgraph.vsize"); AdaptGraph(&mgraph, 4, comm); options[0] = 1; options[1] = 7; options[3] = COUPLED; wgtflag = 2; numflag = 0; for (nparts=2*npes; nparts>=npes/2; nparts = nparts/2) { ncon = 1; wgtflag = 0; options[0] = 0; sset(nparts*ncon, 1.0/(float)nparts, tpwgts); ParMETIS_V3_PartKway(mgraph.vtxdist, mgraph.xadj, mgraph.adjncy, NULL, NULL, &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, savepart, &comm); options[0] = 1; wgtflag = 2; for (ncon=1; ncon<=3; ncon+=2) { sset(nparts*ncon, 1.0/(float)nparts, tpwgts); if (ncon > 1) Mc_AdaptGraph(&mgraph, savepart, ncon, nparts, comm); else AdaptGraph(&mgraph, 4, comm); /* idxset(mgraph.nvtxs, 1, mgraph.vwgt); */ for (ipc2redist=1000.0; ipc2redist>=0.001; ipc2redist/=1000.0) { for (opt2=1; opt2<=2; opt2++) { idxcopy(mgraph.nvtxs, savepart, mpart); options[2] = opt2; if (mype == 0) printf("\nTesting ParMETIS_V3_AdaptiveRepart with options[1-3] = {%d %d %d}, ipc2redist: %.3f, Ncon: %d, Nparts: %d\n", options[1], options[2], options[3], ipc2redist, ncon, nparts); ParMETIS_V3_AdaptiveRepart(mgraph.vtxdist, mgraph.xadj, mgraph.adjncy, mgraph.vwgt, mgraph.vsize, NULL, &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, &ipc2redist, options, &edgecut, mpart, &comm); if (mype == 0) { printf("ParMETIS_V3_AdaptiveRepart reported a cut of %d\n", edgecut); } } } } } free(mgraph.vwgt); free(mgraph.vsize); /*====================================================================== / ParMETIS_V3_NodeND /=======================================================================*/ sizes = idxmalloc(2*npes, "TestParMetis_V3: sizes"); order = idxmalloc(graph.nvtxs, "TestParMetis_V3: sizes"); options[0] = 1; options[PMV3_OPTION_DBGLVL] = 3; options[PMV3_OPTION_SEED] = 1; numflag = 0; for (opt2=1; opt2<=2; opt2++) { options[PMV3_OPTION_IPART] = opt2; if (mype == 0) printf("\nTesting ParMETIS_V3_NodeND with options[1-3] = {%d %d %d}\n", options[1], options[2], options[3]); ParMETIS_V3_NodeND(graph.vtxdist, graph.xadj, graph.adjncy, &numflag, options, order, sizes, &comm); } GKfree(&tpwgts, &part, &mpart, &savepart, &order, &sizes, LTERM); }