通过设备阵列上的键减少

时间:2015-06-11 15:09:58

标签: cuda parallel-processing thrust

我使用reduce_by_key来查找int2类型数组中具有相同第一个值的元素数。

例如 阵列:< 1,2> < 1,3> < 1,4> < 2,5 GT; 2,7-> 所以不行。 1为第一元素的元素为3,其中2为2。

代码:

struct compare_int2 : public thrust::binary_function<int2, int2, bool> {
__host__ __device__ bool operator()(const int2 &a,const int2 &b) const{
return (a.x == b.x);}
};

compare_int2 cmp;
int main()
{
        int n,i;
        scanf("%d",&n);

        int2 *h_list = (int2 *) malloc(sizeof(int2)*n);
        int *h_ones = (int *) malloc(sizeof(int)*n);

        int2 *d_list,*C;
        int  *d_ones,*D;
        cudaMalloc((void **)&d_list,sizeof(int2)*n);
        cudaMalloc((void **)&d_ones,sizeof(int)*n);
        cudaMalloc((void **)&C,sizeof(int2)*n);
        cudaMalloc((void **)&D,sizeof(int)*n);

        for(i=0;i<n;i++)
        {
                int2 p;
                printf("Value ? ");
                scanf("%d %d",&p.x,&p.y);
                h_list[i] = p;
                h_ones[i] = 1;
        }

        cudaMemcpy(d_list,h_list,sizeof(int2)*n,cudaMemcpyHostToDevice);
        cudaMemcpy(d_ones,h_ones,sizeof(int)*n,cudaMemcpyHostToDevice);
        thrust::reduce_by_key(d_list, d_list+n, d_ones, C, D,cmp);
        return 0;
}

上面的代码显示了Segmentation Fault。我使用gdb运行上面的代码,它在这个位置报告了段错误。

  

thrust :: system :: detail :: internal :: scalar :: reduce_by_key&gt;   (keys_first = 0x1304740000,keys_last = 0x1304740010,values_first = 0x1304740200,keys_output = 0x1304740400,values_output = 0x1304740600,binary_pred = ...,binary_op = ...)

     

at /usr/local/cuda-6.5/bin/../targets/x86_64-linux/include/thrust/system/detail/internal/scalar/reduce_by_key.h:61 61
  InputKeyType temp_key = * keys_first

如何在设备阵列上使用reduce_by_key?

1 个答案:

答案 0 :(得分:4)

Thrust将普通指针解释为指向主机上的数据:

    thrust::reduce_by_key(d_list, d_list+n, d_ones, C, D,cmp);

因此,推力将为上述算法调用主机路径,并且当它试图取消引用主机代码中的指针时会产生错误。这包含在thrust getting started guide

  

你可能想知道当&#34; raw&#34;指针用作Thrust函数的参数。与STL一样,Thrust允许这种用法,它将调度算法的主机路径。如果有问题的指针实际上是指向设备内存的指针,那么在调用函数之前,你需要用thrust :: device_ptr来包装它。

Thrust有多种机制(例如device_ptrdevice_vector和执行策略)来向算法确定数据是设备驻留的,应该使用设备路径。

对现有代码进行最简单的修改可能是使用device_ptr

#include <thrust/device_ptr.h>
...
thrust::device_ptr<int2> dlistptr(d_list);
thrust::device_ptr<int>  donesptr(d_ones);
thrust::device_ptr<int2> Cptr(C);
thrust::device_ptr<int>  Dptr(D);
thrust::reduce_by_key(dlistptr, dlistptr+n, donesptr, Cptr, Dptr,cmp);

上述问题与another issue you asked about类似。