2013-03-28 82 views
0

所以我目前傳遞2 GPULevel的,我想內核採取其中每一個,然後如果在該陣列levelsarr1我想檢查值是否> = 0,如果它是改變價值。OpenCL for循環給出CL_OUT_OF_RESOURCES

我origonal代碼內核代碼是這樣的:

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循環時,即使我爲了實驗原因添加一個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 

回答

1

LCount是int的指針,並且您將它用作整數。你的循環可能超出範圍。

CL_OUT_OF_RESOURCES通常表示超出範圍尋址。

您的OpenCL編譯器應該發出警告。您可能需要檢查由clGetProgramBuildInfo(...,CL_PROGRAM_BUILD_LOG,...)返回的字符串。

+0

我從構建日誌沒有輸出,也沒有錯誤 – bubblebath

+1

您使用NVIDIA GPU嗎?我經常看到NVIDIA OpenCL驅動程序報告的CL_OUT_OF_RESOURCES錯誤超出了本地內存的訪問範圍。 – Dade916