我试图在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'如代码所示
我的输出全部归零!无论我改变什么,我都会得到它。
__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();
}
你能告诉我哪里出错,它给我零作为输出吗? 谢谢。
答案 0 :(得分:5)
您的代码存在以下问题:
if(x_index>=o_width/2 || y_index>=o_height/2) return;
鉴于o_height = 1
,我们o_height/2 = 0
(o_height
为int
,因此我们在此处进行整数除法,并进行舍入),因此没有线程执行任何操作。要实现你想要的,你可以在这里做浮点算术,或者使用(o_height+1)/2
和(o_width+1)/2
:它会用“算术”舍入进行除法(你将有( x_index >= (8+1)/2 /*= 4*/ && y_index >= (1+1)/2 /*= 1*/ )
)
此外,当你在Y维度中有超过1个线程时,存在解决问题,因为那时你i_thread_id
和o_thread_id
计算是错误的(_withstep
是字节大小,但你用它作为数组索引。)