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

算法

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

在这种情况下,我将有4个线程分别为0、2、4、6,并且我打算使用每个线程处理输入中的两个索引。

我计算avg.EG:如果我的线程ID为'0'-那么avg为(input [0] + input [1])/ 2,然后同时获得要输入的差值-[0]-其余线程的平均数等等。

现在重要的是输出的放置。我为输出创建了一个单独的thread_id,因为使用索引0、2、4、6在将输出放置在正确的索引中时遇到了困难。

我的平均值应该放在前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);

}


以下是我的主要功能:

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

}


您能告诉我哪里出问题了吗?它的输出为零?
谢谢。

最佳答案

您的代码存在以下问题:

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维度上有多个线程时,寻址会出现问题,因为这样i_thread_ido_thread_id计算将是错误的(_withstep是字节大小,但您将其用作数组索引) 。

10-04 14:28
查看更多