22

I understand how to go from a vector to a raw pointer but im skipping a beat on how to go backwards.

// 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 = &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

Can someone explain/point me to an example?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
madmaze
  • 878
  • 3
  • 11
  • 23

3 Answers3

24

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

Thrust provides a good example for this question.

#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 **) &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;
}

And getting the raw pointer from thrust containers is as answered already by yourself..

dbl2* ptrDVec = thrust::raw_pointer_cast(&d_vec[0]);
phoad
  • 1,801
  • 2
  • 20
  • 31
14

You initialize and populate thrust vectors just like standard containers, i.e. via iterators:

#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 &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
}

In your simple example there's no need to go the detour via pointers, as you can just copy the other container directly. In general, if you have a pointer to the beginning of an array, you can use the version for v3 if you supply the array size.

Jared Hoberock
  • 11,118
  • 3
  • 40
  • 76
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • so just from a pointer, without the length there is no way to get back to a device_vector? – madmaze Oct 11 '11 at 13:29
  • 3
    dbl2* ptrDVec = thrust::raw_pointer_cast(&d_vec[0]); is there a way to get back to a device_vector from this? – madmaze Oct 11 '11 at 13:30
  • What do you mean "get back" - isn't it already a device pointer? What exactly do you need? – Kerrek SB Oct 11 '11 at 13:43
  • I need to be able to save a pointer/reference to a device_vector(say i have dVec1 and dVec2), then do a few things and do some conditionals and in the end I want cast either the pointer to dVec1 or dVec2 as device_vector int dVec3.. the idea is passing the dVec's around by reference and at somepoint derefrencing them and using them as device_vectors again – madmaze Oct 11 '11 at 14:04
4

dbl2* ptrDVec = thrust::raw_pointer_cast(&d_vec[0]); is there a way to get back to a device_vector from this?

There is not. Although you should be able to reuse the initial vector variable.

Slava
  • 1,528
  • 1
  • 15
  • 23