void saveRBC( matrix *R, rep *ri, char *filename ){ size_t i; unint nr = R->r; FILE *fp = fopen(filename, "wb"); if( !fp ){ fprintf(stderr, "unable to open output file\n"); exit(1); } safeWrite( &nr, sizeof(unint), 1, fp ); for( i=0; i<nr; i++ ){ unint len = ri[i].len; safeWrite( &len, sizeof(unint), 1, fp ); safeWrite( ri[i].lr, sizeof(unint), len, fp ); safeWrite( ri[i].dists, sizeof(real), len, fp ); safeWrite( &(ri[i].start), sizeof(unint), 1, fp ); safeWrite( &(ri[i].radius), sizeof(real), 1, fp ); } safeWrite( &(R->r), sizeof(unint), 1, fp ); safeWrite( &(R->c), sizeof(unint), 1, fp ); safeWrite( R->mat, sizeof(real), sizeOfMat(*R), fp ); fclose(fp); }
//note: allocates R, ri void loadRBC( matrix *R, rep **ri, char* filename ){ size_t i; unint nr, len, plen; FILE *fp = fopen(filename, "rb"); if( !fp ){ fprintf(stderr, "unable to open output file\n"); exit(1); } safeRead( &nr, sizeof(unint), 1, fp ); (*ri) = (rep*)calloc( CPAD(nr), sizeof(rep) ); for( i=0; i<nr; i++ ){ safeRead( &len, sizeof(unint), 1, fp ); plen = CPAD( len ); (*ri)[i].lr = (unint*)calloc( plen, sizeof(unint) ); (*ri)[i].dists = (real*)calloc( plen, sizeof(real) ); (*ri)[i].len = len; safeRead( (*ri)[i].lr, sizeof(unint), len, fp ); safeRead( (*ri)[i].dists, sizeof(real), len, fp ); safeRead( &((*ri)[i].start), sizeof(unint), 1, fp ); safeRead( &((*ri)[i].radius), sizeof(real), 1, fp ); } unint r,c; safeRead( &r, sizeof(unint), 1, fp ); safeRead( &c, sizeof(unint), 1, fp ); initMat( R, r, c ); R->mat = (real*)calloc( sizeOfMat(*R), sizeof(real) ); safeRead( R->mat, sizeof(real), sizeOfMat(*R), fp ); fclose(fp); }
//Builds the RBC for the One-shot (inexact) method. //Note: allocates memory for r and ri that must be freed //externally. Use freeRBC. void buildOneShot(matrix x, matrix *r, rep *ri, unint numReps){ unint s = numReps; //number of points per rep. Set equal to numReps //as suggested by theory. unint ps = CPAD(s); unint i, j; if( numReps > x.r ){ fprintf( stderr, "number of representatives must be less than the DB size\n"); exit(1); } initMat( r, numReps, x.c ); r->mat = (real*)calloc( sizeOfMat(*r), sizeof(*r->mat)); //pick r random reps pickReps(x,r); //Compute the ownership lists unint **repID = (unint**)calloc(r->pr, sizeof(*repID)); real **dToNNs = (real**)calloc(r->pr, sizeof(*dToNNs)); for( i=0; i<r->pr; i++){ repID[i] = (unint*)calloc(CPAD(ps), sizeof(**repID)); dToNNs[i] = (real*)calloc(CPAD(ps), sizeof(**dToNNs)); } //need to find the radius such that each rep contains s points bruteKHeap(x,*r,repID,dToNNs,s); for( i=0; i<r->pr; i++){ ri[i].lr = (unint*)calloc(ps, sizeof(*ri[i].lr)); ri[i].dists = (real*)calloc(ps, sizeof(*ri[i].dists)); ri[i].len = s; for (j=0; j<s; j++){ ri[i].lr[j] = repID[i][j]; } //ri[i].radius = distVec( *r, x, i, ri[i].lr[s-1]); //Not actually needed by one-shot alg } for( i=0; i<r->pr; i++){ free(dToNNs[i]); free(repID[i]); } free(dToNNs); free(repID); }
//Builds the RBC for exact (1- or K-) NN search. //Note: allocates memory for r and ri that must be freed //externally. Use freeRBC. void buildExact(matrix x, matrix *r, rep *ri, unint numReps){ unint n = x.r; unint i, j; unint longestLength = 0; if( numReps > n ){ fprintf( stderr, "number of representatives must be less than the DB size\n"); exit(1); } initMat(r, numReps, x.c); r->mat = (real*)calloc( sizeOfMat(*r), sizeof(*r->mat) ); //pick r random reps pickReps(x,r); //Compute the rep for each x unint *repID = (unint*)calloc(x.pr, sizeof(*repID)); real *dToReps = (real*)calloc(x.pr, sizeof(*dToReps)); brutePar(*r,x,repID,dToReps); //gather the rep info & store it in struct for(i=0; i<numReps; i++){ ri[i].len = 0; ri[i].radius = 0; } for(i=0; i<n; i++){ ri[repID[i]].radius = MAX( dToReps[i], ri[repID[i]].radius ); ri[repID[i]].len++; } unint **tempI = (unint**)calloc(numReps, sizeof(*tempI)); real **tempD = (real**)calloc(numReps, sizeof(*tempD)); for(i=0; i<numReps; i++){ tempI[i] = (unint*)calloc(ri[i].len, sizeof(**tempI)); tempD[i] = (real*)calloc(ri[i].len, sizeof(**tempD)); ri[i].lr = (unint*)calloc(ri[i].len, sizeof(*ri[i].lr)); ri[i].dists = (real*)calloc(ri[i].len, sizeof(*ri[i].dists)); longestLength = MAX( longestLength, ri[i].len ); } unint *tempCount = (unint*)calloc(numReps, sizeof(*tempCount)); for(i=0; i<n; i++){ tempI[repID[i]][tempCount[repID[i]]] = i; tempD[repID[i]][tempCount[repID[i]]++] = dToReps[i]; } //this stores the owned points in order of distance to the //representative. This ordering is not currently necc. for the search //algorithm, but might be used in the future. size_t *p = (size_t*)calloc(longestLength, sizeof(*p)); for(i=0; i<numReps; i++){ gsl_sort_float_index( p, tempD[i], 1, ri[i].len ); for(j=0; j<ri[i].len; j++){ ri[i].dists[j] = tempD[i][p[j]]; ri[i].lr[j] = tempI[i][p[j]]; } } free(p); for(i=0;i<numReps; i++){ free(tempI[i]); free(tempD[i]); } free(tempI); free(tempD); free(tempCount); free(dToReps); free(repID); }
int main(int argc, char**argv){ matrix x, q; unint i; struct timeval tvB,tvE; printf("********************************\n"); printf("RANDOM BALL COVER -- CPU version\n"); printf("********************************\n"); parseInput(argc,argv); int threadMax = omp_get_max_threads(); printf("number of threads = %d \n",threadMax); initMat( &x, n, d ); initMat( &q, m, d ); x.mat = (real*)calloc( sizeOfMat(x), sizeof(*(x.mat)) ); q.mat = (real*)calloc( sizeOfMat(q), sizeof(*(q.mat)) ); if( !x.mat || !q.mat ){ fprintf(stderr, "memory allocation failure .. exiting \n"); exit(1); } // Read data: if(dataFileXtxt) readDataText(dataFileXtxt, x); else readData(dataFileX, x); if(dataFileQtxt) readDataText(dataFileQtxt, q); else readData(dataFileQ, q); unint **NNs = (unint**)calloc( m, sizeof(*NNs) ); //indices of NNs real **dNNs = (real**)calloc( m, sizeof(*dNNs) ); //dists to NNs for(i=0;i<m; i++){ NNs[i] = (unint*)calloc(K, sizeof(**NNs)); dNNs[i] = (real*)calloc(K, sizeof(**dNNs) ); } matrix rE; //matrix of representatives rep *riE = (rep*)calloc( CPAD(numReps), sizeof(*riE) ); //data struct for RBC // ******** builds the RBC gettimeofday(&tvB,NULL); buildExact(x, &rE, riE, numReps); gettimeofday(&tvE,NULL); double buildTime = timeDiff(tvB,tvE); printf("exact build time elapsed = %6.4f \n", buildTime ); // ******** queries the RBC gettimeofday(&tvB,NULL); if( threadMax<8 ) searchExactK(q, x, rE, riE, NNs, dNNs, K); else searchExactManyCoresK(q, x, rE, riE, NNs, dNNs, K); gettimeofday(&tvE,NULL); double searchTime = timeDiff(tvB,tvE); printf("exact k-nn search time elapsed = %6.4f \n", searchTime ); // ******** runs brute force search. if(runBrute){ printf("running brute force search..\n"); unint **NNsBrute = (unint**)calloc( m, sizeof(*NNsBrute) ); real **dToNNsBrute = (real**)calloc( m, sizeof(*dToNNsBrute) );; for(i=0; i<m; i++){ NNsBrute[i] = (unint*)calloc( K, sizeof(**NNsBrute) ); dToNNsBrute[i] = (real*)calloc( K, sizeof(**dToNNsBrute) ); } gettimeofday(&tvB,NULL); bruteK(x,q,NNsBrute,dToNNsBrute,K); gettimeofday(&tvE,NULL); double bruteTime = timeDiff(tvB,tvE); printf("brute time elapsed = %6.4f \n", bruteTime ); free(NNsBrute); free(dToNNsBrute); } if( outFile || outFiletxt ) writeNeighbs( outFile, outFiletxt, NNs, dNNs ); //clean up freeRBC( rE, riE ); for(i=0;i<m; i++){ free(NNs[i]); free(dNNs[i]); } free(NNs); free(dNNs); free(x.mat); free(q.mat); return 0; }
int main(int argc, char**argv){ matrix x, q; unint i; struct timeval tvB,tvE; printf("********************************\n"); printf("RANDOM BALL COVER -- CPU version\n"); printf("********************************\n"); parseInput(argc,argv); int threadMax = omp_get_max_threads(); printf("number of threads = %d \n",threadMax); initMat( &x, n, d ); initMat( &q, m, d ); x.mat = (real*)calloc( sizeOfMat(x), sizeof(*(x.mat)) ); q.mat = (real*)calloc( sizeOfMat(q), sizeof(*(q.mat)) ); if( !x.mat || !q.mat ){ fprintf(stderr, "memory allocation failure .. exiting \n"); exit(1); } // Read data: if(dataFileXtxt) readDataText(dataFileXtxt, x); else readData(dataFileX, x); if(dataFileQtxt) readDataText(dataFileQtxt, q); else readData(dataFileQ, q); unint **NNs = (unint**)calloc( m, sizeof(*NNs) ); //indices of NNs real **dNNs = (real**)calloc( m, sizeof(*dNNs) ); //dists to NNs for(i=0;i<m; i++){ NNs[i] = (unint*)calloc(K, sizeof(**NNs)); dNNs[i] = (real*)calloc(K, sizeof(**dNNs) ); } matrix r; //matrix of representatives rep *ri = (rep*)calloc( CPAD(numReps), sizeof(*ri) ); //data struct for RBC // ******** builds the RBC gettimeofday(&tvB,NULL); buildOneShot(x, &r, ri, numReps); gettimeofday(&tvE,NULL); double buildTime = timeDiff(tvB,tvE); printf("one-shot build time elapsed = %6.4f \n", buildTime ); // ******** queries the RBC gettimeofday(&tvB,NULL); searchOneShotK(q, x, r, ri, NNs, dNNs, K); gettimeofday(&tvE,NULL); double searchTime = timeDiff(tvB,tvE); printf("one-shot k-nn search time elapsed = %6.4f \n", searchTime ); if( runEval ) evalApproxK(q, x, NNs, K); // ******** runs brute force search. if(runBrute){ printf("running brute force search..\n"); unint **NNsBrute = (unint**)calloc( m, sizeof(*NNsBrute) ); real **dToNNsBrute = (real**)calloc( m, sizeof(*dToNNsBrute) );; for(i=0; i<m; i++){ NNsBrute[i] = (unint*)calloc( K, sizeof(**NNsBrute) ); dToNNsBrute[i] = (real*)calloc( K, sizeof(**dToNNsBrute) ); } gettimeofday(&tvB,NULL); bruteK(x,q,NNsBrute,dToNNsBrute,K); gettimeofday(&tvE,NULL); double bruteTime = timeDiff(tvB,tvE); printf("brute time elapsed = %6.4f \n", bruteTime ); free(NNsBrute); free(dToNNsBrute); } if( outFile || outFiletxt ) writeNeighbs( outFile, outFiletxt, NNs, dNNs ); //try out reading/writing functions /* printf("writing .. \n"); fflush(NULL); */ /* char filename[100] = "tempOut.bin"; \ */ /* saveRBC( &r, ri, filename ); */ /* printf("done \n"); fflush(NULL); */ /* freeRBC( r, ri ); */ /* printf("loading ..\n"); fflush(NULL); */ /* loadRBC( &r, &ri, filename ); */ /* printf("done \n"); fflush(NULL); */ /* printf("R = %d, %d \n", r.r, r.c ); */ /* gettimeofday(&tvB,NULL); */ /* searchOneShotK(q, x, r, ri, NNs, dNNs, K); */ /* gettimeofday(&tvE,NULL); */ /* searchTime = timeDiff(tvB,tvE); */ /* printf("one-shot k-nn search time elapsed = %6.4f \n", searchTime ); */ /* evalApproxK(q, x, NNs, K); */ //clean up freeRBC( r, ri ); for(i=0;i<m; i++){ free(NNs[i]); free(dNNs[i]); } free(NNs); free(dNNs); free(x.mat); free(q.mat); return 0; }