PyCUDA或者未能找到函数在NVIDIA源代码或抛出“可以不具有外部的‘C’链接”的错误(PyCU

2019-10-19 06:24发布

我想使用(和学习), 马克·哈里斯的优化减少内核 ,通过复制自己的源代码转换成一个简单的pycuda应用程序(我尝试下面列出的全部源代码)。

不幸的是,我遇到以下两种错误回报之一。

  1. 在CUDA内核不能编译,抛出以下错误消息。

     kernel.cu(3): error: this declaration may not have extern "C" linkage 
  2. 如果我包括参数no_extern_c=True成编译内核行,以下引发错误:

     pycuda._driver.LogicError: cuModuleGetFunction failed: not found 

我也尝试过包装modStr的内容extern "C" { [...] }no_extern_c变量设置为真或假,没有任何成功。

这个问题似乎涉及线路template <unsigned int blockSize> ,如果我评论的函数体出它仍然引起错误。 但我不明白的问题不够好,对如何解决它的任何更多的想法。

任何意见/建议/帮助将非常赞赏 - 在此先感谢!

from pylab import *

import pycuda.gpuarray as gpuarray
import pycuda.autoinit
import pycuda.driver as drv
from pycuda.compiler import SourceModule

modStr = """
template <unsigned int blockSize>
__global__ void reduce6(int *g_idata, int *g_odata, unsigned int n) {
    extern __shared__ int sdata[];
    unsigned int tid = threadIdx.x;
    unsigned int i = blockIdx.x*(blockSize*2) + tid;
    unsigned int gridSize = blockSize*2*gridDim.x;
    sdata[tid] = 0;
    while (i < n) { 
        sdata[tid] += g_idata[i] + g_idata[i+blockSize]; i += gridSize; 
    }
    __syncthreads();
    if (blockSize >= 512) { if (tid < 256) { sdata[tid] += sdata[tid + 256]; } __syncthreads(); }
    if (blockSize >= 256) { if (tid < 128) { sdata[tid] += sdata[tid + 128]; } __syncthreads(); }
    if (blockSize >= 128) { if (tid < 64) { sdata[tid] += sdata[tid + 64]; } __syncthreads(); }
    if (tid < 32) {
        if (blockSize >= 64) sdata[tid] += sdata[tid + 32];
        if (blockSize >= 32) sdata[tid] += sdata[tid + 16];
        if (blockSize >= 16) sdata[tid] += sdata[tid + 8];
        if (blockSize >= 8) sdata[tid] += sdata[tid + 4];
        if (blockSize >= 4) sdata[tid] += sdata[tid + 2];
        if (blockSize >= 2) sdata[tid] += sdata[tid + 1];
    }
    if (tid == 0) g_odata[blockIdx.x] = sdata[0];
}
"""

mod = SourceModule(modStr,no_extern_c=True) 
# With no_extern_c = True, the error is :
# pycuda._driver.LogicError: cuModuleGetFunction failed: not found
# With no_extern_c = False, the error is :
# kernel.cu(3): error: this declaration may not have extern "C" linkage


cuda_reduce_fn = mod.get_function("reduce6")
iData = arange(32).astype(np.float32)
oData = zeros_like(iData)

cuda_reduce_fn(
    drv.In(iData),
    drv.Out(oData),
    np.int32(32),
    block=(32,1,1), grid=(1,1))

print(iData)
print(oData)

Answer 1:

它是非法的,在C ++中,这就是为什么你在第一种情况下得到的错误C链接模板功能。

在第二种情况下,你会得到一个未找到错误,因为你没有实际实例化模板的任何地方,我可以看到,所以编译器将不会发出任何输出。

当你添加一个实例,你会得到同样的错误,因为该设备的编译代码对象有一个错位的名称 。 您需要在使用重整名称get_function电话。 矛盾的是,你可以不知道什么时候JIT编译源码错位的名字,因为你需要查看编译器的输出,因此不知道先验(任何编译器的消息,PTX,的cubin或目标文件会给你重整名称)。

如果你想在PyCUDA模板内核的工作,我建议他们编制与工具链的cubin自己,然后从加载的cubin在PyCUDA获得从模块称为错位的名称。



文章来源: PyCUDA either fails to find function in NVIDIA source code or throws 'may not have extern “C” Linkage' error
标签: cuda pycuda