0

所以我目前正在传递 2 个 GPULevel,我希望内核获取它们中的每一个,然后如果在有的数组中,levelsarr1想检查值是否 >= 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
4

1 回答 1

1

LCount是一个指向 int 的指针,您将它用作整数。您的循环可能超出范围。

CL_OUT_OF_RESOURCES通常表示超出范围的寻址。

您的 OpenCL 编译器应该发出警告。您可能需要检查clGetProgramBuildInfo(...,CL_PROGRAM_BUILD_LOG,...)返回的字符串。

于 2013-03-29T02:14:03.457 回答