您如何包含标准 CUDA 库以与 NVRTC 代码链接?

Posted

技术标签:

【中文标题】您如何包含标准 CUDA 库以与 NVRTC 代码链接?【英文标题】:How do you include standard CUDA libraries to link with NVRTC code? 【发布时间】:2018-08-06 19:19:10 【问题描述】:

具体来说,我的问题是我的 CUDA 代码需要 <curand_kernel.h> 才能运行。默认情况下,这不包含在 NVRTC 中。大概然后在创建程序上下文时(即调用nvrtcCreateProgram),我必须发送文件名(curand_kernel.h)以及curand_kernel.h的源代码?我觉得我不应该这样做。

很难说;我还没有设法从 NVIDIA 找到一个需要像这样的标准 CUDA 文件作为源的示例,所以我真的不明白语法是什么。一些问题:curand_kernel.h 还包含...我是否必须对这些中的每一个都做同样的事情?我什至不确定 NVRTC 编译器是否会在 curand_kernel.h 上正确运行,因为它不支持某些语言功能,不是吗?

下一步:如果你已经将头文件的源代码发送到nvrtcCreateProgram,我是否还要在要执行的代码中#include它/这样做会导致错误吗?

执行此操作或类似操作的示例代码的链接将比简单的答案更受欢迎;我真的没找到。

【问题讨论】:

【参考方案1】:

您必须分别发送“文件名”和每个标头的来源。

当预处理器完成它的工作时,它会使用任何 #include 文件名作为键来根据您提供的集合查找标头的源。

我怀疑,在这种情况下,编译器(驱动程序)没有文件系统访问权限,因此您必须以与 OpenGL 中包含着色器的方式大致相同的方式为其提供源代码。

所以:

在调用 nvrtcCreateProgram 时包含您的标题名称。编译器将在内部生成等同于 std::map<string,string> 的内容,其中包含由给定名称索引的每个标头的源代码。

在你的内核源代码中,像往常一样使用#include "foo.cuh"

编译器将使用foo.cuh 作为其内部映射(在调用nvrtcCreateProgram 时创建)的索引或键,并从该集合中检索标头源

编译正常进行。

nvrtc 仅提供“子集”功能的一个原因是编译器在某种沙盒环境中运行,而不必拥有离线编译所拥有的所有支持工具和实用程序。因此,您必须手动处理普通nvcc + (gcc | MSVC| clang) 组合提供的很多东西。

一种可能但不理想的解决方案是在 IDE 中预处理您需要的文件,保存结果然后#include。但是,我敢打赌,有更好的方法可以做到这一点。如果您只想要curand,请考虑深入库并提取您需要的部分(blech)或使用另一个GPU 友好的rand 实现。在较旧的 CUDA 版本上,我只是在主机上生成了大量随机浮点数,将其上传到 GPU,然后在内核中对其进行采样。

This related link may be helpful.

【讨论】:

嗯。所以我有一些想法要做关于我如何做到这一点。将使用 curand 的代码预编译到 PTX 中是不可行的......在 CPU 上预生成浮点数是不可行的,因为需要太多......所以我只能通过 curand 库工作获取我需要使用 NVRTC 编译的部分,并找到另一个 rand 实现。因为我真正需要的只是从 0 到 1 的标准统一 PRNG,所以我认为解决方案是找到另一个使用 NVRTC 更容易编译的 PRNG,谢谢! 嗯。 PRNG 的 GPU 实现很难实现。也许我将不得不以某种方式适应 CURAND... @BillySmith 最直接的解决方案是构建一个大缓冲区并使用 rand() 或类似的 CPU 端填充它,然后将其上传到主机。保留一个索引变量,指示缓冲区中“下一个”的值。当你到达缓冲液的末端时,冲洗并重复。

以上是关于您如何包含标准 CUDA 库以与 NVRTC 代码链接?的主要内容,如果未能解决你的问题,请参考以下文章

您可以为您的组织托管一个私有存储库以与 npm 一起使用吗?

将 CUDA-gdb 与 NVRTC 一起使用

NVRTC 编译何时应生成 CUBIN?

NVRTC 对 Win32 不可用吗?

0_Simple__matrixMul + 0_Simple__matrixMul_nvrtc

NVCC 和 NVRTC 在编译到 PTX 上的区别