1#ifndef BP_MAXIMAL_MATCHING_H
2#define BP_MAXIMAL_MATCHING_H
22template <
typename Par_DCSC_Bool,
typename IT>
24 FullyDistVec<IT, IT>& mateCol2Row, FullyDistVec<IT, IT>& degColRecv,
int type,
bool rand=
true)
29 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
30 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
35 nthreads = omp_get_num_threads();
39 FullyDistVec<IT, IT> degCol = degColRecv;
42 FullyDistSpVec<IT, IT> unmatchedRow(mateRow2Col, [](IT mate){
return mate==-1;});
43 FullyDistSpVec<IT, IT> degColSG(
A.getcommgrid(),
A.getncol());
48 FullyDistSpVec<IT, VertexType> unmatchedCol(
A.getcommgrid(),
A.getncol());
50 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
56 FullyDistSpVec<IT, VertexType> fringeRow(
A.getcommgrid(),
A.getnrow());
57 FullyDistSpVec<IT, IT> fringeRow2(
A.getcommgrid(),
A.getnrow());
58 FullyDistSpVec<IT, VertexType> deg1Col(
A.getcommgrid(),
A.getncol());
61 IT curUnmatchedCol = unmatchedCol.getnnz();
62 IT curUnmatchedRow = unmatchedRow.getnnz();
65 double tStart = MPI_Wtime();
66 std::vector<std::vector<double> > timing;
71 cout <<
"=======================================================\n";
72 cout <<
"@@@@@@ Number of processes: " << nprocs << endl;
73 cout <<
"=======================================================\n";
74 cout <<
"It | UMRow | UMCol | newlyMatched | Time "<< endl;
75 cout <<
"=======================================================\n";
78 MPI_Barrier(MPI_COMM_WORLD);
81 while(curUnmatchedCol !=0 && curUnmatchedRow!=0 && newlyMatched != 0 )
86 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
97 std::vector<double> times;
98 double t1 = MPI_Wtime();
101 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
105 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
109 deg1Col = EWiseApply<VertexType>(unmatchedCol, degCol,
114 if(deg1Col.getnnz()>9)
115 SpMV<Select2ndMinSR<bool, VertexType>>(
A, deg1Col, fringeRow,
false);
117 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
120 fringeRow = EWiseApply<VertexType>(fringeRow, mateRow2Col,
122 [](
VertexType vtx, IT mate){
return mate==-1;},
125 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
131 fringeRow2 = EWiseApply<IT>(fringeRow, mateRow2Col,
136 FullyDistSpVec<IT, IT> newMatchedCols = fringeRow2.Invert(
A.getncol());
137 FullyDistSpVec<IT, IT> newMatchedRows = newMatchedCols.Invert(
A.getnrow());
138 mateCol2Row.Set(newMatchedCols);
139 mateRow2Col.Set(newMatchedRows);
140 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
145 unmatchedRow.Select(mateRow2Col, [](IT mate){
return mate==-1;});
146 unmatchedCol.Select(mateCol2Row, [](IT mate){
return mate==-1;});
151 newMatchedRows.Apply([](IT val){
return 1;});
152 SpMV< SelectPlusSR<bool, IT>>(AT, newMatchedRows, degColSG,
false);
154 degCol.EWiseApply(degColSG,
155 [](IT old_deg, IT new_deg){
return old_deg-new_deg;},
156 [](IT old_deg, IT new_deg){
return true;},
157 false,
static_cast<IT
>(0));
159 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
164 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
169 newlyMatched = newMatchedCols.getnnz();
170 times.push_back(std::accumulate(times.begin(), times.end(), 0.0));
171 timing.push_back(times);
175 printf(
"%3d %10lld %10lld %10lld %18lf\n", iteration , curUnmatchedRow, curUnmatchedCol, newlyMatched, times.back());
178 curUnmatchedCol = unmatchedCol.getnnz();
179 curUnmatchedRow = unmatchedRow.getnnz();
180 MPI_Barrier(MPI_COMM_WORLD);
184 IT cardinality = mateRow2Col.Count([](IT mate){
return mate!=-1;});
185 std::vector<double> totalTimes(timing[0].
size(),0);
186 for(
int i=0; i<timing.size(); i++)
188 for(
int j=0; j<timing[i].size(); j++)
190 totalTimes[j] += timing[i][j];
198 cout <<
"==========================================================\n";
199 cout <<
"\n================individual timings =======================\n";
200 cout <<
" SpMV Update-Match Update-UMC Total "<< endl;
201 cout <<
"==========================================================\n";
202 for(
int i=0; i<timing.size(); i++)
204 for(
int j=0; j<timing[i].size(); j++)
206 printf(
"%12.5lf ", timing[i][j]);
211 cout <<
"-------------------------------------------------------\n";
212 for(
int i=0; i<totalTimes.size(); i++)
213 printf(
"%12.5lf ", totalTimes[i]);
216 std::cout <<
"****** maximal matching runtime ********\n";
217 std::cout <<
"nprocesses nthreads ncores algorithm Unmatched-Rows Cardinality Total Time***\n";
218 std::cout << nprocs <<
" " << nthreads <<
" " << nprocs * nthreads <<
" ";
219 if(type ==
DMD) std::cout <<
"DMD";
220 else if(type ==
GREEDY) std::cout <<
"Greedy";
221 else if(type ==
KARP_SIPSER) std::cout <<
"Karp-Sipser";
224 printf(
"%lld %lld %lf\n", curUnmatchedRow, cardinality, totalTimes.back());
225 std::cout <<
"-------------------------------------------------------\n\n";
237template <
typename Par_MAT_Double,
typename IT>
238void WeightedGreedy(Par_MAT_Double &
A, FullyDistVec<IT, IT>& mateRow2Col,
239 FullyDistVec<IT, IT>& mateCol2Row, FullyDistVec<IT, IT>& degCol)
242 typedef VertexTypeML < IT, double>
VertexType;
247 nthreads = omp_get_num_threads();
250 PreAllocatedSPA<VertexType> SPA(
A.seq(), nthreads*4);
252 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
253 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
255 double tStart = MPI_Wtime();
258 FullyDistSpVec<IT, IT> unmatchedRow(mateRow2Col, [](IT mate){
return mate==-1;});
262 FullyDistSpVec<IT, VertexType> unmatchedCol(
A.getcommgrid(),
A.getncol());
264 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
270 FullyDistSpVec<IT, VertexType> fringeRow(
A.getcommgrid(),
A.getnrow());
271 FullyDistSpVec<IT, IT> fringeRow2(
A.getcommgrid(),
A.getnrow());
272 FullyDistSpVec<IT, VertexType> fringeRow3(
A.getcommgrid(),
A.getnrow());
274 IT curUnmatchedCol = unmatchedCol.getnnz();
275 IT curUnmatchedRow = unmatchedRow.getnnz();
279 std::vector<std::vector<double> > timing;
284 cout <<
"=======================================================\n";
285 cout <<
"@@@@@@ Number of processes: " << nprocs << endl;
286 cout <<
"=======================================================\n";
287 cout <<
"It | UMRow | UMCol | newlyMatched | Time "<< endl;
288 cout <<
"=======================================================\n";
291 MPI_Barrier(MPI_COMM_WORLD);
294 while(curUnmatchedCol !=0 && curUnmatchedRow!=0 && newlyMatched != 0 )
301 std::vector<double> times;
302 double t1 = MPI_Wtime();
304 SpMV<WeightMaxMLSR<double, VertexType>>(
A, unmatchedCol, fringeRow,
false, SPA);
307 fringeRow = EWiseApply<VertexType>(fringeRow, mateRow2Col,
309 [](
VertexType vtx, IT mate){
return mate==-1;},
312 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
318 fringeRow2 = EWiseApply<IT>(fringeRow, mateRow2Col,
323 FullyDistSpVec<IT, IT> newMatchedCols = fringeRow2.Invert(
A.getncol());
324 FullyDistSpVec<IT, IT> newMatchedRows = newMatchedCols.Invert(
A.getnrow());
325 mateCol2Row.Set(newMatchedCols);
326 mateRow2Col.Set(newMatchedRows);
327 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
333 unmatchedRow.Select(mateRow2Col, [](IT mate){
return mate==-1;});
334 unmatchedCol.Select(mateCol2Row, [](IT mate){
return mate==-1;});
335 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
340 newlyMatched = newMatchedCols.getnnz();
341 times.push_back(std::accumulate(times.begin(), times.end(), 0.0));
342 timing.push_back(times);
346 printf(
"%3d %10lld %10lld %10lld %18lf\n", iteration , curUnmatchedRow, curUnmatchedCol, newlyMatched, times.back());
349 curUnmatchedCol = unmatchedCol.getnnz();
350 curUnmatchedRow = unmatchedRow.getnnz();
351 MPI_Barrier(MPI_COMM_WORLD);
355 IT cardinality = mateRow2Col.Count([](IT mate){
return mate!=-1;});
356 std::vector<double> totalTimes(timing[0].
size(),0);
357 for(
int i=0; i<timing.size(); i++)
359 for(
int j=0; j<timing[i].size(); j++)
361 totalTimes[j] += timing[i][j];
369 cout <<
"==========================================================\n";
370 cout <<
"\n================individual timings =======================\n";
371 cout <<
" SpMV Update-Match Update-UMC Total "<< endl;
372 cout <<
"==========================================================\n";
373 for(
int i=0; i<timing.size(); i++)
375 for(
int j=0; j<timing[i].size(); j++)
377 printf(
"%12.5lf ", timing[i][j]);
382 cout <<
"-------------------------------------------------------\n";
383 for(
int i=0; i<totalTimes.size(); i++)
384 printf(
"%12.5lf ", totalTimes[i]);
387 std::cout <<
"****** maximal matching runtime ********\n";
388 std::cout <<
"Unmatched-Rows Cardinality Total Time***\n";
389 printf(
"%lld %lld %lf\n", curUnmatchedRow, cardinality, totalTimes.back());
390 std::cout <<
"-------------------------------------------------------\n\n";
398template <
class Par_DCSC_Bool,
class IT,
class NT>
403 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
404 FullyDistSpVec<IT, IT> fringeRow(
A.getcommgrid(),
A.getnrow());
405 FullyDistSpVec<IT, IT> fringeCol(
A.getcommgrid(),
A.getncol());
406 FullyDistSpVec<IT, IT> unmatchedRow(mateRow2Col, [](IT mate){
return mate==-1;});
407 FullyDistSpVec<IT, IT> unmatchedCol(mateCol2Row, [](IT mate){
return mate==-1;});
408 unmatchedRow.setNumToInd();
409 unmatchedCol.setNumToInd();
412 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
413 fringeRow =
EWiseMult(fringeRow, mateRow2Col,
true, (IT) -1);
414 if(fringeRow.getnnz() != 0)
417 std::cout <<
"Not maximal matching!!\n";
423 SpMV<Select2ndMinSR<bool, VertexType>>(tA, unmatchedRow, fringeCol,
false);
424 fringeCol =
EWiseMult(fringeCol, mateCol2Row,
true, (IT) -1);
425 if(fringeCol.getnnz() != 0)
428 std::cout <<
"Not maximal matching**!!\n";
void MaximalMatching(Par_DCSC_Bool &A, Par_DCSC_Bool &AT, FullyDistVec< IT, IT > &mateRow2Col, FullyDistVec< IT, IT > &mateCol2Row, FullyDistVec< IT, IT > °ColRecv, int type, bool rand=true)
bool isMaximalmatching(Par_DCSC_Bool &A, FullyDistVec< IT, NT > &mateRow2Col, FullyDistVec< IT, NT > &mateCol2Row)
void WeightedGreedy(Par_MAT_Double &A, FullyDistVec< IT, IT > &mateRow2Col, FullyDistVec< IT, IT > &mateCol2Row, FullyDistVec< IT, IT > °Col)
Dcsc< IU, typename promote_trait< NU1, NU2 >::T_promote > EWiseMult(const Dcsc< IU, NU1 > &A, const Dcsc< IU, NU2 > *B, bool exclude)