0

したがって、現在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 が正しく返され、2 番目に返された nInput が正しい値として返され、残りが間違っているため、本当に奇妙な結果が得られます。

これは私がカーネル側で本当にやりたいことですが、for ループを追加するとすぐに CL_OUT_OF_RESOURCES が返されます。実験のためにループを取り除いて 1 つだけ追加したとしてもです。

必要なカーネル:

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 である必要があるのは奇妙だと思います (そうしないと、両方で間違った結果が再び生成されます)。この元のカーネルが 2 番目のレベルで台無しになったので、2 番目のカーネルを作成しました。この 2 番目のカーネルでは、まさに私が実装したかったものですが、何らかの理由で 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 に答える