void Compute(graph<vertex>& GA, commandLine P) { long ratio = P.getOptionLongValue("-r",1000); long n = GA.n; printf("Nodes: %d Ratio %d\n", n, ratio); for(size_t i(0); i < n; ++i) { if(i % ratio != 0) continue; intE* ShortestPathLen = newA(intE,n); int* Visited = newA(int,n); //initialize ShortestPathLen to "infinity" {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = INT_MAX/2;} ShortestPathLen[i] = 0; {parallel_for(long i=0;i<n;i++) Visited[i] = 0;} vertexSubset Frontier(n,i); //initial frontier long round = 0; while(!Frontier.isEmpty()){ if(round == n) { //negative weight cycle {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = -(INT_E_MAX/2);} break; } vertexSubset output = edgeMap(GA, Frontier, BF_F(ShortestPathLen,Visited), GA.m/20, DENSE_FORWARD); vertexMap(output,BF_Vertex_F(Visited)); Frontier.del(); Frontier = output; round++; }
void Compute(graph<vertex>& GA, commandLine P) { t1.start(); long start = P.getOptionLongValue("-r",0); if(GA.V[start].getOutDegree() == 0) { cout << "starting vertex has degree 0" << endl; return; } const uintE K = P.getOptionIntValue("-K",10); const uintE N = P.getOptionIntValue("-N",10); const double t = P.getOptionDoubleValue("-t",3); srand (time(NULL)); uintE seed = rand(); const intE n = GA.n; //walk length probabilities double* fact = newA(double,K); fact[0] = 1; for(long k=1;k<K;k++) fact[k] = k*fact[k-1]; double* probs = newA(double,K); for(long k=0;k<K;k++) probs[k] = exp(-t)*pow(t,k)/fact[k]; unordered_map<uintE,double> p; for(long i=0;i<N;i++) { double randDouble = (double) hashInt(seed++) / UINT_E_MAX; long j = 0; double mass = 0; uintE x = start; do { mass += probs[j]; if(randDouble < mass) break; x = walk(x,GA.V,seed++); j++; } while(j <= K); p[x]++; } for(auto it=p.begin();it!=p.end();it++) { p[it->first] /= N; } free(probs); free(fact); t1.stop(); pairIF* A = newA(pairIF,p.size()); long numNonzerosQ = 0; for(auto it = p.begin(); it != p.end(); it++) { A[numNonzerosQ++] = make_pair(it->first,it->second); } sweepObject sweep = sweepCut(GA,A,numNonzerosQ,start); free(A); cout << "number of vertices touched = " << p.size() << endl; cout << "number of edges touched = " << sweep.vol << endl; cout << "conductance = " << sweep.conductance << " |S| = " << sweep.sizeS << " vol(S) = " << sweep.volS << " edgesCrossing = " << sweep.edgesCrossing << endl; t1.reportTotal("computation time"); }
void Compute(graph<vertex>& GA, commandLine P) { long start = P.getOptionLongValue("-r",0); long n = GA.n; //initialize ShortestPathLen to "infinity" intE* ShortestPathLen = newA(intE,n); {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = INT_MAX/2;} ShortestPathLen[start] = 0; int* Visited = newA(int,n); {parallel_for(long i=0;i<n;i++) Visited[i] = 0;} vertexSubset Frontier(n,start); //initial frontier long round = 0; while(!Frontier.isEmpty()){ if(round == n) { //negative weight cycle {parallel_for(long i=0;i<n;i++) ShortestPathLen[i] = -(INT_E_MAX/2);} break; }
void Compute(graph<vertex>& GA, commandLine P) { long start = P.getOptionLongValue("-r",0); long n = GA.n; //creates Parents array, initialized to all -1, except for start uintE* Parents = newA(uintE,n); parallel_for(long i=0;i<n;i++) Parents[i] = UINT_E_MAX; Parents[start] = start; //create bitvector to mark visited vertices long numWords = (n+63)/64; long* Visited = newA(long,numWords); {parallel_for(long i=0;i<numWords;i++) Visited[i] = 0;} Visited[start/64] = (long)1 << (start % 64); vertexSubset Frontier(n,start); //creates initial frontier while(!Frontier.isEmpty()){ //loop until frontier is empty vertexSubset output = edgeMap(GA, Frontier, BFS_F(Parents,Visited),GA.m/20); Frontier.del(); Frontier = output; //set new frontier } Frontier.del(); free(Parents); free(Visited); }
void Compute(graph<vertex>& GA, commandLine P) { t1.start(); long start = P.getOptionLongValue("-r",0); if(GA.V[start].getOutDegree() == 0) { cout << "starting vertex has degree 0" << endl; return; } const int procs = P.getOptionIntValue("-p",0); if(procs > 0) setWorkers(procs); const double t = P.getOptionDoubleValue("-t",3); const double epsilon = P.getOptionDoubleValue("-e",0.000000001); const uintE N = P.getOptionIntValue("-N",1); const intE n = GA.n; const double constant = exp(t)*epsilon/(2*(double)N); double* psis = newA(double,N); double* fact = newA(double,N); fact[0] = 1; for(long k=1;k<N;k++) fact[k] = k*fact[k-1]; double* tm = newA(double,N); {parallel_for(long m=0;m<N;m++) tm[m] = pow(t,m);} {parallel_for(long k=0;k<N;k++) { psis[k] = 0; for(long m=0;m<N-k;m++) psis[k] += fact[k]*tm[m]/(double)fact[m+k]; }} sparseAdditiveSet<float> x = sparseAdditiveSet<float>(10000,1,0.0); sparseAdditiveSet<float> r = sparseAdditiveSet<float>(2,1,0.0); x.insert(make_pair(start,0.0)); r.insert(make_pair(start,1.0)); vertexSubset Frontier(n,start); long j = 0, totalPushes = 0; while(Frontier.numNonzeros() > 0){ totalPushes += Frontier.numNonzeros(); uintT* Degrees = newA(uintT,Frontier.numNonzeros()); {parallel_for(long i=0;i<Frontier.numNonzeros();i++) Degrees[i] = GA.V[Frontier.s[i]].getOutDegree();} long totalDegree = sequence::plusReduce(Degrees,Frontier.numNonzeros()); free(Degrees); if(j+1 < N) { long rCount = r.count(); //make bigger hash table initialized to 0.0's sparseAdditiveSet<float> new_r = sparseAdditiveSet<float>(max(100L,min((long)n,totalDegree+rCount)),LOAD_FACTOR,0.0); vertexMap(Frontier,Local_Update(x,r)); vertexSubset output = edgeMap(GA, Frontier, HK_F<vertex>(x,r,new_r,GA.V,t/(double)(j+1))); r.del(); r = new_r; if(x.m < ((uintT) 1 << log2RoundUp((uintT)(LOAD_FACTOR*min((long)n,rCount+output.numNonzeros()))))) { sparseAdditiveSet<float> new_x = sparseAdditiveSet<float>(LOAD_FACTOR*min((long)n,rCount+output.numNonzeros()),LOAD_FACTOR,0.0); //make bigger hash table new_x.copy(x); x.del(); x = new_x; } output.del(); //compute active set (faster in practice to just scan over r) _seq<ACLpair> vals = r.entries(activeF<vertex>(GA.V,constant/psis[j+1])); uintE* Active = newA(uintE,vals.n); parallel_for(long i=0;i<vals.n;i++) Active[i] = vals.A[i].first; Frontier.del(); vals.del(); Frontier = vertexSubset(n,vals.n,Active); j++; } else { //last iteration
void Compute(graph<vertex>& GA, commandLine P) { t5.start(); long length = P.getOptionLongValue("-r",0); //number of words per vertex char* oFile = P.getOptionValue("-out"); //file to write eccentricites srand (time(NULL)); uintT seed = rand(); cout << "seed = " << seed << endl; t0.start(); long n = GA.n; uintE* ecc = newA(uintE,n); uintE* ecc2 = newA(uintE,n); {parallel_for(long i=0;i<n;i++) { ecc[i] = ecc2[i] = 0; }} t0.stop(); //BEGIN COMPUTE CONNECTED COMPONENTS t1.start(); intE* Labels = newA(intE,n); {parallel_for(long i=0;i<n;i++) { if(GA.V[i].getOutDegree() == 0) Labels[i] = -i-1; //singletons else Labels[i] = INT_E_MAX; }} //get max degree vertex uintE maxV = sequence::reduce<uintE>((intE)0,(intE)n,maxF<intE>(),getDegree<vertex>(GA.V)); //visit large component with BFS CCBFS(maxV,GA,Labels); //visit small components with label propagation Components(GA, Labels); //sort by component ID intPair* CCpairs = newA(intPair,n); {parallel_for(long i=0;i<n;i++) if(Labels[i] < 0) CCpairs[i] = make_pair(-Labels[i]-1,i); else CCpairs[i] = make_pair(Labels[i],i); } free(Labels); intSort::iSort(CCpairs, n, n+1,firstF<uintE,uintE>()); uintE* changes = newA(uintE,n); changes[0] = 0; {parallel_for(long i=1;i<n;i++) changes[i] = (CCpairs[i].first != CCpairs[i-1].first) ? i : UINT_E_MAX;} uintE* CCoffsets = newA(uintE,n); uintE numCC = sequence::filter(changes, CCoffsets, n, nonMaxF()); CCoffsets[numCC] = n; free(changes); t1.stop(); //END COMPUTE CONNECTED COMPONENTS //init data structures t0.start(); length = max((long)1,min((n+63)/64,(long)length)); long* VisitedArray = newA(long,n*length); long* NextVisitedArray = newA(long,n*length); int* flags = newA(int,n); {parallel_for(long i=0;i<n;i++) flags[i] = -1;} uintE* starts = newA(uintE,n); intPair* pairs = newA(intPair,n); t0.stop(); //BEGIN COMPUTE ECCENTRICITES PER COMPONENT for(long k = 0; k < numCC; k++) { t2.start(); uintE o = CCoffsets[k]; uintE CCsize = CCoffsets[k+1] - o; if(CCsize == 2) { //size 2 CC's have ecc of 1 ecc[CCpairs[o].second] = ecc[CCpairs[o+1].second] = 1; t2.stop(); } else if(CCsize > 1) { //size 1 CC's already have ecc of 0 //do main computation long myLength = min((long)length,((long)CCsize+63)/64); //initialize bit vectors for component vertices {parallel_for(long i=0;i<CCsize;i++) { uintT v = CCpairs[o+i].second; parallel_for(long j=0;j<myLength;j++) VisitedArray[v*myLength+j] = NextVisitedArray[v*myLength+j] = 0; }} long sampleSize = min((long)CCsize,(long)64*myLength); uintE* starts2 = newA(uintE,sampleSize); //pick random vertices (could have duplicates) {parallel_for(ulong i=0;i<sampleSize;i++) { uintT index = hashInt(i+seed) % CCsize; if(flags[index] == -1 && CAS(&flags[index],-1,(int)i)) { starts[i] = CCpairs[o+index].second; NextVisitedArray[CCpairs[o+index].second*myLength + i/64] = (long) 1<<(i%64); } else starts[i] = UINT_E_MAX; }} //remove duplicates uintE numUnique = sequence::filter(starts,starts2,sampleSize,nonMaxF()); //reset flags parallel_for(ulong i=0;i<sampleSize;i++) { uintT index = hashInt(i+seed) % CCsize; if(flags[index] == i) flags[index] = -1; } //first phase vertexSubset Frontier(n,numUnique,starts2); //initial frontier //note: starts2 will be freed inside the following loop uintE round = 0; while(!Frontier.isEmpty()){ round++; vertexMap(Frontier, Ecc_Vertex_F(myLength,VisitedArray,NextVisitedArray)); vertexSubset output = edgeMap(GA, Frontier, Ecc_F(myLength,VisitedArray,NextVisitedArray,ecc,round), GA.m/20); Frontier.del(); Frontier = output; } Frontier.del(); t2.stop(); //second phase if size of CC > 64 if(CCsize > 1024) { //sort by ecc t3.start(); {parallel_for(long i=0;i<CCsize;i++) { pairs[i] = make_pair(ecc[CCpairs[o+i].second],CCpairs[o+i].second); }} intPair maxR = sequence::reduce(pairs,CCsize,maxFirstF()); intSort::iSort(pairs, CCsize, 1+maxR.first, firstF<uintE,uintE>()); t3.stop(); t4.start(); //reset bit vectors for component vertices {parallel_for(long i=0;i<CCsize;i++) { uintT v = CCpairs[o+i].second; parallel_for(long j=0;j<myLength;j++) VisitedArray[v*myLength+j] = NextVisitedArray[v*myLength+j] = 0; }} starts2 = newA(uintE,sampleSize); //pick starting points with highest ecc ("fringe" vertices) {parallel_for(long i=0;i<sampleSize;i++) { intE v = pairs[CCsize-i-1].second; starts2[i] = v; NextVisitedArray[v*myLength + i/64] = (long) 1<<(i%64); }} vertexSubset Frontier2(n,sampleSize,starts2); //initial frontier //note: starts2 will be freed inside the following loop round = 0; while(!Frontier2.isEmpty()){ round++; vertexMap(Frontier2, Ecc_Vertex_F(myLength,VisitedArray,NextVisitedArray)); vertexSubset output = edgeMap(GA, Frontier2,Ecc_F(myLength,VisitedArray,NextVisitedArray,ecc2,round), GA.m/20); Frontier2.del(); Frontier2 = output; } Frontier2.del(); {parallel_for(long i=0;i<n;i++) ecc[i] = max(ecc[i],ecc2[i]);} t4.stop(); } }