 	int sum;
 	int count;
 	int num;
+	int dist;
 	int is_duplicate;
 //	__shared__ int D[m*m];
 
 	computeDist(m, n, V);
 	__syncthreads();
 	// let the first thread select the k-min dist
-	i = blockIdx.x;
-	if(threadIdx.x == 0)
+	i = threadIdx.x;
+	if(threadIdx.y == 0)
 	{
 		for(count=0; count<k; count++)
 		{

	
				if(!is_duplicate)
				{
					if(D[i*m+j] < temp)
					{
						temp = D[i*m+j];
						out[i*k+count] = j;
					}
				}


__device__ void computeDist(int m, int n, int *V)
{
	int i=threadIdx.x;
   	int j=threadIdx.y;
	int k;
	int dist = 0;
	//reduce duplications
	if(i < j)
	{
		for(k=0; k<n; k++)
		{
			dist += (V[i*n+k]-V[j*n+k])*(V[i*n+k]-V[j*n+k]);
		}
	}
	D[i*m+j] = dist;
}

//paralle reduction?
//cannot use D now!
__device__ int prmin(int m, int *D, int *R)
{
	int j = threadIdx.y;
	int s = blockDim.y/2;
	R[j] = j;
	__syncthreads();
	for(s=blockDim.y; s>0; s>>=1)
	{
		if(j < s)
		{
			D[j] = D[j]<D[j+s]? D[j]: D[j+s]; 
			R[j] = R[j]<R[j+s]? R[j]: R[j+s]; 
		}
		__syncthreads();
	}
	return R[0];
}

__global__ void knn(int m, int n, int k, int *V, int *out)
