qut*_*ron 2 c++ iterator stl cuda thrust
我试图以这种方式访问向量元素
struct point
{
unsigned int x;
unsigned int y;
};
...
thrust::device_vector<point> devPoints(hPoints.begin(), hPoints.end());
for(thrust::device_vector<point>::iterator iter = devPoints.begin(); iter != devPoints.end(); iter++)
{
std::cout << iter->x << " " << iter->y << " " << std::endl; (1)
}
Run Code Online (Sandbox Code Playgroud)
device_vector已正确初始化.我收到以下错误:
error: expression must have pointer type (at 1)
error: no suitable user-defined conversion from "const thrust::detail::normal_iterator<thrust::device_ptr<point>>" to "thrust::device_ptr<point>" exists
detected during instantiation of "Pointer thrust::experimental::iterator_facade<Derived, Pointer, Value, Space, Traversal, Reference, Difference>::operator->() const [with Derived=thrust::detail::normal_iterator<thrust::device_ptr<point>>, Pointer=thrust::device_ptr<point>, Value=point, Space=thrust::detail::cuda_device_space_tag, Traversal=thrust::random_access_traversal_tag, Reference=thrust::device_reference<point>, Difference=ptrdiff_t]"
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
好吧,这个比我想象的要复杂一点:)
以下是我调查的结果:
你的问题来自于推力的实施.Thrust使用一个名为的类型device_reference,正如其文档所述:http://wiki.thrust.googlecode.com/hg/html/classthrust_1_1device__reference.html
device_reference充当存储在设备存储器中的对象的类似引用的对象.device_reference不打算直接使用; 相反,这种类型是引用a的结果device_ptr.同样地,取a的地址device_reference得到adevice_ptr.
但是,在某些情况下,我们隐含地处理device_reference.例如,当device_reference作为参数传递给等待POD的函数时(或多或少你正在尝试处理operator<<),会出现以下问题:
另一种常见的情况
device_reference是,当将它们作为参数传递给printf具有varargs参数的函数时,不能直接使用它来代替它的指示对象.因为varargs参数必须是普通旧数据,所以 当传递给printf时,device_reference到POD类型需要强制转换:
话虽如此,您所要做的就是将您device_reference投入到您正在处理的POD中.在你的情况下,你会做:
for(thrust::device_vector<point>::iterator iter = devPoints.begin(); iter != devPoints.end(); iter++) {
std::cout << (static_cast<point>(*iter)).x << " " << (static_cast<point>(*iter)).y << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这不是最优雅的解决方案,我宁愿使用std::copy算法打印你point班级的内容.因此,我编写了一个小示例文件,使用您的point类并使用三种不同的方式打印它:
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <cstdlib>
#include <algorithm>
#include <iostream>
struct point
{
unsigned int x;
unsigned int y;
};
__host__
point getRandomPoint() {
point p;
p.x = rand();
p.y = rand();
return p;
}
__host__
std::ostream& operator<< (std::ostream& os, const point& p) {
os << "[ " << p.x << " ; " << p.y << " ]";
return os;
}
int main() {
// fill the host_vector with random points
thrust::host_vector<point> hPoints(512);
thrust::generate(hPoints.begin(), hPoints.end(), getRandomPoint);
// copy hPoints content to device memory
thrust::device_vector<point> devPoints(hPoints.begin(), hPoints.end());
// first way
for(thrust::device_vector<point>::iterator iter = devPoints.begin(); iter != devPoints.end(); iter++) {
std::cout << (static_cast<point>(*iter)).x << " " << (static_cast<point>(*iter)).y << std::endl;
}
// second way
for(thrust::device_vector<point>::iterator iter = devPoints.begin(); iter != devPoints.end(); iter++)
{
std::cout << *iter << std::endl;
}
// third way
std::copy(devPoints.begin(), devPoints.end(), std::ostream_iterator< point >(std::cout, " $ ") );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以选择自己喜欢的那个!