1#ifndef BP_MAXIMAL_MATCHING_H
2#define BP_MAXIMAL_MATCHING_H
4#include "CombBLAS/CombBLAS.h"
23template <
typename Par_DCSC_Bool,
typename IT>
31 MPI_Comm comm =
A.getcommgrid()->GetWorld();
32 MPI_Comm_size(comm,&
nprocs);
33 MPI_Comm_rank(comm,&myrank);
38 nthreads = omp_get_num_threads();
53 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
64 IT curUnmatchedCol = unmatchedCol.
getnnz();
65 IT curUnmatchedRow = unmatchedRow.getnnz();
68 double tStart = MPI_Wtime();
69 std::vector<std::vector<double> > timing;
74 cout <<
"=======================================================\n";
75 cout <<
"@@@@@@ Number of processes: " <<
nprocs << endl;
76 cout <<
"=======================================================\n";
77 cout <<
"It | UMRow | UMCol | newlyMatched | Time "<< endl;
78 cout <<
"=======================================================\n";
84 while(curUnmatchedCol !=0 && curUnmatchedRow!=0 && newlyMatched != 0 )
89 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
100 std::vector<double> times;
101 double t1 = MPI_Wtime();
104 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
108 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
112 deg1Col = EWiseApply<VertexType>(unmatchedCol, degCol,
120 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
123 fringeRow = EWiseApply<VertexType>(fringeRow, mateRow2Col,
128 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
134 fringeRow2 = EWiseApply<IT>(fringeRow, mateRow2Col,
141 mateCol2Row.
Set(newMatchedCols);
142 mateRow2Col.
Set(newMatchedRows);
143 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
148 unmatchedRow.Select(mateRow2Col, [](
IT mate){
return mate==-1;});
149 unmatchedCol.
Select(mateCol2Row, [](
IT mate){
return mate==-1;});
154 newMatchedRows.
Apply([](
IT val){
return 1;});
155 SpMV< SelectPlusSR<bool, IT>>(AT, newMatchedRows, degColSG,
false);
158 [](
IT old_deg,
IT new_deg){
return old_deg-new_deg;},
159 [](
IT old_deg,
IT new_deg){
return true;},
160 false,
static_cast<IT>(0));
162 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
167 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
172 newlyMatched = newMatchedCols.getnnz();
173 times.push_back(std::accumulate(times.begin(), times.end(), 0.0));
174 timing.push_back(times);
178 printf(
"%3d %10lld %10lld %10lld %18lf\n", iteration , curUnmatchedRow, curUnmatchedCol, newlyMatched, times.back());
181 curUnmatchedCol = unmatchedCol.
getnnz();
182 curUnmatchedRow = unmatchedRow.getnnz();
187 IT cardinality = mateRow2Col.
Count([](
IT mate){
return mate!=-1;});
188 std::vector<double> totalTimes(timing[0].
size(),0);
189 for(
int i=0; i<timing.size(); i++)
191 for(
int j=0; j<timing[i].size(); j++)
193 totalTimes[j] += timing[i][j];
201 cout <<
"==========================================================\n";
202 cout <<
"\n================individual timings =======================\n";
203 cout <<
" SpMV Update-Match Update-UMC Total "<< endl;
204 cout <<
"==========================================================\n";
205 for(
int i=0; i<timing.size(); i++)
207 for(
int j=0; j<timing[i].size(); j++)
209 printf(
"%12.5lf ", timing[i][j]);
214 cout <<
"-------------------------------------------------------\n";
215 for(
int i=0; i<totalTimes.size(); i++)
216 printf(
"%12.5lf ", totalTimes[i]);
219 std::cout <<
"****** maximal matching runtime ********\n";
220 std::cout <<
"nprocesses nthreads ncores algorithm Unmatched-Rows Cardinality Total Time***\n";
221 std::cout <<
nprocs <<
" " << nthreads <<
" " <<
nprocs * nthreads <<
" ";
222 if(type ==
DMD) std::cout <<
"DMD";
223 else if(type ==
GREEDY) std::cout <<
"Greedy";
224 else if(type ==
KARP_SIPSER) std::cout <<
"Karp-Sipser";
227 printf(
"%lld %lld %lf\n", curUnmatchedRow, cardinality, totalTimes.back());
228 std::cout <<
"-------------------------------------------------------\n\n";
240template <
typename Par_MAT_Double,
typename IT>
250 nthreads = omp_get_num_threads();
255 MPI_Comm comm =
A.getcommgrid()->GetWorld();
256 MPI_Comm_size(comm,&
nprocs);
257 MPI_Comm_rank(comm,&myrank);
267 unmatchedCol = EWiseApply<VertexType>(unmatchedCol, degCol,
277 IT curUnmatchedCol = unmatchedCol.
getnnz();
278 IT curUnmatchedRow = unmatchedRow.getnnz();
282 std::vector<std::vector<double> > timing;
287 cout <<
"=======================================================\n";
288 cout <<
"@@@@@@ Number of processes: " <<
nprocs << endl;
289 cout <<
"=======================================================\n";
290 cout <<
"It | UMRow | UMCol | newlyMatched | Time "<< endl;
291 cout <<
"=======================================================\n";
297 while(curUnmatchedCol !=0 && curUnmatchedRow!=0 && newlyMatched != 0 )
304 std::vector<double> times;
305 double t1 = MPI_Wtime();
307 SpMV<WeightMaxMLSR<double, VertexType>>(
A, unmatchedCol, fringeRow,
false, SPA);
310 fringeRow = EWiseApply<VertexType>(fringeRow, mateRow2Col,
315 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
321 fringeRow2 = EWiseApply<IT>(fringeRow, mateRow2Col,
328 mateCol2Row.
Set(newMatchedCols);
329 mateRow2Col.
Set(newMatchedRows);
330 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
336 unmatchedRow.Select(mateRow2Col, [](
IT mate){
return mate==-1;});
337 unmatchedCol.Select(mateCol2Row, [](
IT mate){
return mate==-1;});
338 if(myrank == 0){times.push_back(MPI_Wtime()-t1); t1 = MPI_Wtime();}
343 newlyMatched = newMatchedCols.getnnz();
344 times.push_back(std::accumulate(times.begin(), times.end(), 0.0));
345 timing.push_back(times);
349 printf(
"%3d %10lld %10lld %10lld %18lf\n", iteration , curUnmatchedRow, curUnmatchedCol, newlyMatched, times.back());
352 curUnmatchedCol = unmatchedCol.getnnz();
353 curUnmatchedRow = unmatchedRow.getnnz();
358 IT cardinality = mateRow2Col.
Count([](
IT mate){
return mate!=-1;});
359 std::vector<double> totalTimes(timing[0].
size(),0);
360 for(
int i=0; i<timing.size(); i++)
362 for(
int j=0; j<timing[i].size(); j++)
364 totalTimes[j] += timing[i][j];
372 cout <<
"==========================================================\n";
373 cout <<
"\n================individual timings =======================\n";
374 cout <<
" SpMV Update-Match Update-UMC Total "<< endl;
375 cout <<
"==========================================================\n";
376 for(
int i=0; i<timing.size(); i++)
378 for(
int j=0; j<timing[i].size(); j++)
380 printf(
"%12.5lf ", timing[i][j]);
385 cout <<
"-------------------------------------------------------\n";
386 for(
int i=0; i<totalTimes.size(); i++)
387 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";
403template <
class Par_DCSC_Bool,
class IT,
class NT>
408 MPI_Comm comm =
A.getcommgrid()->GetWorld();
409 MPI_Comm_rank(comm,&myrank);
415 unmatchedCol.setNumToInd();
418 SpMV<Select2ndMinSR<bool, VertexType>>(
A, unmatchedCol, fringeRow,
false);
419 fringeRow =
EWiseMult(fringeRow, mateRow2Col,
true, (
IT) -1);
420 if(fringeRow.
getnnz() != 0)
423 std::cout <<
"Not maximal matching!!\n";
429 SpMV<Select2ndMinSR<bool, VertexType>>(tA, unmatchedRow, fringeCol,
false);
430 fringeCol =
EWiseMult(fringeCol, mateCol2Row,
true, (
IT) -1);
431 if(fringeCol.
getnnz() != 0)
434 std::cout <<
"Not maximal matching**!!\n";
void Select(const FullyDistVec< IT, NT1 > &denseVec, _UnaryOperation unop)
void Apply(_UnaryOperation __unary_op)
FullyDistSpVec< IT, NT > Invert(IT globallen)
void ApplyInd(_BinaryOperation __binary_op)
void EWiseApply(const FullyDistVec< IT, NT2 > &other, _BinaryOperation __binary_op, _BinaryPredicate _do_op, const bool useExtendedBinOp)
void Set(const FullyDistSpVec< IT, NT > &rhs)
IT Count(_Predicate pred) const
Return the number of elements for which pred is true.
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)
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)
Dcsc< IU, typename promote_trait< NU1, NU2 >::T_promote > EWiseMult(const Dcsc< IU, NU1 > &A, const Dcsc< IU, NU2 > *B, bool exclude)