如何将 cuPrintf 与 .cpp 文件中具有 main() 的 cuda 项目一起使用?
Posted
技术标签:
【中文标题】如何将 cuPrintf 与 .cpp 文件中具有 main() 的 cuda 项目一起使用?【英文标题】:How to do you use cuPrintf with cuda projects that have the main() in a .cpp file? 【发布时间】:2012-04-30 04:21:51 【问题描述】:所以我正在尝试加速一些碰撞检测代码,该代码使用 SDL 将一些碰撞球绘制到 Mac OS X 中的表面/窗口。我可以进行碰撞并以顺序方式绘制东西已经很好了。我希望能够使用 cuPrintf 调试 cuda 版本,但由于我的 main() 不在 .cu 文件中,我无法让它工作。所以无法初始化cuPrintf,也无法打印缓冲区。如果我创建几个外部“C”函数并将它们构建到 .cpp 文件中,我什么也得不到。如果我尝试将包装函数与我的 cuda 代码的其余部分一起放在 .cu 文件中,我会收到“错误:不支持使用外部函数......”。 我在较小的项目中使用过它,所有内容都在一个大的 .cu 文件中,效果很好。但是这次我不能这样做,因为我必须将 SDL 和 cuda 代码分开,并且 SDL 也必须进入 main()。
其他人有过这个问题吗?
【问题讨论】:
我不确定,因为我已经从那个项目中删除了 cuPrint 东西,但它可能是我在非 Fermi 卡上定义了 Fermi 架构。我将 -arch=sm_20 传递给 nvcc 命令以消除一堆关于假设设备上的指针指向全局内存的无用警告。我之前必须使用它来启用双精度,但我去了一个旧项目并验证了 cuPrint 在这些条件下不起作用。我将在我当前的项目中重新实现它,然后带着结果返回这里。 我上面的评论是正确的。我没有从 cuPrintf 获得输出,因为我正在强制编译 Fermi 架构(编译时将标志 -arch=sm_20 传递给 nvcc)。下面是一个代码示例,说明我如何解决我需要在 .cpp 文件的 main() 函数中实现它的事实。 【参考方案1】:我基本上为 cuPrintf 提供的 3 个调用创建了一个包装器,这些调用需要放在主函数中。在我的 kernel.cu 文件中,我定义了一些外部“C”函数。然后在 main.cpp 中,我声明它们将它们纳入范围。
在 kernel.cu 中:
// Include section
#include "cuPrintf.cu"
//define all __device__ and __global__ functions for the kernel here
extern "C"
void LaunchKernel(<type> *input) kernel<<< grid, dim >>>(input);
void InitCuPrintf() cudaPrintfInit();
void DisplayCuPrintf() cudaPrintfDisplay(stdout, 1);
void EndCuPrintf() cudaPrintfEnd();
在 main.cpp 中:
// you do NOT need to include any cuPrintf files here. Just in the kernel.cu file
#include <SDL.h> // this is the library requiring me to do this stuff ...
#include "SDL_helper.h" // all of the SDL functions I defined are separated out
#include <cuda_runtime.h>
// in global space
extern "C"
void LaunchKernel(struct circle *circles);
void InitCuPrintf();
void DisplayCuPrintf();
void EndCuPrintf();
int main(nt argc, char **argv)
// put these where you would normally place the cuPrintf functions they correspond to
InitCuPrintf();
// I left his in here because if you're needing to do this for cuPrintf, you prolly need
// need a wrapper to lauch your kernel from outside the .cu file as well.
LaunchKernel( input );
DisplayCuPrintf();
// SDL functions from SDL.h and SDL_helper.h would be in here somewhere
EndCuPrintf()
就是这样!我在我的项目目录中制作了 cuPrintf.cu 和 cuPrintf.cuh 的副本,因此我不必在编译中链接到某个随机目录。我的 nvcc / g++ 命令如下。我在 MAC 上编码,所以它们是 Mac OS X 特定的......
nvcc ./kernel.cu -I./ -I/usr/local/cuda/include/ -c -m64
g++ ./main.cpp -I./ -I/usr/include/ -I/usr/local/cuda/include/ -L/usr/local/cuda/lib/ -lcudart -LSDLmain -lSDL -framework Cocoa ./SDL_helper.o ./kernel.o
注意:我将所有 SDL 函数分离到一个单独的 SDL_helper.c 文件中,我在运行 nvcc 之前编译了该文件:
g++ ./SDL_helper.c -I./ -c
我希望这对其他人有帮助。
【讨论】:
以上是关于如何将 cuPrintf 与 .cpp 文件中具有 main() 的 cuda 项目一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
在 C 和 C++ 中,链接器如何找到具有已实现函数的正确文件?