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_referenceドキュメントに記載されているように、次のタイプを使用します:http ://wiki.thrust.googlecode.com/hg/html/classthrust_1_1device__reference.html

device_referenceデバイスメモリに格納されているオブジェクトへの参照のようなオブジェクトとして機能します。 device_reference直接使用することを意図したものではありません。むしろ、このタイプは、を延期した結果です device_ptr。同様に、device_referenceyields のアドレスを取得するとdevice_ptr

ただし、暗黙的にを扱っている場合がありdevice_referenceます。たとえば、device_referenceがPOD(多かれ少なかれあなたがやろうとしていることoperator<<)を待っている関数にパラメーターとして渡されると、次の問題が発生します。

指示対象オブジェクトの代わりにを直接使用できないもう1つの一般的なケースは、 varargsパラメーターを持つdevice_reference関数にパラメーターとして渡すときに発生します。printfvarargsパラメーターはPlainOldDataでなければならないため device_reference、POD型へのaは printfに渡されるときにキャストが必要です。

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クラスを使用し、3つの異なる方法を使用して印刷する小さなサンプルファイルを作成しました。

#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 に答える