-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
143 lines (117 loc) · 4.66 KB
/
Copy pathmain.cpp
File metadata and controls
143 lines (117 loc) · 4.66 KB
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
#include "graph.h"
#include "bfs.h"
#include "utils.h"
#include <iostream>
#include <vector>
#include <string>
#include <limits>
#include <algorithm>
#include <random>
#include <omp.h> // Add OpenMP header
// Calculate BFS statistics
BFSStats calculateBFSStats(const std::vector<int>& distances, int source,
double time_ms, int num_vertices, int num_edges,
const std::string& implementation) {
//count number of visited vertices
int visited = 0;
int max_distance = -1;
for (int d : distances) {
if (d != std::numeric_limits<int>::max()){ // If the vertex is reachable
visited++;
max_distance = std::max(max_distance, d);
}
}
return BFSStats{
source,
time_ms,
num_vertices,
num_edges,
visited,
max_distance,
implementation
};
}
int main (int argc, char* argv[]) {
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << " <graph_file> <source_vertex> [directed=1] [num_runs=1] [num_threads=4]" << std::endl;
return 1;
}
std::string graph_file = argv[1];
int source = std::stoi(argv[2]);
bool directed = ( argc > 3) ? std::stoi(argv[3]) !=0 : true; // Default to directed graph
int num_runs = (argc > 4) ? std::stoi(argv[4]) : 1; // Default to 1 run
int num_threads = (argc > 5) ? std::stoi(argv[5]) : 4; // Default to 4 threads
// Load the graph from the file
std::cout << "Loading graph from file: " << graph_file << std::endl;
Graph graph = Graph::loadFromFile(graph_file, directed);
//Print Graph stats
graph.printStats();
//Validate source vertex
if (source < 0 || source >= graph.getNumVertices()) {
std::cerr << "Error: Source vertex " << source << " out of range [0, "
<< graph.getNumVertices() - 1 << "]" << std::endl;
// Choose a random valid source instead
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(0, graph.getNumVertices() - 1);
source = distrib(gen);
std::cout << "Randomly selected source vertex: " << source << std::endl;
}
// Run Sequential BFS
std::cout << "\nRunning Sequential BFS..." << std::endl;
Timer timer;
std::vector<int> reference_distances;
double total_seq_time = 0.0;
for (int run = 0; run < num_runs; run++) {
timer.start();
auto distances = bfsSequential(graph, source);
double elapsed_ms = timer.elapsed();
total_seq_time += elapsed_ms;
if (run == 0) {
reference_distances = distances;
auto stats = calculateBFSStats(
distances, source, elapsed_ms,
graph.getNumVertices(), graph.getNumEdges(), "Sequential"
);
stats.print();
} else {
std::cout << "Run " << run + 1 << ": " << elapsed_ms << " ms" << std::endl;
}
}
if (num_runs > 1) {
std::cout << "Average Sequential BFS time: " << (total_seq_time / num_runs) << " ms" << std::endl;
}
// Run OpenMP BFS
std::cout << "\nRunning OpenMP BFS with " << num_threads << " threads..." << std::endl;
double total_omp_time = 0.0;
for (int run = 0; run < num_runs; run++) {
timer.start();
auto distances = bfsOpenMP(graph, source, num_threads);
double elapsed_ms = timer.elapsed();
total_omp_time += elapsed_ms;
if (run == 0) {
// Verify results match sequential version
bool correct = verifyBFS(distances, reference_distances);
if (!correct) {
std::cerr << "ERROR: OpenMP BFS results do not match sequential results!" << std::endl;
} else {
std::cout << "OpenMP results verified correct." << std::endl;
}
auto stats = calculateBFSStats(
distances, source, elapsed_ms,
graph.getNumVertices(), graph.getNumEdges(), "OpenMP"
);
stats.print();
// Calculate and display speedup
double speedup = total_seq_time / elapsed_ms;
std::cout << "Speedup over sequential: " << speedup << "x" << std::endl;
} else {
std::cout << "Run " << run + 1 << ": " << elapsed_ms << " ms" << std::endl;
}
}
if (num_runs > 1) {
std::cout << "Average OpenMP BFS time: " << (total_omp_time / num_runs) << " ms" << std::endl;
std::cout << "Average speedup: " << (total_seq_time / total_omp_time) << "x" << std::endl;
}
return 0;
}