2012-02-15 92 views
1

我有我的程序有2個問題。 這裏是我的程序的一部分C CUDA卷積bug(s)

主程序將調用卷積2d函數 此時內核只包含順序代碼。 因爲我可以測試所有的數據傳遞是否正確。

問題1是經過過濾的dev_filter在kenel 我嘗試了很多東西,但沒有奏效

問題2是如何在順序部分的所有這些循環並行化這一點。

我希望我做了我的問題,明確


#define FILTER_WIDTH   3 
#define FILTER_HEIGTH   3 

float SOBEL_FILTER_X[FILTER_HEIGTH][FILTER_WIDTH] = { {-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1} }; 
float SOBEL_FILTER_Y[FILTER_HEIGTH][FILTER_WIDTH] = { { 1, 2, 1}, { 0, 0, 0}, {-1,-2,-1} }; 


gray_image_t convolution2D(gray_image_t in, int imgW, int imgH, float filter[FILTER_HEIGTH][FILTER_WIDTH]) { 
    int imgS = imgW * imgH; 
    gray_image_t out, dev_in, dev_out; 
    float dev_filter[FILTER_HEIGTH][FILTER_WIDTH]; 
    int filterS = FILTER_HEIGTH * FILTER_WIDTH; 


    //allocate memory 
    out = (gray_image_t) calloc(imgS, sizeof(float)); 
    if (out == NULL) return NULL; 
    checkCudaCall(cudaMalloc(&dev_in, imgS * sizeof(float))); 
    checkCudaCall(cudaMalloc(&dev_out, imgS * sizeof(float))); 

    //memcopy 
    checkCudaCall(cudaMemcpy(dev_in,in,imgS * sizeof(float), cudaMemcpyHostToDevice)); 


    timer convolution2D_kernel_timer("Convolution2D_kernel_timer"); 
    convolution2D_kernel_timer.start(); 
    convolution_2DKernel<<<AMOUNT_OF_BLOCKS, THREADS_PER_BLOCK>>>(dev_in,dev_out,imgW,imgH,dev_filter); 
    convolution2D_kernel_timer.stop(); 

    std::cout << convolution2D_kernel_timer; 
    checkCudaCall(cudaThreadSynchronize()); 

    checkCudaCall(cudaMemcpy(out,dev_out,imgS * sizeof(float), cudaMemcpyDeviceToHost)); 
    cudaFree(dev_in); 
    cudaFree(dev_out); 
    return out; 
} 

,這裏是內核

__global__ void convolution_2DKernel(gray_image_t dev_in, gray_image_t dev_out, int imgW,int imgH,float dev_filter[FILTER_HEIGTH][FILTER_WIDTH]){ 
    // find center position of kernel (half of kernel size) 
    int kCenterX = FILTER_WIDTH/2; 
    int kCenterY = FILTER_HEIGTH/2; 

    for(int y=0; y < imgH; y++) { 
     for(int x=0; x < imgW; x++) { 
      for(int m=0; m < FILTER_HEIGTH; ++m) { 
       for(int n=0; n < FILTER_WIDTH; ++n) { 

        // index of input signal, used for checking boundary 
        int yy = y + (m - kCenterY); 
        int xx = x + (n - kCenterX); 

        // ignore input samples which are out of bound 
        if(yy >= 0 && yy < imgH && xx >= 0 && xx < imgW) { 
         dev_out[y*imgW+x] += dev_in[yy*imgW+xx] * dev_filter[m][n]; 
        } 
       } 
      } 
     } 
    } 
} 

您好我試過它與使用cudaMallocPitch和cudaMemcpy2D ,但我仍然得到相同的錯誤

+0

這段代碼有很多低效率的問題,所以你可以考慮使用一個已經可用的CUDA卷積包。免責聲明是,我工作的一個,我認爲會對你有用,ArrayFire,http://www.accelereyes.com/arrayfire_cuda/group__CONV__mat.htm – arrayfire 2012-02-15 03:37:03

回答

2

將dev_filter傳遞到內核的問題是dev_filter是主機內存指針。你應該像使用dev_in和dev_out一樣使用cudaMalloc來分配它。

有一個涵蓋Sobel Filtering的CUDA SDK示例。 SDK中還有其他CUDA示例演示了其他類型的卷積,例如, this one。更好的辦法是查看CUDA工具箱附帶的NPP library。 CUDA 4.1增加了1000多種圖像處理功能,必將成爲您可以使用的一種。

+0

嗨,我試過它與cudaMallocPitch和cudaMemcpy2D但我仍然得到相同的錯誤 – Bgvv1983 2012-02-15 12:04:35

+0

你需要指定你得到的錯誤或我們無法幫助的錯誤。 – harrism 2012-02-15 14:27:00

+1

實際上,有一個專門針對Sobel過濾器的SDK示例:http://developer.nvidia.com/cuda-cc-sdk-code-samples#SobelFilter – ArchaeaSoftware 2012-02-16 16:49:32