-
Notifications
You must be signed in to change notification settings - Fork 1
/
3DbinImBCgpu.cpp
106 lines (92 loc) · 3.13 KB
/
3DbinImBCgpu.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
#include <iostream>
#include <cmath>
#include <chrono>
#include <cstring>
#include <fstream>
#include "bcCUDA3D.cuh"
// Function to convert points to a 3D binary image
void pointsTo3DImage(unsigned char* matrix, int* idxarr, int n) {
for (int i = 0; i < n; i++)
matrix[idxarr[i]] = 1;
}
int main(int argc, char* argv[]) {
// Check command line arguments
if (argc != 4) {
std::cerr << "Usage: " << argv[0] << " <grid_num> <input_file> <output_file>\n";
return 1;
}
// Constants
const int m = std::stoi(argv[1]);
const int nn = std::log2(m) - 1;
const unsigned char bits_m = nn + 1; // 2^bits_m = m
// Read input file
const char* filename = argv[2];
int* idxarr = new int[m * m * m];
std::ifstream infile(filename);
if (!infile) {
std::cerr << "Failed to open file: " << filename << std::endl;
delete[] idxarr;
return 1;
}
int n, i = 0;
while (infile >> n)
idxarr[i++] = n;
// Allocate memory and set threads per block
unsigned char* I3d = nullptr;
unsigned int* n3d = nullptr;
const unsigned int TPB = 128;
// Check CUDA status for memory allocation
cudaError_t cudaStatus;
cudaStatus = cudaMallocHost((void**)&I3d, sizeof(unsigned char) * m * m * m);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "CUDA Runtime Error: %s\n", cudaGetErrorString(cudaStatus));
delete[] idxarr;
return 1;
}
cudaStatus = cudaMallocHost((void**)&n3d, sizeof(unsigned int) * nn);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "CUDA Runtime Error: %s\n", cudaGetErrorString(cudaStatus));
cudaFreeHost(I3d);
delete[] idxarr;
return 1;
}
// Convert points to 3D binary image
std::memset(I3d, 0, sizeof(unsigned char) * m * m * m);
pointsTo3DImage(I3d, idxarr, i);
// Perform 3D GPU box-counting
for (int i = 0; i < nn; i++)
n3d[i] = 0;
auto start = std::chrono::system_clock::now();
cudaStatus = CudaBC3D(I3d, m, bits_m, TPB, nn, n3d);
auto stop = std::chrono::system_clock::now();
std::chrono::duration<double> time_gpu = stop - start;
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "CudaBC3D failed!");
cudaFreeHost(I3d);
delete[] idxarr;
cudaFreeHost(n3d);
return 1;
}
// Display box-counting results
// for (int i = 0; i < nn; i++)
// std::cout << " Magnification: " << (2 << i) << " -- Box counts: " << n3d[i] << std::endl;
// Write output file
const char* outputFilename = argv[3];
std::ofstream outfile(outputFilename);
if (!outfile) {
std::cerr << "Failed to open file: " << outputFilename << std::endl;
cudaFreeHost(I3d);
delete[] idxarr;
cudaFreeHost(n3d);
return 1;
}
for (int i = 0; i < nn; i++)
outfile << (2 << i) << " " << n3d[i] << std::endl;
// Display execution time
// std::cout << " 3D GPU box-counting duration: " << time_gpu.count() << " seconds" << std::endl;
// Clean up memory
cudaFreeHost(I3d);
delete[] idxarr;
cudaFreeHost(n3d);
return 0;
}