-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.cpp
171 lines (143 loc) · 4.96 KB
/
Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <stdlib.h>
#include <map>
#include <cstdio>
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_set>
#include <set>
#include <algorithm>
#include <cassert>
#include <omp.h>
#include <chrono>
#include <math.h>
/*
To run on cluster do the following:
>> export OMP_NUM_THREADS=numThreads
>> g++ -fopenmp Main.cpp -std=gnu++11
*/
#define TimerStart a1 = std::chrono::high_resolution_clock::now()
#define TimerEnd a2 = std::chrono::high_resolution_clock::now()
#define getTime (double)std::chrono::duration_cast<std::chrono::microseconds>( a2 - a1 ).count() / 1000000.0
#define TS b1 = std::chrono::high_resolution_clock::now()
#define TE b2 = std::chrono::high_resolution_clock::now()
#define gT (double)std::chrono::duration_cast<std::chrono::microseconds>( b2 - b1 ).count() / 1000000.0
#define startTimer1 auto t1 = std::chrono::high_resolution_clock::now()
#define endTimer1 auto t2 = std::chrono::high_resolution_clock::now()
#define printTime1 auto durationSeq1 = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count(); std::cout << "Time Seq: " << durationSeq1 / 1000000.0<< " sec\n"
#define startTimer2 auto l1 = std::chrono::high_resolution_clock::now()
#define endTimer2 auto l2 = std::chrono::high_resolution_clock::now()
#define printTime2 auto durationSeq2 = std::chrono::duration_cast<std::chrono::microseconds>( l2 - l1 ).count(); std::cout << "Time Par: " << durationSeq2 / 1000000.0<< " sec\n"
#define nn std::cout << "\n"
using namespace std;
// Timing stuff
// To get times insert into timesmap
vector<pair<string,double>> times;
map<string,double> timesMap;
vector<string> toMap = {"Calc Best","Multi Pref","Find Parents","Rewrite Vector","Rename to Supervertex","Insert into MST","Resort edgelist","cutoff","Return MST"};
std::chrono::_V2::system_clock::time_point a1;
std::chrono::_V2::system_clock::time_point a2;
std::chrono::_V2::system_clock::time_point b1;
std::chrono::_V2::system_clock::time_point b2;
#include "headers/parasort.h"
#include "headers/Prefix.h"
#include "headers/ParAggregate.h"
#include "headers/PrefixAnySize.h"
#include "headers/vectorOperations.h"
#include "headers/FindCorrectPlace.h"
#include "headers/Structures.h"
#include "headers/finParentsUndirected.h"
#include "headers/primSteps.h"
#include "headers/CSR_Format.h"
#include "headers/EdgelistToAdjArray.h"
#include "headers/BoruvkaSeq.h"
#include "headers/KruskalSeq.h"
#include "headers/CheckConnectivity.h"
#include "headers/PrimSeq.h"
#include "headers/SequentialCutoff.h"
#include "headers/BoruvkaPara.h"
#include "headers/rewriteVector.h"
#include "headers/cutEdgelist.h"
#include "headers/ImpStep.h"
#include "headers/ImpBoruvkaPara.h"
#include "headers/TestCases.h"
// We want the output to be an edgelist with edgeids, sorted
int main() {
// Setup I/O and timing
ifstream f;
f.open("Resources/BarabasiSparse1M3E.txt");
vector<edge> edgelist;
vector<edge> edgelistSingle;
for(auto e : toMap){
timesMap.insert(make_pair(e,0));
}
int source,dest,weight;
int n,m;
int i = 0;
while(f >> source && f >> dest && f >> weight){
n = max(n,max(source,dest));
m++;
edge e1 = edge(source,dest,weight,i++);
edge e2 = edge(e1.dest,e1.source, e1.weight, e1.idx);
edgelist.push_back(e1);
edgelist.push_back(e2);
edgelistSingle.push_back(e1);
assert(e1.weight > 0 && "Weights may not be 0");
}
// We add two edges
n += 1;
int nSafe = n;
int msingle = m;
m = 2*m;
std::cout << "Read everything\n";
// Sort the edgelist
auto compara = [](edge e1, edge e2){return e1.source < e2.source;};
sort(edgelist.begin(), edgelist.end(), compara);
std::cout << "Passes Sorting\n";
// Count outgoing sizes -> This can be parallel
vector<int> outgoingEdges(n);
for(int i = 0; i < m; i++){
outgoingEdges[edgelist[i].source]++;
}
TimerStart;
vector<edge> sols = MinimumSpanningTreeBoruvkaSeq(edgelistSingle, n, msingle);
TimerEnd;
times.push_back(make_pair("Sequential Runtime", getTime));
std::cout << "Start Parallel:\n";
TimerStart;
std::cout << "Starts\n";
int nrThreads = 8;
int cutoff = 100;
vector<edge> solp = ParBoruvkaImp(edgelist, edgelistSingle, outgoingEdges, n, m, nrThreads, cutoff);
TimerEnd;
times.push_back(make_pair("Parallel Runtime", getTime));
assert(is_Connected(sols, nSafe) && "Solution seq is not connected");
assert(is_Connected(solp, nSafe) && "Solution par is not connected");
int parRes = 0;
set<int> seqSet;
set<int> parSet;
std::cout << "Found Parallel MST:\n";
for(auto e : solp){
//std::cout << e.source << ' ' << e.dest;nn;
parSet.insert(e.idx);
parRes += e.weight;
}
nn;
int seqRes = 0;
for(auto e : sols){
seqSet.insert(e.idx);
seqRes += e.weight;
}
std::cout << "ImpBor: " << parRes;nn;
std::cout << "SeqBor: " << seqRes;nn;
std::cout << "\nTiming:\n--------------------\n";
for(auto e : times){
std::cout << e.first << " : " << e.second;nn;
}
std::cout << "\nBreakdown:\n--------------------\n";
for(auto e : timesMap){
std::cout << e.first << " : " << e.second;nn;
}
nn;
return 0;
}