2014-02-16 64 views
0

我正在尋找一個函數來重新分配CUDA(設備)數組,如果數據超過它的容器。背景是稀疏的數據,我保存在數組中,我從0開始緩慢地開始填充。函數重新分配在cuda中增長的內存

我開始了一個分配給定數量的開始:

的main():

int number_of_blocks = 30; 
int dyn_cells = number_of_blocks * (BLOCK_WIDTH-4) * (BLOCK_HEIGHT-4); 
HANDLE_ERROR(cudaMalloc(&h_dev, dyn_cells * sizeof(float))); 

我然後做了一些計算,越來越多的在h_dev塊的習慣了。如果其中一半以上被使用,我想讓陣列變大。我用這個功能來做到這一點:

void grow_array(float **ptr, int length, int length_new) 
{ 
    float *ptr_new; 
    int width = length_new * (BLOCK_WIDTH - 4); 
    int height= (BLOCK_HEIGHT- 4); 
    HANDLE_ERROR(cudaMalloc(&ptr_new , width * height * sizeof(float))); 
    //this is the copy kernel 
    dim3 threads(BLOCK_WIDTH-4,BLOCK_HEIGHT-4); 
    dim3 blocks(length_new); 
    copy_kernel<<<blocks,threads>>>(*ptr,ptr_new, length, length_new); 

    float *old_ptr; 
    old_ptr = *ptr; 
    HANDLE_ERROR(cudaFree(old_ptr)); 
    *ptr = ptr_new; 
} 

我稱之爲是這樣的:

void memory_manager(int &blocks_available, int blocks_used, float** h_dev) 
{ 
    double ratio = (double)blocks_used/(double)blocks_available; 
    if (ratio > 0.5) 
    { 
     int new_length = 1.5 * blocks_available; 
     grow_array(h_dev , blocks_available, new_length); 
     (...) 
    { 
{ 

複製內核看起來如下:

__global__ void copy_kernel(float* old_vector, float* new_vector, int old_size, int new_size) 
{ 
    int x = blockIdx.x * blockDim.x + threadIdx.x; 
    int y = threadIdx.y; 
    int offset_new = x + y * new_size * (BLOCK_WIDTH-4); 
    int offset_old = x + y * old_size * (BLOCK_WIDTH-4); 
    if (blockIdx.x < old_size) 
    { 
     new_vector[offset_new] = old_vector[offset_old]; 
    } 
    else 
    { 
     new_vector[offset_new] = 42.0f; 
    } 
} 

我最初寫這個原型後其中使用了malloc和免費(非CUDA)這似乎工作。但是,這會讓我的程序崩潰,並提示超出內存訪問範圍。我很確定我缺少一些參考/解引用問題,但無法找到問題的確切位置。任何指向爲什麼會失敗的指針?

+2

您可能需要顯示*全部*相關代碼。例如,啓動一個2-D線程塊的一維網格看起來很奇怪。你當然可以做到這一點,但它會引發一些問題,你如何計算你沒有顯示的'copy_kernel'中的索引。如果它是您所指的設備越界地址,則最好顯示設備代碼。你能更清楚地說明「讓我的程序崩潰」嗎?這是否意味着seg故障,或其他?你嘗試過'cuda-memcheck'嗎?請顯示其他人可以編譯和運行的* complete *應用程序。是的,這需要努力。 –

+0

[這是我的嘗試](http://pastebin.com/8HeBCv4b)圍繞你所展示的內容('grow_array'和'memory_manager')構建一個代碼。它似乎工作正常。如果您需要幫助,請提供*完整*示例,就像我所做的那樣。投票結束。 –

+0

親愛的克羅維拉先生,感謝您抽出時間發表評論。我已經包含了有關複製內核的問題。我沒有添加它,因爲在另一個內核中出現越界錯誤,如果我工作在「靜態」大小的內存上,它工作正常。這讓我相信代碼的內存管理部分可能存在一個明顯的錯誤。 –

回答

1

用新的更大的指針代替指針的代碼顯然不是超出邊界錯誤的原因,儘管它觸發了它。在不相關的內核中找到錯誤並修復它。謝謝大家。