CUDA中的HAAR小波变换

时间:2012-05-23 18:51:40

标签: cuda haar-wavelet

我试图在CUDA中为一维数组实现HAAR小波变换。

算法

我在输入数组中有8个索引

使用此条件if(x_index>=o_width/2 || y_index>=o_height/2)我将有4个线程这应该是0,2,4,6,我打算handletwo指数与它们中的每一个的输入端。

我计算avg.EG:如果我的线程ID是“0'则平均值是(输入[0] +输入[1])/ 2,然后在同一时间我得到这将是输入[所述差异0] -avg等等其他线程。

现在重要的是output.I的放置创建了一个单独的thread_id用于输出作为使用索引0,2,4,6与在正确的索引输出的放置产生的困难。

我的avgs应放在前4个指数中,即输出的0,1,2,3,而o_thread_id应为0,1,2,3。 同样地,为了将差异放在4,5,6,7,我增加了0,1,2,3,其中'4'如代码所示

问题

我的输出全部归零!无论我改变什么,我都会得到它。

CODE

__global__ void cal_haar(int input[],float output [],int i_widthstep,int o_widthstep,int o_width,int o_height)
{

    int x_index=blockIdx.x*blockDim.x+threadIdx.x;
    int y_index=blockIdx.y*blockDim.y+threadIdx.y;

    if(x_index>=o_width/2 || y_index>=o_height/2) return;

    int i_thread_id=y_index*i_widthstep+(2*x_index);
    int o_thread_id=y_index*o_widthstep+x_index;

    float avg=(input[i_thread_id]+input[i_thread_id+1])/2;
    float diff=input[i_thread_id]-avg;
    output[o_thread_id]=avg;
    output[o_thread_id+4]=diff;

}

void haar(int input[],float output [],int i_widthstep,int o_widthstep,int o_width,int o_height)
{

    int * d_input;
    float * d_output;

    cudaMalloc(&d_input,i_widthstep*o_height);
    cudaMalloc(&d_output,o_widthstep*o_height);

    cudaMemcpy(d_input,input,i_widthstep*o_height,cudaMemcpyHostToDevice);

    dim3 blocksize(16,16);
    dim3 gridsize;
    gridsize.x=(o_width+blocksize.x-1)/blocksize.x;
    gridsize.y=(o_height+blocksize.y-1)/blocksize.y;

    cal_haar<<<gridsize,blocksize>>>(d_input,d_output,i_widthstep,o_widthstep,o_width,o_height);


    cudaMemcpy(output,d_output,o_widthstep*o_height,cudaMemcpyDeviceToHost);

    cudaFree(d_input);
    cudaFree(d_output);

}

以下是我的主要功能: -

void main()
{
    int in_arr[8]={1,2,3,4,5,6,7,8};
    float out_arr[8];
    int i_widthstep=8*sizeof(int);
    int o_widthstep=8*sizeof(float);
    haar(in_arr,out_arr,i_widthstep,o_widthstep,8,1);

    for(int c=0;c<=7;c++)
    {cout<<out_arr[c]<<endl;}
    cvWaitKey();

}

你能告诉我哪里出错,它给我零作为输出吗? 谢谢。

1 个答案:

答案 0 :(得分:5)

您的代码存在以下问题:

if(x_index>=o_width/2 || y_index>=o_height/2) return;

鉴于o_height = 1,我们o_height/2 = 0o_heightint,因此我们在此处进行整数除法,并进行舍入),因此没有线程执行任何操作。要实现你想要的,你可以在这里做浮点算术,或者使用(o_height+1)/2(o_width+1)/2:它会用“算术”舍入进行除法(你将有( x_index >= (8+1)/2 /*= 4*/ && y_index >= (1+1)/2 /*= 1*/ )

此外,当你在Y维度中有超过1个线程时,存在解决问题,因为那时你i_thread_ido_thread_id计算是错误的(_withstep是字节大小,但你用它作为数组索引。)