我有一个虚函数,根据派生类的不同返回不同的lambda表达式:
class Base
{
public:
virtual std::function<float()> foo(void) = 0;
};
class Derived : public Base
{
public:
std::function<float()> foo(void) {
return [] __device__ (void) {
return 1.0f;
};
}
};
我想将这个 lambda 函数传递给 CUDA 核并从设备上调用它。换句话说,我想做到这一点:
template<typename Func>
__global__ void kernel(Func f) {
f();
}
int main(int argc, char** argv)
{
Base* obj = new Derived;
kernel<<<1, 1>>>(obj->foo());
cudaDeviceSynchronize();
return 0;
}
以上代码出现了如下错误:
从 __global__ 函数("kernel< ::std::function<float ()> > ") 调用 __host__ 函数("std::function<float ()> ::operator ()") 是不允许的
。可以看到,lambda被声明为
__device__
,但是foo()
方法将其存储在std::function
中以便返回它。因此,传递给kernel()
的是主机地址,当然无法工作。这就是我的问题所在,对吧?所以我有以下问题:
是否有可能创建一个
__device__ std::function
并从foo()
方法中返回它?如果不可能,是否有其他方法动态选择lambda并将其传递给CUDA kernel?硬编码多次调用
kernel()
以包含所有可能的lambda选项不是一个选择。
提前感谢。
std::function
,这就是编译错误的来源。 - talonmies__device__
lambda作为内核参数/参数肯定是可行的,但你可能正在使用std::function
,因为你想要“泛型化”它 - 你不喜欢每个lambda都有一个唯一的类型。我不认为你能用std::function
来解决这个问题。使用functor可能会更容易些。 - Robert Crovella