Как создать неглубокую копию тяги device_vector - PullRequest
0 голосов
/ 19 января 2019

У меня device_vector H. Я хочу создать поверхностную копию H, используя выбранные индексы. Я называю это J. Я хочу изменить элементы J, тем самым модифицируя соответствующие элементы H.

Моя попытка ниже не дает возможности изменить элементы H, когда я меняю элементы J. Похоже, что тяга выделяет новую память для 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 голосов
/ 22 января 2019

Я пробовал с итераторами. Вроде работает. Результаты публикуются после кода. Ячейка памяти также перезаписана.

#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,
0 голосов
/ 25 января 2019

Я хочу создать поверхностную копию H, используя выбранные индексы.

Нет, вы не хотите создавать поверхностную копию.

Я называю это J [и], чтобы модифицировать элементы J, тем самым изменяя соответствующие элементы H.

То, что вы действительно хотите сделать - и в итоге сделали - этоизменение поддиапазона диапазона элементов контейнера.В C ++ мы делаем это с помощью итераторов;во многих случаях эти итераторы, по сути, являются просто указателями.

Еще один способ сделать это - когда элементы смежны в памяти - это использовать std::span - но это C ++20 (и у вас могут возникнуть некоторые проблемы из-за отсутствия явной поддержки CUDA, то есть потенциального отсутствия атрибутов __device__; то же самое относится и к gsl::span в некоторых реализациях).

0 голосов
/ 19 января 2019

Это:

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

- это копия конструкции .Невозможно сделать то, что вы хотите, не прибегая к указателям на базовое хранилище, и даже в этом случае вам нужно быть осторожным, чтобы исходный вектор никогда не выпадал из области действия

Два вектора не могут использовать одно и то же базовое распределение.Это истинно для std::vector, и это верно для векторов тяги.

Вы можете сделать что-то похожее на то, что вы предлагаете с thrust::device_ptr:

$ cat t4.cu
#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_ptr<int> J(H.data()+3);
  thrust::device_ptr<int> 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;
}
$ nvcc -o t4 t4.cu
$ ./t4
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,
$
...