我不能重現這一點。如果從兩個.cu文件構建應用程序,一個包含__constant__符號和一個簡單內核,另一個包含運行時API咒語來填充該常量內存並調用內核,則僅在啓用可重定位設備代碼時才能工作,即:
__constant__ float gdDomainOrigin[2];
__global__
void kernel(float *inout)
{
inout[0] = gdDomainOrigin[0];
inout[1] = gdDomainOrigin[1];
}
和
#include <cstdio>
extern __constant__ float gdDomainOrigin;
extern __global__ void kernel(float *);
inline
void gpuAssert(cudaError_t code, char * file, int line, bool Abort=true)
{
if (code != 0) {
fprintf(stderr, "GPUassert: %s %s %d\n",
cudaGetErrorString(code),file,line);
if (Abort) exit(code);
}
}
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
int main(void)
{
const float mDomainOrigin[2] = { 1.234f, 5.6789f };
const size_t sz = sizeof(float) * size_t(2);
float * dbuf, * hbuf;
gpuErrchk(cudaFree(0));
gpuErrchk(cudaMemcpyToSymbol(gdDomainOrigin, mDomainOrigin, sz));
gpuErrchk(cudaMalloc((void **)&dbuf, sz));
kernel<<<1,1>>>(dbuf);
gpuErrchk(cudaPeekAtLastError());
hbuf = new float[2];
gpuErrchk(cudaMemcpy(hbuf, dbuf, sz, cudaMemcpyDeviceToHost));
fprintf(stdout, "%f %f\n", hbuf[0], hbuf[1]);
return 0;
}
編譯和用開普勒GPU 64位Linux系統上在CUDA 5運行這些產生以下:
$ nvcc -arch=sm_30 -o shared shared.cu shared_dev.cu
$ ./shared
GPUassert: invalid device symbol shared.cu 23
$ nvcc -arch=sm_30 -rdc=true -o shared shared.cu shared_dev.cu
$ ./shared
1.234000 5.678900
您可以看到,在第一次編譯時,沒有可重定位的GPU代碼生成,找不到符號。在第二種情況下,重新定位的GPU代碼生成,它被發現,並在目標文件中ELF頭看起來就像你所期望的:
$ nvcc -arch=sm_30 -rdc=true -c shared_dev.cu
$ cuobjdump -symbols shared_dev.o
Fatbin elf code:
================
arch = sm_30
code version = [1,6]
producer = cuda
host = linux
compile_size = 64bit
identifier = shared_dev.cu
symbols:
STT_SECTION STB_LOCAL .text._Z6kernelPf
STT_SECTION STB_LOCAL .nv.constant3
STT_SECTION STB_LOCAL .nv.constant0._Z6kernelPf
STT_CUDA_OBJECT STB_LOCAL _param
STT_SECTION STB_LOCAL .nv.callgraph
STT_FUNC STB_GLOBAL _Z6kernelPf
STT_CUDA_OBJECT STB_GLOBAL gdDomainOrigin
Fatbin ptx code:
================
arch = sm_30
code version = [3,1]
producer = cuda
host = linux
compile_size = 64bit
compressed
identifier = shared_dev.cu
ptxasOptions = --compile-only
也許你可以試試我的代碼和編譯/診斷步驟,看看你的Windows工具鏈會發生什麼?
根據您的代碼結構,您[可能需要]使用(http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#code-changes-for-separate-compilation )'extern'或'static'來聲明符號的可見性。您還沒有提供足夠的信息,說明哪些模塊正在聲明符號以及哪些模塊正在引用它們。 – 2013-03-18 02:52:44
感謝您的回覆。上述兩個代碼片段都在相同的.cu文件中。此外,該符號僅在此文件中引用。但是,我想用extern聲明一些曾經是.cu文件一部分的內核,並在不同的.cu文件中定義它們以使我的代碼更易讀。但是,這些內核不能訪問上面提到的符號。 – scttrbrn 2013-03-18 03:39:10