0

CUDA 5を使用して個別のコンパイルを実行しようとしています。このため、Visual Studio 2010で[再配置可能デバイスコードの生成]を[はい(-rdc = true)]に設定しました。プログラムはエラーなしでコンパイルされますが、無効になります。 cudaMemcpyToSymbolを使用してデバイス定数を初期化しようとすると、デバイスシンボルエラーが発生します。

つまり、私は次の定数を持っています

__constant__ float gdDomainOrigin[2];

で初期化してみてください

cudaMemcpyToSymbol(gdDomainOrigin, mDomainOrigin, 2*sizeof(float));

これはエラーにつながります。前述のオプションを設定せずにすべてをコンパイルしても、エラーは発生しません。誰かがそれを手伝ってくれませんか?

4

1 に答える 1

0

これは再現できません。2つの.cuファイルからアプリケーションをビルドする場合。1つは__constant__シンボルと単純なカーネルを含み、もう1つはその定数メモリにデータを入力してカーネルを呼び出すランタイム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;
}

KeplerGPUを搭載した64ビットLinuxシステムのCUDA5でこれらをコンパイルして実行すると、次のようになります。

$ 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コードを生成せずに、最初のコンパイルでシンボルが見つからないことがわかります。2番目のケースでは、再配置可能な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ツールチェーンで何が起こるかを確認できます。

于 2013-03-18T15:09:04.603 に答える