如何将 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++ 中,链接器如何找到具有已实现函数的正确文件?

如何将对象向量从类返回到 main.cpp

“属性在此上下文中受保护”具有继承和 .h 和 .cpp 文件

如何将 fltk 文件与其他文件一起编译?

如何将 .cpp 源文件编译成 .dll?

如何在 Linux 中编译 ISPC 代码并将其与普通 cpp 文件链接?