forked from Adam27X/hybrid_BC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.cu
149 lines (125 loc) · 3.69 KB
/
util.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
149
#include "util.cuh"
//Note: Times are returned in seconds
void start_clock(cudaEvent_t &start, cudaEvent_t &end)
{
checkCudaErrors(cudaEventCreate(&start));
checkCudaErrors(cudaEventCreate(&end));
checkCudaErrors(cudaEventRecord(start,0));
}
float end_clock(cudaEvent_t &start, cudaEvent_t &end)
{
float time;
checkCudaErrors(cudaEventRecord(end,0));
checkCudaErrors(cudaEventSynchronize(end));
checkCudaErrors(cudaEventElapsedTime(&time,start,end));
checkCudaErrors(cudaEventDestroy(start));
checkCudaErrors(cudaEventDestroy(end));
return time/(float)1000;
}
program_options parse_arguments(int argc, char *argv[])
{
program_options op;
int c;
static struct option long_options[] =
{
{"device",required_argument,0,'d'},
{"help",no_argument,0,'h'},
{"infile",required_argument,0,'i'},
{"approx",required_argument,0,'k'},
{"printscores",optional_argument,0,'p'},
{"verify",no_argument,0,'v'},
{0,0,0,0} //Terminate with null
};
int option_index = 0;
while((c = getopt_long(argc,argv,"d:hi:k:p::v",long_options,&option_index)) != -1)
{
switch(c)
{
case 'd':
op.device = atoi(optarg);
break;
case 'h':
std::cout << "Usage: " << argv[0] << " -i <input graph file> [-v verify GPU calculation] [-p <output file> print BC scores] [-d <device ID> choose GPU (starting from 0)]" << std::endl;
exit(0);
case 'i':
op.infile = optarg;
break;
case 'k':
op.approx = true;
op.k = atoi(optarg);
break;
case 'p':
op.printBCscores = true;
op.scorefile = optarg;
break;
case 'v':
op.verify = true;
break;
case '?': //Invalid argument: getopt will print the error msg itself
exit(-1);
default: //Fatal error
std::cerr << "Fatal error parsing command line arguments. Terminating." << std::endl;
exit(-1);
}
}
if(op.infile == NULL)
{
std::cerr << "Command line error: Input graph file is required. Use the -i switch." << std::endl;
}
return op;
}
void choose_device(int &max_threads_per_block, int &number_of_SMs, program_options op)
{
int count;
checkCudaErrors(cudaGetDeviceCount(&count));
cudaDeviceProp prop;
if(op.device == -1)
{
int maxcc=0, bestdev=0;
for(int i=0; i<count; i++)
{
checkCudaErrors(cudaGetDeviceProperties(&prop,i));
if((prop.major + 0.1*prop.minor) > maxcc)
{
maxcc = prop.major + 0.1*prop.minor;
bestdev = i;
}
}
checkCudaErrors(cudaSetDevice(bestdev));
checkCudaErrors(cudaGetDeviceProperties(&prop,bestdev));
}
else if((op.device < -1) || (op.device >= count))
{
std::cerr << "Invalid device argument. Valid devices on this machine range from 0 through " << count-1 << "." << std::endl;
exit(-1);
}
else
{
checkCudaErrors(cudaSetDevice(op.device));
checkCudaErrors(cudaGetDeviceProperties(&prop,op.device));
}
std::cout << "Chosen Device: " << prop.name << std::endl;
std::cout << "Compute Capability: " << prop.major << "." << prop.minor << std::endl;
std::cout << "Number of Streaming Multiprocessors: " << prop.multiProcessorCount << std::endl;
std::cout << "Size of Global Memory: " << prop.totalGlobalMem/(float)(1024*1024*1024) << " GB" << std::endl << std::endl;
max_threads_per_block = prop.maxThreadsPerBlock;
number_of_SMs = prop.multiProcessorCount;
}
void verify(graph g, const std::vector<float> bc_cpu, const std::vector<float> bc_gpu)
{
double error = 0;
double max_error = 0;
for(int i=0; i<g.n; i++)
{
double current_error = abs(bc_cpu[i] - bc_gpu[i]);
error += current_error*current_error;
if(current_error > max_error)
{
max_error = current_error;
}
}
error = error/(float)g.n;
error = sqrt(error);
std::cout << "RMS Error: " << error << std::endl;
std::cout << "Maximum error: " << max_error << std::endl;
}