在一个应用程序中,我有一堆CUDA内核。有些使用动态并行,有些则不使用。出于提供回退选项的目的,如果不支持,或只是允许应用程序继续但具有减少/部分可用的功能,我该如何进行编译?
目前,当我在670(最大invalid device function
)上运行使用-arch=sm_35
编译但不需要计算机3.5的内核时,我得到sm_30
。
AFAIK您无法使用多个-arch=sm_*
参数并使用多个-gencode=*
也无济于事。另外,对于可分离的编译,我必须使用-dlink
创建一个额外的目标文件,但是在使用计算3.0(nvlink fatal : no candidate found in fatbinary
时由于-lcudadevrt
而无法创建,我已经需要3.5),我该如何处理?
答案 0 :(得分:2)
我相信现在CUDA 6已经解决了这个问题。
这是我的简单测试:
$ cat t264.cu
#include <stdio.h>
__global__ void kernel1(){
printf("Hello from DP Kernel\n");
}
__global__ void kernel2(){
#if __CUDA_ARCH__ >= 350
kernel1<<<1,1>>>();
#else
printf("Hello from non-DP Kernel\n");
#endif
}
int main(){
kernel2<<<1,1>>>();
cudaDeviceSynchronize();
return 0;
}
$ nvcc -O3 -gencode arch=compute_20,code=sm_20 -gencode arch=compute_35,code=sm_35 -rdc=true -o t264 t264.cu -lcudadevrt
$ CUDA_VISIBLE_DEVICES="0" ./t264
Hello from non-DP Kernel
$ CUDA_VISIBLE_DEVICES="1" ./t264
Hello from DP Kernel
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2013 NVIDIA Corporation
Built on Sat_Jan_25_17:33:19_PST_2014
Cuda compilation tools, release 6.0, V6.0.1
$
在我的情况下,设备0是Quadro5000,cc 2.0设备,设备1是GeForce GT 640,cc 3.5设备。
答案 1 :(得分:1)
我不相信有一种方法可以使用CUDA 5.5中的运行时API来完成此操作。
我能想到解决问题的唯一方法是使用驱动程序API来执行您自己的架构选择,并在运行时从不同的cubin文件加载代码。 API可以安全地混合,因此只需要使用驱动程序API完成上下文建立 - 设备选择 - 模块加载阶段。您可以在此之后使用运行时API - 内核启动时需要一些自制的语法糖,但在其他运行时API代码中不需要更改代码。