I just struggled with this for a bit so I wanted to post it somewhere where it may be helpful for someone else.
This function can be used for creating a thrust iterator that correctly indexes a cv::cuda::GpuMat.
struct step_functor : public thrust::unary_function
{
int columns;
int step;
step_functor(int columns_, int step_) : columns(columns_), step(step_) { };
__host__ __device__
int operator()(int x) const
{
int row = x / columns;
int idx = (row * step) + x % columns;
return idx;
}
};
template
thrust::permutation_iterator, thrust::transform_iterator>> GpuMatBeginItr(cv::cuda::GpuMat mat)
{
return thrust::make_permutation_iterator(thrust::device_pointer_cast(mat.ptr(0)),
thrust::make_transform_iterator(thrust::make_counting_iterator(0),
step_functor(mat.cols, mat.step / sizeof(T))));
}
template
thrust::permutation_iterator, thrust::transform_iterator>> GpuMatEndItr(cv::cuda::GpuMat mat)
{
return thrust::make_permutation_iterator(thrust::device_pointer_cast(mat.ptr(0)),
thrust::make_transform_iterator(thrust::make_counting_iterator(mat.rows),
step_functor(mat.cols, mat.step / sizeof(T))));
}
Thus performing thrust operations on rows / columns is as easy as:
cv::cuda::GpuMat d_test(h_test);
auto keyBegin = GpuMatBeginItr(d_test.col(4));
auto keyEnd = GpuMatEndItr(d_test.col(4));
auto valueBegin = GpuMatBeginItr(d_test.col(5));
thrust::sort_by_key(keyBegin, keyEnd, valueBegin);
↧