4#include "CombBLAS/CombBLAS.h"
11template <
typename PARMAT>
16 MPI_Comm_size(MPI_COMM_WORLD,&
nprocs);
17 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
20 FullyDistVec<int64_t, int64_t> * ColSums =
new FullyDistVec<int64_t, int64_t>(
A.getcommgrid());
21 FullyDistVec<int64_t, int64_t> * RowSums =
new FullyDistVec<int64_t, int64_t>(
A.getcommgrid());
22 FullyDistVec<int64_t, int64_t> nonisoRowV;
23 FullyDistVec<int64_t, int64_t> nonisoColV;
24 FullyDistVec<int64_t, int64_t> nonisov;
26 A.Reduce(*ColSums,
Column, std::plus<int64_t>(),
static_cast<int64_t>(0));
27 A.Reduce(*RowSums,
Row, std::plus<int64_t>(),
static_cast<int64_t>(0));
38 nonisoColV = ColSums->FindInds(bind2nd(std::greater<int64_t>(), 0));
39 nonisoRowV = RowSums->FindInds(bind2nd(std::greater<int64_t>(), 0));
45 nonisoColV.RandPerm();
46 nonisoRowV.RandPerm();
50 int64_t nrows1=
A.getnrow(), ncols1=
A.getncol(), nnz1 =
A.getnnz();
51 double avgDeg1 = (double) nnz1/(nrows1+ncols1);
54 A.operator()(nonisoRowV, nonisoColV,
true);
56 int64_t nrows2=
A.getnrow(), ncols2=
A.getncol(), nnz2 =
A.getnnz();
57 double avgDeg2 = (double) nnz2/(nrows2+ncols2);
62 std::cout <<
"ncol nrows nedges deg \n";
63 std::cout << nrows1 <<
" " << ncols1 <<
" " << nnz1 <<
" " << avgDeg1 <<
" \n";
64 std::cout << nrows2 <<
" " << ncols2 <<
" " << nnz2 <<
" " << avgDeg2 <<
" \n";
67 MPI_Barrier(MPI_COMM_WORLD);
79template <
class IT,
class NT>
80bool isMatching(FullyDistVec<IT,NT> & mateCol2Row, FullyDistVec<IT,NT> & mateRow2Col)
84 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
85 for(
int i=0; i< mateRow2Col.glen ; i++)
87 int t = mateRow2Col[i];
89 if(t!=-1 && mateCol2Row[t]!=i)
92 std::cout <<
"Does not satisfy the matching constraints\n";
97 for(
int i=0; i< mateCol2Row.glen ; i++)
99 int t = mateCol2Row[i];
100 if(t!=-1 && mateRow2Col[t]!=i)
103 std::cout <<
"Does not satisfy the matching constraints\n";
113bool CheckMatching(FullyDistVec<IT,IT> & mateRow2Col, FullyDistVec<IT,IT> & mateCol2Row)
117 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
118 int64_t nrow = mateRow2Col.TotalLength();
119 int64_t ncol = mateCol2Row.TotalLength();
120 FullyDistSpVec<IT,IT> mateRow2ColSparse (mateRow2Col, [](
IT mate){
return mate!=-1;});
121 FullyDistSpVec<IT,IT> mateCol2RowSparse (mateCol2Row, [](
IT mate){
return mate!=-1;});
122 FullyDistSpVec<IT,IT> mateRow2ColInverted = mateRow2ColSparse.Invert(ncol);
123 FullyDistSpVec<IT,IT> mateCol2RowInverted = mateCol2RowSparse.Invert(nrow);
128 if((mateCol2RowSparse == mateRow2ColInverted) && (mateRow2ColSparse == mateCol2RowInverted))
132 SpParHelper::Print(
"Warning: This is not a matching! Need to check the correctness of the matching (HWPM) code\n");
135 bool isPerfectMatching =
false;
136 if((mateRow2ColSparse.getnnz()==nrow) && (mateCol2RowSparse.getnnz() == ncol))
137 isPerfectMatching =
true;
138 return isPerfectMatching;
143template <
class IT,
class NT,
class DER>
144NT MatchingWeight( SpParMat < IT, NT, DER > &
A, FullyDistVec<IT,IT> mateRow2Col, FullyDistVec<IT,IT>& mateCol2Row)
147 auto commGrid =
A.getcommgrid();
148 int myrank=commGrid->GetRank();
149 MPI_Comm World = commGrid->GetWorld();
150 MPI_Comm ColWorld = commGrid->GetColWorld();
151 MPI_Comm RowWorld = commGrid->GetRowWorld();
152 int nprocs = commGrid->GetSize();
153 int pr = commGrid->GetGridRows();
154 int pc = commGrid->GetGridCols();
155 int rowrank = commGrid->GetRankInProcRow();
156 int colrank = commGrid->GetRankInProcCol();
157 int diagneigh = commGrid->GetComplementRank();
162 IT nrows =
A.getnrow();
163 IT ncols =
A.getncol();
164 IT m_perproc = nrows / pr;
165 IT n_perproc = ncols / pc;
166 DER* spSeq =
A.seqptr();
167 Dcsc<IT, NT>* dcsc = spSeq->GetDCSC();
168 IT lnrow = spSeq->getnrow();
169 IT lncol = spSeq->getncol();
170 IT localRowStart = colrank * m_perproc;
171 IT localColStart = rowrank * n_perproc;
176 int xsize = (int) mateCol2Row.LocArrSize();
179 MPI_Sendrecv(&xsize, 1, MPI_INT, diagneigh,
TRX, &trxsize, 1, MPI_INT, diagneigh,
TRX, World, &status);
180 std::vector<IT> trxnums(trxsize);
181 MPI_Sendrecv(mateCol2Row.GetLocArr(), xsize, MPIType<IT>(), diagneigh,
TRX, trxnums.data(), trxsize, MPIType<IT>(), diagneigh,
TRX, World, &status);
184 std::vector<int> colsize(pc);
185 colsize[colrank] = trxsize;
186 MPI_Allgather(MPI_IN_PLACE, 1, MPI_INT, colsize.data(), 1, MPI_INT, ColWorld);
187 std::vector<int> dpls(pc,0);
188 std::partial_sum(colsize.data(), colsize.data()+pc-1, dpls.data()+1);
189 int accsize = std::accumulate(colsize.data(), colsize.data()+pc, 0);
190 std::vector<IT> RepMateC2R(accsize);
191 MPI_Allgatherv(trxnums.data(), trxsize, MPIType<IT>(), RepMateC2R.data(), colsize.data(), dpls.data(), MPIType<IT>(), ColWorld);
202 for(
auto colit = spSeq->begcol(); colit != spSeq->endcol(); ++colit)
204 IT lj = colit.colid();
205 IT mj = RepMateC2R[lj];
206 if(mj >= localRowStart && mj < (localRowStart+lnrow) )
208 for(
auto nzit = spSeq->begnz(colit); nzit < spSeq->endnz(colit); ++nzit)
210 IT li = nzit.rowid();
211 IT i = li + localRowStart;
224 MPI_Allreduce(MPI_IN_PLACE, &w, 1, MPIType<NT>(), MPI_SUM, World);
237template <
typename PARMAT>
static void Print(const std::string &s)
bool CheckMatching(FullyDistVec< IT, IT > &mateRow2Col, FullyDistVec< IT, IT > &mateCol2Row)
void removeIsolated(PARMAT &A)
NT MatchingWeight(std::vector< NT > &RepMateWC2R, MPI_Comm RowWorld, NT &minw)
void Symmetricize(PARMAT &A)
bool isMatching(FullyDistVec< IT, NT > &mateCol2Row, FullyDistVec< IT, NT > &mateRow2Col)