0

例如,如果我编写了一个 CUDA 库,有一些函数使用了一些独有的 SM 3.X 特性(例如,shuffle 内在函数)。

而其他功能仅使用 SM 2.X 功能。

我想将所有这些 lib 函数编译成一个 DLL 并让 DLL 在运行时选择适当的函数,这在 CUDA 中可能吗?

像:

static __global__ void Kernel_SM2x(void)
//...
static __global__ void Kernel_SM3x(void)
//...

使用 DLL 中的入口函数,基于硬件特性测试,启动合适的内核/例程。

4

1 回答 1

0

如果您有相同的条目点(例如内核名称、启动参数、参数相同),那么您可以依赖预编译器(这是来自 grabCut CUDA SDK 示例):

#if __CUDA_ARCH__ < 200
        unsigned int gmm_flags_bvec = 0;
        for (int i=0; i<32; ++i)
        {
            if (gmm_flags[i] > 0)
            {
                gmm_flags_bvec |= 1 << i;
            }
        }
        tile_gmms[blockIdx.y * gridDim.x + blockIdx.x] = gmm_flags_bvec;
#else
        tile_gmms[blockIdx.y * gridDim.x + blockIdx.x] = __ballot(gmm_flags[threadIdx.x] > 0);
#endif

那么你必须将几个 -gencode 参数传递给 NVCC - 它会构建不同的内核并将它们包含在你的可执行文件中。当应用程序运行时,驱动程序将自动为您的设备选择正确的内核。

然后,如果您的主机代码在不同的设备架构之间有所不同(例如,如果设备真的很旧,您可以在设备上执行较少的操作),您可以为不同的计算能力创建多个 CU - 并且每个 CU 文件都将导出主机函数作为条目观点。根据可用硬件使用正确的入口点将是您的应用程序的责任。

例如,您将拥有 application_logic_sm3x.cu,其中包含使用 SM 3.x 功能的内核和一个名为 compute_sm3x(...) 的常规 C 函数。Application_logic_sm2x.cu 将使用 SM 2.x 功能和一个名为 compute_sm2x(...) 的包含 C 函数。

您的 main.cpp 函数将使用 cudaGetDeviceProperties,然后根据可用硬件调用 compute_sm3x 或 compute_sm2x。

更新您可以查看 CUDA Toolkit 5.0 中的 simplePrintf 示例 - 它对于 1.x 和 2.x 及更高版本的代码路径略有不同。

于 2013-03-21T21:10:54.933 回答