2011-07-05 129 views
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]" 

我在做什麼錯?

回答

5

確定這一個有點超過我的預期:)
這裏是我的調查結果複雜:

你的問題來自推力的實現。推力使用稱爲device_reference哪種類型的,因爲它的文件說:http://wiki.thrust.googlecode.com/hg/html/classthrust_1_1device__reference.html

device_reference充當 參考狀物體與存儲在設備存儲器中的對象 。 device_reference並不旨在是直接使用 ;而,這種類型是 deferencing一個 device_ptr的結果。同樣,採取device_reference的 地址產生一個 device_ptr

但是,有些情況下,我們暗中處理device_reference。例如,當一個device_reference作爲參數傳遞給等待POD功能(或多或少你正在嘗試與operator<<做),會出現以下問題:

另一種常見的情況下一個 device_reference不能直接代替其對象指涉的 可以使用 傳遞它們時作爲參數 像printf具有 可變參數參數的函數發生。由於可變參數 參數必須是普通的舊數據,一個 device_reference到POD類型需要投 傳遞給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類和使用三種不同的方式打印出來:

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

現在,它是由你來選擇一個你喜歡!

+0

不幸的是,它並沒有幫助。 – qutron

+0

@qutron:我解決了你的問題!再次檢查我的答案。它現在應該適合你。 – jopasserat

+0

Tnank你的答案!現在它工作正常。 – qutron

4
std::cout << iter->x << " " << iter->y << " " << std::endl; 
             ^^^^ 

:))

+0

你說得對。錯誤的複製粘貼)) – qutron

+1

@qutrun:還有什麼是我們不知道的? –

+0

沒有什麼有趣的。 hPoints是一個host_vector。它被正確初始化,並且使用這種方法工作正常。我發現Thrust中的容器類型僅限於基本類型。也許我的錯誤與此有關。 – qutron