2012-08-05 18 views
1

我試圖使用推力指數爲每個給設備矢量某些值 這裏是代碼如何獲得推力的foreach

const uint N = 222222; 
struct assign_functor 
{ 
    template <typename Tuple> 
    __device__ 
    void operator()(Tuple t) 
    { 
    uint x = threadIdx.x + blockIdx.x * blockDim.x; 
    uint y = threadIdx.y + blockIdx.y * blockDim.y; 
    uint offset = x + y * blockDim.x * gridDim.x; 

    thrust::get<0>(t) = offset; 
    } 
}; 
int main(int argc, char** argv) 
{ 

    thrust::device_vector <float> d_float_vec(N); 

    thrust::for_each(
    thrust::make_zip_iterator( 
     thrust::make_tuple(d_float_vec.begin()) 
    ), 
    thrust::make_zip_iterator( 
     thrust::make_tuple(d_float_vec.end()) 
    ), 
    assign_functor() 
); 

    std::cout<<d_float_vec[10]<<" "<<d_float_vec[N-2] 
} 

d_float_vec的輸出[N-2]被認爲是222220;但事實證明1036.我的代碼怎麼了?

我知道我可以使用thrust :: sequence給這個向量賦一個序列值。我只想知道如何獲得推力foreach函數的真實指數。謝謝!

+0

爲什麼輸出應該是N-2? – talonmies 2012-08-05 13:31:12

+0

uint x = threadIdx.x + blockIdx.x * blockDim.x; uint y = threadIdx.y + blockIdx.y * blockDim.y; uint offset = x + y * blockDim.x * gridDim.x;偏移量是索引。我希望每個矢量都有自己的索引 – user1536720 2012-08-05 14:37:28

+0

是的,但是您隱式假定每個線程正好處理數組中的1個輸出點,並且在您計算的2D線索索引與數組中的某個位置之間存在直接關係。這些事情都不一定是真的。 – talonmies 2012-08-05 15:11:39

回答

2

正如在評論中指出,你的做法是絕不可能的工作,因爲你承擔了多項關於thrust::for_each內部工作這可能是不正確的,包括事物的方式:

  • 您隱含假設了for_each使用單個線程來處理每個輸入元素。這幾乎肯定不是這樣;在操作過程中推力將更有可能處理每個螺紋的多個元素。
  • 您還假定執行順序是爲了讓第N個線程處理第N個數組元素。這可能不是這種情況,並且在不能已知的順序,可能會發生執行先驗
  • 您假設for_each處理整個輸入數據在單個內核laumch

推力算法應設置視爲內部操作未定義的黑盒子,並且不需要他們的知識來實現​​用戶定義的仿函數。在你的例子中,如果你需要一個函子內部的順序索引,傳遞一個計數迭代器。重新寫你的榜樣的一個方法是這樣的:

#include "thrust/device_vector.h" 
#include "thrust/for_each.h" 
#include "thrust/tuple.h" 
#include "thrust/iterator/counting_iterator.h" 

typedef unsigned int uint; 
const uint N = 222222; 
struct assign_functor 
{ 
    template <typename Tuple> 
    __device__ 
    void operator()(Tuple t) 
    { 
    thrust::get<1>(t) = (float)thrust::get<0>(t); 
    } 
}; 

int main(int argc, char** argv) 
{ 
    thrust::device_vector <float> d_float_vec(N); 
    thrust::counting_iterator<uint> first(0); 
    thrust::counting_iterator<uint> last = first + N; 

    thrust::for_each(
    thrust::make_zip_iterator( 
     thrust::make_tuple(first, d_float_vec.begin()) 
    ), 
    thrust::make_zip_iterator( 
     thrust::make_tuple(last, d_float_vec.end()) 
    ), 
    assign_functor() 
); 

    std::cout<<d_float_vec[10]<<" "<<d_float_vec[N-2]<<std::endl; 
} 

這裏的計數迭代器獲取的元組與數據陣列一起傳遞,允許其對應於數據陣列條目的順序索引函子訪問它正在處理。

+0

謝謝!真的很感激它! – user1536720 2012-08-06 02:57:32