lukasbindreiter · GitHub

There appears to be an issue in the nearest neighbour function in the CUDA and OpenCL Backend (CPU returns the correct results).
Here is a small Test Case Illustrating the issue:

TEST(NearestNeighbour, CUDA)
{
    af::setBackend(AF_BACKEND_CUDA);
    double train[1 * 2] = {
        5, 5,
    };
    double query[5 * 2] = {
        0, 0,
        3.5, 4,
        5, 5,
        6, 5,
        8, 6.5
    };
    array t(2, 1, train);
    array q(2, 5, query);
    array indices;
    array distances;
    nearestNeighbour(indices, distances, q, t, 0, 1, AF_SSD);
    double expectedDistances[5] = {
        (5 - 0) * (5 - 0) + (5 - 0) * (5 - 0),
        (5 - 3.5) * (5 - 3.5) + (5 - 4) * (5 - 4),
        (5 - 5) * (5 - 5) + (5 - 5) * (5 - 5),
        (5 - 6) * (5 - 6) + (5 - 5) * (5 - 5),
        (5 - 8) * (5 - 8) + (5 - 6.5) * (5 - 6.5)
    };
    double* actualDistances = distances.host<double>();
    for (int i = 0; i < 5; i++)
    {
        EXPECT_EQ(expectedDistances[i], actualDistances[i]);
    }
}

The formula for calculating the sum of square distance between Point p1 and p2 is: (p1.x - p2.x)^2 + (p1.y - p2.y)^2
When trying to calculate the distance of every point in query to (5 | 5) the CPU Backend returns the correct results (those in expectedDistances). Those are:
50.0000 3.2500 0.0000 1.0000 11.2500

However the CUDA and OpenCL backend return the following values:
50.0000 27.2500 25.0000 26.0000 34.0000

This issue does not only affect the AF_SSD match type, but also the AF_SAD (sum of absolute difference). Here the correct results would be:
10.0000 2.5000 0.0000 1.0000 4.5000
but instead are:
10.0000 6.5000 5.0000 6.0000 8.0000

I am using ArrayFire v3.4.0 installed with the binaries from your website.

ArrayFire v3.4.0 (CUDA, 64-bit Windows, build 10d9716)
Platform: CUDA Toolkit 7.5, Driver: CUDA Driver Version: 7050
[0] GeForce GT 730M, 1024 MB, CUDA Compute 3.5

Read the original on github.com ↗