我为我的测试NVIDIA和AMD GPU编写了以下代码
kernel void computeLayerOutput_Rolled(
global Layer* layers,
global float* weights,
global float* output,
constant int* restrict netSpec,
int layer)
{
const int n = get_global_size(0);
const int nodeNumber = get_global_id(0); //There will be an offset depending on the layer we are operating on
int numberOfWeights;
float t;
//getPosition(i, netSpec, &layer, &nodeNumber);
numberOfWeights = layers[layer].nodes[nodeNumber].numberOfWeights;
//if (sizeof(Layer) > 60000) // This is the extra code add for nvidia
// exit(0);
t = 0;
for (unsigned int j = 0; j != numberOfWeights; ++j)
t += threeD_access(weights, layer, nodeNumber, j, MAXSIZE, MAXSIZE) *
twoD_access(output, layer-1, j, MAXSIZE);
twoD_access(output, layer, nodeNumber, MAXSIZE) = sigmoid(t);
}
一开始,我没有添加检查Layer大小的代码,它可以在AMD Kalindi GPU上运行,但崩溃并在NVIDIA Tesla C2075上报告错误代码-36。
由于我之前重写了结构类型Layer
并减小了它的大小,我决定检查Layer
的大小以确定此结构是否在内核代码中定义良好。然后我添加了这段代码
if (sizeof(Layer) > 60000)
exit(0);
然后在NVIDIA上就可以了。然而,奇怪的是,当我在此之前添加//
时,就像上面的给定代码一样,它仍然有效。 (我相信当我在内核代码中重写某些东西时我不需要make clean && make
,但我仍然这样做了)然而,当我回滚到不包含此注释的版本时,它失败并出现错误代码-36再次。这让我很困惑。我认为我的代码的两个版本是相同的,不是吗?