2014-11-04 93 views
1

我想在啓動需要這些值的內核之前,在我的GPU的常量內存上設置常量值。CUDA常量內存問題:無效的設備符號與cudaGetSymbolAddress

我的代碼(簡化):

__constant__ size_t con_N; 

int main() 
{ 

    size_t N; 
    size_t* dev_N = NULL; 
    cudaError_t cudaStatus; 

    //[...] 

    cudaStatus = cudaGetSymbolAddress((void **)&dev_N, &con_N); 
    if (cudaStatus != cudaSuccess) { 
     cout<<"cudaGetSymbolAddress (dev_N) failed: "<<cudaGetErrorString(cudaStatus)<<endl; 
    } 

我打算cudaMemcpyNdev_N之後。

然而,所有我在代碼中的這一點上得到的是:

cudaGetSymbolAddress (dev_N) failed: invalid device symbol 

我和CUDA 6.5工作,所以它不是一個引用符號的問題,因爲它是在大多數將q & A I的至今一直在檢查。

我試圖替換con_Ncon_N[1](和前con_NcudaGetSymbolAddress參數除去&):相同的結果。

由於這個功能的原型是cudaGetSymbolAddress(void **devPtr , const void* symbol),我猜想它是想給我的符號的地址。不過,我嘗試了cudaStatus = cudaGetSymbolAddress((void **)&dev_N, (const void*) con_N);,我收到了同樣的信息。

當我刪除cudaGetSymbolAddress((void **)&dev_N, &con_N)並直接使用cudaMemcpyToSymbol(&con_N, &N, sizeof(size_t))代替時,我也收到了非常相同的錯誤消息。

恐怕我錯過了一些必不可少的東西。任何幫助將不勝感激。

回答

1

cudaGetSymbolAddress的正確用法是

cudaGetSymbolAddress((void **)&dev_N, con_N) 

我展示與下面的簡單的例子這一點。

正如文檔解釋,符號應該物理上駐留在設備上。因此,在API調用中使用&con_N似乎沒有意義,因爲作爲主機API的cudaGetSymbolAddress不應該可能直接從主機訪問駐留在設備上的某些東西的地址。我不知道,如果出現的CUDA運行時API文檔中的原型應`更好地閱讀

template<class T> 
cudaError_t cudaGetSymbolAddress (void **devPtr, const T symbol) 

設備符號引用而不是設備符號地址

#include <stdio.h> 

__constant__ int const_symbol; 

/********************/ 
/* CUDA ERROR CHECK */ 
/********************/ 
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true) 
{ 
    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

/***************/ 
/* TEST KERNEL */ 
/***************/ 
__global__ void kernel() { 

    printf("Address of symbol from device = %p\n", &const_symbol); 

} 

/********/ 
/* MAIN */ 
/********/ 
int main() 
{ 
    const int N = 16; 
    int *pointer = NULL; 

    gpuErrchk(cudaGetSymbolAddress((void**)&pointer, const_symbol)); 

    kernel<<<1,1>>>(); 

    printf("Address of symbol from host = %p\n", pointer); 

    return 0; 
} 
+0

謝謝,這是完全意義上的。我必須補充說,我無法編譯'cudaGetSymbolAddress((void **)&dev_N,con_N)',但那只是因爲我所說的所有代碼都在.cpp文件中而不是.cu文件中。包裝我的電話解決了我的編譯問題(感謝這個主題:http://stackoverflow.com/questions/20535683/cuda-5-5-cudamemcpytosymbol-constant-and-out-of-scope-error) – eyam 2014-11-05 11:14:17

0

在我看來,你的代碼行應該像下面那樣修復。

cudaStatus = cudaGetSymbolAddress((void **)&dev_N, con_N); 

希望這可以幫助你。

+0

感謝您的回答! 這個函數的原型是cudaGetSymbolAddress(void * * devPtr,const void * symbol),所以我認爲它想要給我的符號的地址。 但是,我試過(我必須將con_N作爲const void *),而且我仍然堅持使用相同的錯誤消息。 – eyam 2014-11-04 14:13:02

+0

您不應該將con_N作爲const void *。這是錯誤的原因。此外,您不需要遵循處理像cudaGetSymbolAddress,cudaMemcpyToSymbol這樣的符號的函數的原型,因爲它們可能會因cuda環境而有所不同。 – 2014-11-04 14:26:01

+0

@Wang_Wang:好的,謝謝你的提示。 但是,我的IDE不編譯沒有這個演員...(否則我會很高興沒有它) – eyam 2014-11-04 14:36:45