将 cv::cuda::GpuMat 与推力和测试推力 API 一起使用时出现问题
Posted
技术标签:
【中文标题】将 cv::cuda::GpuMat 与推力和测试推力 API 一起使用时出现问题【英文标题】:Problems when using cv::cuda::GpuMat with thrust and testing thrust 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<double>(compare_vari));
使用 idxBegin 和 idxEnd 可以很好地与thrust::sequence()、sort() 等一起使用,但是当将它们应用于thrust::find_if() 时,它会提示“没有运算符'=' 与这些操作数匹配”。
问题 2:
*//std::cout << *d_iter << std::endl;*
我想通过上面的代码检查结果,但是在调试时它说 abort() 已被调用。我想知道 d_iter 是否在设备内存中,如果是,我需要将其复制到主机内存中吗?但是我不知道如何将迭代器复制到主机内存中。
任何帮助将不胜感激。
【问题讨论】:
【参考方案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<double>(compare_vari));
无法编译。我在linkhere 中使用的 idxBegin 和 idxEnd 在使用thrust::find_if() 时出错。我改变了我的帖子。
您是否尝试将谓词类型从 double
更改为 int
?
是的,我按照你的帖子改了类型,问题2就解决了。
我的意思是你把这个:d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred<double>(compare_vari));
改成这个:d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred<int>(compare_vari));
是的,我已经改成这个并试过了,但它无法编译并出现错误 no operator '=' 与这些操作数匹配。以上是关于将 cv::cuda::GpuMat 与推力和测试推力 API 一起使用时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 cmak 在 qt creator 中使用 opencv Cuda
cuda 推力::for_each 与推力::counting_iterator