微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

不允许从 __host__ __device__ 函数调用 __host__ 函数

如何解决不允许从 __host__ __device__ 函数调用 __host__ 函数

我正在尝试在 Opencv 类中使用推力。最终的代码会更复杂,包括使用设备内存,但这个简单的例子没有成功构建。

#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,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

如何在 opencv 类中使用推力 remove_if?

(我的计划是将来使用带有 cv::KeyPoint 数组的 remove_if)

解决方法

正如评论中指出的那样,对于您显示的代码,您收到了警告,可以安全地忽略此警告。

用于 CUDA 设备代码:

对于可在 CUDA 设备代码中使用的 C++ 类,将在 CUDA 设备代码中显式或隐式使用的任何相关成员函数,带有 __device__ 装饰器的 must be marked。 (有一些例外,例如默认构造函数在这里不适用。)

您尝试使用的 OpenCV 类 (cv::KeyPoint) 不满足在设备代码中使用的这些要求。它将无法按原样使用。

可能有几个选项:

  1. 也许看看用 CUDA 构建的 OpenCV 是否有替代版本(正确设计/装饰)(我猜它可能没有)

  2. 重写 OpenCV 本身,考虑所有必要的设计更改,以允许 cv::KeyPoint 类在设备代码中可用。

  3. 作为建议 1 的变体,将相关数据 cv::KeyPoint 复制到一组单独的类或只是一个裸数组,然后根据它进行选择工作。在那里完成的选择工作可以用来“过滤”原始数组。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。