【问题标题】:Building GPL C program with CUDA module使用 CUDA 模块构建 GPL C 程序
【发布时间】:2023-03-26 18:43:01
【问题描述】:

我正在尝试修改用 C 编写的 GPL 程序。我的目标是用 CUDA 实现替换一种方法,这意味着我需要使用 nvcc 而不是 gcc 进行编译。我需要帮助来构建项目 - 而不是实施它(我认为您不需要了解任何有关 CUDA C 的信息来提供帮助)。

这是我第一次尝试更改涉及 .configure 和 Makefile 的中等复杂度的 C 项目。老实说,这是我很长时间以来第一次在 C 中做任何事情,包括涉及 gcc 或 g++ 的任何事情,所以我很迷茫。

我对学习配置和 Makefile 不是很感兴趣——这更像是一个实验。在花时间创建正确的构建脚本之前,我想看看项目实施是否顺利。 (不是不​​愿意学习必要的,只是想给出一个范围的想法)。

话虽如此,我在构建这个项目时有哪些选择?我有无数的问题...

  • 我尝试在 AC_PROG_CC 之后将“CC=nvcc”添加到 configure.in 文件。这似乎有效 - 运行 configure 和 make 的输出显示 nvcc 作为编译器。但是 make 无法使用 CUDA 内核编译源文件,无法识别 CUDA 特定的语法。我不知道为什么,希望这能奏效。

  • 是否可以使用 nvcc 编译源文件,然后在主程序的 make 过程中的链接步骤中包含它?如果是这样,怎么做? (这个问题可能没有意义——我对此真的很生疏)

  • 正确的做法是什么?

  • 有没有一种快速而肮脏的方法可以用于测试目的?

  • 是否有一些每个人都可以使用的秘密工具来设置和理解这些配置和 Makefile?这比我习惯的 Apache Ant 脚本还要糟糕(是的,我不在我的领域)

【问题讨论】:

  • 您可能错过的是文件扩展名。 nvcc 使用文件扩展名来确定哪些包含设备代码,哪些不包含 - 任何包含文件的设备代码都必须具有 .cu 扩展名才能正确编译。
  • 只是好奇,你在 CUDA 函数中做什么?
  • 关于 .cu 文件的要点。我会尝试重命名一些源文件。
  • 我正在尝试调整 fcrackzip 以在 CUDA 内核中执行。这是我选择的一个学校项目,希望它仍然在范围内,因为它不完全是家庭作业。

标签: cuda makefile nvcc


【解决方案1】:

您不需要使用 nvcc 编译所有内容。您猜测您可以使用 NVCC 编译您的 CUDA 代码并保留其他所有内容(链接除外)是正确的。这是我开始使用的方法。

  1. 添加 1 个新标头(例如 myCudaImplementation.h)和 1 个新源文件(扩展名为 .cu,例如 myCudaImplementation.cu)。源文件包含您的内核实现以及一个(主机)C 包装函数,该函数使用适当的执行配置(又名<<<>>>)和参数调用内核。头文件包含 C 包装函数的原型。让我们调用这个包装函数runCudaImplementation()

  2. 我还将在源文件中提供另一个主机 C 函数(在头文件中带有原型),该函数查询和配置存在的 GPU 设备,如果成功则返回 true,否则返回 false。我们称这个函数为configureCudaDevice()

  3. 现在在您通常调用 CPU 实现的原始 C 代码中,您可以执行此操作。

    // 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
    
  4. 现在,由于您将所有 CUDA 代码放在一个新的 .cu 文件中,您只需使用 nvcc 编译该文件。其他一切都保持不变,除了您必须链接到 nvcc 输出的目标文件。例如

    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

【讨论】:

  • 太好了,感谢您花时间解释这一点。我可以处理这种方法。
  • 你不应该使用 extern "C" 除非你只有 C 链接(例如从 .c 文件中调用它)。
  • @harrism 说用 g++ 编译的源代码可以具有 cuda 运行时 API 是否正确,例如 cudaMalloc(&p) 和 cudaMemcpy(p) - 但它不能具有内核启动,例如 foo>>(p)?
  • 对于 cuda 5.0 及更高版本:devblogs.nvidia.com/parallelforall/…
  • @user1823664 是的,这是正确的说法。但是有 cudaLaunch() API 可以在没有 &lt;&lt;&lt;&gt;&gt;&gt; 的情况下启动。
猜你喜欢
  • 1970-01-01
  • 2014-07-20
  • 2014-08-11
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
  • 2015-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多