Neural network 这个OpenCL内核会导致错误CL\U INVALID\U COMMAND\U QUEUE吗
我在实现前馈多层感知器时遇到了一个问题,使用JOCL在Java中的OpenCL中使用了back-prop学习。以下是计算阶段的核心代码:Neural network 这个OpenCL内核会导致错误CL\U INVALID\U COMMAND\U QUEUE吗,neural-network,opencl,Neural Network,Opencl,我在实现前馈多层感知器时遇到了一个问题,使用JOCL在Java中的OpenCL中使用了back-prop学习。以下是计算阶段的核心代码: #pragma OPENCL EXTENSION cl_khr_fp64 : enable __kernel void Neuron(__global const double *inputPatterns, __global double *weights,
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
__kernel void Neuron(__global const double *inputPatterns,
__global double *weights,
__global const int *numInputs,
__global const int *activation,
__global const double *bias,
__global const int *usingBias,
__global double *values,
__global const int *maxNumFloats,
__global const int *patternIndex,
__global const int *inputPatternSize,
__global const int *indexOffset,
__global const int *isInputNeuron,
__global const int *inputs)
{
int gid = get_global_id(0);
double sum = 0.0;
for(int i = 0; i < numInputs[gid+indexOffset[0]]; i++)
{
sum += values[inputs[(gid+indexOffset[0]) * maxNumFloats[0] + i]] *
weights[(gid+indexOffset[0]) * maxNumFloats[0] + i];
}
if(usingBias[gid+indexOffset[0]])
sum += bias[gid+indexOffset[0]];
if(isInputNeuron[gid+indexOffset[0]])
sum += inputPatterns[gid+indexOffset[0]+(patternIndex[0] * inputPatternSize[0])];
if(activation[gid+indexOffset[0]] == 1)
sum = 1.0 / (1.0 + exp(-sum));
values[gid + indexOffset[0]] = sum;
}
#pragma OPENCL扩展cl_khr_fp64:启用
__内核空神经元(uu全局常数双*输入模式,
__全球双*权重,
__全局常量int*numinput,
__全局常量int*激活,
__全局常数双*偏差,
__全局常量int*使用偏差,
__全局双*值,
__全局常量int*maxNumFloats,
__全局常量int*patternIndex,
__全局常量int*inputPatternSize,
__全局常量int*indexOffset,
__全局常量int*isInputNeuron,
__全局常量int*输入)
{
int gid=获取全局id(0);
双和=0.0;
for(int i=0;i
基本上,我为网络中的每一层运行这个内核。对于第一层,没有“输入”,因此循环不会执行。然而,由于第一层是一个输入节点层,因此它确实添加了输入模式中的相关值。这执行得很好,此时我可以读回值
但是,当我尝试运行第二层时(第一层的每个节点都有输入),对clFinish()的调用会返回错误CL\u INVALID\u COMMAND\u QUEUE。有时,此错误还伴随着驾驶员碰撞和恢复。例如,我已经读过很多文章,说这可能是TDR超时的问题,并试图提高限制,但不确定这是否会产生任何影响
我正在检查对clSetKernelArg()的调用,以检查是否有任何愚蠢的行为,但是有人能在代码中发现任何明显的错误吗?由于包含for循环,似乎在第二层引入了错误。。。如果需要的话,我可以澄清其中的任何参数,但对于一篇最初的帖子来说,这似乎有点过头了
此外,我完全知道这段代码可能会冒犯各地有能力的编码人员,但请随意使用:p
编辑:主机代码:
//Calc
for(int k = 0; k < GPUTickList.length; k++)
{
clFlush(clCommandQueue);
clFinish(clCommandQueue);
//If input nodes
if(k == 0)
//Set index offset to 0
GPUMapIndexOffset.asIntBuffer().put(0, 0);
else
//Update index offset
GPUMapIndexOffset.asIntBuffer().put(0,
GPUMapIndexOffset.asIntBuffer().get(0) + GPUTickList[k-1]);
//Write index offset to GPU buffer
ret = clEnqueueWriteBuffer(clCommandQueue, memObjects[12], CL_TRUE, 0,
Sizeof.cl_int, Pointer.to(GPUMapIndexOffset.position(0)), 0, null, null);
//Set work size (width of layer)
global_work_size[0] = GPUTickList[k];
ret = clEnqueueNDRangeKernel(clCommandQueue, kernel_iterate, 1,
global_work_offset, global_work_size, local_work_size,
0, null, null);
}
//计算
for(int k=0;k
编辑2:我已将完整代码上载到。我不确定循环上面有什么。。是否使用此循环以外的队列?下面是一些你可能想尝试的东西
//flush + finish if you need to before the loop, otherwise remove these lines
clFlush(clCommandQueue);
clFinish(clCommandQueue);
cl_event latestEvent;
//Calc
for(int k = 0; k < GPUTickList.length; k++)
{
//If input nodes
if(k == 0)
//Set index offset to 0
GPUMapIndexOffset.asIntBuffer().put(0, 0);
else
//Update index offset
GPUMapIndexOffset.asIntBuffer().put(0,
GPUMapIndexOffset.asIntBuffer().get(0) + GPUTickList[k-1]);
//Write index offset to GPU buffer
ret = clEnqueueWriteBuffer(clCommandQueue, memObjects[12], CL_TRUE, 0,
Sizeof.cl_int, Pointer.to(GPUMapIndexOffset.position(0)), 0, null, null);
//Set work size (width of layer)
global_work_size[0] = GPUTickList[k];
ret = clEnqueueNDRangeKernel(clCommandQueue, kernel_iterate, 1,
global_work_offset, global_work_size, local_work_size,
0, null, &latestEvent);
clWaitForEvents(1, &latestEvent);
}
//如果需要,请在循环之前刷新并完成,否则请删除这些行
clFlush(clCommandQueue);
clFinish(clCommandQueue);
cl_事件延迟;
//计算
for(int k=0;k
已解决。修复了此错误,将所有使用[0]编制索引的内容设置为直接内核参数,而不是缓冲区。很明显,硬件不喜欢很多东西同时访问缓冲区的一个特定元素。您有一部分主机代码要共享吗?如果内核运行于第一层神经元,我怀疑内核本身是否存在问题。另外,您是否尝试过使用clWaitForEvents()而不是clFinish()?当然,添加了这个内核在循环中排队的位置,如果需要,可以发布更多,只需说什么。我确实尝试过事件,但它给我带来了麻烦,所以我坚持阻止调用和clFinish(),我现在再尝试一次,看看效果如何。另外,我有整个文件,GPUTrain函数是重要的一个(它有点单一)。谢谢你的意见!不客气。我不知道您正在使用java+ocl。我希望指针的东西仍然有效。我再看一眼这张照片