2013-05-08 67 views
1

我寫下面的代碼在CUDA發出帶有映射的2D到1D陣列中的CUDA

__global__ void test(int *b_dev) 
{ 
    int index=blockDim.x*blockIdx.x+threadIdx.x; 
    b_dev[index]=1; 
} 

int main() 
{ 
    int **a; 
    int *b_dev; 
    a=(int**)malloc(sizeof(int*)*4); 
    for(i=0;i<4;i++) 
    a[i]=(int*)malloc(sizeof(int)*4); 

    //initialise array a here with 0 

    cudaMalloc((void**)&b_dev,sizeof(int)*16); 
    cudaMemcpy(b_dev,a,sizeof(int)*16,cudaMemcpyHostToDevice); 
    test<<<4,4>>>(dev_b); 
    cudaMemcpy(a,b_dev,sizeof(int)*16,cudaMemcpyDeviceToHost); 
    for(i=0;i<4;i++) 
    for(j=0;j<4;j++) 
     cout<<a[i][j]; 
    } 

我在宿主這2D陣列我弄平一維陣列和處理在GPU但是這個代碼產生分割當我嘗試在主機中打印數組a時出錯,但是當我在內核中註釋掉b_dev[valindex]=1行時,它會打印帶有初始化零的數組a。 visual C++調試器指示

CXX0030:無法評估錯誤表達式。

好心請帶我走

+1

您錯誤地將數據複製到和從GPU。以這種方式分配的2D陣列不能通過使用單個存儲器副本直接複製。另外,不應該指定的語句是'b_dev [index] = 1;'? – sgarizvi 2013-05-08 18:08:25

+0

雅這是b_dev [指數] = 1.這是一個錯字..你可以指點我如何可以實現這個 – Stormvirux 2013-05-08 18:18:37

+0

還是有任何其他的手段? – Stormvirux 2013-05-08 18:30:34

回答

2

當你在你做的方式分配數組的數組,你有沒有機制保障,每個陣列會在內存中是連續的。更具體地說,在您的示例中,您有一個int**陣列a,它由4個int*陣列組成,a[0],a[1],a[2]a[3]。在每個數組a [i](其中i是您的二維數組中的數組索引)內存將是連續的。然而,沒有保證陣列a[i]的存儲器和陣列a[i+1]的存儲器是。也就是說,在您撥打malloc的電話之間,分配的內存可以來自您的免費商店中的任何地方,並且它們是否連續是否達到malloc。 (順便說一句,如果你在堆棧中分配內存,那麼它將是連續的,或者作爲一維數組在堆上)。

因此,您不能期待1個致電cudaMemcpy複製您的所有陣列。相反,您必須爲每個1D陣列執行多個cudaMemcpy調用以複製所有這些數組,並在目標指針上進行指針運算,以確保將它們複製到正確的位置。

當連續的二維數據時,您可以使用cudaMemcpy2D,其中有簽名:當使用

cudaError_t cudaMemcpy2D (void* dst, size_t dpitch, const void* src, size_t spitch, size_t width, size_t height, cudaMemcpyKind kind) 

,如果你知道的源和目標間距長度,你可以利用這一點,並採取瀝青考慮數據。但是,這個函數假定數據維度是連續的,所以它不會幫助你。當然,最簡單的解決方案是選擇一個數組維度協議並堅持使用它(例如,要麼所有的內存都是2D或全部爲1D,但不要混合它們,除非有令人信服的理由)。我

而且會是失職,如果我沒有離開的鏈接relevant CUDA documentation about cudaMemcpy