有没有办法在单个DLL中将具有不同计算功能的设备的代码混合在一起?

时间:2013-03-21 19:40:36

标签: dll cuda gpu nvidia

例如,如果我编写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中的入口函数,基于硬件功能测试,启动合适的内核/例程。

1 个答案:

答案 0 :(得分: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文件都将导出将服务的主机功能作为切入点。根据可用的硬件,使用正确的入口点将是您的应用程序。

E.g。你将拥有application_logic_sm3x.cu,它包含使用SM 3.x特性的内核和一个名为compute_sm3x(...)的常规C函数。 Application_logic_sm2x.cu将使用SM 2.x功能和包含C函数compute_sm2x(...)。

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

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