Из thrust::device_vector в необработанный указатель и обратно?

#c #cuda #thrust

#c #cuda #thrust

Вопрос:

Я понимаю, как перейти от вектора к необработанному указателю, но я пропускаю удар о том, как вернуться назад.

 // our host vector
thrust::host_vector<dbl2> hVec;

// pretend we put data in it here

// get a device_vector
thrust::device_vector<dbl2> dVec = hVec;

// get the device ptr
thrust::device_ptr devPtr = amp;d_vec[0];

// now how do i get back to device_vector?
thrust::device_vector<dbl2> dVec2 = devPtr; // gives error
thrust::device_vector<dbl2> dVec2(devPtr); // gives error
  

Может кто-нибудь объяснить / указать мне на пример?

Ответ №1:

http://code.google.com/p/thrust/source/browse/examples/cuda/wrap_pointer.cu

Thrust дает хороший пример для этого вопроса.

 #include <thrust/device_ptr.h>
#include <thrust/fill.h>
#include <cuda.h>

int main(void)
{
    size_t N = 10;

    // obtain raw pointer to device memory
    int * raw_ptr;
    cudaMalloc((void **) amp;raw_ptr, N * sizeof(int));

    // wrap raw pointer with a device_ptr 
    thrust::device_ptr<int> dev_ptr = thrust::device_pointer_cast(raw_ptr);

    // use device_ptr in Thrust algorithms
    thrust::fill(dev_ptr, dev_ptr   N, (int) 0);    

    // access device memory transparently through device_ptr
    dev_ptr[0] = 1;

    // free memory
    cudaFree(raw_ptr);

    return 0;
}
  

И получение необработанного указателя из контейнеров thrust — это ответ, на который вы уже ответили сами..

 dbl2* ptrDVec = thrust::raw_pointer_cast(amp;d_vec[0]);
  

Ответ №2:

Вы инициализируете и заполняете векторы thrust так же, как стандартные контейнеры, т.Е. с помощью итераторов:

 #include <thrust/device_vector.h>
#include <thrust/device_ptr.h>

int main()
{
  thrust::device_vector<double> v1(10);                    // create a vector of size 10
  thrust::device_ptr<double> dp = v1.data();               // or amp;v1[0]

  thrust::device_vector<double> v2(v1);                    // from copy
  thrust::device_vector<double> v3(dp, dp   10);           // from iterator range
  thrust::device_vector<double> v4(v1.begin(), v1.end());  // from iterator range
}
  

В вашем простом примере нет необходимости обходить с помощью указателей, так как вы можете просто скопировать другой контейнер напрямую. В общем, если у вас есть указатель на начало массива, вы можете использовать версию для v3 , если вы указываете размер массива.

Комментарии:

1. значит, только из указателя, без длины, нет способа вернуться к device_vector?

2. dbl2* ptrDVec = thrust::raw_pointer_cast(amp;d_vec[0]); есть ли способ вернуться к device_vector из этого?

3. Что значит «вернуться» — разве это уже не указатель устройства? Что именно вам нужно?

4. Мне нужно иметь возможность сохранять указатель / ссылку на device_vector (скажем, у меня есть dVec1 и dVec2), затем выполнить несколько действий и выполнить некоторые условные обозначения, и в конце я хочу привести либо указатель на dVec1, либо dVec2 как device_vector int dVec3.. идея заключается в том, чтобы передавать dVec по ссылке и в какой-то момент разыменовывать их и снова использовать их как device_vectors

Ответ №3:

dbl2* ptrDVec = thrust::raw_pointer_cast(amp;d_vec[0]); есть ли способ вернуться к device_vector из этого?

Нет. Хотя вы должны иметь возможность повторно использовать начальную векторную переменную.