-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
109 lines (85 loc) · 3.38 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
#include "pch.h"
#include "file_io.h"
#include "serialization.h"
#include "local_buf.h"
#include "sorting.h"
#include "string_process.h"
int main(int argc, char** argv)
{
int my_rank, comm_sz;
// Raw string buffer local to each process
char* local_buffer;
int32_t local_buf_sz;
// User input variables
int min_word, max_word;
char order;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
if(my_rank == 0)
{
// Get user input into an aggregated raw string buffer
std::string buffer;
file_io::getInput(buffer, min_word, max_word, order);
// Split buffer into chunks for each process and send them
local_buf::sendLocalBuffer(buffer, &local_buffer, local_buf_sz, comm_sz);
}
else
{
// Receive chunk from process 0
local_buf::receiveLocalBuffer(&local_buffer, local_buf_sz);
}
// Broadcast word length limits to all processes
MPI_Bcast(&max_word, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&min_word, 1, MPI_INT, 0, MPI_COMM_WORLD);
double start_count = MPI_Wtime();
// Split string into individual words with counts
std::unordered_map<std::string_view, int64_t> words;
// Transform string to lowercase and split to individual words
string_process::transformStringLower(local_buffer, local_buf_sz);
string_process::splitString(std::string_view{local_buffer}, words, min_word, max_word);
char* serial_buffer;
if (my_rank != 0)
{
// Serialize unordered_map and send to process 0
int64_t serial_buf_sz = serialization::calculateSerializeMapSize(words);
serial_buffer = new char[serial_buf_sz];
serialization::serializeMap(words, serial_buffer);
MPI_Send(serial_buffer, serial_buf_sz, MPI_BYTE, 0, 0, MPI_COMM_WORLD);
delete[] serial_buffer;
}
else
{
// Deserialize buffers received into unordered_map
for(int i = 1; i < comm_sz; ++i)
{
int32_t serial_buf_sz;
MPI_Status status;
// Get size of serial buffer
MPI_Probe(MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_BYTE, &serial_buf_sz);
serial_buffer = new char[serial_buf_sz];
MPI_Recv(serial_buffer, serial_buf_sz, MPI_BYTE, status.MPI_SOURCE, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
std::unordered_map<std::string_view, int64_t> local_words;
serialization::deserializeBuffer(serial_buffer, words);
}
// Sorting and output to file
if (order == 'n')
{
// Sort by word count and output in descending order
std::multimap<int64_t, std::string_view> sorted_words = sorting::sortByCount(words);
file_io::fileOutput(sorted_words);
}
else if (order == 'a')
{
// Sort by alphabetical order and output in ascending order
std::map<std::string_view, int64_t> sorted_words = sorting::sortByAlphabet(words);
file_io::fileOutput(sorted_words);
}
double end_count = MPI_Wtime();
std::cout << "Counting words : " << end_count - start_count << std::endl;
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // False positive
delete[] serial_buffer;
}
MPI_Finalize();
}