我遇到了推力库的 reduce_by_key 函数的问题。对我来说,这似乎是个错误,但我想在报告之前先确定一下。

首先,我的设置是:CUDA 7.0,Windows 8,NIVIDA GeForce 820m。整个过程使用Visual Studio 2010和nvcc在 Release模式下(64位)进行编译。

现在,说明问题的练习。

我在设备上生成了一个随机数 vector devData
我将一个称为 devIndices 的索引 vector 制成表格,其大小定义如下:

  • 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 以获得以下简化 vector :
  • 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次失败...)

    下面是我用来如上所述操纵两个 vector 并最终输出o​​jit_strong 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;
    }
    

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

    所以现在问题部分:
  • 我在某个地方错了吗? Reduce_by_key对我来说似乎是正确的工具
  • 是否有人会复制这种不可复制性?
  • 如果确实是一个bug,通常的报告方式是什么?
  • 最佳答案



    推力::: reduce_by_key的documentation指出:



    您已在代码中破坏了该先决条件:

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

    因此,您的代码已损坏,并且不代表任何显示推力错误的内容。 thrust::reduce_by_key不是可以就地执行的强制操作。

    09-06 20:31