我正在尝试修改用C编写的GPL程序。我的目标是用CUDA实现替换一个方法,这意味着我需要使用nvcc而不是gcc进行编译。我需要帮助构建项目 - 不实现它(你不需要了解CUDA C的任何帮助,我不认为)。
这是我第一次尝试更改涉及.configure和Makefile的中等复杂度的C项目。老实说,这是我第一次用C做很长时间的事情,包括任何涉及gcc或g ++的事情,所以我很遗憾。
我对学习configure和Makefiles并不是很感兴趣 - 这更像是一个实验。我想在花费时间创建正确的构建脚本之前看看项目实现是否顺利。 (并不是不愿意在必要时学习,只是试图了解范围)。
话虽如此,我有什么选择来构建这个项目?我有无数的问题......
我尝试在AC_PROG_CC之后将“CC = nvcc”添加到configure.in文件中。这似乎工作 - 从运行configure和make输出显示nvcc作为编译器。但是,无法使用CUDA内核编译源文件,而无法识别CUDA特定语法。我不知道为什么,希望这会有效。
是否可以使用nvcc编译源文件,然后将其包含在主程序的make过程的链接步骤中?如果是这样,怎么样? (这个问题可能没有意义 - 我真的生气了)
这样做的正确方法是什么?
我可以使用快速而肮脏的方式进行测试吗?
每个人都使用一些秘密工具来设置和理解这些配置和Makefile吗?这比我习惯的Apache Ant脚本更糟糕(是的,我不在我的境界)
答案 0 :(得分:19)
您不需要使用nvcc编译所有内容。您猜测您可以使用NVCC编译CUDA代码并保留其他所有内容(链接除外)是正确的。这是我用来开始的方法。
添加1个新标题(例如myCudaImplementation.h)和1个新的源文件(扩展名为.cu,例如myCudaImplementation.cu)。源文件包含内核实现以及(主机)C包装函数,该函数使用适当的执行配置(即<<<>>>
)和参数调用内核。头文件包含C包装函数的原型。我们称之为包装函数runCudaImplementation()
我还会在源文件中提供另一个主机C函数(标题中有原型),查询和配置存在的GPU设备,如果成功则返回true,否则返回false。我们称这个函数为configureCudaDevice()
。
现在,在您原来的C代码中,您通常可以调用CPU实现。
// must include your new header
#include "myCudaImplementation.h"
// at app initialization
// store this variable somewhere you can access it later
bool deviceConfigured = configureCudaDevice;
...
// then later, at run time
if (deviceConfigured)
runCudaImplementation();
else
runCpuImplementation(); // run the original code
现在,由于您将所有CUDA代码放在新的.cu文件中,因此您只需使用nvcc编译该文件。除了你必须在nvcc输出的目标文件中链接外,其他所有内容都保持不变。 e.g。
nvcc -c -o myCudaImplementation.o myCudaImplementation.cu <other necessary arguments>
然后将myCudaImplementation.o添加到您的链接行(类似:) g ++ -o myApp myCudaImplementation.o
现在,如果你有一个复杂的应用程序使用configure并且已经有一个复杂的makefile,它可能比上面更复杂,但这是一般的方法。最重要的是你不想用nvcc编译所有的源文件,只需要编译.cu文件。将主机编译器用于其他所有事情。
我不是配置专家所以不能真正帮助那里。您可以运行configure来生成一个makefile,然后编辑该makefile - 它不是一般的解决方案,但它会帮助您入门。
请注意,在某些情况下,您可能还需要将.cu
文件的编译与链接它们分开。在这种情况下,您需要使用NVCC的单独编译和链接功能,this blog post might be helpful。