C++ C++;CUDA:为什么每次代码都返回不同的结果?

C++ C++;CUDA:为什么每次代码都返回不同的结果?,c++,cuda,C++,Cuda,更新:我发现了错误。因为我以前发布的代码非常复杂,我简化了它们,只在问题出现时保留部分 if (number >= dim * num_points) return; 但实际上,我只有num_点,我想使用num_点线程,所以正确的方法应该是 if (number >= num_points) return; 谢谢大家的帮助 我正在从CPU到GPU重写一些C++代码。代码粘贴在下面。抱歉,时间太长了,因为我认为用这种方法更容易发现问题 在代码中,对于每个线程,我都

更新:我发现了错误。因为我以前发布的代码非常复杂,我简化了它们,只在问题出现时保留部分

if (number >= dim * num_points)
    return;
但实际上,我只有num_点,我想使用num_点线程,所以正确的方法应该是

if (number >= num_points)
    return;
谢谢大家的帮助


我正在从CPU到GPU重写一些C++代码。代码粘贴在下面。抱歉,时间太长了,因为我认为用这种方法更容易发现问题

在代码中,对于每个线程,我都需要一些矩阵格式的中间结果,因此我为这些中间结果分配设备内存,例如d_dir2、d_R、d_Stick、d_PStick。结果不是我期望的结果,所以为了调试,我尝试以这种方式输出一些中间结果R:

if (k == 0) { results[tmp_int1 + i * dim + j] = R[tmp_int1 + i * dim + j]; } 如果(k==0) { 结果[tmp_int1+i*dim+j]=R[tmp_int1+i*dim+j]; }

以后,在C++中,我打印结果。 然而,我发现每次结果都给出不同的值。有时给出正确答案R,有时给出PStick的值,有时给出R和PStick的组合,有时给出R和0的组合(结果在开始时初始化为0)

我很困惑是什么导致了这个问题。有什么想法吗?非常感谢:)

\uuuuu全局\uuuuuuo无效粘滞注释(常数整型、常数整型、常数整型网格、浮点西格玛、浮点*输入、浮点*dir2、浮点*R、浮点*棒、浮点*PStick、浮点*结果){
浮动阈值=4*Sigma;
浮点数c=(-16*log(0.1f)*(sqrt(Sigma)-1))/3.1415926f/3.1415926f;
int row=blockIdx.y*blockDim.y+threadIdx.y;
int col=blockIdx.x*blockDim.x+threadIdx.x;
整数=行*块大小*网格x+列;
如果(number>=dim*num_points)///错误就在这里!
返回;
}
外部“C”void KernelStickVote(int dim,int num_points,float Sigma,float*输入,float*结果){
const int totalpoints=num_点;
const int totalpoints_input=(dim+1)*(dim+1)*num_points;
const int totalpoints_output=dim*dim*num_points;
大小\u t大小\u输入=总点数\u输入*sizeof(浮点);
大小\u t大小\u输出=总点数\u输出*sizeof(浮点);
浮点*d_输入;
表皮安全壳(Cudamaloc((void**)和d_输入、尺寸_输入);
浮点*d_结果;
表皮安全球(Cudamaloc((void**)和d_结果、大小_输出);
//用于保存目录,并计算目录*dir'
浮动*d_dir2;
表皮安全球(cudaMalloc((void**)和d_dir2,dim*num_points*sizeof(float));
//用于保存R:dim*dim*N
浮动*d_R;
表皮安全壳(Cudamaloc((void**)和d_R,尺寸_输出));
//用于保存斗杆:dim*dim*N
浮球*d_棒;
表皮安全壳(Cudamaloc((void**)和d_棒,尺寸_输出);
//用于保存斗杆:dim*dim*N
浮点数*d\u刻度;
角质安全壳(cudaMalloc((void**)和d_-PStick,尺寸_-output));
//将输入数据从主机复制到设备
cudaMemcpy(d_输入,输入,大小_输入,cudamemcpyhostodevice);
int totalblock=(totalpoints%BLOCKPOINTS==0?totalpoints/BLOCKPOINTS:(int(totalpoints/BLOCKPOINTS)+1));
int gridx=(65535
问题的原始海报执行了进一步的代码简化和调试,发现内核中的guard语句:

if (number >= dim * num_points)
    return;
事实上,这是不正确的,本应如此

if (number >= num_points)
    return;
这就是错误的根源


此答案已添加为社区wiki答案,目的是将此问题从未回答的队列中删除。

是什么让您认为在这堆代码中(不是看起来很糟糕,只是很多)比在nice中更容易检测到问题?您有不完整的API错误检查,你确定内核实际上正在运行吗?对Talonmes:谢谢你的回复。内核正在运行,因为d_R在开始时没有值,在内核之后,通过变量结果返回的R有时是正确的。对于leftaroundabout:Thank你的评论,我理解如果它是紧凑格式的,它应该更清晰。但问题是我不知道哪一部分是安全的。所以如果我压缩一些东西,真正的问题可能会被消除。很抱歉给您带来麻烦。请检查所有API调用的返回值,特别是内核启动后的cudaMemcpy,以及所有其他调用的返回值。正如@leftaroundabout所说,创建一个简短的示例会有所帮助,至少它应该是可编译和可执行的。
if (number >= num_points)
    return;