4

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

算法

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

在这种情况下if(x_index>=o_width/2 || y_index>=o_height/2),我将有 4 个线程,它们应该是 0、2、4、6,我计划用它们中的每一个处理输入中的两个索引。

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

现在重要的是输出的位置。我为输出创建了一个单独的 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);

}

以下是我的主要功能:-

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

}

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

4

1 回答 1

5

您的代码的问题是以下情况:

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

给定o_height = 1,我们有o_height/2 = 0( o_heightis int,所以我们在这里有整数除法和向下舍入),所以没有线程执行任何操作。为了实现你想要的,你可以在这里做浮点算术,或者使用(o_height+1)/2and (o_width+1)/2: 它会用“算术”舍入执行除法(你将有( x_index >= (8+1)/2 /*= 4*/ && y_index >= (1+1)/2 /*= 1*/ )

此外,当您在 Y 维度上有超过 1 个线程时,寻址存在问题,因为那时您i_thread_ido_thread_id计算将是错误的(_withstep以字节为单位的大小,但您将其用作数组索引)。

于 2012-05-23T20:35:45.653 回答