Stable release of RBC
[RBC.git] / driver.cu
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<cuda.h>
4 #include<sys/time.h>
5 #include<math.h>
6 #include "defs.h"
7 #include "utils.h"
8 #include "utilsGPU.h"
9 #include "rbc.h"
10 #include "brute.h"
11 #include "sKernel.h"
12
13 void parseInput(int,char**);
14 void readData(char*,int,int,real*);
15 void orgData(real*,int,int,matrix,matrix);
16
17
18 char *dataFile, *outFile;
19 int n=0, m=0, d=0, numReps=0, s=0;
20 int deviceNum=0;
21 int main(int argc, char**argv){
22 real *data;
23 matrix x, q;
24 int *NNs, *NNsBrute;
25 int i;
26 struct timeval tvB,tvE;
27
28 printf("*****************\n");
29 printf("RANDOM BALL COVER\n");
30 printf("*****************\n");
31
32 parseInput(argc,argv);
33
34 cuInit(0);
35 printf("Using GPU #%d\n",deviceNum);
36 if(cudaSetDevice(deviceNum) != cudaSuccess){
37 printf("Unable to select device %d.. exiting. \n",deviceNum);
38 exit(1);
39 }
40
41 unsigned int memFree, memTot;
42 CUcontext pctx;
43 unsigned int flags=0;
44 int device;
45 cudaGetDevice(&device);
46 cuCtxCreate(&pctx,flags,device);
47 cuMemGetInfo(&memFree, &memTot);
48 printf("GPU memory free = %u/%u (MB) \n",memFree/(1024*1024),memTot/(1024*1024));
49
50 data = (real*)calloc( (n+m)*d, sizeof(*data) );
51 x.mat = (real*)calloc( PAD(n)*PAD(d), sizeof(*(x.mat)) );
52
53 //Need to allocate extra space, as each group of q will be padded later.
54 q.mat = (real*)calloc( PAD(m)*PAD(d), sizeof(*(q.mat)) );
55 x.r = n; x.c = d; x.pr = PAD(n); x.pc = PAD(d); x.ld = x.pc;
56 q.r = m; q.c = d; q.pr = PAD(m); q.pc = PAD(d); q.ld = q.pc;
57
58 NNs = (int*)calloc( m, sizeof(*NNs) );
59 for(i=0; i<m; i++)
60 NNs[i]=-1;
61 NNsBrute = (int*)calloc( m, sizeof(*NNsBrute) );
62
63 readData(dataFile, (n+m), d, data);
64 orgData(data, (n+m), d, x, q);
65 free(data);
66
67
68
69 /* printf("db:\n"); */
70 /* printMat(x); */
71 /* printf("\nqueries: \n"); */
72 /* printMat(q); */
73 /* printf("\n\n"); */
74
75 for(i=0;i<m;i++)
76 NNs[i]=NNsBrute[i]=DUMMY_IDX;
77
78 /* printf("running brute force..\n"); */
79 /* gettimeofday(&tvB,NULL); */
80 /* bruteSearch(x,q,NNsBrute); */
81 /* gettimeofday(&tvE,NULL); */
82 /* printf("\t.. time elapsed = %6.4f \n",timeDiff(tvB,tvE)); */
83
84
85 printf("\nrunning rbc..\n");
86 gettimeofday(&tvB,NULL);
87 rbc(x,q,numReps,s,NNs);
88 gettimeofday(&tvE,NULL);
89 printf("\t.. total time elapsed for rbc = %6.4f \n",timeDiff(tvB,tvE));
90 printf("finished \n");
91
92 cudaError_t cE = cudaGetLastError();
93 if( cE != cudaSuccess ){
94 printf("Execution failed; error type: %s \n", cudaGetErrorString(cE) );
95 }
96
97 printf("\nComputing error rates (this might take a while)\n");
98 real *ranges = (real*)calloc(q.pr,sizeof(*ranges));
99 for(i=0;i<q.r;i++)
100 ranges[i] = distL1(q,x,i,NNs[i]) - 10e-6;
101
102 int *cnts = (int*)calloc(q.pr,sizeof(*cnts));
103
104 bruteRangeCount(x,q,ranges,cnts);
105
106 long int nc=0;
107 for(i=0;i<m;i++){
108 nc += cnts[i];
109 }
110 double mean = ((double)nc)/((double)m);
111 double var = 0.0;
112 for(i=0;i<m;i++) {
113 var += (((double)cnts[i])-mean)*(((double)cnts[i])-mean)/((double)m);
114 }
115 printf("\tavg rank = %6.4f; std dev = %6.4f \n\n", mean, sqrt(var));
116
117 if(outFile){
118 FILE* fp = fopen(outFile, "a");
119 fprintf( fp, "%d %d %6.5f %6.5f \n", numReps, s, mean, sqrt(var) );
120 fclose(fp);
121 }
122
123 free(ranges);
124 free(cnts);
125 free(NNs);
126 free(NNsBrute);
127 free(x.mat);
128 free(q.mat);
129 }
130
131
132 void parseInput(int argc, char **argv){
133 int i=1;
134 if(argc <= 1){
135 printf("\nusage: \n testRBC -f datafile (bin) -n numPts (DB) -m numQueries -d dim -r numReps -s numPtsPerRep [-o outFile] [-g GPU num]\n\n");
136 exit(0);
137 }
138
139 while(i<argc){
140 if(!strcmp(argv[i], "-f"))
141 dataFile = argv[++i];
142 else if(!strcmp(argv[i], "-n"))
143 n = atoi(argv[++i]);
144 else if(!strcmp(argv[i], "-m"))
145 m = atoi(argv[++i]);
146 else if(!strcmp(argv[i], "-d"))
147 d = atoi(argv[++i]);
148 else if(!strcmp(argv[i], "-r"))
149 numReps = atoi(argv[++i]);
150 else if(!strcmp(argv[i], "-s"))
151 s = atoi(argv[++i]);
152 else if(!strcmp(argv[i], "-o"))
153 outFile = argv[++i];
154 else if(!strcmp(argv[i], "-g"))
155 deviceNum = atoi(argv[++i]);
156 else{
157 fprintf(stderr,"%s : unrecognized option.. exiting\n",argv[i]);
158 exit(1);
159 }
160 i++;
161 }
162
163 if( !n || !m || !d || !numReps || !s || !dataFile){
164 fprintf(stderr,"more arguments needed.. exiting\n");
165 exit(1);
166 }
167
168 if(numReps>n){
169 fprintf(stderr,"can't have more representatives than points.. exiting\n");
170 exit(1);
171 }
172 }
173
174
175 void readData(char *dataFile, int rows, int cols, real *data){
176 FILE *fp;
177 int numRead;
178
179 fp = fopen(dataFile,"r");
180 if(fp==NULL){
181 fprintf(stderr,"error opening file.. exiting\n");
182 exit(1);
183 }
184
185 numRead = fread(data,sizeof(real),rows*cols,fp);
186 if(numRead != rows*cols){
187 fprintf(stderr,"error reading file.. exiting \n");
188 exit(1);
189 }
190 fclose(fp);
191 }
192
193
194 //This function splits the data into two matrices, x and q, of
195 //their specified dimensions. The data is split randomly.
196 //It is assumed that the number of rows of data (the parameter n)
197 //is at least as large as x.r+q.r
198 void orgData(real *data, int n, int d, matrix x, matrix q){
199
200 int i,fi,j;
201 int *p;
202 p = (int*)calloc(n,sizeof(*p));
203
204 randPerm(n,p);
205
206 for(i=0,fi=0 ; i<x.r ; i++,fi++){
207 for(j=0;j<x.c;j++){
208 x.mat[IDX(i,j,x.ld)] = data[IDX(p[fi],j,d)];
209 }
210 }
211
212 for(i=0 ; i<q.r ; i++,fi++){
213 for(j=0;j<q.c;j++){
214 q.mat[IDX(i,j,q.ld)] = data[IDX(p[fi],j,d)];
215 }
216 }
217
218 free(p);
219 }
220