2012-10-18 4 views
14

Das ProblemFehler in cudaMemcpyToSymbol CUDA unter Verwendung von 5

Ich habe eine Probe CUDA Code bereit, den konstanten Speicher. Ich kann das 4.2 erfolgreich in CUDA laufen, aber ich „ungültig Gerätesymbol“, wenn ich die CUDA 5. kompilieren ich mit dem Beispielcode hier angebracht haben.

Der Kodex

#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; 
} 

ich WINDOWS versucht: CUDA 5.0 Produktionsfreigabe und die Grafikkarte ist GTX 590.
Jede Hilfe geschätzt wird.

+0

Ich habe ein Beispiel http://stackoverflow.com/a/16045453/596547 hinzugefügt – phoad

Antwort

23

In dem Bemühen zu vermeiden, "Stringly Typed" zu sein, wurde die Verwendung von Zeichenfolgen für Gerätesymbole in CUDA-Laufzeit-API-Funktionen in CUDA 4.1 veraltet und in CUDA 5.0 entfernt.

Die CUDA 5 release notes lesen:

** Die Verwendung einer Zeichenkette ein Gerätesymbol, um anzuzeigen, die mit bestimmten API-Funktionen möglich war, wird nicht mehr unterstützt. Stattdessen sollte das Symbol direkt verwendet werden.

Wenn Sie Ihren Code zu den folgenden ändern, sollte es funktionieren.

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

enter image description here

+0

Vielen Dank .... Es funktionierte für mich ... –

+0

@ran_pal Wenn Sie mit seiner Antwort zufrieden sind, können Sie wählen sie das Häkchen zu akzeptieren? –

+0

Ich habe ein Beispiel zu diesem Thema http hinzugefügt: // Stackoverflow.com/a/16045453/596547 – phoad

10

Vom CUDA 5.0 Release Notes:

** Die Verwendung einer Zeichenkette ein Gerätesymbol, um anzuzeigen, die mit bestimmten API-Funktionen möglich war, wird nicht mehr unterstützt. Stattdessen sollte das Symbol direkt verwendet werden. "

Diese API-Funktionen gibt es immer noch, aber sie akzeptieren das Zielsymbol Argument nur als bloße Kennung jetzt, nicht als entweder eine bloße Kennung oder einem Stringliteral eine ident zu benennen. Eg

__ device__ __ constant__ type ident; 

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

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

So loszuwerden dies:

#define PARAMETER "CONSTANT_PARAMETER" 

Und dies ändern:

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

Um dies:

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

Und ich denke, es wird funktionieren.

+1

Meine Antwort war zuerst und enthält ein Kätzchen. :) – harrism

+1

Miezekatze bekommt eine Aufwertung! –

+5

SO sollte ein Abzeichen haben "gute Katze: erste lolcat Antwort mit einem Score von mindestens 1" – harrism

Verwandte Themen