OpenCL enqueueNDRangeKernel 导致访问冲突错误

ssa*_*ngi 2 opencl

我正在尝试构建的所有内核不断收到访问冲突错误。我从书中获取的其他内核似乎工作得很好。

\n\n

https://github.com/ssarangi/VideoCL - 这是代码所在的位置。

\n\n

这其中似乎缺少了一些东西。有人可以帮我解决这个问题吗?

\n\n

非常感谢。

\n\n

[詹姆斯] - 谢谢你的建议,你是对的。我在 Win 7 上使用 AMD Redwood 卡进行此操作。我有带有 AMD APP SDK 2.5 的 Catalyst 11.7 驱动程序。我发布下面的代码。

\n\n
#include <iostream>\n#include "bmpfuncs.h"\n\n#include "CLManager.h"\n\nvoid main()\n{\n    float theta = 3.14159f/6.0f;\n    int W ;\n    int H ;\n\n    const char* inputFile = "input.bmp";\n    const char* outputFile = "output.bmp";\n\n    float* ip = readImage(inputFile, &W, &H);\n    float *op = new float[W*H];\n\n    //We assume that the input image is the array \xe2\x80\x9cip\xe2\x80\x9d\n    //and the angle of rotation is theta\n    float cos_theta = cos(theta);\n    float sin_theta = sin(theta);\n\n    try\n    {\n        CLManager* clMgr = new CLManager();\n\n        // Build the Source\n        unsigned int pgmID = clMgr->buildSource("rotation.cl");\n\n        // Create the kernel\n        cl::Kernel* kernel = clMgr->makeKernel(pgmID, "img_rotate");\n\n        // Create the memory Buffers\n        cl::Buffer* clIp = clMgr->createBuffer(CL_MEM_READ_ONLY, W*H*sizeof(float));\n        cl::Buffer* clOp = clMgr->createBuffer(CL_MEM_READ_WRITE, W*H*sizeof(float));\n\n        // Get the command Queue\n        cl::CommandQueue* queue = clMgr->getCmdQueue();\n        queue->enqueueWriteBuffer(*clIp, CL_TRUE, 0, W*H*sizeof(float), ip);\n\n        // Set the arguments to the kernel\n        kernel->setArg(0, clOp);\n        kernel->setArg(1, clIp);\n        kernel->setArg(2, W);\n        kernel->setArg(3, H);\n        kernel->setArg(4, sin_theta);\n        kernel->setArg(5, cos_theta);\n\n        // Run the kernel on specific NDRange\n        cl::NDRange globalws(W, H);\n\n\n        queue->enqueueNDRangeKernel(*kernel, cl::NullRange, globalws, cl::NullRange);\n\n        queue->enqueueReadBuffer(*clOp, CL_TRUE, 0, W*H*sizeof(float), op);\n\n        storeImage(op, outputFile, H, W, inputFile);\n    }\n    catch(cl::Error error)\n    {\n        std::cout << error.what() << "(" << error.err() << ")" << std::endl;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我在queue->enqueueNDRangeKernel 行收到错误。\n我将队列和内核存储在一个类中。

\n\n
CLManager::CLManager()\n    : m_programIDs(-1)\n{\n    // Initialize the Platform\n    cl::Platform::get(&m_platforms);\n\n    // Create a Context\n    cl_context_properties cps[3] = {\n        CL_CONTEXT_PLATFORM,\n        (cl_context_properties)(m_platforms[0])(),\n        0\n    };\n\n    m_context = cl::Context(CL_DEVICE_TYPE_GPU, cps);\n\n    // Get a list of devices on this platform\n    m_devices = m_context.getInfo<CL_CONTEXT_DEVICES>();\n\n    cl_int err;\n\n    m_queue = new cl::CommandQueue(m_context, m_devices[0], 0, &err);\n}\n\n\ncl::Kernel* CLManager::makeKernel(unsigned int programID, std::string kernelName)\n{\n    cl::CommandQueue queue = cl::CommandQueue(m_context, m_devices[0]);\n\n    cl::Kernel* kernel = new cl::Kernel(*(m_programs[programID]), kernelName.c_str());\n\n    m_kernels.push_back(kernel);\n\n    return kernel;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

rdo*_*eui 5

我检查了你的代码。不过我用的是Linux。在运行时我收到 Error -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));
Run Code Online (Sandbox Code Playgroud)

然后将缓冲区作为指针传递:

kernel->setArg(0, clOp);
kernel->setArg(1, clIp);
Run Code Online (Sandbox Code Playgroud)

setArg需要一个值,因此应该取消引用缓冲区指针:

kernel->setArg(0, *clOp);
kernel->setArg(1, *clIp);
Run Code Online (Sandbox Code Playgroud)

进行这些更改后,猫会旋转;)