C CUDA сверточные ошибки - PullRequest
       34

C CUDA сверточные ошибки

1 голос
/ 15 февраля 2012

У меня 2 проблемы с моей программой. вот часть моей программы

Основная программа будет вызывать функцию свертки 2d В настоящее время ядро ​​состоит только из последовательного кода. потому что так я могу проверить, все ли данные правильно переданы.

Проблема 1 с передачей фильтра в dev_filter в кенеле Я много чего пробовал, но ничего не получалось

Проблема 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 но я все еще получаю ту же ошибку

1 Ответ

2 голосов
/ 15 февраля 2012

Проблема с передачей dev_filter вашему ядру состоит в том, что dev_filter является указателем памяти хоста.Вы должны распределить его с помощью cudaMalloc так же, как и с dev_in и dev_out.

Существует пример CUDA SDK, охватывающий Sobel Filtering .В SDK есть другие образцы CUDA, которые демонстрируют другие типы свертки, например этот .А еще лучше, посмотрите библиотеку NPP , входящую в комплект инструментов CUDA.В CUDA 4.1 добавлено более 1000 функций обработки изображений, и вы обязательно сможете использовать одну из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...