【发布时间】:2011-04-12 06:44:06
【问题描述】:
我正在编写一些代码来激活 CUDA 上的神经网络,但遇到了问题。我没有得到进入给定神经元的权重的正确总和。
这里是内核代码,我将尝试用变量更清楚地解释它。
__global__ void kernelSumWeights(float* sumArray, float* weightArray, int2* sourceTargetArray, int cLength)
{
int nx = threadIdx.x + TILE_WIDTH*threadIdx.y;
int index_in = (blockIdx.x + gridDim.x*blockIdx.y)*TILE_WIDTH*TILE_WIDTH + nx;
if(index_in < cLength)
{
sumArray[sourceTargetArray[index_in].y] += fabs(weightArray[index_in]);
//__threadfence();
__threadfence_block();
}
}
首先,网络中的连接数是cLength。对于每个连接,都有一个源神经元和一个目标神经元,以及该连接的权重。 SourceTargetArray 包含该信息。所以sourceTargetArray的索引i是连接i的源神经元索引,连接i的目标神经元索引。 weightArray 包含权重信息(因此weightArray 的索引i 对应于连接i)。
如您所见,SumArray 是我存储总和的位置。所以内核将sumArray(在连接i的目标神经元索引处)增加了连接权重的绝对值i。直观地说,对于到神经元的所有传入连接,将所有权重相加。这就是我试图用这个内核做的所有事情。最终,我将使用这个总和对权重进行归一化。
问题是它是错误的。我已经连续完成了这个,答案是不同的。答案不同,通常相差约 12-15 倍(因此正确答案将是 700.0,而我得到的结果在 50 年代范围内)。
您可以看到我添加了__threadfence()(和__threadfence_block(),以确保每个线程不会同时进行写入)。我不确定这是否是我的代码的问题。我确保权重数组与我测试的串行版本相同,并且源/目标信息也相同。我做错了什么?
编辑:作为参考,CUDA Programming Guide v3.1 附录 B.5 Memory Fence Functions 中描述了使用的__threadfence()
【问题讨论】:
标签: cuda parallel-processing gpu gpgpu