【问题标题】:Mixing cuda and cpp templates and lambdas混合 cuda 和 cpp 模板和 lambda
【发布时间】:2023-04-01 21:33:01
【问题描述】:

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

  • 我想在 .cu 文件中拥有一个内核,该文件将扩展的 __host__ __device__lambda 作为参数并使用它来操作数据。
  • 我正在使用.cuh 文件将内核执行包装在包装函数中。
  • 我将.cuh 文件包含在main.cpp 中,并使用包装函数进行计算。
  • 我需要这种.cuh, .cu 类型的代码组织
  • 我使用的是 c++20

示例代码无法编译。我应该在.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

【问题讨论】:

  • 为什么不把内核和包装函数放到.cuh文件中呢?
  • 因为我得到:In file included from Mixing-cuda-and-cpp-templates-and-lambdas/main.cpp:8: Mixing-cuda-and-cpp-templates-and-lambdas/kernel.cuh: In function ‘std::vector&lt;float&gt; wrapper(const std::vector&lt;float&gt;&amp;, FUNC)’: Mixing-cuda-and-cpp-templates-and-lambdas/kernel.cuh:35:13: error: expected primary-expression before ‘&lt;’ token 35 | kernel&lt;&lt;&lt;256, 256&gt;&gt;&gt;(da, db, a.size(), func); | ^ Mixing-cuda-and-cpp-templates-and-lambdas/kernel.cuh:35:24: error: expected primary-expression before ‘&gt;’ token 35 | kernel&lt;&lt;&lt;256, 256&gt;&gt;&gt;(da, db, a.size(), func);
  • 你用 CUDA 编译器编译 main.cpp 吗?
  • 不,我不是。如果我这样做,它适用于这个示例,但对于其他较大的项目,它会给出奇怪的错误。

标签: c++ lambda cuda


【解决方案1】:

你的方法有两个问题。

首先,每个 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 文件中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-24
    • 2019-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    相关资源
    最近更新 更多