-
Notifications
You must be signed in to change notification settings - Fork 3
/
knns.c
136 lines (91 loc) · 2.35 KB
/
knns.c
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
/**
*
* This file contains the appropriate sequential functions that are used
* to find the k nearest neighbors of each query.
*
* The CUDA parallel implementations "comments" the sequential code and
* calls the appropriate functions from the knn_gpu_utils.cu file. You
* can "uncomment" the sequential code and use it as a benchmark.
*
*
* Modified by: Christos Nikolaou
* Date: August 2014
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "utils.h"
#include "knn_gpu_utils.h"
// This function has been changed to use a parallel version
/*
double euclidean_distance(double *X, double *Y, int N){
int i = 0;
double dst = 0;
for(i=0; i<N; i++){
double tmp = (X[i] - Y[i]);
dst += tmp * tmp;
}
return(dst);
}
*/
void compute_distance(knn_struct* queries, knn_struct* dataset, double* dist) {
int Q = queries->secondary_dim;
int N = dataset->secondary_dim;
int D = dataset->leading_dim;
double *data = dataset->data;
double *query = queries->data;
compute_distance_gpu(data, query, D, Q, N, dist);
}
// This function has been changed to use a parallel version
/*
int findMax(double* X, int k){
int i=0;
int maxidx = 0;
double maxval = X[0];
for(i=1; i<k; i++){
if(maxval<X[i]){
maxval = X[i];
maxidx = i;
}
}
return(maxidx);
}
*/
// This function has been changed to use a parallel version
/*
void kselect(double* dist, double* NNdist, int* NNidx, int N, int k) {
int i = 0;
for(i=0; i<k; i++){
NNdist[i] = dist[i];
NNidx[i] = i;
}
int maxidx = findMax(NNdist, k);
for(i=k; i<N; i++){
if(NNdist[maxidx]>dist[i]){
NNdist[maxidx] = dist[i];
NNidx[maxidx] = i;
maxidx = findMax(NNdist, k);
}
}
}
*/
void selection(double* dist, double* NNdist, int* NNidx, int N, int Q, int k) {
selection_gpu(dist, NNdist, NNidx, N, Q, k);
// This function has been changed to use a parallel version
/*
int i = 0, j = 0;
for(i=0; i<Q; i++){
kselect(&dist[i*N], &NNdist[i*k], &NNidx[i*k], N, k);
}
*/
}
void knns(knn_struct* queries, knn_struct* dataset, double *NNdist,
int *NNidx, int k) {
double *dist;
int q = queries->secondary_dim;
int n = dataset->secondary_dim;
dist = (double*)malloc(n*q*sizeof(double));
compute_distance(queries, dataset, dist);
selection(dist, NNdist, NNidx, n, q, k);
free(dist);
}