在CUDA中使用推力::排序时出现分段错误

在CUDA中使用推力::排序时出现分段错误,cuda,parallel-processing,thrust,Cuda,Parallel Processing,Thrust,我试图通过将比较函数作为参数传递给推力排序,根据类对象的类型对类对象数组进行排序 类定义: class TetraCutInfo { public: int tetraid; unsigned int ncutEdges; unsigned int ncutNodes; unsigned int type_cut; __host__ __device__ TetraCutInfo(); }; 排序

我试图通过将比较函数作为参数传递给推力排序,根据类对象的类型对类对象数组进行排序

类定义

class TetraCutInfo
{

        public:
        int tetraid;
        unsigned int ncutEdges;
        unsigned int ncutNodes;
        unsigned int type_cut;
        __host__ __device__ TetraCutInfo();
};
排序:

   thrust::sort(cutInfoptr,cutInfoptr+n,cmp());
cutInfoptr是一个类型为TetraCutInfo的指针,具有使用cudaMalloc分配的设备内存地址

比较功能

struct cmp
{
  __host__ __device__
  bool operator()(const TetraCutInfo x, TetraCutInfo y)
  {
        return (x.type_cut < y.type_cut);
  }
};
struct-cmp
{
__主机设备__
布尔运算符()
{
返回(x型切割
在运行这个程序时,我遇到了分段错误,但是我能够在另一个内核中迭代cutInfoptr


PS:我参考了链接中的示例

SEG故障更可能由主机代码引起,我建议先检查CPU代码路径

cutInfoptr是一个类型为TetraCutInfo的指针,具有使用cudaMalloc分配的设备内存地址

尽管您还没有展示完整的代码,但根据上面的陈述,事情可能不会成功,我预计当指针被取消引用时会出现seg错误

请注意以下文件中给出的信息:

您可能想知道当“原始”指针用作推力函数的参数时会发生什么。与STL一样,推力允许这种使用,它将调度算法的主机路径。如果所讨论的指针实际上是一个指向设备内存的指针,那么在调用函数之前,您需要使用推力::device_ptr将其包装起来

您引用的
cudaMalloc
创建的
cutInfoptr
是一个“原始指针”(也恰好是一个设备指针)。当您将它传递给推力时,推力会看到它是一个原始指针,并分派“主机路径”。当您传递的(设备)指针在主机路径的主机代码中被取消引用时,您将获得seg故障

一种解决方案是将其封装在一个推力::设备_ptr指针中,这里摘录了《快速入门指南》示例:

size_t N = 10;

// raw pointer to device memory
int * raw_ptr;
cudaMalloc((void **) &raw_ptr, N * sizeof(int));

// wrap raw pointer with a device_ptr 
thrust::device_ptr<int> dev_ptr(raw_ptr);

// use device_ptr in thrust algorithms
thrust::fill(dev_ptr, dev_ptr + N, (int) 0);
size\u t N=10;
//指向设备内存的原始指针
int*原始ptr;
cudamaloc((void**)和raw_ptr,N*sizeof(int));
//用设备包装原始指针\u ptr
推力:设备的开发(原始);
//在推力算法中使用设备ptr
推力:填充(dev_ptr,dev_ptr+N,(int)0);

另一种可能的解决方案是使用适当的工具进行调度,例如
推力::设备

,您应该提供完整的代码。不能将Cudamaloc返回的指针直接用于推力函数。先用推力::装置ptr将其包裹起来。阅读github快速入门指南。这可能是对原始问题的评论,而不是答案。