1 #ifndef BP_MAXIMAL_MATCHING_H 2 #define BP_MAXIMAL_MATCHING_H 4 #include "../CombBLAS.h" 24 template <
typename Par_DCSC_Bool,
typename IT>
31 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
32 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
37 nthreads = omp_get_num_threads();
52 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
53 [](VertexType vtx, IT deg){
return VertexType();},
54 [](VertexType vtx, IT deg){
return deg>0;},
63 IT curUnmatchedCol = unmatchedCol.
getnnz();
64 IT curUnmatchedRow = unmatchedRow.getnnz();
67 double tStart = MPI_Wtime();
68 std::vector<std::vector<double> > timing;
73 cout <<
"=======================================================\n";
74 cout <<
"@@@@@@ Number of processes: " << nprocs << endl;
75 cout <<
"=======================================================\n";
76 cout <<
"It | UMRow | UMCol | newlyMatched | Time "<< endl;
77 cout <<
"=======================================================\n";
80 MPI_Barrier(MPI_COMM_WORLD);
83 while(curUnmatchedCol !=0 && curUnmatchedRow!=0 && newlyMatched != 0 )
85 unmatchedCol.ApplyInd([](VertexType vtx, IT idx){
return VertexType(idx,idx);});
88 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
89 [](VertexType vtx, IT deg){
return VertexType(vtx.parent,deg);},
90 [](VertexType vtx, IT deg){
return true;},
95 unmatchedCol.Apply([](VertexType vtx){
return VertexType(vtx.
parent, static_cast<IT>((
GlobalMT.
rand() * 9999999)+1));});
99 std::vector<double> times;
100 double t1 = MPI_Wtime();
103 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
107 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
111 deg1Col = EWiseApply<VertexType>(unmatchedCol, degCol,
112 [](VertexType vtx, IT deg){
return vtx;},
113 [](VertexType vtx, IT deg){
return deg==1;},
114 false, VertexType());
116 if(deg1Col.getnnz()>9)
119 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
122 fringeRow = EWiseApply<VertexType>(fringeRow, mateRow2Col,
123 [](VertexType vtx, IT mate){
return vtx;},
124 [](VertexType vtx, IT mate){
return mate==-1;},
125 false, VertexType());
127 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
133 fringeRow2 = EWiseApply<IT>(fringeRow, mateRow2Col,
134 [](VertexType vtx, IT mate){
return vtx.parent;},
135 [](VertexType vtx, IT mate){
return true;},
136 false, VertexType());
140 mateCol2Row.
Set(newMatchedCols);
141 mateRow2Col.Set(newMatchedRows);
142 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
147 unmatchedRow.Select(mateRow2Col, [](IT mate){
return mate==-1;});
148 unmatchedCol.Select(mateCol2Row, [](IT mate){
return mate==-1;});
153 newMatchedRows.
Apply([](IT val){
return 1;});
154 SpMV< SelectPlusSR<bool, IT>>(AT, newMatchedRows, degColSG,
false);
156 degCol.EWiseApply(degColSG,
157 [](IT old_deg, IT new_deg){
return old_deg-new_deg;},
158 [](IT old_deg, IT new_deg){
return true;},
159 false,
static_cast<IT
>(0));
161 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
162 [](VertexType vtx, IT deg){
return vtx;},
163 [](VertexType vtx, IT deg){
return deg>0;},
164 false, VertexType());
166 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
171 newlyMatched = newMatchedCols.getnnz();
172 times.push_back(std::accumulate(times.begin(), times.end(), 0.0));
173 timing.push_back(times);
177 printf(
"%3d %10lld %10lld %10lld %18lf\n", iteration , curUnmatchedRow, curUnmatchedCol, newlyMatched, times.back());
180 curUnmatchedCol = unmatchedCol.getnnz();
181 curUnmatchedRow = unmatchedRow.getnnz();
182 MPI_Barrier(MPI_COMM_WORLD);
186 IT cardinality = mateRow2Col.
Count([](IT mate){
return mate!=-1;});
187 std::vector<double> totalTimes(timing[0].
size(),0);
188 for(
int i=0; i<timing.size(); i++)
190 for(
int j=0; j<timing[i].size(); j++)
192 totalTimes[j] += timing[i][j];
200 cout <<
"==========================================================\n";
201 cout <<
"\n================individual timings =======================\n";
202 cout <<
" SpMV Update-Match Update-UMC Total "<< endl;
203 cout <<
"==========================================================\n";
204 for(
int i=0; i<timing.size(); i++)
206 for(
int j=0; j<timing[i].size(); j++)
208 printf(
"%12.5lf ", timing[i][j]);
213 cout <<
"-------------------------------------------------------\n";
214 for(
int i=0; i<totalTimes.size(); i++)
215 printf(
"%12.5lf ", totalTimes[i]);
218 std::cout <<
"****** maximal matching runtime ********\n";
219 std::cout <<
"nprocesses nthreads ncores algorithm Unmatched-Rows Cardinality Total Time***\n";
220 std::cout << nprocs <<
" " << nthreads <<
" " << nprocs * nthreads <<
" ";
221 if(type ==
DMD) std::cout <<
"DMD";
222 else if(type ==
GREEDY) std::cout <<
"Greedy";
223 else if(type ==
KARP_SIPSER) std::cout <<
"Karp-Sipser";
226 printf(
"%lld %lld %lf\n", curUnmatchedRow, cardinality, totalTimes.back());
227 std::cout <<
"-------------------------------------------------------\n\n";
239 template <
typename Par_MAT_Double,
typename IT>
249 nthreads = omp_get_num_threads();
254 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
255 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
257 double tStart = MPI_Wtime();
266 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
267 [](VertexType vtx, IT deg){
return VertexType();},
268 [](VertexType vtx, IT deg){
return deg>0;},
276 IT curUnmatchedCol = unmatchedCol.
getnnz();
277 IT curUnmatchedRow = unmatchedRow.getnnz();
281 std::vector<std::vector<double> > timing;
286 cout <<
"=======================================================\n";
287 cout <<
"@@@@@@ Number of processes: " << nprocs << endl;
288 cout <<
"=======================================================\n";
289 cout <<
"It | UMRow | UMCol | newlyMatched | Time "<< endl;
290 cout <<
"=======================================================\n";
293 MPI_Barrier(MPI_COMM_WORLD);
296 while(curUnmatchedCol !=0 && curUnmatchedRow!=0 && newlyMatched != 0 )
299 unmatchedCol.ApplyInd([](VertexType vtx, IT idx){
return VertexType(idx,idx);});
303 std::vector<double> times;
304 double t1 = MPI_Wtime();
306 SpMV<WeightMaxMLSR<double, VertexType>>(
A, unmatchedCol, fringeRow,
false, SPA);
309 fringeRow = EWiseApply<VertexType>(fringeRow, mateRow2Col,
310 [](VertexType vtx, IT mate){
return vtx;},
311 [](VertexType vtx, IT mate){
return mate==-1;},
312 false, VertexType());
314 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
320 fringeRow2 = EWiseApply<IT>(fringeRow, mateRow2Col,
321 [](VertexType vtx, IT mate){
return vtx.parent;},
322 [](VertexType vtx, IT mate){
return true;},
323 false, VertexType());
327 mateCol2Row.
Set(newMatchedCols);
328 mateRow2Col.Set(newMatchedRows);
329 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
335 unmatchedRow.Select(mateRow2Col, [](IT mate){
return mate==-1;});
336 unmatchedCol.Select(mateCol2Row, [](IT mate){
return mate==-1;});
337 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
342 newlyMatched = newMatchedCols.getnnz();
343 times.push_back(std::accumulate(times.begin(), times.end(), 0.0));
344 timing.push_back(times);
348 printf(
"%3d %10lld %10lld %10lld %18lf\n", iteration , curUnmatchedRow, curUnmatchedCol, newlyMatched, times.back());
351 curUnmatchedCol = unmatchedCol.getnnz();
352 curUnmatchedRow = unmatchedRow.getnnz();
353 MPI_Barrier(MPI_COMM_WORLD);
359 IT cardinality = mateRow2Col.
Count([](IT mate){
return mate!=-1;});
360 std::vector<double> totalTimes(timing[0].
size(),0);
361 for(
int i=0; i<timing.size(); i++)
363 for(
int j=0; j<timing[i].size(); j++)
365 totalTimes[j] += timing[i][j];
373 cout <<
"==========================================================\n";
374 cout <<
"\n================individual timings =======================\n";
375 cout <<
" SpMV Update-Match Update-UMC Total "<< endl;
376 cout <<
"==========================================================\n";
377 for(
int i=0; i<timing.size(); i++)
379 for(
int j=0; j<timing[i].size(); j++)
381 printf(
"%12.5lf ", timing[i][j]);
386 cout <<
"-------------------------------------------------------\n";
387 for(
int i=0; i<totalTimes.size(); i++)
388 printf(
"%12.5lf ", totalTimes[i]);
391 std::cout <<
"****** maximal matching runtime ********\n";
392 std::cout <<
"Unmatched-Rows Cardinality Total Time***\n";
393 printf(
"%lld %lld %lf\n", curUnmatchedRow, cardinality, totalTimes.back());
394 std::cout <<
"-------------------------------------------------------\n\n";
402 template <
class Par_DCSC_Bool,
class IT,
class NT>
407 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
413 unmatchedCol.setNumToInd();
416 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
417 fringeRow =
EWiseMult(fringeRow, mateRow2Col,
true, (IT) -1);
418 if(fringeRow.getnnz() != 0)
421 std::cout <<
"Not maximal matching!!\n";
427 SpMV<Select2ndMinSR<bool, VertexType>>(tA, unmatchedRow, fringeCol,
false);
428 fringeCol =
EWiseMult(fringeCol, mateCol2Row,
true, (IT) -1);
429 if(fringeCol.getnnz() != 0)
432 std::cout <<
"Not maximal matching**!!\n";
std::shared_ptr< CommGrid > getcommgrid() const
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)
void Set(const FullyDistSpVec< IT, NT > &rhs)
Dcsc< IU, typename promote_trait< NU1, NU2 >::T_promote > EWiseMult(const Dcsc< IU, NU1 > &A, const Dcsc< IU, NU2 > *B, bool exclude)
FullyDistSpVec< IT, NT > Invert(IT globallen)
bool isMaximalmatching(Par_DCSC_Bool &A, FullyDistVec< IT, NT > &mateRow2Col, FullyDistVec< IT, NT > &mateCol2Row)
IT Count(_Predicate pred) const
Return the number of elements for which pred is true.
FullyDistSpVec< IT, VT > SpMV(const SpParMat< IT, bool, UDER > &A, const FullyDistSpVec< IT, VT > &x, OptBuf< int32_t, VT > &optbuf)
void WeightedGreedy(Par_MAT_Double &A, FullyDistVec< IT, IT > &mateRow2Col, FullyDistVec< IT, IT > &mateCol2Row, FullyDistVec< IT, IT > °Col)
void Apply(_UnaryOperation __unary_op)