-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompute.cu
148 lines (124 loc) · 4.01 KB
/
compute.cu
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
#include <iostream>
#include <fstream>
#include <sstream>
#include <unistd.h>
#include <string>
#define THREADS_PER_BLOCK 16
uint secondsToSleep = 1;
__global__ void arrayDifference(const float *a, const float *b, float *results, size_t elementCount)
{
size_t i = blockDim.x * blockIdx.x + threadIdx.x;
if (i < elementCount)
{
results[i] = a[i] - b[i];
}
}
__host__ void executeKernel(float *a, float *b, float *results, size_t elementCount)
{
dim3 dimGrid((elementCount + THREADS_PER_BLOCK - 1) / THREADS_PER_BLOCK, 1, 1);
dim3 dimBlock(THREADS_PER_BLOCK, 1, 1);
arrayDifference<<<dimGrid, dimBlock>>>(a, b, results, elementCount);
cudaDeviceSynchronize();
std::cout << "Input files loaded and processed, results:\n";
for (size_t i = 0; i < elementCount; i++)
{
std::cout << results[i] << (i == elementCount - 1 ? "\n" : ",");
}
}
__host__ void loadInputFile(float *a, float *b, size_t elementCount)
{
bool inputIsReady = false;
while (!inputIsReady)
{
std::ifstream lockA("./input_a.lock");
std::ifstream lockB("./input_b.lock");
inputIsReady = lockA.is_open() && lockB.is_open();
std::cout << "Waiting for input files...\n";
sleep(secondsToSleep);
}
std::cout << "Loading data...\n";
std::cout << "Removing output files...\n";
std::remove("./output_a.csv");
std::remove("./output_a.lock");
std::remove("./output_b.csv");
std::remove("./output_b.lock");
std::string lineA;
std::string lineB;
std::cout << "Parsing input files...\n";
std::ifstream inputA("./input_a.csv");
std::ifstream inputB("./input_b.csv");
auto parseLine = [](float *data, std::string line)
{
size_t i = 0;
std::string token;
std::istringstream tokenStream(line);
while (std::getline(tokenStream, token, ','))
{
data[i++] = std::stof(token);
}
};
if (inputA.is_open() && inputB.is_open())
{
getline(inputA, lineA);
parseLine(a, lineA);
inputA.close();
getline(inputB, lineB);
parseLine(b, lineB);
inputB.close();
}
}
__host__ void saveOutputFile(float *results, size_t elementCount)
{
std::cout << "Saving data...\n";
std::ofstream outputA("./output_a.csv");
std::ofstream outputB("./output_b.csv");
for (size_t i = 0; i < elementCount; i++)
{
outputA << results[i] << (i == elementCount - 1 ? "" : ",");
outputB << (0 - results[i]) << (i == elementCount - 1 ? "" : ",");
}
outputA << '\n';
outputB << '\n';
outputA.close();
outputB.close();
}
#define EXPECTED_ARGC 3 // <element_count> <runs_to_execute> <seconds_to_sleep>
int main(int argc, char *argv[])
{
if (argc != EXPECTED_ARGC + 1)
{
std::cout << "Usage: <element_count> <runs_to_execute> <seconds_to_sleep>\n";
return EXIT_FAILURE;
}
size_t elementCount = std::stoul(argv[1]);
size_t runsToExecute = std::stoul(argv[2]);
secondsToSleep = std::stoul(argv[3]);
float *a, *b, *results;
cudaMallocManaged(&a, elementCount * sizeof(float));
cudaMallocManaged(&b, elementCount * sizeof(float));
cudaMallocManaged(&results, elementCount * sizeof(float));
for (size_t i = 0; i < runsToExecute; i++)
{
std::cout << "Run " << i + 1 << " of " << runsToExecute << '\n';
loadInputFile(a, b, elementCount);
executeKernel(a, b, results, elementCount);
saveOutputFile(results, elementCount);
remove("./input_a.lock");
remove("./input_b.lock");
auto signalOutputProcessed = [](const char *filename)
{
std::fstream lock;
lock.open(filename, std::ios::out);
lock.is_open();
lock.close();
};
signalOutputProcessed("./output_a.lock");
signalOutputProcessed("./output_b.lock");
}
cudaFree(a);
cudaFree(b);
cudaFree(results);
cudaDeviceReset();
std::cout << "Done!\n";
return EXIT_SUCCESS;
}