Thrust_interop.hpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #pragma once
  2. #include <opencv2/core/cuda.hpp>
  3. #include <thrust/iterator/permutation_iterator.h>
  4. #include <thrust/iterator/transform_iterator.h>
  5. #include <thrust/iterator/counting_iterator.h>
  6. #include <thrust/device_ptr.h>
  7. /*
  8. @Brief step_functor is an object to correctly step a thrust iterator according to the stride of a matrix
  9. */
  10. //! [step_functor]
  11. template<typename T> struct step_functor : public thrust::unary_function<int, int>
  12. {
  13. int columns;
  14. int step;
  15. int channels;
  16. __host__ __device__ step_functor(int columns_, int step_, int channels_ = 1) : columns(columns_), step(step_), channels(channels_) { };
  17. __host__ step_functor(cv::cuda::GpuMat& mat)
  18. {
  19. CV_Assert(mat.depth() == cv::DataType<T>::depth);
  20. columns = mat.cols;
  21. step = mat.step / sizeof(T);
  22. channels = mat.channels();
  23. }
  24. __host__ __device__
  25. int operator()(int x) const
  26. {
  27. int row = x / columns;
  28. int idx = (row * step) + (x % columns)*channels;
  29. return idx;
  30. }
  31. };
  32. //! [step_functor]
  33. //! [begin_itr]
  34. /*
  35. @Brief GpuMatBeginItr returns a thrust compatible iterator to the beginning of a GPU mat's memory.
  36. @Param mat is the input matrix
  37. @Param channel is the channel of the matrix that the iterator is accessing. If set to -1, the iterator will access every element in sequential order
  38. */
  39. template<typename T>
  40. thrust::permutation_iterator<thrust::device_ptr<T>, thrust::transform_iterator<step_functor<T>, thrust::counting_iterator<int>>> GpuMatBeginItr(cv::cuda::GpuMat mat, int channel = 0)
  41. {
  42. if (channel == -1)
  43. {
  44. mat = mat.reshape(1);
  45. channel = 0;
  46. }
  47. CV_Assert(mat.depth() == cv::DataType<T>::depth);
  48. CV_Assert(channel < mat.channels());
  49. return thrust::make_permutation_iterator(thrust::device_pointer_cast(mat.ptr<T>(0) + channel),
  50. thrust::make_transform_iterator(thrust::make_counting_iterator(0), step_functor<T>(mat.cols, mat.step / sizeof(T), mat.channels())));
  51. }
  52. //! [begin_itr]
  53. //! [end_itr]
  54. /*
  55. @Brief GpuMatEndItr returns a thrust compatible iterator to the end of a GPU mat's memory.
  56. @Param mat is the input matrix
  57. @Param channel is the channel of the matrix that the iterator is accessing. If set to -1, the iterator will access every element in sequential order
  58. */
  59. template<typename T>
  60. thrust::permutation_iterator<thrust::device_ptr<T>, thrust::transform_iterator<step_functor<T>, thrust::counting_iterator<int>>> GpuMatEndItr(cv::cuda::GpuMat mat, int channel = 0)
  61. {
  62. if (channel == -1)
  63. {
  64. mat = mat.reshape(1);
  65. channel = 0;
  66. }
  67. CV_Assert(mat.depth() == cv::DataType<T>::depth);
  68. CV_Assert(channel < mat.channels());
  69. return thrust::make_permutation_iterator(thrust::device_pointer_cast(mat.ptr<T>(0) + channel),
  70. thrust::make_transform_iterator(thrust::make_counting_iterator(mat.rows*mat.cols), step_functor<T>(mat.cols, mat.step / sizeof(T), mat.channels())));
  71. }
  72. //! [end_itr]