混合 cuda 和 cpp 模板和 lambda
Mixing cuda and cpp templates and lambdas
示例代码: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
你的方法有两个问题。
首先,即使参数和函数体相同,每个 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
文件中。
示例代码: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
你的方法有两个问题。
首先,即使参数和函数体相同,每个 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
文件中。