thrust::device_reference
Defined in thrust/device_reference.h
-
template<typename T>
class device_reference : public thrust::reference<T, thrust::device_ptr<T>, thrust::device_reference<T>> device_referenceacts as a reference-like object to an object stored in device memory.device_referenceis not intended to be used directly; rather, this type is the result of dereferencing adevice_ptr. Similarly, taking the address of adevice_referenceyields adevice_ptr.device_referencemay often be used from host code in place of operations defined on its associatedvalue_type. For example, whendevice_referencerefers to an arithmetic type, arithmetic operations on it are legal:#include <thrust/device_vector.h> int main() { thrust::device_vector<int> vec(1, 13); thrust::device_reference<int> ref_to_thirteen = vec[0]; int x = ref_to_thirteen + 1; // x is 14 return 0; }
Similarly, we can print the value of
ref_to_thirteenin the above code by using aniostream:#include <thrust/device_vector.h> #include <iostream> int main() { thrust::device_vector<int> vec(1, 13); thrust::device_reference<int> ref_to_thirteen = vec[0]; std::cout << ref_to_thirteen << std::endl; // 13 is printed return 0; }
Of course, we needn’t explicitly create a
device_referencein the previous example, because one is returned bydevice_vector'sbracket operator. A more natural way to print the value of adevice_vectorelement might be:#include <thrust/device_vector.h> #include <iostream> int main() { thrust::device_vector<int> vec(1, 13); std::cout << vec[0] << std::endl; // 13 is printed return 0; }
These kinds of operations should be used sparingly in performance-critical code, because they imply a potentially expensive copy between host and device space.
Some operations which are possible with regular objects are impossible with their corresponding
device_referenceobjects due to the requirements of the C++ language. For example, because the member access operator cannot be overloaded, member variables and functions of a referent object cannot be directly accessed through itsdevice_reference.The following code, which generates a compiler error, illustrates:
#include <thrust/device_vector.h> struct foo { int x; }; int main() { thrust::device_vector<foo> foo_vec(1); thrust::device_reference<foo> foo_ref = foo_vec[0]; foo_ref.x = 13; // ERROR: x cannot be accessed through foo_ref return 0; }
Instead, a host space copy must be created to access
foo'sxmember:#include <thrust/device_vector.h> struct foo { int x; }; int main() { thrust::device_vector<foo> foo_vec(1); // create a local host-side foo object foo host_foo; host_foo.x = 13; thrust::device_reference<foo> foo_ref = foo_vec[0]; foo_ref = host_foo; // foo_ref's x member is 13 return 0; }
Another common case where a
device_referencecannot directly be used in place of its referent object occurs when passing them as parameters to functions likeprintfwhich have varargs parameters. Because varargs parameters must be Plain Old Data, adevice_referenceto a POD type requires a cast when passed toprintf:#include <stdio.h> #include <thrust/device_vector.h> int main() { thrust::device_vector<int> vec(1,13); // vec[0] must be cast to int when passing to printf printf("%d\n", (int) vec[0]); return 0; }
See also
See also
Public Types
-
using value_type = typename super_t::value_type
The type of the value referenced by this type of
device_reference.
-
using pointer = typename super_t::pointer
The type of the expression
&ref, whererefis adevice_reference.
Public Functions
-
template<typename OtherT>
inline device_reference(const device_reference<OtherT> &other, thrust::detail::enable_if_convertible_t<typename device_reference<OtherT>::pointer, pointer>* = 0) This copy constructor accepts a const reference to another
device_reference. After thisdevice_referenceis constructed, it shall refer to the same object asother.The following code snippet demonstrates the semantics of this copy constructor.
#include <thrust/device_vector.h> #include <assert.h> ... thrust::device_vector<int> v(1,0); thrust::device_reference<int> ref = v[0]; // ref equals the object at v[0] assert(ref == v[0]); // the address of ref equals the address of v[0] assert(&ref == &v[0]); // modifying v[0] modifies ref v[0] = 13; assert(ref == 13);
Note
This constructor is templated primarily to allow initialization of
device_reference<const T>fromdevice_reference<T>.- Parameters
other – A
device_referenceto copy from.
-
inline explicit device_reference(const pointer &ptr)
This copy constructor initializes this
device_referenceto refer to an object pointed to by the givendevice_ptr. After thisdevice_referenceis constructed, it shall refer to the object pointed to byptr.The following code snippet demonstrates the semantic of this copy constructor.
#include <thrust/device_vector.h> #include <assert.h> ... thrust::device_vector<int> v(1,0); thrust::device_ptr<int> ptr = &v[0]; thrust::device_reference<int> ref(ptr); // ref equals the object pointed to by ptr assert(ref == *ptr); // the address of ref equals ptr assert(&ref == ptr); // modifying *ptr modifies ref *ptr = 13; assert(ref == 13);
- Parameters
ptr – A
device_ptrto copy from.
-
template<typename OtherT>
inline device_reference &operator=(const device_reference<OtherT> &other) This assignment operator assigns the value of the object referenced by the given
device_referenceto the object referenced by thisdevice_reference.- Parameters
other – The
device_referenceto assign from.- Returns
*this
-
inline device_reference &operator=(const value_type &x)
Assignment operator assigns the value of the given value to the value referenced by this
device_reference.- Parameters
x – The value to assign from.
- Returns
*this
Friends
-
inline friend void swap(device_reference &x, device_reference &y) noexcept(noexcept(x.swap(y)))
swaps the value of one
device_referencewith another.xThe firstdevice_referenceof interest.yThe seconddevice_referenceof interest.
-
using value_type = typename super_t::value_type