11 #include "../CombBLAS.h" 52 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
53 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
62 A.
Reduce(*ColSums,
Column, plus<int64_t>(), static_cast<int64_t>(0));
63 A.
Reduce(*RowSums,
Row, plus<int64_t>(), static_cast<int64_t>(0));
74 nonisoColV = ColSums->
FindInds(bind2nd(greater<int64_t>(), 0));
75 nonisoRowV = RowSums->
FindInds(bind2nd(greater<int64_t>(), 0));
87 double avgDeg1 = (double) nnz1/(nrows1+ncols1);
90 A.operator()(nonisoRowV, nonisoColV,
true);
93 double avgDeg2 = (double) nnz2/(nrows2+ncols2);
98 cout <<
"ncol nrows nedges deg \n";
99 cout << nrows1 <<
" " << ncols1 <<
" " << nnz1 <<
" " << avgDeg1 <<
" \n";
100 cout << nrows2 <<
" " << ncols2 <<
" " << nnz2 <<
" " << avgDeg2 <<
" \n";
103 MPI_Barrier(MPI_COMM_WORLD);
112 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
115 cout <<
"\n-------------- usage --------------\n";
116 cout <<
"Usage (random matrix): ./bpmm <er|g500|ssca> <Scale> <EDGEFACTOR> <init><diropt><prune><graft>\n";
117 cout <<
"Usage (input matrix): ./bpmm <input> <matrix> <init><diropt><prune><graft>\n\n";
119 cout <<
" \n-------------- meaning of arguments ----------\n";
120 cout <<
"** er: Erdos-Renyi, g500: Graph500 benchmark, ssca: SSCA benchmark\n";
121 cout <<
"** scale: matrix dimention is 2^scale\n";
122 cout <<
"** edgefactor: average degree of vertices\n";
123 cout <<
"** (optional) init : maximal matching algorithm used to initialize\n ";
124 cout <<
" none: noinit, greedy: greedy init , ks: Karp-Sipser, dmd: dynamic mindegree\n";
125 cout <<
" default: none\n";
126 cout <<
"** (optional) randMaximal: random parent selection in greedy/Karp-Sipser\n" ;
128 cout <<
"** (optional) prune: discard trees as soon as an augmenting path is found\n" ;
130 cout <<
"** (optional) moreSplit: more splitting of Matrix.\n" ;
131 cout <<
"** (optional) randPerm: Randomly permute the matrix for load balance.\n" ;
132 cout <<
"** (optional) saveMatching: Save the matching vector in a file (filename: inputfile_matching.txt).\n" ;
133 cout <<
"(order of optional arguments does not matter)\n";
136 cout <<
" \n-------------- examples ----------\n";
137 cout <<
"Example: mpirun -np 4 ./bpmm g500 18 16" << endl;
138 cout <<
"Example: mpirun -np 4 ./bpmm g500 18 16 ks diropt graft" << endl;
139 cout <<
"Example: mpirun -np 4 ./bpmm input cage12.mtx randPerm ks diropt graft\n" << endl;
146 for(
int i=0; i<argc; i++)
148 allArg += string(argv[i]);
151 if(allArg.find(
"prune")!=string::npos)
153 if(allArg.find(
"fewexp")!=string::npos)
155 if(allArg.find(
"moreSplit")!=string::npos)
157 if(allArg.find(
"saveMatching")!=string::npos)
159 if(allArg.find(
"randMM")!=string::npos)
161 if(allArg.find(
"randMaximal")!=string::npos)
163 if(allArg.find(
"randPerm")!=string::npos)
165 if(allArg.find(
"greedy")!=string::npos)
167 else if(allArg.find(
"ks")!=string::npos)
169 else if(allArg.find(
"dmd")!=string::npos)
180 tinfo <<
"\n---------------------------------\n";
181 tinfo <<
"Calling maximum-cardinality matching with options: " << endl;
185 if(
init ==
DMD) tinfo <<
" dynamic mindegree, ";
187 if(
randMaximal) tinfo <<
" random parent selection in greedy/Karp-Sipser, ";
188 if(
prune) tinfo <<
" tree pruning, ";
190 if(
randPerm) tinfo <<
" Randomly permute the matrix for load balance ";
191 if(
saveMatching) tinfo <<
" Write the matcing in a file";
192 tinfo <<
"\n---------------------------------\n\n";
193 SpParHelper::Print(tinfo.str());
285 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
286 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
295 time_start=MPI_Wtime();
297 double time_dmd = MPI_Wtime()-time_start;
300 time_start=MPI_Wtime();
302 double time_mm_dmd = MPI_Wtime()-time_start;
309 time_start=MPI_Wtime();
311 double time_ks = MPI_Wtime()-time_start;
314 time_start=MPI_Wtime();
316 double time_mm_ks = MPI_Wtime()-time_start;
324 time_start=MPI_Wtime();
326 double time_greedy = MPI_Wtime()-time_start;
329 time_start=MPI_Wtime();
331 double time_mm_greedy = MPI_Wtime()-time_start;
338 cout <<
"\n maximal matching experiment \n";
339 cout << cardGreedy <<
" " << mmcardGreedy <<
" " << time_greedy <<
" " << time_mm_greedy <<
" " << cardKS <<
" " << mmcardKS <<
" " << time_ks <<
" " << time_mm_ks <<
" " << cardDMD <<
" " << mmcardDMD <<
" " << time_dmd <<
" " << time_mm_dmd <<
" \n";
345 int main(
int argc,
char* argv[])
350 MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &provided);
351 if (provided < MPI_THREAD_SERIALIZED)
353 printf(
"ERROR: The MPI library does not have MPI_THREAD_SERIALIZED support\n");
354 MPI_Abort(MPI_COMM_WORLD, 1);
357 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
358 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
376 SpParHelper::Print(
"***** I/O and other preprocessing steps *****\n");
383 if(
string(argv[1]) ==
string(
"input"))
387 string filename(argv[2]);
389 tinfo <<
"\n**** Reading input matrix: " << filename <<
" ******* " << endl;
390 SpParHelper::Print(tinfo.str());
396 tinfo <<
"Reader took " << t02-t01 <<
" seconds" << endl;
397 SpParHelper::Print(tinfo.str());
401 ofname = filename +
".matching.out";
414 unsigned scale = (unsigned) atoi(argv[2]);
415 unsigned EDGEFACTOR = (unsigned) atoi(argv[3]);
417 if(
string(argv[1]) == string(
"er"))
424 cout <<
"Randomly generated ER matric\n";
426 else if(
string(argv[1]) == string(
"g500"))
433 cout <<
"Randomly generated G500 matric\n";
435 else if(
string(argv[1]) == string(
"ssca"))
442 cout <<
"Randomly generated SSCA matric\n";
447 printf(
"The input type - %s - is not recognized.\n", argv[2]);
448 MPI_Abort(MPI_COMM_WORLD, 1);
451 SpParHelper::Print(
"Generating input matrix....\n");
460 tinfo <<
"Generator took " << t02-t01 <<
" seconds" << endl;
461 SpParHelper::Print(tinfo.str());
465 SpParHelper::Print(
"Generated matrix symmetricized....\n");
476 SpParHelper::Print(
"Performing random permutation of matrix.\n");
480 pcol.iota(ABool->
getncol(), 0);
483 (*ABool)(prow, pcol,
true);
484 SpParHelper::Print(
"Performed random permutation of matrix.\n");
494 A.
Reduce(degCol,
Column, plus<int64_t>(), static_cast<int64_t>(0));
500 int splitPerThread = 1;
502 nthreads = omp_get_num_threads();
506 tinfo <<
"Threading activated with " << nthreads <<
" threads, and matrix split into "<<
cblas_splits <<
" parts" << endl;
507 SpParHelper::Print(tinfo.str());
513 SpParHelper::Print(
"**************************************************\n\n");
void experiment_maximal(Par_DCSC_Bool &A, Par_DCSC_Bool &AT, FullyDistVec< int64_t, int64_t > degCol)
FullyDistVec< IT, NT > Reduce(Dim dim, _BinaryOperation __binary_op, NT id, _UnaryOperation __unary_op) const
std::shared_ptr< CommGrid > getcommgrid() const
void ActivateThreading(int numsplits)
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.
SpParMat< int64_t, double, SpDCCols< int64_t, double > > Par_DCSC_Double
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 experiment(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
SpParMat< int64_t, int64_t, SpDCCols< int64_t, int64_t > > Par_DCSC_int64_t
IT Count(_Predicate pred) const
Return the number of elements for which pred is true.
void iota(IT globalsize, NT first)
void maximumMatching(PSpMat_s32p64 &Aeff, FullyDistVec< int64_t, int64_t > &mateRow2Col, FullyDistVec< int64_t, int64_t > &mateCol2Row)
void removeIsolated(Par_DCSC_Bool &A)
void ParallelWrite(const std::string &filename, bool onebased, HANDLER handler, bool includeindices=true)
void Apply(_UnaryOperation __unary_op)
void defaultExp(Par_DCSC_Bool &A, Par_DCSC_Bool &AT, FullyDistVec< int64_t, int64_t > degCol)
int main(int argc, char *argv[])
void GetOptions(char *argv[], int argc)
void Symmetricize(PARMAT &A)
void ParallelReadMM(const std::string &filename, bool onebased, _BinaryOperation BinOp)