混合 cuda 和 cpp 模板和 lambda

Mixing cuda and cpp templates and lambdas

示例代码:https://github.com/Saitama10000/Mixing-cuda-and-cpp-templates-and-lambdas

示例代码无法编译。我应该在 .cu 文件中添加一个模板实例化,但我不知道该怎么做。我试过这个:

typedef float(*op)(float);
template std::vector<float> f<op>(std::vector<float> const&, op);

但我仍然得到这个编译错误:

In file included from Mixing-cuda-and-cpp-templates-and-lambdas/main.cpp:6:
Mixing-cuda-and-cpp-templates-and-lambdas/kernel.cuh:6:20: error: ‘std::vector<float> f(const std::vector<float>&, FUNC) [with FUNC = main()::<lambda(float)>]’, declared using local type ‘main()::<lambda(float)>’, is used but never defined [-fpermissive]
    6 | std::vector<float> f(std::vector<float> const& a, FUNC func);
      |                    ^
Mixing-cuda-and-cpp-templates-and-lambdas/kernel.cuh:6:20: warning: ‘std::vector<float> f(const std::vector<float>&, FUNC) [with FUNC = main()::<lambda(float)>]’ used but never defined
make[2]: *** [CMakeFiles/main.dir/build.make:82: CMakeFiles/main.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:103: all] Error 2

你的方法有两个问题。

首先,即使参数和函数体相同,每个 lambda 都有自己的类型。

例如,以下断言失败

#include <type_traits>

int main(){
    auto lambda1 = [](){};
    auto lambda2 = [](){};

    static_assert(std::is_same<decltype(lambda1), decltype(lambda2)>::value, "not same");
}

这意味着,即使您以某种方式设法使用 lambda 类型明确实例化您的模板,它也不会是您将传递给函数的 lambda 类型。这个问题可以通过使用函子而不是 lambda 来解决。定义一组可用于调用函数的仿函数,并将它们用于模板实例化。

其次,你想传递一个__host__ __device__函数。此注释是 CUDA C++ 扩展,无法使用标准 C++ 编译器进行编译。您必须改用 CUDA 编译器,它又允许您将内核和包装器放在 .cuh 文件中。