COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
ApproxWeightPerfectMatching.cpp
Go to the documentation of this file.
1
2#ifdef THREADED
3#ifndef _OPENMP
4#define _OPENMP
5#endif
6
7#include <omp.h>
8int cblas_splits = 1;
9#endif
10
11#include "CombBLAS/CombBLAS.h"
12#include <mpi.h>
13#include <sys/time.h>
14#include <iostream>
15#include <functional>
16#include <algorithm>
17#include <vector>
18#include <string>
19#include <sstream>
20#include <limits>
21
22
23#include "BPMaximalMatching.h"
24#include "BPMaximumMatching.h"
26
27using namespace std;
28using namespace combblas;
29
35
37{
38 int myrank;
40 if(myrank == 0)
41 {
42 cout << "\n-------------- usage --------------\n";
43 cout << "Usage: ./awpm -input <filename>\n";
44 cout << "Optional parameters: -randPerm: randomly permute the matrix for load balance (default: no random permutation)\n";
45 cout << " -optsum: Optimize the sum of diagonal (default: Optimize the product of diagonal)\n";
46 cout << " -noWeightedCard: do not use weighted cardinality matching (default: use weighted cardinality matching)\n";
47 cout << " -output <output file>: output file name \n";
48 //cout << " -saveMCM <output file>: output file where maximum cardinality matching is saved \n";
49 cout << " \n-------------- examples ----------\n";
50 cout << "Example: mpirun -np 4 ./awpm -input cage12.mtx \n" << endl;
51 cout << "(output matching is saved to cage12.mtx.awpm.txt)\n" << endl;
52 }
53}
54
55
56
57
58
59
60
61int main(int argc, char* argv[])
62{
63
64 // ------------ initialize MPI ---------------
65 int provided;
68 {
69 printf("ERROR: The MPI library does not have MPI_THREAD_SERIALIZED support\n");
71 }
72 int nprocs, myrank;
75 if(argc < 3)
76 {
77 ShowUsage();
79 return -1;
80 }
81
82 bool randPerm = false;
83 bool optimizeProd = true; // by default optimize sum_log_abs(aii) (after equil)
84
85 bool weightedCard = true;
86 string ifilename = "";
87 string ofname = "";
88 //string ofnameMCM = "";
89 for(int i = 1; i<argc; i++)
90 {
91 if (string(argv[i]) == string("-input")) ifilename = argv[i+1];
92 if (string(argv[i]) == string("-output")) ofname = argv[i+1];
93 //if (string(argv[i]) == string("-saveMCM")) ofnameMCM = argv[i+1];
94 if (string(argv[i]) == string("-optsum")) optimizeProd = false;
95 if (string(argv[i]) == string("-noWeightedCard")) weightedCard = false;
96 if (string(argv[i]) == string("-randPerm")) randPerm = true;
97 }
98
99
100
101
102 // ------------ Process input arguments and build matrix ---------------
103 {
106 tinfo << fixed;
107 cout << fixed;
108 double t01, t02;
109 if(ifilename!="")
110 {
112 t01 = MPI_Wtime();
113 AWeighted->ParallelReadMM(ifilename, true, maximum<double>()); // one-based matrix market file
114 t02 = MPI_Wtime();
115
116 if(AWeighted->getnrow() != AWeighted->getncol())
117 {
118 SpParHelper::Print("Rectangular matrix: Can not compute a perfect matching.\n");
119 MPI_Finalize();
120 return -1;
121 }
122
123 tinfo.str("");
124 tinfo << "Input file name: " << ifilename << endl;
125 tinfo << "Reading the input matrix in" << t02-t01 << " seconds" << endl;
127
128 SpParHelper::Print("Pruning explicit zero entries\n");
129 AWeighted->Prune([](double val){return fabs(val)==0;}, true);
130
131 AWeighted->PrintInfo();
132 }
133 else
134 {
135 ShowUsage();
136 MPI_Finalize();
137 return -1;
138 }
139
140
141
142 // ***** careful: if you permute the matrix, you have the permute the matching vectors as well!!
143 // randomly permute for load balance
144
146 if(randPerm)
147 {
148 if(AWeighted->getnrow() == AWeighted->getncol())
149 {
150 randp.iota(AWeighted->getnrow(), 0);
151 randp.RandPerm();
152 double oldbalance = AWeighted->LoadImbalance();
153 (*AWeighted)(randp,randp,true);
154 double newbalance = AWeighted->LoadImbalance();
155 SpParHelper::Print("Matrix is randomly permuted for load balance.\n");
156 stringstream s;
157 s << "load-balance: before:" << oldbalance << " after:" << newbalance << endl;
158 SpParHelper::Print(s.str());
159 }
160 else
161 {
162 SpParHelper::Print("Rectangular matrix: Can not apply symmetric permutation.\n");
163 }
164 }
165
166
167 Par_DCSC_Bool A = *AWeighted; //just to compute degree
168 // Reduce is not multithreaded, so I am doing it here
170 A.Reduce(degCol, Column, plus<int64_t>(), static_cast<int64_t>(0));
171
172 int64_t maxdeg = degCol.Reduce(maximum<int64_t>(), static_cast<int64_t>(0));
173 tinfo.str("");
174 tinfo << "Maximum degree: " << maxdeg << endl;
176
177 SpParHelper::Print("Preprocessing is done.\n");
178 SpParHelper::Print("----------------------------------------\n");
179
180 FullyDistVec<int64_t, int64_t> mateRow2Col ( A.getcommgrid(), A.getnrow(), (int64_t) -1);
181 FullyDistVec<int64_t, int64_t> mateCol2Row ( A.getcommgrid(), A.getncol(), (int64_t) -1);
182
183 double startT = MPI_Wtime();
185 double endT = MPI_Wtime();
186
187
188
189 if(optimizeProd)
191 else
192 TransformWeight(*AWeighted, false);
194 double origWeight = Trace(*AWeighted, diagnnz);
196 tinfo.str("");
197 tinfo << "Matching is computed " << endl;
198 tinfo << "Sum of Diagonal (with transformation)" << endl;
199 tinfo << " After matching: "<< mWeight << endl;
200 tinfo << " Before matching: " << origWeight << endl;
201
202 tinfo << "Time: " << endT - startT << endl;
203 tinfo << "----------------------------------------\n";
205
206 //revert random permutation if applied before
207 if(randPerm==true && randp.TotalLength() >0)
208 {
209 // inverse permutation
212 }
213 if(ofname!="")
214 {
215 mateRow2Col.ParallelWrite(ofname,false,false);
216 }
217
218
219 }
220 MPI_Finalize();
221 return 0;
222}
223
224
SpParMat< int64_t, bool, SpDCCols< int64_t, bool > > Par_DCSC_Bool
SpParMat< int64_t, double, SpCCols< int64_t, double > > Par_CSC_Double
SpParMat< int64_t, bool, SpCCols< int64_t, bool > > Par_CSC_Bool
SpParMat< int64_t, double, SpDCCols< int64_t, double > > Par_DCSC_Double
SpParMat< int64_t, int64_t, SpDCCols< int64_t, int64_t > > Par_DCSC_int64_t
string ofname
bool randPerm
int cblas_splits
Definition BcastTest.cpp:26
int main()
Definition Driver.cpp:12
static void Print(const std::string &s)
int nprocs
Definition comms.cpp:55
@ Column
Definition SpDefs.h:115
NT MatchingWeight(std::vector< NT > &RepMateWC2R, MPI_Comm RowWorld, NT &minw)
void TransformWeight(SpParMat< IT, NT, DER > &A, bool applylog)
NT Trace(SpParMat< IT, NT, DER > &A, IT &rettrnnz=0)
void AWPM(SpParMat< IT, NT, SpDCCols< IT, NT > > &A1, FullyDistVec< IT, IT > &mateRow2Col, FullyDistVec< IT, IT > &mateCol2Row, bool optimizeProd=true, bool weightedCard=true)
double A