我想使用Thrust的流壓縮功能(copy_if)從元素中提取元素的索引,如果元素遵守一些約束。其中一個約束取決於相鄰元素的值(2D中8個,3D中26個)。我的問題是:我如何獲得Thrust中元素的鄰居?Thrust - 訪問鄰居
函子爲「copy_if」函數調用操作基本上看起來像:
__host__ __device__ bool operator()(float x) {
bool mark = x < 0.0f;
if (mark) {
if (left neighbor of x > 1.0f) return false;
if (right neighbor of x > 1.0f) return false;
if (top neighbor of x > 1.0f) return false;
//etc.
}
return mark;
}
目前我使用一個變通方法,首先推出了CUDA核心(其中很容易訪問鄰居)適當地標記元素。之後,我將標記的元素傳遞給Thrust的copy_if以提取標記元素的索引。
我遇到了counting_iterator作爲直接使用threadIdx和blockIdx獲取處理元素的索引的一種替代方法。我嘗試了下面的解決方案,但在編譯時,它給了我一個「/usr/include/cuda/thrust/detail/device/cuda/copy_if.inl(151):錯誤:不支持未對齊的內存訪問」。據我所知,我沒有試圖以不對齊的方式訪問內存。任何人都知道發生了什麼和/或如何解決這個問題?
struct IsEmpty2 {
float* xi;
IsEmpty2(float* pXi) { xi = pXi; }
__host__ __device__ bool operator()(thrust::tuple<float, int> t) {
bool mark = thrust::get<0>(t) < -0.01f;
if (mark) {
int countindex = thrust::get<1>(t);
if (xi[countindex] > 1.01f) return false;
//etc.
}
return mark;
}
};
thrust::copy_if(indices.begin(),
indices.end(),
thrust::make_zip_iterator(thrust::make_tuple(xi, thrust::counting_iterator<int>())),
indicesEmptied.begin(),
IsEmpty2(rawXi));
您可以在函子類的構造函數中提供全局數組的地址。你也可以訪問threadIdx.x,並且可以在上面的__device__方法中使用共享內存(你應該在你的情況下使用共享內存)。 – phoad
將指向全局數組的指針傳遞給函數的構造函數是可能的,然後將其存儲爲成員變量。但那不會解決我的問題。我應該訪問全局數組的哪些元素?我只有浮動x到我的處置,而不是指向x的指針。 至於使用共享內存,在我的情況下,這是不必要的。我只加載數據一次,並檢查它的特定值。 – Bart
Thrust中的Zip迭代器可以解決查找全局數組中float值的位置的問題。您可以使用threadIdx.x值,但需要稍有不同。關於使用共享內存,因爲您需要頂部,左側,右側,底部等,所以每個值所需的數據會有重疊,您可以使用局部性將這些數據從全局內存加載到寄存器一次,即共享內存(雖然全局內存緩存也可以)。 – phoad