2011-12-18 174 views
2

我不斷地收到一個訪問衝突錯誤,我試圖建立我的所有內核。我從書中拿的其他內核似乎工作正常。OpenCL enqueueNDRangeKernel導致訪問衝突錯誤

https://github.com/ssarangi/VideoCL - 這是代碼的地方。

東西似乎缺少在這。有人可以幫我解決這個問題。

非常感謝。

[James] - 感謝您的建議,並且您是對的。我在Win 7上使用AMD Redwood卡做這件事。我有AMD APP SDK 2.5的Catalyst 11.7驅動程序。我張貼下面的代碼。

#include <iostream> 
#include "bmpfuncs.h" 

#include "CLManager.h" 

void main() 
{ 
    float theta = 3.14159f/6.0f; 
    int W ; 
    int H ; 

    const char* inputFile = "input.bmp"; 
    const char* outputFile = "output.bmp"; 

    float* ip = readImage(inputFile, &W, &H); 
    float *op = new float[W*H]; 

    //We assume that the input image is the array 「ip」 
    //and the angle of rotation is theta 
    float cos_theta = cos(theta); 
    float sin_theta = sin(theta); 

    try 
    { 
     CLManager* clMgr = new CLManager(); 

     // Build the Source 
     unsigned int pgmID = clMgr->buildSource("rotation.cl"); 

     // Create the kernel 
     cl::Kernel* kernel = clMgr->makeKernel(pgmID, "img_rotate"); 

     // Create the memory Buffers 
     cl::Buffer* clIp = clMgr->createBuffer(CL_MEM_READ_ONLY, W*H*sizeof(float)); 
     cl::Buffer* clOp = clMgr->createBuffer(CL_MEM_READ_WRITE, W*H*sizeof(float)); 

     // Get the command Queue 
     cl::CommandQueue* queue = clMgr->getCmdQueue(); 
     queue->enqueueWriteBuffer(*clIp, CL_TRUE, 0, W*H*sizeof(float), ip); 

     // Set the arguments to the kernel 
     kernel->setArg(0, clOp); 
     kernel->setArg(1, clIp); 
     kernel->setArg(2, W); 
     kernel->setArg(3, H); 
     kernel->setArg(4, sin_theta); 
     kernel->setArg(5, cos_theta); 

     // Run the kernel on specific NDRange 
     cl::NDRange globalws(W, H); 


     queue->enqueueNDRangeKernel(*kernel, cl::NullRange, globalws, cl::NullRange); 

     queue->enqueueReadBuffer(*clOp, CL_TRUE, 0, W*H*sizeof(float), op); 

     storeImage(op, outputFile, H, W, inputFile); 
    } 
    catch(cl::Error error) 
    { 
     std::cout << error.what() << "(" << error.err() << ")" << std::endl; 
    } 
} 

我得到的錯誤在queue-> enqueueNDRangeKernel行。 我有隊列和內核存儲在一個類中。

CLManager::CLManager() 
    : m_programIDs(-1) 
{ 
    // Initialize the Platform 
    cl::Platform::get(&m_platforms); 

    // Create a Context 
    cl_context_properties cps[3] = { 
     CL_CONTEXT_PLATFORM, 
     (cl_context_properties)(m_platforms[0])(), 
     0 
    }; 

    m_context = cl::Context(CL_DEVICE_TYPE_GPU, cps); 

    // Get a list of devices on this platform 
    m_devices = m_context.getInfo<CL_CONTEXT_DEVICES>(); 

    cl_int err; 

    m_queue = new cl::CommandQueue(m_context, m_devices[0], 0, &err); 
} 


cl::Kernel* CLManager::makeKernel(unsigned int programID, std::string kernelName) 
{ 
    cl::CommandQueue queue = cl::CommandQueue(m_context, m_devices[0]); 

    cl::Kernel* kernel = new cl::Kernel(*(m_programs[programID]), kernelName.c_str()); 

    m_kernels.push_back(kernel); 

    return kernel; 
} 
+0

嗨,ssarangi。你沒有提到足以在這裏得到認真的幫助。你應該告訴我們你的平臺和CL的實現,併發布有問題的代碼,包括你已經做了什麼來讓你自己的工作。鏈接到外部存儲庫是一個不好的主意,因爲該鏈接可能無法在路上有效。 – James 2011-12-19 01:06:10

回答

4

我檢查了你的代碼。儘管我在Linux上。在運行時,我得到錯誤-38,這意味着CL_INVALID_MEM_OBJECT。所以我去檢查你的緩衝區。

cl::Buffer* clIp = clMgr->createBuffer(CL_MEM_READ_ONLY, W*H*sizeof(float)); 
cl::Buffer* clOp = clMgr->createBuffer(CL_MEM_READ_WRITE, W*H*sizeof(float)); 

然後,你將緩衝區的指針:

kernel->setArg(0, clOp); 
kernel->setArg(1, clIp); 

setArg期待值,因此緩衝區指針應解除引用:

kernel->setArg(0, *clOp); 
kernel->setArg(1, *clIp); 

這些變化後貓旋轉;)

+0

數組的添加可能與所顯示的代碼一致,因爲您將數組作爲內核參數傳遞給數組(實際上是指向第一個值的指針)。 – rdoubleui 2011-12-19 12:45:54

+0

非常感謝。我忽略這一點是愚蠢的。這實際上確實解決了這個問題。再次感謝。 – ssarangi 2011-12-19 13:24:50