【问题标题】:Can i just define CUDA kernels in .h files?我可以在 .h 文件中定义 CUDA 内核吗?
【发布时间】:2014-07-26 22:51:07
【问题描述】:

我很难理解在 CUDA 程序中处理不同文件的方式:

我正在尝试重组我已经研究了一段时间的 CUDA 程序。到目前为止,它或多或少是一个单文件程序。我有 1 个 .cu 文件,其中包含所有 CUDA 代码以及主要功能。我有几个包含在内的头文件,但它们只包含非 CUDA 函数。程序变得越来越大,越来越混乱,我想将内核构建成不同的文件以提高可读性。

最初我认为这样做的方法是拥有 .cuh 文件。我没有让它工作,所以我试着了解this,它建议一个.h 文件和一个.cu 文件。但是,在其中包含其他 .cu 文件后,该程序将不再构建。它通常要么无法识别诸如“__global__”之类的 CUDA 关键字,要么会在外部包含中抛出错误,这似乎不相关。

然而,我注意到它是在我在 .h 文件中定义内核时构建的。我觉得这不是一个好主意,但不知道它有什么问题。 困扰我的是,根据我的理解,.h 文件甚至不应该由 nvcc 编译,那么它仍然如何工作? 我很难理解最好的方法是什么。

我正在使用 Visual Studio 2012 和 CUDA 5.5

【问题讨论】:

  • “最初我认为这样做的方法是拥有 .cuh 文件。我没有让它工作......” New Item -> NVIDIA CUDA -> Code -> CUDA C/C++ Header ?
  • 是的,这基本上就是我所做的:添加一个新的 .cuh,将其包含在我的主文件 (a .cu) 中并期望它能够工作。但事实并非如此。 .h 文件也是如此,并且有效。
  • 哦,cmon,您只是将措辞从“我没有让它起作用”改为“期望它起作用但它没有”:D 说真的,怎么会有人知道你的问题是什么用你的方法遇到过吗?

标签: cuda


【解决方案1】:

这里的规则和行为在概念上与 C 或 C++ 编码中允许的规则和行为没有任何不同。

对于通过#include 指令显式包含在另一个文件中的文件,文件名以及文件扩展名 - .cu.h.cuh.hpp 或者你有什么,真的没关系。这只是对编译器的一个指令,用于拾取该文件,并将其插入源代码中的这一点,就好像它已在此处键入一样。

所以像我无法让.cuh 工作但我可以让.h 工作这样的声明真的没有意义。编译器不关心文件名。 .cuh.h 之类的只是命名约定,以帮助我们组织大型代码库。

文件不会被编译,除非它们位于或包含在源模块中(例如 .cu.c.cpp 等)编译器不会单独编译头文件(预编译的头文件是另一个主题,与本次讨论无关)。只有在源模块中包含它们时才会编译它们。

在头文件中定义函数的危险在于,如果您将头文件包含在多个源模块中,则该函数将被定义(即编译)多个源模块。通常你不想要这个,因为它往往会导致多个定义错误。

如果您打算将头文件包含在一个且仅一个源模块中,则将一些代码(即定义)放入该头文件中没有真正的问题。但是头文件的典型用法是声明,而不是定义

用于本次讨论的__global__ 函数实际上与任何其他 C/C++ 函数没有什么不同。如果将内核定义包含在多个源模块中,则将内核定义放在头文件中会产生多个定义错误的风险。如果您只将它包含在一个源模块中,那么如果您想要这样做就可以了。

【讨论】:

  • 感谢您的澄清。您所写的包含工作方式的内容是有道理的,尽管它没有解释为什么“.cuh”中的相同代码不会构建,而“.h”中却可以。可能是我在 Visual Studio 中犯了一些其他错误或设置干扰。
猜你喜欢
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 2011-06-12
  • 2015-09-15
  • 1970-01-01
相关资源
最近更新 更多