如何创建推力device_vector的浅表副本

时间:2019-01-19 07:23:19

标签: cuda thrust shallow-copy

我有一个device_vectorH。我想使用选定的索引创建H的浅表副本。我称它为J。我想修改J的元素,从而修改H的相应元素。

当我更改J的元素时,下面的尝试未能修改H的元素。看来推力为J分配了新的内存,而不是使用分配给H的内存。

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sequence.h>
#include <thrust/execution_policy.h>

#include <iostream>

int main(void)
{
  // H has storage for 4 integers
  thrust::device_vector<int> H(10);
  thrust::sequence(thrust::device, H.begin(), H.end(),1);

  std::cout << "H="<< std::endl;
  thrust::copy(H.begin(), H.end(), std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  thrust::device_vector<int> J(H.begin()+3,H.begin()+9);

  std::cout << "Before modifying J="<< std::endl;
  thrust::copy(J.begin(), J.end(), std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  thrust::sequence(thrust::device, J.begin(), J.end(),10);

  std::cout << "after modifying J="<< std::endl;
  thrust::copy(J.begin(), J.end(), std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  std::cout << "After modifying H="<< std::endl;
  thrust::copy(H.begin(), H.end(), std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  return 0;
}

3 个答案:

答案 0 :(得分:2)

此:

FormData

复制结构。如果不求助于指向底层存储的指针,就无法做您想做的事情,即使这样,您也要注意,源向量永远不会超出范围

两个向量不能使用相同的基础分配。 is true代表thrust::device_vector<int> J(H.begin()+3,H.begin()+9); ,推力矢量也是如此。

您可以执行与std::vector相似的建议:

thrust::device_ptr

答案 1 :(得分:1)

我尝试了迭代器。它似乎有效。结果将发布在代码之后。内存位置似乎也被覆盖。

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sequence.h>
#include <thrust/execution_policy.h>
#include <thrust/device_ptr.h>

#include <iostream>

int main(void)
{
  // H has storage for 4 integers
  thrust::device_vector<int> H(10);
  thrust::sequence(thrust::device, H.begin(), H.end(),1);

  std::cout << "H="<< std::endl;
  thrust::copy(H.begin(), H.end(), std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  thrust::device_vector<int>::iterator J = H.begin()+3;
  thrust::device_vector<int>::iterator J_end = J+6;

  std::cout << "Before modifying J="<< std::endl;
  thrust::copy(J, J_end, std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  thrust::sequence(thrust::device, J, J_end,10);

  std::cout << "after modifying J="<< std::endl;
  thrust::copy(J, J_end, std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  std::cout << "After modifying H="<< std::endl;
  thrust::copy(H.begin(), H.end(), std::ostream_iterator<int>(std::cout, ","));
  std::cout<< std::endl;

  return 0;
}

结果:

./ a.out

H=
1,2,3,4,5,6,7,8,9,10,
Before modifying J=
4,5,6,7,8,9,
after modifying J=
10,11,12,13,14,15,
After modifying H=
1,2,3,10,11,12,13,14,15,10,

答案 2 :(得分:1)

  

我想使用选定的索引创建H的浅表副本。

否,您不想创建浅表副本。

  

我称之为J [和]来修改J的元素,从而修改H的相应元素。

您实际上想要做的-最终要做的-就是修改容器元素范围的子范围。在C ++中,我们使用迭代器执行此操作;在许多情况下,这些迭代器本质上只是指针。

另一种实现方法-当元素在内存中连续时-使用std::span-但这是C ++ 20构造(由于缺少显式CUDA支持,您可能会遇到一些麻烦,即可能缺少__device__属性;在某些实现中gsl::span也是如此)。