我試圖使用(並從中學習)Mark Harris's optimized reduction kernel,通過將其源代碼複製到一個簡單的pycuda應用程序中下面列出了我的嘗試的來源)。PyCUDA無法在NVIDIA源代碼中找到函數或拋出「可能沒有外部」C「Linkage」錯誤
不幸的是,我遇到了以下兩個錯誤之一。
的CUDA內核不能編譯,拋出以下錯誤消息。
kernel.cu(3): error: this declaration may not have extern "C" linkage
如果包括我的論點
no_extern_c=True
成編譯內核行,以下引發錯誤:pycuda._driver.LogicError: cuModuleGetFunction failed: not found
我自己也嘗試包裝modStr的內容extern "C" { [...] }
與將no_extern_c
變量設置爲True或False,但沒有任何成功。
問題看起來好像我評論的函數體出它仍然引起錯誤涉及線路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)