14

問題

コンスタントメモリを使用してサンプルCUDAコードを1つ用意しました。これはcuda4.2で正常に実行できますが 、CUDA 5を使用してコンパイルすると、 「無効なデバイスシンボル」が表示されます。ここにサンプルコードを添付しました。

コード

#include <iostream>
#include <stdio.h>
#include <cuda_runtime.h>
#include <cuda.h>

struct CParameter
{
    int A;  
    float B;
    float C;
    float D;
};

__constant__ CParameter * CONSTANT_PARAMETER;   
#define PARAMETER "CONSTANT_PARAMETER"

bool ERROR_CHECK(cudaError_t Status)
{
    if(Status != cudaSuccess)
    {
        printf(cudaGetErrorString(Status));
        return false;
    }   
    return true;
}

// Kernel that executes on the CUDA device
__global__ void square_array(float *a, int N)
{
  int idx = blockIdx.x * blockDim.x + threadIdx.x;
  if (idx<N)
  {
      a[idx] = CONSTANT_PARAMETER->A * a[idx];
  }
}
////Main Function/////
int main(void)
{
    /////Variable Definition
    const int N = 10;
    size_t size = N * sizeof(float);
    cudaError_t Status = cudaSuccess;

    CParameter * m_dParameter;
    CParameter * m_hParameter;
    float * m_D;
    float * m_H;

    //Memory Allocation Host
    m_hParameter = new CParameter;
    m_H = new float[N];

    //Memory Allocation Device
    cudaMalloc((void **) &m_D, size);
    cudaMalloc((void**)&m_dParameter,sizeof(CParameter));

    ////Data Initialization
    for (int i=0; i<N; i++) 
        m_H[i] = (float)i;

    m_hParameter->A = 5;
    m_hParameter->B = 3;
    m_hParameter->C = 98;
    m_hParameter->D = 100;

    //Memory Copy from Host To Device
    Status = cudaMemcpy(m_D, m_H, size, cudaMemcpyHostToDevice);
    ERROR_CHECK(Status);

    Status = cudaMemcpy(m_dParameter,m_hParameter,sizeof(CParameter),cudaMemcpyHostToDevice);
    ERROR_CHECK(Status);        

    Status = cudaMemcpyToSymbol(PARAMETER, &m_dParameter, sizeof(m_dParameter));
    ERROR_CHECK(Status);

    // Do calculation on device:
    int block_size = 4;

    int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);

    square_array <<<n_blocks, block_size>>>(m_D,N);

    // Retrieve result from device and store it in host array
    cudaMemcpy(m_H, m_D, sizeof(float)*N, cudaMemcpyDeviceToHost);

    // Print results
    for (int i=0; i<N; i++)
        printf("%d %f\n", i, m_H[i]);

    // Cleanup
    free(m_H);
    free(m_hParameter);
    cudaFree(m_dParameter);
    cudaFree(m_D);
    return 0;   
}

WINDOWS:CUDA 5.0 Production Releaseを試しましたが、グラフィックカードはGTX590
です。ご協力いただければ幸い です。

4

2 に答える 2

23

"Stringly Typed"であることを回避するために、文字列を使用してデバイス シンボルを参照することは、CUDA 4.1 の CUDA ランタイム API 関数で非推奨になり、CUDA 5.0 で削除されました。

CUDA 5 のリリース ノートには次のように書かれています。

** 特定の API 関数で可能だった、デバイス シンボルを示す文字列の使用はサポートされなくなりました。代わりに、シンボルを直接使用する必要があります。

コードを次のように変更すると、動作するはずです。

Status = cudaMemcpyToSymbol(CONSTANT_PARAMETER, &m_dParameter, sizeof(m_dParameter));
ERROR_CHECK(Status);

ここに画像の説明を入力

于 2012-10-18T06:14:55.070 に答える
10

CUDA 5.0 リリース ノートから:

** 特定の API 関数で可能だった、デバイス シンボルを示す文字列の使用はサポートされなくなりました。代わりに、シンボルを直接使用する必要があります。"

これらの API 関数はまだ存在しますが、ターゲット シンボルの引数をそのままの識別子としてのみ受け入れるようになりました。例えば

__ device__ __ constant__ type ident;

main() { cudaMemcpyToSymbol("ident", ...); } // no longer valid, returns cudaErrorInvalidSymbol

main() { cudaMemcpyToSymbol(ident, ...); }   // valid

だからこれを取り除く:

#define PARAMETER "CONSTANT_PARAMETER"

そしてこれを変更します:

Status = cudaMemcpyToSymbol(PARAMETER, &m_dParameter, sizeof(m_dParameter)); 

これに:

Status = cudaMemcpyToSymbol(CONSTANT_PARAMETER, &m_dParameter, sizeof(m_dParameter)); 

そして、それはうまくいくと思います。

于 2012-10-18T06:16:15.117 に答える