【问题标题】:Problems when using cv::cuda::GpuMat with thrust and testing thrust API将 cv::cuda::GpuMat 与推力和测试推力 API 一起使用时出现问题
【发布时间】:2021-03-13 17:52:15
【问题描述】:

我想将 cv::cuda::GpuMat 传递给推力函数,我发现 this function 可用于创建索引 cv::cuda::GpuMat 的推力迭代器。我在以下代码中有 2 个问题:

#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;
    }

问题 1: 此代码无法遵守:d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred&lt;double&gt;(compare_vari)); 使用 idxBegin 和 idxEnd 可以很好地与thrust::sequence()、sort() 等一起使用,但是当将它们应用于thrust::find_if() 时,它会提示“没有运算符'=' 与这些操作数匹配”。

问题 2:

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

我想通过上面的代码检查结果,但是在调试时它说 abort() 已被调用。我想知道 d_iter 是否在设备内存中,如果是,我需要将其复制到主机内存中吗?但是我不知道如何将迭代器复制到主机内存中。

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ opencv cuda thrust


    【解决方案1】:

    问题 2:

    *//std::cout d_iter 我想通过上面的代码检查结果,但是在调试时它说 abort() 已被调用。我想知道 d_iter 是否在设备内存中,如果是,我需要将其复制到主机内存中吗?但是我不知道如何将迭代器复制到主机内存中。

    (您不想将 迭代器 复制到主机内存,您希望将 迭代器指向的内容 复制到主机内存。)

    这里的问题是您没有为有问题的device_vector 提供任何实际大小:

        thrust::device_vector<int> d_thrust_data;
    

    创建一个没有分配的空向量。因此,没有引用该向量的迭代器将指向任何有效的内容,因为没有与该向量关联的分配。如果我们修改为:

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

    我们现在已经创建了一个包含 22 个元素的向量,然后您的其余代码(包括您的 std::cout ... 语句)将是明智的。 (21 或更大也很重要,因为您的 find_if 正在寻找值 20 的元素。)

    以下代码解决了上述问题,并且对我来说似乎可以正确编译和运行:

    $ 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
    $
    

    【讨论】:

    • 感谢您的帮助。很抱歉,我发现我在问题 1 中输入了错误的代码,d_iter = thrust::find_if(d_thrust_data.begin(), d_thrust_data.end(), greater_than_value_pred(compare_vari)) can compile。它是d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred&lt;double&gt;(compare_vari)); 无法编译。我在linkhere 中使用的 idxBegin 和 idxEnd 在使用thrust::find_if() 时出错。我改变了我的帖子。
    • 您是否尝试将谓词类型从 double 更改为 int
    • 是的,我按照你的帖子改了类型,问题2就解决了。
    • 我的意思是你把这个:d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred&lt;double&gt;(compare_vari)); 改成这个:d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred&lt;int&gt;(compare_vari));
    • 是的,我已经改成这个并试过了,但它无法编译并出现错误 no operator '=' 与这些操作数匹配。
    猜你喜欢
    • 2017-02-14
    • 2016-08-19
    • 2013-07-26
    • 2014-07-01
    • 1970-01-01
    • 2019-08-29
    • 2019-04-24
    • 2016-09-02
    • 2014-08-31
    相关资源
    最近更新 更多