wgttype dotProduct(idxtype* a, wgttype *a_wgts, int a_length, idxtype* b, wgttype *b_wgts, int b_length, int sort) { if ( sort > 0 ) { ParallelQSort(a, a_wgts, 0, a_length-1); ParallelQSort(b, b_wgts, 0, b_length-1); } wgttype result= 0; for ( int i=0, j=0; i<a_length && j < b_length; ) { if ( a[i] == b[j] ) { result += a_wgts[i]*b_wgts[j]; i++; j++; } else if ( a[i] > b[j] ) { j++; } else i++; } return result; }
/* Sorts the arrays a and b, according to the order imposed by a. [start,end] is the inclusive range of the two arrays i.e. the length of the two arrays is end-start+1, not end-start. */ void ParallelQSort(idxtype *a, wgttype *b, int start, int end) { int q; if ( start < end ) { q=ParallelRandomPartition(a,b,start,end); ParallelQSort(a,b,start,q-1); ParallelQSort(a,b,q+1,end); } }
void n_sortAdjLists(int nvtxs, idxtype* xadj, idxtype* adjncy, wgttype* adjwgt) { int i,j; for(i=0;i<nvtxs;i++) { ParallelQSort(adjncy,adjwgt,xadj[i],xadj[i+1]-1); } }
Matrix* setupCanonicalMatrix(int nvtxs, int nedges, idxtype* xadj, idxtype* adjncy, idxtype* adjwgt, int ncutify) { int i,j; Matrix* ret; if ( ncutify ) ret=allocMatrix(nvtxs,nedges,1,0,0); else ret=allocMatrix(nvtxs,nedges,0,0,0); idxcopy(nvtxs+1, xadj, ret->xadj); idxcopy(nedges, adjncy, ret->adjncy); if ( adjwgt != NULL ) { if ( ncutify ) { for(i=0;i<ret->nvtxs;i++) { ret->adjwgtsum[i]=0; for(j=ret->xadj[i];j<ret->xadj[i+1];j++) { ret->adjwgt[j]=(wgttype)adjwgt[j]; ret->adjwgtsum[i]+=ret->adjwgt[j]; } } //ncutifyWeights(ret,1,ncutify); //YK removed } else { for(i=0;i<nedges;i++) ret->adjwgt[i]=(wgttype)adjwgt[i]; } normalizeColumns(ret,1,0); } else { if ( ncutify ) ncutifyWeights(ret,0,ncutify); normalizeColumns(ret,0,0); } // sort each column in ascending order. This is necessary for // getDprAdjMatrix. for(i=0;i<nvtxs;i++) { ParallelQSort(ret->adjncy,ret->adjwgt,ret->xadj[i],ret->xadj[i+1]-1); } return ret; }
void sortAdjLists(int nvtxs, idxtype* xadj, idxtype* adjncy, wgttype* adjwgt) { int i,j; for(i=0;i<nvtxs;i++) { if ( xadj[i] > xadj[i+1] ) { printf("Yikes! something wrong with xadjs."); printf("xadj of %d < xadj of %d\n", (i+1), i); abort(); } ParallelQSort(adjncy,adjwgt,xadj[i],xadj[i+1]-1); } }
// this actually undoes the permutation Matrix* permuteRowsAndColumns(const Matrix *M, const idxtype* rowPerm, const idxtype* colPerm) { Matrix *ret = allocMatrix(M->nvtxs, M->nnz, 0, 0, 0); int i; idxtype* revRowPerm = idxmalloc(M->nvtxs, "permuteRowsAndColumns:revRowPerm"); // idxtype* revColPerm = idxmalloc(M->nvtxs, // "permuteRowsAndColumns:revColPerm"); for ( i=0; i<M->nvtxs; i++ ) { revRowPerm[rowPerm[i]] = i; // revColPerm[colPerm[i]] = i; } ret->xadj[0]=0; for ( i=0; i<M->nvtxs; i++ ) { int orgI = revRowPerm[i]; int j; ret->xadj[i+1] = ret->xadj[i] + ( M->xadj[orgI+1] - M->xadj[orgI] ); for ( j=ret->xadj[i]; j<ret->xadj[i+1]; j++ ) { int orgJ = M->xadj[orgI] + j - ret->xadj[i]; ret->adjncy[j] = colPerm[M->adjncy[orgJ]]; ret->adjwgt[j] = M->adjwgt[orgJ]; } ParallelQSort( ret->adjncy, ret->adjwgt, ret->xadj[i], ret->xadj[i+1]-1 ); } ret->nnz = M->nnz; // GKfree ( (void**)&revRowPerm, (void**)&revColPerm, LTERM ); GKfree ( (void**)&revRowPerm, LTERM ); return ret; }
/* This function returns the vertices of the graph sorted in * ascending order according to the number of neighbours they * have. The idea is that during matching, if the vertices with * low degrees are matched first, then there is lesser risk of * some vertices being "orphaned". */ void permuteDegreeOrder(int n, idxtype *p, idxtype *xadj) { idxtype* degrees=idxmalloc(n,"permuteDegreeOrder:degrees"); wgttype* temp_p=(wgttype*)malloc(sizeof(wgttype)*n); int i; for( i=0; i<n; i++ ) { degrees[i]=xadj[i+1]-xadj[i]; temp_p[i]=i; } ParallelQSort(degrees,temp_p,0,n-1); for ( i=0; i<n; i++ ) p[i]=(idxtype)temp_p[i]; free(degrees); free(temp_p); }
// this actually undoes the permutation Matrix* permuteRowsAndColumns(Matrix* M, idxtype* perm) { Matrix *ret = allocMatrix(M->nvtxs, M->nnz, 0, 0, 0); int i; idxtype* revPerm = idxmalloc(M->nvtxs, "permuteRowsAndColumns:revPerm"); for ( i=0; i<M->nvtxs; i++ ) { revPerm[perm[i]] = i; } ret->xadj[0]=0; for ( i=0; i<M->nvtxs; i++ ) { int orgI = revPerm[i]; int j; ret->xadj[i+1] = ret->xadj[i] + ( M->xadj[orgI+1] - M->xadj[orgI] ); for ( j=ret->xadj[i]; j<ret->xadj[i+1]; j++ ) { int orgJ = M->xadj[orgI] + j - ret->xadj[i]; ret->adjncy[j] = perm[M->adjncy[orgJ]]; ret->adjwgt[j] = M->adjwgt[orgJ]; } ParallelQSort( ret->adjncy, ret->adjwgt, ret->xadj[i], ret->xadj[i+1]-1 ); } ret->nnz = M->nnz; free ( revPerm ); return ret; }