通过构造函数将 device_vector 存储在函子中?

Qua*_* Ha 1 cuda functor thrust

我正在尝试将 a 存储thrust::device_vector在函子内。简单的解释如下:

struct StructOperator : public thrust::unary_function<float, int>  {
  int num_;
  thrust::device_vector<int> v_test;

  explicit StructOperator(thrust::device_vector<int> const& input_v) :
    v_test(input_v), num_(input_v.size()) {};

  __host__ __device__
   float operator()(int index) {
      // magic happens
   }
};
Run Code Online (Sandbox Code Playgroud)

无法编译 -nvcc一直说不允许__host__从 a调用 a __host__ __device__。我见过这个问题 - 这是实现这一目标的唯一方法吗?

Rob*_*lla 5

当您将__device__装饰器放在您的函子运算符上时,您现在已将您在该运算符主体中可以执行的操作限制为与 CUDA 设备代码兼容的内容。

Athrust::device_vector是一个类定义,旨在促进推力的表达/计算模型(大致类似于 STL 容器/算法)。因此,它包括主机和设备代码。a 中的主机代码thrust::device_vector没有为在设备上使用而进行修饰,普通的主机代码在 CUDA 设备代码中是不可用的。

thrust::device_vector不设计也不打算直接在设备代码中使用。它不能按照您的建议使用。与可能的猜测相反,它并非设计std::vector为可在 CUDA 设备代码中使用的模拟。它被设计为可std::vector用于推力算法的模拟(根据设计,可从主机代码调用/使用)。这就是为什么您在编译时会收到消息,并且没有简单的方法 (*) 来解决这个问题。

据推测, 的主要目的thrust::device_vector是作为一个容器来保存在设备上可用/可访问的数据。CUDA 设备代码中已经支持的 POD 类型数据中最直接的等价物是数组或指向数据的指针。

因此,我认为用“是”回答您的问题是合理的 - 这是实现这一目标的唯一方法。

  • 我在各种类似的方法中混为一谈,例如传递推力指针而不是裸指针。
  • (*) 我忽略了这样的想法,例如编写允许在设备上使用的自己的容器类,或者进行大量修改以推动自身以某种方式允许这种行为。

这是一个完整的示例,围绕您所展示的内容:

$ cat t1385.cu
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/transform.h>
#include <thrust/copy.h>


struct StructOperator : public thrust::unary_function<float, int>  {
  int num_;
  int *v_test;

  explicit StructOperator(int *input_v, int input_v_size) :
    v_test(input_v), num_(input_v_size) {};

  __host__ __device__
   float operator()(int index) {
      if (index < num_)  return v_test[index] + 0.5;
      return 0.0f;
   }
};

const int ds = 3;
int main(){

  thrust::device_vector<int> d(ds);
  thrust::sequence(d.begin(), d.end());
  thrust::device_vector<float> r(ds);
  thrust::transform(d.begin(), d.end(), r.begin(), StructOperator(thrust::raw_pointer_cast(d.data()), d.size()));
  thrust::copy(r.begin(), r.end(), std::ostream_iterator<float>(std::cout, ","));
  std::cout << std::endl;
}
$ nvcc t1385.cu -o t1385
$ ./t1385
0.5,1.5,2.5,
$
Run Code Online (Sandbox Code Playgroud)

  • 我添加了一个例子 (2认同)