推力/ cuda reduce_by_key错误?

时间:2015-08-12 13:31:01

标签: c++ cuda thrust

我遇到推力库的 reduce_by_key 功能问题。对我来说这看起来像个错误,但我想在报告之前确定。

首先,我的设置:CUDA 7.0,Windows 8,NIVIDA GeForce 820m。整个过程是使用visual studio 2010和nvcc在发布模式下编写的,64位。

现在,说明问题的练习。

我的设备上生成了一个名为 devData 的随机数向量。 我列出了一个名为 devIndices 的索引向量,其大小与下面定义的相同:

  • devIndices = [0,0,0,0,1,1,1,1,... K-1,K-1,K-1,K-1]
  • devData = [1,4,5,7,5,8,9,6,... 7,8,9,6]

在此示例中, devIndices 中的每个值都会重复 mod = 4 时间。

然后,我只想使用 devIndices 来reduce_by_key devData 来获取后面的简化向量:

  • devIndices = [0,1,...,K-1]
  • devData = [17,28,...,30]

(如果我对算术正确:))

现在,我确信 devIndices 的元素应该总结为由以下关系给出的值T:

  • T = [(K-1)* K / 2](例如:[0 1 2 3] - > 6 =(K-1)* K / 2 = 3 * 4/2)

我试图在我的机器上执行此操作,它适用于少量元素,但对于大型元素则无效。 (100,000失败......)

下面是我用来操纵我的两个向量的代码,如上所述,最后输出 devIndices 的总和。您可以使用基本上设置元素数量的参数k。

#include <cuda.h>
#include <thrust/random.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/iterator/counting_iterator.h>
#include <fstream>
typedef typename thrust::device_vector<int>     tDevVecInt;
typedef typename thrust::device_vector<float>   tDevVecFlt;

struct rando : public thrust::unary_function<unsigned int, float>
{
    unsigned int mainSeed;
    rando(unsigned int _mainSeed):mainSeed(_mainSeed) {}
    __host__ __device__ float operator()(unsigned int x) 
    {
        unsigned int seed = x * mainSeed;
        thrust::random::taus88 mac(seed);
        thrust::uniform_real_distribution<float> dist(0,1);
        return dist(mac);
    }
};

struct modSim : public thrust::unary_function<int, int>  
{
    int sz;
    modSim(int in)
    {
        this->sz = in;
    }
    __host__ __device__ int operator()(const int &x) 
    {
        return x/sz;
    }
};

int main() 
{
    int mod = 10;
    int k = 10000;
    int szData = k*mod;

    tDevVecFlt devData(szData, 0.);
    tDevVecInt devIndices(szData, 0.);

    thrust::transform(thrust::make_counting_iterator(0), thrust::make_counting_iterator(0) + szData, devData.begin(), rando(123456789));    
    thrust::tabulate(devIndices.begin(), devIndices.end(), modSim(mod)); 
    thrust::reduce_by_key(devIndices.begin(), devIndices.end(), devData.begin(), devIndices.begin(), devData.begin());
    std::cout << thrust::reduce(devIndices.begin(), devIndices.begin()+ k, 0) << std::endl;
    return 0;
}

最糟糕的是:当我运行多次相同的代码时,我会得到不同的结果!随机向量与此无关(它是种子......我顺便检查了它。)

现在问题部分:

  • 我错了吗? Reduce_by_key对我来说似乎是合适的工具
  • 是否有人重现这种不可再现性?
  • 如果这确实是一个错误,通常的报告方式是什么?

1 个答案:

答案 0 :(得分:3)

  

我错了吗?

推力:: reduce_by_key的documentation状态:

  

前提条件输入范围不应与输出范围重叠。

你已经破坏了代码中的前提条件:

thrust::reduce_by_key(devIndices.begin(), devIndices.end(), devData.begin(), devIndices.begin(), devData.begin());

因此,您的代码已被破坏,并且无法代表任何显示推力错误的内容。 thrust::reduce_by_key不是可以就地完成的推力操作。