요소가 여러 제약 조건을 준수하면 벡터에서 요소의 색인을 추출하는 데 Thrust의 스트림 압축 기능 (copy_if)을 사용하고 싶습니다. 이러한 제한 중 하나는 인접 요소의 값에 따라 다릅니다 (2D는 8, 3D는 26). 내 질문은 : 추력에서 요소의 이웃을 어떻게 얻을 수 있습니까? 같은이웃에 대한 추력 접근
'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 커널을 실행하여 주위에 작업-A를 사용 요소를 적절하게 표시 할 수 있습니다. 그 후, 표시된 요소를 Thrust의 copy_if에 전달하여 표시된 요소의 색인을 추출합니다.
I는 직접 처리 요소의 인덱스를 취득하고 threadIdx blockIdx를 사용하는 대신에 일종의 counting_iterator 우연히. 아래의 솔루션을 시도했지만 컴파일 할 때 "/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));
전역 배열의 주소를 Functor 클래스의 생성자에 제공 할 수 있습니다. 또한 threadIdx.x에 액세스 할 수 있으며 위의 __device__ 메소드에서 공유 메모리를 사용할 수도 있습니다 (생각한 경우 공유 메모리를 사용해야합니다). – phoad
전역 배열에 대한 포인터를 펑터 생성자에 전달한 다음이를 멤버 변수로 저장할 수 있습니다. 하지만 그건 내 문제를 해결하지 못할 것이다. 그렇다면 전역 배열의 어떤 요소에 액세스해야합니까? 나는 x에 대한 포인터가 아니라 내 처분에 대한 float x를 가진다. 공유 메모리를 사용하는 경우 필자의 경우에는 필요하지 않습니다. 한 번만 데이터를로드하고 특정 값을 확인하십시오. – Bart
Thrust의 Zip 반복자는 전역 배열에서 float 값의 위치를 찾는 문제를 해결할 수 있습니다. threadIdx.x 값을 사용할 수도 있지만 조금 다르게 접근해야합니다. 위쪽, 왼쪽, 오른쪽, 아래 등이 필요하기 때문에 공유 메모리를 사용하면 값당 필요한 데이터가 겹치기 때문에 공유 메모리를 사용하여 전역 메모리에서 레지스터로 한 번만로드 할 수 있습니다 (전역 mem 캐시 괜찮을 수도 있습니다). – phoad