11#include "CombBLAS/CombBLAS.h"
52 MPI_Comm comm =
A.getcommgrid()->GetWorld();
53 MPI_Comm_size(comm,&
nprocs);
54 MPI_Comm_rank(comm,&myrank);
63 A.Reduce(*ColSums,
Column, plus<int64_t>(),
static_cast<int64_t>(0));
64 A.Reduce(*RowSums,
Row, plus<int64_t>(),
static_cast<int64_t>(0));
75 nonisoColV = ColSums->
FindInds(bind2nd(greater<int64_t>(), 0));
76 nonisoRowV = RowSums->
FindInds(bind2nd(greater<int64_t>(), 0));
87 int64_t nrows1=
A.getnrow(), ncols1=
A.getncol(), nnz1 =
A.getnnz();
88 double avgDeg1 = (double) nnz1/(nrows1+ncols1);
91 A.operator()(nonisoRowV, nonisoColV,
true);
93 int64_t nrows2=
A.getnrow(), ncols2=
A.getncol(), nnz2 =
A.getnnz();
94 double avgDeg2 = (double) nnz2/(nrows2+ncols2);
99 cout <<
"ncol nrows nedges deg \n";
100 cout << nrows1 <<
" " << ncols1 <<
" " << nnz1 <<
" " << avgDeg1 <<
" \n";
101 cout << nrows2 <<
" " << ncols2 <<
" " << nnz2 <<
" " << avgDeg2 <<
" \n";
113 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
116 cout <<
"\n-------------- usage --------------\n";
117 cout <<
"Usage (random matrix): ./bpmm <er|g500|ssca> <Scale> <EDGEFACTOR> <init><diropt><prune><graft>\n";
118 cout <<
"Usage (input matrix): ./bpmm <input> <matrix> <init><diropt><prune><graft>\n\n";
120 cout <<
" \n-------------- meaning of arguments ----------\n";
121 cout <<
"** er: Erdos-Renyi, g500: Graph500 benchmark, ssca: SSCA benchmark\n";
122 cout <<
"** scale: matrix dimention is 2^scale\n";
123 cout <<
"** edgefactor: average degree of vertices\n";
124 cout <<
"** (optional) init : maximal matching algorithm used to initialize\n ";
125 cout <<
" none: noinit, greedy: greedy init , ks: Karp-Sipser, dmd: dynamic mindegree\n";
126 cout <<
" default: none\n";
127 cout <<
"** (optional) randMaximal: random parent selection in greedy/Karp-Sipser\n" ;
129 cout <<
"** (optional) prune: discard trees as soon as an augmenting path is found\n" ;
131 cout <<
"** (optional) moreSplit: more splitting of Matrix.\n" ;
132 cout <<
"** (optional) randPerm: Randomly permute the matrix for load balance.\n" ;
133 cout <<
"** (optional) saveMatching: Save the matching vector in a file (filename: inputfile_matching.txt).\n" ;
134 cout <<
"(order of optional arguments does not matter)\n";
137 cout <<
" \n-------------- examples ----------\n";
138 cout <<
"Example: mpirun -np 4 ./bpmm g500 18 16" << endl;
139 cout <<
"Example: mpirun -np 4 ./bpmm g500 18 16 ks diropt graft" << endl;
140 cout <<
"Example: mpirun -np 4 ./bpmm input cage12.mtx randPerm ks diropt graft\n" << endl;
147 for(
int i=0; i<argc; i++)
149 allArg += string(argv[i]);
152 if(allArg.find(
"prune")!=string::npos)
154 if(allArg.find(
"fewexp")!=string::npos)
156 if(allArg.find(
"moreSplit")!=string::npos)
158 if(allArg.find(
"saveMatching")!=string::npos)
160 if(allArg.find(
"randMM")!=string::npos)
162 if(allArg.find(
"randMaximal")!=string::npos)
164 if(allArg.find(
"randPerm")!=string::npos)
166 if(allArg.find(
"greedy")!=string::npos)
168 else if(allArg.find(
"ks")!=string::npos)
170 else if(allArg.find(
"dmd")!=string::npos)
181 tinfo <<
"\n---------------------------------\n";
182 tinfo <<
"Calling maximum-cardinality matching with options: " << endl;
186 if(
init ==
DMD) tinfo <<
" dynamic mindegree, ";
188 if(
randMaximal) tinfo <<
" random parent selection in greedy/Karp-Sipser, ";
189 if(
prune) tinfo <<
" tree pruning, ";
191 if(
randPerm) tinfo <<
" Randomly permute the matrix for load balance ";
192 if(
saveMatching) tinfo <<
" Write the matcing in a file";
193 tinfo <<
"\n---------------------------------\n\n";
194 SpParHelper::Print(tinfo.str());
286 MPI_Comm comm =
A.getcommgrid()->GetWorld();
287 MPI_Comm_size(comm,&
nprocs);
288 MPI_Comm_rank(comm,&myrank);
297 time_start=MPI_Wtime();
299 double time_dmd = MPI_Wtime()-time_start;
302 time_start=MPI_Wtime();
304 double time_mm_dmd = MPI_Wtime()-time_start;
311 time_start=MPI_Wtime();
313 double time_ks = MPI_Wtime()-time_start;
316 time_start=MPI_Wtime();
318 double time_mm_ks = MPI_Wtime()-time_start;
326 time_start=MPI_Wtime();
328 double time_greedy = MPI_Wtime()-time_start;
331 time_start=MPI_Wtime();
333 double time_mm_greedy = MPI_Wtime()-time_start;
340 cout <<
"\n maximal matching experiment \n";
341 cout << cardGreedy <<
" " << mmcardGreedy <<
" " << time_greedy <<
" " << time_mm_greedy <<
" " << cardKS <<
" " << mmcardKS <<
" " << time_ks <<
" " << time_mm_ks <<
" " << cardDMD <<
" " << mmcardDMD <<
" " << time_dmd <<
" " << time_mm_dmd <<
" \n";
347int main(
int argc,
char* argv[])
352 MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &provided);
353 if (provided < MPI_THREAD_SERIALIZED)
355 printf(
"ERROR: The MPI library does not have MPI_THREAD_SERIALIZED support\n");
356 MPI_Abort(MPI_COMM_WORLD, 1);
359 MPI_Comm_size(MPI_COMM_WORLD,&
nprocs);
360 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
378 SpParHelper::Print(
"***** I/O and other preprocessing steps *****\n");
385 if(
string(argv[1]) ==
string(
"input"))
389 string filename(argv[2]);
391 tinfo <<
"\n**** Reading input matrix: " << filename <<
" ******* " << endl;
392 SpParHelper::Print(tinfo.str());
398 tinfo <<
"Reader took " << t02-t01 <<
" seconds" << endl;
399 SpParHelper::Print(tinfo.str());
403 ofname = filename +
".matching.out";
416 unsigned scale = (unsigned) atoi(argv[2]);
417 unsigned EDGEFACTOR = (unsigned) atoi(argv[3]);
419 if(
string(argv[1]) == string(
"er"))
426 cout <<
"Randomly generated ER matric\n";
428 else if(
string(argv[1]) == string(
"g500"))
435 cout <<
"Randomly generated G500 matric\n";
437 else if(
string(argv[1]) == string(
"ssca"))
444 cout <<
"Randomly generated SSCA matric\n";
449 printf(
"The input type - %s - is not recognized.\n", argv[2]);
450 MPI_Abort(MPI_COMM_WORLD, 1);
453 SpParHelper::Print(
"Generating input matrix....\n");
462 tinfo <<
"Generator took " << t02-t01 <<
" seconds" << endl;
463 SpParHelper::Print(tinfo.str());
467 SpParHelper::Print(
"Generated matrix symmetricized....\n");
478 SpParHelper::Print(
"Performing random permutation of matrix.\n");
485 (*ABool)(prow, pcol,
true);
486 SpParHelper::Print(
"Performed random permutation of matrix.\n");
496 A.Reduce(degCol,
Column, plus<int64_t>(),
static_cast<int64_t>(0));
519 SpParHelper::Print(
"**************************************************\n\n");
int main(int argc, char *argv[])
void experiment_maximal(Par_DCSC_Bool &A, Par_DCSC_Bool &AT, FullyDistVec< int64_t, int64_t > degCol)
SpParMat< int64_t, bool, SpDCCols< int64_t, bool > > Par_DCSC_Bool
SpParMat< int64_t, bool, SpCCols< int64_t, bool > > Par_CSC_Bool
void GetOptions(char *argv[], int argc)
SpParMat< int64_t, double, SpDCCols< int64_t, double > > Par_DCSC_Double
void defaultExp(Par_DCSC_Bool &A, Par_DCSC_Bool &AT, FullyDistVec< int64_t, int64_t > degCol)
SpParMat< int64_t, int64_t, SpDCCols< int64_t, int64_t > > Par_DCSC_int64_t
void removeIsolated(Par_DCSC_Bool &A)
void experiment(Par_DCSC_Bool &A, Par_DCSC_Bool &AT, FullyDistVec< int64_t, int64_t > degCol)
void maximumMatching(PSpMat_s32p64 &Aeff, FullyDistVec< int64_t, int64_t > &mateRow2Col, FullyDistVec< int64_t, int64_t > &mateCol2Row)
void GenGraph500Data(double initiator[4], int log_numverts, int edgefactor, bool scramble=false, bool packed=false)
FullyDistVec< IT, IT > FindInds(_Predicate pred) const
Return the indices where pred is true.
void ParallelWrite(const std::string &filename, bool onebased, HANDLER handler, bool includeindices=true)
void iota(IT globalsize, NT first)
IT Count(_Predicate pred) const
Return the number of elements for which pred is true.
void Apply(_UnaryOperation __unary_op)
void ParallelReadMM(const std::string &filename, bool onebased, _BinaryOperation BinOp)
std::shared_ptr< CommGrid > getcommgrid() const
void Symmetricize(PARMAT &A)
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)
Compute the maximum of two values.