2

我正在尝试以这种方式访问​​矢量元素

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)
}

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]"

我究竟做错了什么?

4

2 回答 2

5

好的,这比我预期的要复杂一点:)
以下是我的调查结果:

您的问题来自推力的实施。Thrust 使用一种称为device_referencewhich 的类型,正如其文档所述:http ://wiki.thrust.googlecode.com/hg/html/classthrust_1_1device__reference.html

device_reference充当存储在设备内存中的对象的类引用对象。 device_reference不打算直接使用;相反,这种类型是尊重 a 的结果 device_ptr。同样,获取 a 的地址会device_reference产生 a device_ptr

但是,在某些情况下,我们隐式处理device_reference. 例如,当 device_reference 作为参数传递给等待 POD 的函数时(或多或少是您尝试使用的operator<<),会出现以下问题:

device_reference另一种无法直接使用 a 代替其引用对象的常见情况 发生在将它们作为参数传递给printf具有可变参数的函数时。因为 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;
}

在我看来,这不是最优雅的解决方案,我宁愿使用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;
}

现在,由您来选择您喜欢的那个!

于 2011-07-06T07:11:29.690 回答
4
std::cout << iter->x << " " << iter->y << " " << std::endl; 
                                      ^^^^

:))

于 2011-07-05T16:10:10.620 回答