如何使用PyCUDA使用子内核

时间:2018-01-24 19:03:16

标签: python-3.x cuda pycuda

我的python代码有一个gpu内核函数,在一个来自主机的for循环中被多次调用,如下所示:

for i in range:   
    gpu_kernel_func(blocksize, grid)   

由于此函数调用需要多次主机和gpu设备之间的通信,这是无效的,我想将其作为

gpu_kernel_function(){  
    for(){ 
        computation } ;  
}

但这需要额外的步骤来确保网格中的所有块都同步。根据动态并行性,调用虚拟子内核应该确保每个线程(在整个网格中)应该在代码继续运行之前完成该子内核。所以我像gpu_kernel_function一样定义了另一个内核,我尝试了这个:

GPUcode = '''

\__global__ gpu_kernel_function() {... }  
\__global__ dummy_child_kernel(){ ... }
'''

gpu_kernel_function(){  
    for() {
        computation } ;  
    dummy_child_kernel(void);  
}

但是我收到了这个错误" nvcc致命:选项' - cubin(-cubin)'编译虚拟计算体系结构时不允许"

我正在使用Tesla P100(计算6.0),python 3.5,cuda.8.0.44。我正在编译我的sourcemodule:

mod = SourceModule(GPUcode, options=['-rdc=true' ,'-lcudart','-lcudadevrt','--machine=64'],arch='compute_60' )

我也尝试了compute_35,它会产生同样的错误。

1 个答案:

答案 0 :(得分:1)

错误消息明确告诉您问题所在。 compute_60virtual architecture。您无法将虚拟体系结构静态编译为机器代码。它们用于生成PTX(虚拟机汇编程序),以便运行时将JIT转换为机器代码。 PyCUDA使用CUDA工具链将代码编译为二进制有效负载(" cubin"),然后通过驱动程序API将其加载到CUDA上下文中。因此错误。

您可以通过指定有效的物理GPU目标架构来修复错误。因此,您应该将源模块构造函数调用修改为以下内容:

mod = SourceModule(GPUcode, 
                   options=['-rdc=true','-lcudart','-lcudadevrt','--machine=64'],
                   arch='sm_60' )

这应该可以解决编译错误。

但请注意,使用动态并行需要设备代码链接,我99%确定PyCUDA仍然不支持此功能,因此您很可能无法通过设置代码进行操作一个SourceModule。您可以使用PyCUDA外部的编译器手动链接您自己的cubin,然后将该cubin加载到PyCUDA中。您将找到许多如何在搜索时正确编译动态并行性的示例。