PyCUDA要么在NVIDIA源代码中找不到函数,要么抛出';“可能没有外部文件”;";联动装置';错误

PyCUDA要么在NVIDIA源代码中找不到函数,要么抛出';“可能没有外部文件”;";联动装置';错误,cuda,pycuda,Cuda,Pycuda,我试图通过将他的源代码复制到一个简单的pycuda应用程序中来使用(并从中学习)(下面列出了我尝试的完整源代码) 不幸的是,我遇到了以下两个错误之一 cuda内核不编译,抛出以下错误消息 kernel.cu(3): error: this declaration may not have extern "C" linkage 如果在编译内核的行中包含参数no\u extern\u c=True,则会引发以下错误: pycuda._driver.LogicError: cuModuleGetF

我试图通过将他的源代码复制到一个简单的pycuda应用程序中来使用(并从中学习)(下面列出了我尝试的完整源代码)

不幸的是,我遇到了以下两个错误之一

  • cuda内核不编译,抛出以下错误消息

    kernel.cu(3): error: this declaration may not have extern "C" linkage
    
  • 如果在编译内核的行中包含参数
    no\u extern\u c=True
    ,则会引发以下错误:

    pycuda._driver.LogicError: cuModuleGetFunction failed: not found
    
  • 我还尝试将modStr的内容包装在
    extern“C”{[…]}
    中,将
    no_extern_C
    变量设置为True或False,但没有成功

    问题似乎涉及到行
    模板
    ,就好像我注释掉了函数体一样,它仍然会引发错误。但我对这个问题的理解还不够透彻,没有更多的想法来解决它

    任何建议/建议/帮助都将不胜感激——提前感谢

    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)
    
    从pylab导入*
    将pycuda.gpuarray导入为gpuarray
    导入pycuda.autoinit
    将pycuda.driver作为drv导入
    从pycuda.compiler导入SourceModule
    modStr=”“”
    模板
    __全局无效归约6(int*g\u-idata,int*g\u-odata,无符号int-n){
    外部共享数据数据[];
    unsigned int tid=threadIdx.x;
    无符号整数i=blockIdx.x*(blockSize*2)+tid;
    unsigned int gridSize=blockSize*2*gridDim.x;
    sdata[tid]=0;
    而(i=512){if(tid<256){sdata[tid]+=sdata[tid+256];}
    if(blockSize>=256){if(tid<128){sdata[tid]+=sdata[tid+128];}
    if(blockSize>=128){if(tid<64){sdata[tid]+=sdata[tid+64];}
    如果(tid<32){
    如果(块大小>=64)sdata[tid]+=sdata[tid+32];
    如果(块大小>=32)sdata[tid]+=sdata[tid+16];
    如果(块大小>=16)sdata[tid]+=sdata[tid+8];
    如果(块大小>=8)sdata[tid]+=sdata[tid+4];
    如果(块大小>=4)sdata[tid]+=sdata[tid+2];
    如果(块大小>=2)sdata[tid]+=sdata[tid+1];
    }
    如果(tid==0)g_odata[blockIdx.x]=sdata[0];
    }
    """
    mod=SourceModule(modStr,no\u extern\u c=True)
    #如果no_extern_c=True,则错误为:
    #pycuda.\u driver.LogicError:cuModuleGetFunction失败:未找到
    #如果no_extern_c=False,则错误为:
    #cu(3):错误:此声明可能没有外部“C”链接
    cuda_reduce_fn=mod.get_函数(“reduce6”)
    iData=arange(32).aType(np.32)
    oData=类零(iData)
    cuda_reduce_fn(
    在(iData)中的drv,
    drv.Out(奥达塔),
    np.int32(32),
    块=(32,1,1),网格=(1,1))
    印刷品(iData)
    打印(oData)
    
    > > P>在C++中使用C链接模板函数是非法的,这就是为什么在第一种情况下会出错的原因。 在第二种情况下,您会得到一个not found错误,因为您没有在我可以看到的任何地方实际实例化模板,因此编译器不会发出任何输出

    当您添加实例时,您将得到相同的错误,因为设备的已编译代码对象有一个错误。您需要在
    get\u函数
    调用中使用损坏的名称。自相矛盾的是,当JIT从源代码处编译时,您无法知道损坏的名称,因为您需要查看编译器输出,而这不是先验的(任何编译器消息、PTX、cubin或对象文件都会给出损坏的名称)


    如果您想使用PyCUDA中的模板内核,我建议您使用工具链将它们编译到cubin中,然后从PyCUDA中的cubin中加载,以从模块中获得已知的损坏名称。

    如何找到损坏名称?@Yuval.R:“任何编译器消息、PTX、cubin或对象文件都将为您提供损坏名称”运行此命令时:
    nvcc-arch=sm_86--cubinmain.cu
    它只打印
    main.cu
    ,是否可以从PyCUDA调用非
    \uuu全局函数?(就像调用main函数或任何
    int func(params){}
    )一样,您需要检查cubin文件的内容。没有,没有办法调用主机代码