【问题标题】:Segmentation error when using thrust::sort in CUDA在 CUDA 中使用推力::排序时出现分段错误
【发布时间】:2015-02-26 16:53:54
【问题描述】:

我正在尝试通过将比较函数作为参数传递给推力排序来根据其类型对类对象数组进行排序。

类定义

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);
  }
};

在运行此程序时,我遇到了分段错误,但是我能够在另一个内核中遍历 cutInfoptr。

PS:我参考了链接https://code.google.com/p/thrust/source/browse/examples/sort.cu中的例子

【问题讨论】:

  • 您应该提供完整的代码。您不能将 cudaMalloc 返回的指针直接用于推力函数。首先将它们包裹在推力::device_ptr 中。阅读 github 推力快速入门指南。

标签: cuda parallel-processing thrust


【解决方案1】:

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

虽然您没有显示完整的代码,但根据您所做的上述陈述,事情可能无法正常工作,并且我预计会出现 seg 错误,因为该指针被取消引用。

注意thrust quick start guide中给出的信息:

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

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

一种解决方案是将其包装在推力::device_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);

另一种可能的解决方案是使用适当的execution policy 进行调度,例如thrust::device

【讨论】:

    【解决方案2】:

    段错误更有可能是由主机代码引起的,我建议先检查 CPU 代码路径。

    【讨论】:

    • 这可能应该作为对原始问题的评论而不是答案发布。
    猜你喜欢
    • 2013-11-12
    • 2012-09-11
    • 2021-03-18
    • 2016-05-09
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    相关资源
    最近更新 更多