所以我目前正在传递 2 个 GPULevel,我希望内核获取它们中的每一个,然后如果在有的数组中,levels
我arr1
想检查值是否 >= 0 以及它是否改变了值。
我的原始代码内核代码是这样的:
typedef struct GPULevelDef
{
int nInput, nOutput;
float arr1[100];
float arr2[100];
}GPULevel;
__kernel void levelComposition(__global GPULevel *lLevels, __global GPULevel *oLevels, __global int *LCount)
{
int lIndex = get_global_id(1);
int wIndex = get_global_id(0);
int wCount = 0;
if(lIndex < LCount)
{
wCount = lLevels[lIndex].nInput*lLevels[lIndex].nOutput;
if(wIndex < wCount)
{
if(lLevels[lIndex].arr1[wIndex] >= 0)
{
oLevels[lIndex].arr1[wIndex] = (lLevels[lIndex].arr1[wIndex]) + 350;
}
}
}
}
但是,它会给我带来非常奇怪的结果,因为返回的第一个 GPULevel 是正确的,而第二个返回的只有 nInput 作为正确的值,其余的都是错误的。
这是我真正想要在内核方面做的事情,但是一旦我添加一个 for 循环,我就会得到一个返回的 CL_OUT_OF_RESOURCES,即使我出于实验原因将它剥离并只添加一个。
所需内核:
typedef struct GPULevelDef
{
int nInput, nOutput;
float arr1[100];
float arr2[100];
}GPULevel;
__kernel void levelComposition(__global GPULevel *lLevels, __global GPULevel *oLevels, __global int *lCount )
{
for(int lIndex = get_global_id(0); lIndex < lCount; lIndex++)
{
int wCount = lLevels[lIndex].nInput*lLevels[lIndex].nOutput;
for(int wIndex = get_global_id(0); wIndex < wCount; wIndex++)
{
if(lLevels[lIndex].arr1[wIndex] >= 0)
{
oLevels[lIndex].arr1[wIndex] = (lLevels[lIndex].arr1[wIndex]) + 350;
}
}
}
}
以下是重要的主机代码:
GPULevel* levelIn = (GPULevel*)malloc(sizeof(GPULevel)*levelCount);
GPULevel* levelOut = (GPULevel*)malloc(sizeof(GPULevel)*levelCount);
size_t dataSize = sizeof(GPULevel)*levelCount;
layerBuffer = clCreateBuffer(gpu.context,CL_MEM_READ_ONLY,dataSize,NULL,&err);
err = clEnqueueWriteBuffer(queue,layerBuffer,CL_TRUE,0,dataSize,(void*)layerIn,0,NULL,NULL);
cl_mem bufferB = clCreateBuffer(gpu.context,CL_MEM_WRITE_ONLY,dataSize,NULL,&err);
err = clEnqueueWriteBuffer(queue,bufferB,CL_TRUE,0,dataSize,(void*)layerOut,0,NULL,NULL);
GPULayer* val1 = (GPULevel*)calloc(sizeof(levelIn), sizeof(GPULevel));
GPULayer* val2 = (GPULevel*)calloc(sizeof(levelOut), sizeof(GPULevel));
err = clEnqueueReadBuffer(queue, layerBuffer, CL_TRUE, 0, dataSize, val1, 0, NULL, NULL);
err = clEnqueueReadBuffer(queue, bufferB, CL_TRUE, 0, dataSize, val2, 0, NULL, NULL);
总结一下:我使用了第一个内核,因为我认为这会给我想要的结果,因为我的印象是它是一个并行实现。我确实觉得奇怪的是 get_global_id() 对于 lIndex 确实需要为 1,对于 wIndex 需要为 0 才能使其正常工作(否则它会再次对两者产生错误的结果)。因此,当这个原始内核在第二层出现问题时,我创建了第二个内核。在第二个内核中,这正是我想要实现的,但由于某种原因,for 循环的引入会导致 CL_OUT_OF_RESOURCES 错误(-5)。我需要知道我应该使用和坚持使用哪个内核以及如何获得我想要的
谢谢
不确定这张图是否也有帮助
levels[0]
nInput = 2
nOutput = 5
arr1 [0] = 2
arr1 [1] = 7
arr1 [...] = -32
arr1 [n] = -1
arr2 [0] = 3
arr2 [1] = -2
arr2 [...] = 5
arr2 [n] = -3
levels[1]
nInput = 5
nOutput = 1
arr1 [0] = 3
arr1 [1] = 7
arr1 [...] = 72
arr1 [n] = -1
arr2 [0] = 5
arr2 [1] = -2
arr2 [...] = 1
arr2 [n] = -1
Parallel Parallel
------->oLevels[0].arr1[0] =lLevels[0].arr1[0] +350
lLevels[0] ------->oLevels[0].arr1[1] =lLevels[0].arr1[1] +350
------->oLevels[0].arr1[...] NOTHING
------->oLevels[0].arr1[n] NOTHING
------->oLevels[1].arr1[0] =lLevels[0].arr1[0] +350
lLevels[1] ------->oLevels[1].arr1[1] =lLevels[0].arr1[1] +350
------->oLevels[1].arr1[...] =lLevels[0].arr1[...] +350
------->oLevels[1].arr1[n] NOTHING