不允许从 __host__ __device__ 函数调用 __host__ 函数
calling a __host__ function from a __host__ __device__ functon is not allowed
我正尝试在 Opencv 中使用 thrust 类。最终代码会更复杂,包括使用设备内存,但这个简单的例子没有成功构建。
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
//#include <thrust/copy.h>
#include <thrust/remove.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/cudaarithm.hpp>
#include <iostream>
struct is_zero
{
__host__ __device__
bool operator()(const cv::KeyPoint x)
{
return x.response == 0.0;
}
};
int main(void){
cv::KeyPoint h_data[5];
h_data[0]= cv::KeyPoint(cv::Point2f(3,4),0.3);
h_data[1]= cv::KeyPoint(cv::Point2f(2,6),0.3);
h_data[2]= cv::KeyPoint(cv::Point2f(1,1),0.3);
h_data[3]= cv::KeyPoint(cv::Point2f(2,8),0.3);
h_data[4]= cv::KeyPoint(cv::Point2f(2,6),0.3);
h_data[0].response=0.3;
h_data[1].response=0.0;
h_data[2].response=0.5;
h_data[3].response=0.0;
h_data[4].response=0.6;
cv::KeyPoint *new_data_end = thrust::remove_if(h_data, h_data + 5, is_zero()); //this does not work
}
如您所见,我什至没有将主机内存变量传递给设备内存或任何东西。
当我尝试构建时,我得到了
/usr/local/cuda/include/thrust/system/cuda/detail/par.h(141): warning: calling a __host__ function("cv::Point_<float> ::Point_") from a __host__ __device__ function("cv::KeyPoint::KeyPoint") is not allowed
/usr/local/cuda/include/thrust/system/cuda/detail/par.h(141): warning: calling a __host__ function("cv::Point_<float> ::Point_") from a __host__ __device__ function("cv::KeyPoint::KeyPoint [subobject]") is not allowed
/usr/local/cuda/include/thrust/system/cuda/detail/par.h(141): warning: calling a __host__ function("cv::Point_<float> ::operator =") from a __host__ __device__ function("cv::KeyPoint::operator =") is not allowed
如何将 thrust remove_if 与 opencv 类 一起使用?
(我的计划是以后用remove_if和cv::KeyPoint
的数组)
正如评论中所指出的,对于您显示的代码,您会收到一个警告并且这个警告可以安全忽略。
在 CUDA 设备代码中的使用:
对于要在 CUDA 设备代码中使用的 C++ class,将在 CUDA 设备代码中显式或隐式使用的任何相关成员函数,must be marked 与 __device__
装饰器. (有一些例外,例如此处不适用的默认构造函数。)
您尝试使用的 OpenCV class (cv::KeyPoint
) 不满足这些在设备代码中使用的要求。它不能按原样使用。
可能有几个选项:
使用 cv::KeyPoint
重铸您的作品,以使用一些 class 提供类似的功能,您自己编写,以适当的方式设计和装饰。
也许在这里看看用 CUDA 构建的 OpenCV 是否有替代版本(正确的是 designed/decorated)(我猜它可能没有)
重写 OpenCV 本身,考虑所有必要的设计更改,以允许 cv::KeyPoint
class 在设备代码中可用。
作为建议 1 的变体,将相关数据 .response
复制到一组单独的 classes 或只是一个裸数组,并根据您的选择工作那。那里完成的选择工作可以用来“过滤”原始数组。
我正尝试在 Opencv 中使用 thrust 类。最终代码会更复杂,包括使用设备内存,但这个简单的例子没有成功构建。
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
//#include <thrust/copy.h>
#include <thrust/remove.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/cudaarithm.hpp>
#include <iostream>
struct is_zero
{
__host__ __device__
bool operator()(const cv::KeyPoint x)
{
return x.response == 0.0;
}
};
int main(void){
cv::KeyPoint h_data[5];
h_data[0]= cv::KeyPoint(cv::Point2f(3,4),0.3);
h_data[1]= cv::KeyPoint(cv::Point2f(2,6),0.3);
h_data[2]= cv::KeyPoint(cv::Point2f(1,1),0.3);
h_data[3]= cv::KeyPoint(cv::Point2f(2,8),0.3);
h_data[4]= cv::KeyPoint(cv::Point2f(2,6),0.3);
h_data[0].response=0.3;
h_data[1].response=0.0;
h_data[2].response=0.5;
h_data[3].response=0.0;
h_data[4].response=0.6;
cv::KeyPoint *new_data_end = thrust::remove_if(h_data, h_data + 5, is_zero()); //this does not work
}
如您所见,我什至没有将主机内存变量传递给设备内存或任何东西。
当我尝试构建时,我得到了
/usr/local/cuda/include/thrust/system/cuda/detail/par.h(141): warning: calling a __host__ function("cv::Point_<float> ::Point_") from a __host__ __device__ function("cv::KeyPoint::KeyPoint") is not allowed
/usr/local/cuda/include/thrust/system/cuda/detail/par.h(141): warning: calling a __host__ function("cv::Point_<float> ::Point_") from a __host__ __device__ function("cv::KeyPoint::KeyPoint [subobject]") is not allowed
/usr/local/cuda/include/thrust/system/cuda/detail/par.h(141): warning: calling a __host__ function("cv::Point_<float> ::operator =") from a __host__ __device__ function("cv::KeyPoint::operator =") is not allowed
如何将 thrust remove_if 与 opencv 类 一起使用?
(我的计划是以后用remove_if和cv::KeyPoint
的数组)
正如评论中所指出的,对于您显示的代码,您会收到一个警告并且这个警告可以安全忽略。
在 CUDA 设备代码中的使用:
对于要在 CUDA 设备代码中使用的 C++ class,将在 CUDA 设备代码中显式或隐式使用的任何相关成员函数,must be marked 与 __device__
装饰器. (有一些例外,例如此处不适用的默认构造函数。)
您尝试使用的 OpenCV class (cv::KeyPoint
) 不满足这些在设备代码中使用的要求。它不能按原样使用。
可能有几个选项:
使用
cv::KeyPoint
重铸您的作品,以使用一些 class 提供类似的功能,您自己编写,以适当的方式设计和装饰。也许在这里看看用 CUDA 构建的 OpenCV 是否有替代版本(正确的是 designed/decorated)(我猜它可能没有)
重写 OpenCV 本身,考虑所有必要的设计更改,以允许
cv::KeyPoint
class 在设备代码中可用。作为建议 1 的变体,将相关数据
.response
复制到一组单独的 classes 或只是一个裸数组,并根据您的选择工作那。那里完成的选择工作可以用来“过滤”原始数组。