COMBINATORIAL_BLAS
1.6
Loading...
Searching...
No Matches
BPMaximalMatching.cpp
Go to the documentation of this file.
1
#include "CombBLAS/CombBLAS.h"
2
#include <mpi.h>
3
#include <
sys/time.h
>
4
#include <iostream>
5
#include <functional>
6
#include <algorithm>
7
#include <vector>
8
#include <string>
9
#include <sstream>
10
#include "
BPMaximalMatching.h
"
11
12
13
#ifdef THREADED
14
#ifndef _OPENMP
15
#define _OPENMP
16
#endif
17
18
#include <omp.h>
19
int
cblas_splits
= 1;
20
#endif
21
22
using namespace
std;
23
using namespace
combblas
;
24
25
26
bool
prune
,
mvInvertMate
,
randMM
,
moreSplit
;
27
int
init
;
28
bool
randMaximal
;
29
bool
fewexp
;
30
31
template
<
typename
PARMAT>
32
void
Symmetricize
(
PARMAT
&
A
)
33
{
34
// boolean addition is practically a "logical or"
35
// therefore this doesn't destruct any links
36
PARMAT
AT
=
A
;
37
AT
.Transpose();
38
A
+=
AT
;
39
}
40
41
42
struct
VertexType
43
{
44
public
:
45
VertexType
(
int64_t
p=-1,
int64_t
r
=-1,
int16_t
pr=0){
parent
=p;
root
=
r
;
prob
= pr;};
46
47
friend
bool
operator<
(
const
VertexType
&
vtx1
,
const
VertexType
&
vtx2
)
48
{
49
if
(
vtx1
.prob==
vtx2
.prob)
return
vtx1
.parent<
vtx2
.parent;
50
else
return
vtx1
.prob<
vtx2
.prob;
51
};
52
friend
bool
operator==
(
const
VertexType
&
vtx1
,
const
VertexType
&
vtx2
){
return
vtx1
.parent==
vtx2
.parent;};
53
friend
ostream&
operator<<
(ostream&
os
,
const
VertexType
&
vertex
){
os
<<
"("
<<
vertex
.parent <<
","
<<
vertex
.root <<
")"
;
return
os
;};
54
//private:
55
int64_t
parent
;
56
int64_t
root
;
57
int16_t
prob
;
// probability of selecting an edge
58
59
};
60
61
62
63
64
typedef
SpParMat < int64_t, bool, SpDCCols<int64_t,bool>
>
PSpMat_Bool
;
65
66
/*
67
Remove isolated vertices and purmute
68
*/
69
void
removeIsolated
(
PSpMat_Bool
&
A
)
70
{
71
72
int
nprocs
, myrank;
73
MPI_Comm
comm
=
A
.getcommgrid()->GetWorld();
74
MPI_Comm_size
(
comm
,&
nprocs
);
75
MPI_Comm_rank
(
comm
,&myrank);
76
77
78
FullyDistVec<int64_t, int64_t>
*
ColSums
=
new
FullyDistVec<int64_t, int64_t>
(
A
.getcommgrid());
79
FullyDistVec<int64_t, int64_t>
*
RowSums
=
new
FullyDistVec<int64_t, int64_t>
(
A
.getcommgrid());
80
FullyDistVec<int64_t, int64_t>
nonisoRowV
;
// id's of non-isolated (connected) Row vertices
81
FullyDistVec<int64_t, int64_t>
nonisoColV
;
// id's of non-isolated (connected) Col vertices
82
FullyDistVec<int64_t, int64_t>
nonisov
;
// id's of non-isolated (connected) vertices
83
84
A
.Reduce(*
ColSums
,
Column
,
plus<int64_t>
(),
static_cast<
int64_t
>
(0));
85
A
.Reduce(*
RowSums
,
Row
,
plus<int64_t>
(),
static_cast<
int64_t
>
(0));
86
87
// this steps for general graph
88
/*
89
ColSums->EWiseApply(*RowSums, plus<int64_t>()); not needed for bipartite graph
90
nonisov = ColSums->FindInds(bind2nd(greater<int64_t>(), 0));
91
nonisov.RandPerm(); // so that A(v,v) is load-balanced (both memory and time wise)
92
A.operator()(nonisov, nonisov, true); // in-place permute to save memory
93
*/
94
95
// this steps for bipartite graph
96
nonisoColV
=
ColSums
->FindInds(
bind2nd
(
greater<int64_t>
(), 0));
97
nonisoRowV
=
RowSums
->FindInds(
bind2nd
(
greater<int64_t>
(), 0));
98
delete
ColSums
;
99
delete
RowSums
;
100
101
102
{
103
nonisoColV
.RandPerm();
104
nonisoRowV
.RandPerm();
105
}
106
107
108
int64_t
nrows1
=
A
.getnrow(),
ncols1
=
A
.getncol(),
nnz1
=
A
.getnnz();
109
double
avgDeg1
= (
double
)
nnz1
/(
nrows1
+
ncols1
);
110
111
112
A
.operator()(
nonisoRowV
,
nonisoColV
,
true
);
113
114
int64_t
nrows2
=
A
.getnrow(),
ncols2
=
A
.getncol(),
nnz2
=
A
.getnnz();
115
double
avgDeg2
= (
double
)
nnz2
/(
nrows2
+
ncols2
);
116
117
118
if
(myrank == 0)
119
{
120
cout
<<
"ncol nrows nedges deg \n"
;
121
cout
<<
nrows1
<<
" "
<<
ncols1
<<
" "
<<
nnz1
<<
" "
<<
avgDeg1
<<
" \n"
;
122
cout
<<
nrows2
<<
" "
<<
ncols2
<<
" "
<<
nnz2
<<
" "
<<
avgDeg2
<<
" \n"
;
123
}
124
125
MPI_Barrier
(
comm
);
126
127
128
}
129
130
131
132
133
134
135
136
void
ShowUsage
()
137
{
138
int
myrank;
139
MPI_Comm_rank
(
MPI_COMM_WORLD
,&myrank);
140
if
(myrank == 0)
141
{
142
cout
<<
"\n-------------- usage --------------\n"
;
143
cout
<<
"Usage (random matrix): ./maximal <er|g500|ssca> <Scale> <EDGEFACTOR> <algo><rand><moreSplit>\n"
;
144
cout
<<
"Usage (input matrix): ./maximal <input> <matrix> <algo><rand><moreSplit>\n\n"
;
145
146
cout
<<
" \n-------------- meaning of arguments ----------\n"
;
147
cout
<<
"** er: Erdos-Renyi, g500: Graph500 benchmark, ssca: SSCA benchmark\n"
;
148
cout
<<
"** scale: matrix dimention is 2^scale\n"
;
149
cout
<<
"** edgefactor: average degree of vertices\n"
;
150
cout
<<
"** algo : maximal matching algorithm used to initialize\n "
;
151
cout
<<
" greedy: greedy init , ks: Karp-Sipser, dmd: dynamic mindegree\n"
;
152
cout
<<
" default: dynamic mindegree\n"
;
153
cout
<<
"** (optional) rand: random parent selection in greedy/Karp-Sipser\n"
;
154
cout
<<
"** (optional) moreSplit: more splitting of Matrix.\n"
;
155
cout
<<
"(order of optional arguments does not matter)\n"
;
156
157
cout
<<
" \n-------------- examples ----------\n"
;
158
cout
<<
"Example: mpirun -np 4 ./maximal g500 18 16 ks rand"
<<
endl
;
159
cout
<<
"Example: mpirun -np 4 ./maximal input cage12.mtx dmd\n"
<<
endl
;
160
}
161
}
162
163
void
GetOptions
(
char
*
argv
[],
int
argc
)
164
{
165
string
allArg
=
""
;
166
for
(
int
i=0; i<
argc
; i++)
167
{
168
allArg
+=
string
(
argv
[i]);
169
}
170
171
if
(
allArg
.find(
"moreSplit"
)!=string::npos)
172
moreSplit
=
true
;
173
if
(
allArg
.find(
"randMaximal"
)!=string::npos)
174
randMaximal
=
true
;
175
if
(
allArg
.find(
"greedy"
)!=string::npos)
176
init
=
GREEDY
;
177
else
if
(
allArg
.find(
"ks"
)!=string::npos)
178
init
=
KARP_SIPSER
;
179
else
if
(
allArg
.find(
"dmd"
)!=string::npos)
180
init
=
DMD
;
181
else
182
init
=
DMD
;
183
184
}
185
186
void
showCurOptions
()
187
{
188
ostringstream
tinfo
;
189
tinfo
.str(
""
);
190
tinfo
<<
"\n---------------------------------\n"
;
191
tinfo
<<
" Maximal matching algorithm options: "
;
192
if
(
init
==
KARP_SIPSER
)
tinfo
<<
" Karp-Sipser, "
;
193
if
(
init
==
DMD
)
tinfo
<<
" dynamic mindegree, "
;
194
if
(
init
==
GREEDY
)
tinfo
<<
" greedy, "
;
195
if
(
randMaximal
)
tinfo
<<
" random parent selection in greedy/Karp-Sipser, "
;
196
if
(