Cuda 通过构造函数在函子中存储设备向量?

Cuda 通过构造函数在函子中存储设备向量?,cuda,functor,thrust,Cuda,Functor,Thrust,我试图在一个函子中存储一个推力::设备向量。简单的解释如下: 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_t

我试图在一个函子中存储一个
推力::设备向量。简单的解释如下:

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
   }
};
结构运算符:公共推力::一元函数{ int num_u2;; 推力:装置矢量v_测试; 显式结构运算符(推力::设备向量常量和输入): v_测试(input_v),num_测试(input_v.size()){}; __主机设备__ 浮点运算符()(int索引){ //奇迹发生了 } };

它不编译-
nvcc
一直说不允许从
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu设备调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuu。我看到了一个问题-这是实现这一点的唯一方法吗?

当您将
\uuuu设备\uuuu
装饰器放在functor操作符上时,您现在已经将在该操作符体中可以执行的操作限制为与CUDA设备代码兼容的操作

一个
推力::设备向量
是一个类定义,旨在促进推力的表达式/计算模型(大致类似于STL容器/算法)。因此,它包含主机和设备代码。
asch::device_vector
中的主机代码未修饰以在设备上使用,普通主机代码在CUDA设备代码中不可用

推力::设备_向量
不是设计的,也不打算直接用于设备代码中。它不能像你建议的那样使用。与可能的推测相反,它不是设计为可在CUDA设备代码中使用的
std::vector
的模拟。它被设计为std::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,
$
$cat t1385.cu
#包括
#包括
#包括
#包括
结构运算符:公共推力::一元函数{
int num_u2;;
int*v_检验;
显式结构运算符(int*input\u v,int-input\u v\u size):
v_测试(input_v),num_(input_v_size){};
__主机设备__
浮点运算符()(int索引){
如果(指数std::cout当您将
\uuuu设备\uuuuu
装饰器放在functor操作符上时,您现在已经将在该操作符体中可以执行的操作限制为与CUDA设备代码兼容的操作

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

推力::设备向量
既不是设计的,也不是打算直接用于设备代码。它不能按照您的建议使用。与可能的推测相反,它不是设计为可用于CUDA设备代码的
std::vector
的模拟。它是设计为可用于CUDA设备代码的
std::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,
$
$cat t1385.cu
#包括
#包括
#包括
#包括
结构运算符:公共推力::一元函数{
int num_u2;;
int*v_检验;
显式结构运算符(int*input\u v,int-input\u v\u size):
v_测试(input_v),num_(input_v_size){};
__主机设备__
浮点运算符()(int索引){
如果(指数