要素が多くの制約に準拠している場合、ベクトルから要素のインデックスを抽出するために、Thrust のストリーム圧縮機能 (copy_if) を使用したいと考えています。これらの制約の 1 つは、隣接する要素の値に依存します (2D では 8、3D では 26)。私の質問は、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 に渡し、マークされた要素のインデックスを抽出します。
処理された要素のインデックスを取得するために、threadIdx と blockIdx を直接使用する代わりに、counting_iterator を見つけました。以下の解決策を試しましたが、コンパイルすると、「/usr/include/cuda/thrust/detail/device/cuda/copy_if.inl(151): Error: Unaligned memory accesses not supported」というメッセージが表示されます。私の知る限り、整列されていない方法でメモリにアクセスしようとしているわけではありません。何が起こっているのか、および/またはこれを修正する方法を知っている人はいますか?
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));