gpt4 book ai didi

c++ - 为什么这个 CUDA 内核给出与原始代码不同的结果?

转载 作者:行者123 更新时间:2023-11-28 03:28:02 28 4
gpt4 key购买 nike

我移植了这段代码:

    if(_layersCount > 1)
{
for(int i=_layersCount-2;i>=0;i--)
{
for(int j=0;j<_neuronsPerLayerCount[i];j++) // cuda kernel
{
localGradients[indexByLayerAndNeuron(i, j)] = 0;

for(int k=0;k<_neuronsPerLayerCount[i+1];k++)
{
localGradients[indexByLayerAndNeuron(i, j)] += _neuronsInputsWeights[indexByLayerNeuronAndInput(i+1, k, j)]
* localGradients[indexByLayerAndNeuron(i+1, k)];
}

localGradients[indexByLayerAndNeuron(i, j)] *= derivatives[indexByLayerAndNeuron(i, j)];
}
}
}

到 CUDA:

    if(_layersCount > 1)
{
for(int i=_layersCount-2;i>=0;i--)
{
// calculateLocalGradientsForAnotherLayers
blocksCount = floor((double) _neuronsPerLayerCount[i] / threads.x) + 1;
blocks = dim3(blocksCount, 1);

calculateLocalGradientsForAnotherLayers <<<blocks, threads>>> (deviceLocalGradients, _neuronsInputsWeights, deviceDerivatives, _neuronsPerLayerCount[i], _neuronsInPreviousLayers[i], _neuronsInPreviousLayers[i+1], _neuronsPerLayerCount[i+1], _inputsInPreviousLayers[i], _inputsInCurrentLayer[i]);
}
}

calculateLocalGradientsForAnotherLayers 内核:

__global__ void calculateLocalGradientsForAnotherLayers(double * localGradients, double * neuronsInputsWeights, double * derivatives, int neuronsCount, int neuronsInPreviousLayers, int neuronsInPreviousLayersWithCurrent, int neuronsInNextLayer, int inputsInPreviousLayers, int inputsInCurrentLayer)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;

if(idx < neuronsCount)
{
int neuron = neuronsInPreviousLayers + idx;

localGradients[neuron] = 0;

// this to Kernel, then reduce localGradients.
for(int k=0;k<neuronsInNextLayer;k++)
{
localGradients[neuron] += neuronsInputsWeights[inputsInPreviousLayers + k*inputsInCurrentLayer + idx]
* localGradients[neuronsInPreviousLayersWithCurrent + k];
}

localGradients[neuron] *= derivatives[neuron];
}
}

但是我从小数点后第二位看到了结果的差异。为什么误差这么大?除此以外,所有内核都运行良好。

我的 GPU 是 NV GF555M。它支持 double 。

最佳答案

在内核主体中,您需要通过 localGradients 数组进行某种 block 间同步:

for(int k=0;k<neuronsInNextLayer;k++)
{
localGradients[neuron] += neuronsInputsWeights[inputsInPreviousLayers + k*inputsInCurrentLayer + idx]
* localGradients[neuronsInPreviousLayersWithCurrent + k];
}

并发读/写访问可能会破坏 localGradients 元素的实际值。由于读/写没有同步,您可能会看到随机结果。

关于c++ - 为什么这个 CUDA 内核给出与原始代码不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13414256/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com