CUDA中的HAAR小波变换

Cod*_*mer 4 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' - 然后avg是(输入[0] +输入[1])/ 2然后同时我得到将输入[0]的差异 - avg等等其余的线程.

现在重要的是输出的位置.我为输出创建了一个单独的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"如代码所示

问题

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

__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);

}
Run Code Online (Sandbox Code Playgroud)

以下是我的主要功能: -

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();

}
Run Code Online (Sandbox Code Playgroud)

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

ala*_*and 5

您的代码存在以下问题:

if(x_index>=o_width/2 || y_index>=o_height/2) return;
Run Code Online (Sandbox Code Playgroud)

考虑到o_height = 1,我们有o_height/2 = 0(o_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大小以字节为单位,但你用它作为数组索引).