例如,如果我编写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中的入口函数,基于硬件功能测试,启动合适的内核/例程。
答案 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及更新版本的代码路径略有不同。