2012-02-15 5 views
1

私のプログラムには2つの問題があります。 は私のプログラムの一部ですC CUDAコンボリューションバグ

メインプログラムはコンボリューション2d関数を呼び出します この時点では、カーネルはシーケンシャルコードのみで構成されています。 私はすべてのデータの受け渡しが正しいかどうかテストできます。

問題1は、私は多くのものを試してみましたが、何も

問題2は、シーケンシャル部分にすべてのそれらのループでこれを並列化する方法である働いたkenel にdev_filterにフィルタを渡してあります。

私はこんにちは、私はcudaMallocPitchとcudaMemcpy2D でそれを試してみましたが、私はまだ取得


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

であると思います

同じエラー

+0

このコードには多くの非効率性があるため、すでに利用可能なCUDAコンボリューションパッケージの1つを使用することを検討することがあります。免責事項は、私があなたに役立つと思うもの、ArrayFire、http://www.accelereyes.com/arrayfire_cuda/group__CONV__mat.htm – arrayfire

答えて

2

dev_filterをカーネルに渡す際の問題は、dev_filterがホストメモリポインタであることです。あなたはdev_inとdev_outのようにcudaMallocで割り当てなければなりません。

Sobel FilteringをカバーするCUDA SDKサンプルがあります。他のタイプの畳み込みを示す他のCUDAサンプルがSDKにあります。 this one。さらに、CUDAツールキットに含まれているNPP libraryをチェックしてください。 CUDA 4.1には1000以上の画像処理機能が追加されており、使用できるバインディングがあります。

+0

で作業していることです。こんにちは、私はcudaMallocPitchとcudaMemcpy2Dで試しましたが、まだ同じエラーが発生します – Bgvv1983

+0

あなたが得るエラーを指定する必要があります。 – harrism

+1

実際、Sobelフィルタ専用のSDKサンプルがあります:http://developer.nvidia.com/cuda-cc-sdk-code-samples#SobelFilter – ArchaeaSoftware