0
votes

I want to pass cv::cuda::GpuMat to thrust function and I find this function which can be used for creating a thrust iterator that indexes a cv::cuda::GpuMat. I have 2 problems in the following code:

#include <stdio.h>
#include<io.h>
#include <stdlib.h>
#include <fstream>
#include<string>
#include<iostream>
#include <time.h>
#include <vector> 
  
#include <cuda_runtime.h>
#include "device_launch_parameters.h"

#include <thrust/host_vector.h>
#include<thrust/functional.h>
#include <thrust/device_vector.h>
#include <thrust/generate.h>
#include <thrust/sort.h>
#include <thrust/copy.h>

#include<opencv2/opencv.hpp>
#include<cudaimgproc.hpp>
#include<opencv2/cudafilters.hpp>
#include<opencv2/cudaarithm.hpp>


template<typename T>
    struct greater_than_value_pred
    {
        T value;
    greater_than_value_pred(T value) : value(value) {}

    __host__ __device__
        bool operator()(T v) const { return v > value; }
};

    using namespace std;


    int main()
    {
        int compare_vari = 20;
    
    
        cv::cuda::GpuMat d_data_open(1, 100, CV_32SC2);
        // Thrust compatible begin and end iterators to channel 0 of this matrix
        auto idxBegin = GpuMatBeginItr<int>(d_data_open, 1);
        auto idxEnd = GpuMatEndItr<int>(d_data_open, 1);
        // Fill the index channel with a sequence of numbers from 0 to 100
        thrust::sequence(idxBegin, idxEnd);
        d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred<int>(compare_vari));

        /*Use thrust::device_data to test */
        thrust::device_vector<int> d_thrust_data;
        thrust::device_vector<int>::iterator d_iter;
        thrust::sequence(d_thrust_data.begin(), d_thrust_data.end());
        d_iter = thrust::find_if(d_thrust_data.begin(), d_thrust_data.end(), greater_than_value_pred<int>(compare_vari));
        //std::cout << *d_iter << std::endl;
    }

Question 1: This code cannot complie: d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred<double>(compare_vari)); Using idxBegin and idxEnd works well with thrust::sequence(), sort() and so on, but when applying them to thrust::find_if(), it will hint "no operator '=' matches these operands".

Question 2:

*//std::cout << *d_iter << std::endl;*

I want to check the result by the above code, but when debugging it says abort() has been called. I wonder if d_iter is in device memory, if so I need to copy it to host memory? But I don't know how to copy iterator to the host memory.

Any help will be appreciated.

1

1 Answers

1
votes

Question 2:

*//std::cout << d_iter << std::endl; I want to check the result by the above code, but when debugging it says abort() has been called. I wonder if d_iter is in device memory, if so I need to copy it to host memory? But I don't know how to copy iterator to the host memory.

(You don't want to copy the iterator to host memory, what you desire is to copy what the iterator points to to host memory.)

The issue here is that you are not giving any actual size to the device_vector in question:

    thrust::device_vector<int> d_thrust_data;

that creates an empty vector with no allocation. Therefore no iterator referencing that vector will point to anything valid, because there is no allocation associated with that vector. If we modify it to:

    thrust::device_vector<int> d_thrust_data(22);

we have now created a vector with 22 elements, and the rest of your code, including your std::cout ... statement, will then be sensible. (21 or larger is also important because your find_if is looking for an element of value 20.)

The following code has the above issues addressed and seems to compile and run correctly for me:

$ cat t100.cu
#include <stdio.h>
#include <stdlib.h>

#include <thrust/host_vector.h>
#include <thrust/functional.h>
#include <thrust/device_vector.h>
#include <thrust/generate.h>
#include <thrust/sort.h>
#include <thrust/copy.h>


template<typename T>
    struct greater_than_value_pred
    {
        T value;
    greater_than_value_pred(T value) : value(value) {}

    __host__ __device__
        bool operator()(T v) const { return v > value; }
};

    using namespace std;


    int main()
    {
        int compare_vari = 20;

        /*Use thrust::device_data to test */
        thrust::device_vector<int> d_thrust_data(22);
        thrust::device_vector<int>::iterator d_iter;
        thrust::sequence(d_thrust_data.begin(), d_thrust_data.end());
        d_iter = thrust::find_if(d_thrust_data.begin(), d_thrust_data.end(), greater_than_value_pred<int>(compare_vari));
        std::cout << *d_iter << std::endl;
    }
$ nvcc -o t100 t100.cu
$ ./t100
21
$