-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCodeGenerator.cpp
120 lines (100 loc) · 3.46 KB
/
CodeGenerator.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
#include <array>
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include <chrono>
#include <filesystem>
void generateCombinations(const std::vector<int> &options, std::vector<int> &combination, int index,
std::vector<std::string> &output)
{
if (index == options.size())
{
std::stringstream stringStream;
for (int val : combination)
{
stringStream << val;
}
output.push_back(stringStream.str());
return;
}
for (int i = 0; i < options[index]; ++i)
{
combination[index] = i;
generateCombinations(options, combination, index + 1, output);
}
}
int main(int argc, char *argv[])
{
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
/// Check if a command line argument was provided
if (argc < 2)
{
std::cerr << "Usage: " << argv[0] << " <command>" << std::endl;
return 1;
}
/// The command to run is passed as the first argument
std::string fileName = argv[1];
std::string cmd = "CUDA-transformer --analyze " + fileName + " -- --cuda-gpu-arch=sm_86";
/// Create a pipe to run the command
std::array<char, 128> buffer;
std::stringstream result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe)
{
std::cerr << "Failed to run command.\n";
return 1;
}
/// Read the output of the command
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
{
result << buffer.data();
}
std::string output = result.str();
std::vector<int> optionCounts;
/// Number of options for each type of optimization
std::vector<int> typeOptions = {5, 3, 2, 3, 3, 5, 5, 3, 4, 5};
/// Parse the output to get the optimization possibilities
for (char c : output)
{
if (isdigit(c))
{
int typeIndex = c - '0';
optionCounts.push_back(typeOptions[typeIndex]);
}
}
/// Generate all possible combinations of optimization choices
std::vector<int> combination(optionCounts.size(), 0);
std::vector<std::string> outputStrings;
generateCombinations(optionCounts, combination, 0, outputStrings);
/// For polybench include options or other include options
std::string includeOptions;
if (argv[2])
{
includeOptions = argv[2];
}
/// Clean up
if (std::filesystem::exists("results"))
{
std::filesystem::remove_all("results");
}
std::filesystem::create_directory("results");
#pragma omp parallel
#pragma omp for
for (const std::string &choices : outputStrings)
{
std::cout << "Processing options " + choices +"...\n";
std::string outputFilename = "-o results/" + choices + ".cu ";
std::string newCmd =
"CUDA-transformer --choices=" + choices + " " + outputFilename + fileName + " -- " + includeOptions +" --cuda-gpu-arch=sm_86 &";
std::system(newCmd.c_str());
}
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "Optimization types: " << output << std::endl;
std::cout << "Time taken = " << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << "[ms]" << std::endl;
std::cout << "Number of files generated: ";
std::system("cd results && ls -l | grep -v '^d' | wc -l");
return 0;
}