Fix errors and optimize kernel.
This commit is contained in:
@ -122,92 +122,99 @@ inline __device__ __host__ float3 normalize(float3 v)
|
||||
// http://www.miislita.com/information-retrieval-tutorial/matrix-tutorial-3-eigenvalues-eigenvectors.html
|
||||
inline __device__ __host__ float3 firstEigenVector( float matrix[6] )
|
||||
{
|
||||
// 8 iterations seems to be more than enough.
|
||||
// 8 iterations seems to be more than enough.
|
||||
|
||||
float3 v = make_float3(1.0f, 1.0f, 1.0f);
|
||||
for(int i = 0; i < 8; i++) {
|
||||
float x = v.x * matrix[0] + v.y * matrix[1] + v.z * matrix[2];
|
||||
float y = v.x * matrix[1] + v.y * matrix[3] + v.z * matrix[4];
|
||||
float z = v.x * matrix[2] + v.y * matrix[4] + v.z * matrix[5];
|
||||
float m = max(max(x, y), z);
|
||||
float iv = 1.0f / m;
|
||||
#if __DEVICE_EMULATION__
|
||||
if (m == 0.0f) iv = 0.0f;
|
||||
#endif
|
||||
v = make_float3(x*iv, y*iv, z*iv);
|
||||
}
|
||||
float3 v = make_float3(1.0f, 1.0f, 1.0f);
|
||||
for(int i = 0; i < 8; i++) {
|
||||
float x = v.x * matrix[0] + v.y * matrix[1] + v.z * matrix[2];
|
||||
float y = v.x * matrix[1] + v.y * matrix[3] + v.z * matrix[4];
|
||||
float z = v.x * matrix[2] + v.y * matrix[4] + v.z * matrix[5];
|
||||
float m = max(max(x, y), z);
|
||||
float iv = 1.0f / m;
|
||||
#if __DEVICE_EMULATION__
|
||||
if (m == 0.0f) iv = 0.0f;
|
||||
#endif
|
||||
v = make_float3(x*iv, y*iv, z*iv);
|
||||
}
|
||||
|
||||
return v;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline __device__ float3 bestFitLine(const float3 * colors)
|
||||
inline __device__ void colorSums(const float3 * colors, float3 * sums)
|
||||
{
|
||||
#if __DEVICE_EMULATION__
|
||||
float3 color_sum = make_float3(0.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
color_sum += colors[i];
|
||||
}
|
||||
|
||||
// Compute covariance matrix of the given colors.
|
||||
float3 center = make_float3(0.0f, 0.0f, 0.0f);
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
center += colors[i];
|
||||
}
|
||||
center /= 16.0f;
|
||||
|
||||
float covariance[6] = {0, 0, 0, 0, 0, 0};
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
float3 a = colors[i] - center;
|
||||
covariance[0] += a.x * a.x;
|
||||
covariance[1] += a.x * a.y;
|
||||
covariance[2] += a.x * a.z;
|
||||
covariance[3] += a.y * a.y;
|
||||
covariance[4] += a.y * a.z;
|
||||
covariance[5] += a.z * a.z;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
sums[i] = color_sum;
|
||||
}
|
||||
#else
|
||||
|
||||
const int idx = threadIdx.x;
|
||||
const int idx = threadIdx.x;
|
||||
|
||||
__shared__ float3 colorSum[16];
|
||||
colorSum[idx] = colors[idx];
|
||||
|
||||
// Unrolled parallel reduction.
|
||||
if (idx < 8) {
|
||||
colorSum[idx] += colorSum[idx + 8];
|
||||
colorSum[idx] += colorSum[idx + 4];
|
||||
colorSum[idx] += colorSum[idx + 2];
|
||||
colorSum[idx] += colorSum[idx + 1];
|
||||
}
|
||||
|
||||
// @@ Eliminate two-way bank conflicts here.
|
||||
// @@ It seems that doing that and unrolling the reduction doesn't help...
|
||||
__shared__ float covariance[16*6];
|
||||
colorSum[idx] = colors[idx] - colorSum[0] / 16.0f;
|
||||
|
||||
covariance[6 * idx + 0] = colorSum[idx].x * colorSum[idx].x; // 0, 6, 12, 2, 8, 14, 4, 10, 0
|
||||
covariance[6 * idx + 1] = colorSum[idx].x * colorSum[idx].y;
|
||||
covariance[6 * idx + 2] = colorSum[idx].x * colorSum[idx].z;
|
||||
covariance[6 * idx + 3] = colorSum[idx].y * colorSum[idx].y;
|
||||
covariance[6 * idx + 4] = colorSum[idx].y * colorSum[idx].z;
|
||||
covariance[6 * idx + 5] = colorSum[idx].z * colorSum[idx].z;
|
||||
|
||||
for(int d = 8; d > 0; d >>= 1)
|
||||
{
|
||||
if (idx < d)
|
||||
{
|
||||
covariance[6 * idx + 0] += covariance[6 * (idx+d) + 0];
|
||||
covariance[6 * idx + 1] += covariance[6 * (idx+d) + 1];
|
||||
covariance[6 * idx + 2] += covariance[6 * (idx+d) + 2];
|
||||
covariance[6 * idx + 3] += covariance[6 * (idx+d) + 3];
|
||||
covariance[6 * idx + 4] += covariance[6 * (idx+d) + 4];
|
||||
covariance[6 * idx + 5] += covariance[6 * (idx+d) + 5];
|
||||
}
|
||||
}
|
||||
sums[idx] = colors[idx];
|
||||
sums[idx] += sums[idx^8];
|
||||
sums[idx] += sums[idx^4];
|
||||
sums[idx] += sums[idx^2];
|
||||
sums[idx] += sums[idx^1];
|
||||
|
||||
#endif
|
||||
|
||||
// Compute first eigen vector.
|
||||
return firstEigenVector(covariance);
|
||||
}
|
||||
|
||||
inline __device__ float3 bestFitLine(const float3 * colors, float3 color_sum)
|
||||
{
|
||||
// Compute covariance matrix of the given colors.
|
||||
#if __DEVICE_EMULATION__
|
||||
float covariance[6] = {0, 0, 0, 0, 0, 0};
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
float3 a = colors[i] - color_sum * (1.0f / 16.0f);
|
||||
covariance[0] += a.x * a.x;
|
||||
covariance[1] += a.x * a.y;
|
||||
covariance[2] += a.x * a.z;
|
||||
covariance[3] += a.y * a.y;
|
||||
covariance[4] += a.y * a.z;
|
||||
covariance[5] += a.z * a.z;
|
||||
}
|
||||
#else
|
||||
|
||||
const int idx = threadIdx.x;
|
||||
|
||||
float3 diff = colors[idx] - color_sum * (1.0f / 16.0f);
|
||||
|
||||
// @@ Eliminate two-way bank conflicts here.
|
||||
// @@ It seems that doing that and unrolling the reduction doesn't help...
|
||||
__shared__ float covariance[16*6];
|
||||
|
||||
covariance[6 * idx + 0] = diff.x * diff.x; // 0, 6, 12, 2, 8, 14, 4, 10, 0
|
||||
covariance[6 * idx + 1] = diff.x * diff.y;
|
||||
covariance[6 * idx + 2] = diff.x * diff.z;
|
||||
covariance[6 * idx + 3] = diff.y * diff.y;
|
||||
covariance[6 * idx + 4] = diff.y * diff.z;
|
||||
covariance[6 * idx + 5] = diff.z * diff.z;
|
||||
|
||||
for(int d = 8; d > 0; d >>= 1)
|
||||
{
|
||||
if (idx < d)
|
||||
{
|
||||
covariance[6 * idx + 0] += covariance[6 * (idx+d) + 0];
|
||||
covariance[6 * idx + 1] += covariance[6 * (idx+d) + 1];
|
||||
covariance[6 * idx + 2] += covariance[6 * (idx+d) + 2];
|
||||
covariance[6 * idx + 3] += covariance[6 * (idx+d) + 3];
|
||||
covariance[6 * idx + 4] += covariance[6 * (idx+d) + 4];
|
||||
covariance[6 * idx + 5] += covariance[6 * (idx+d) + 5];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Compute first eigen vector.
|
||||
return firstEigenVector(covariance);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user