OpenCL 2.1 C ++ HelloWorld:无效的上下文?

时间:2018-04-22 14:22:05

标签: c++11 opencl

this question类似,我试图通过Wesley Shillingford从this video实现HelloWorld示例,除了这次使用OpenCL 2.1。如果我使用默认上下文,我可以让它运行,但如果我创建自己的(如视频那样)则不能。

当我使用自己的上下文时,它会产生一个cl :: Error(-34 = CL_INVALID_CONTEXT):

From here

  

CL_INVALID_CONTEXT =给定的上下文无效OpenCL上下文,或与某些参数关联的上下文不相同。

  1. 我不确定如何判断上下文无效。我已尝试将defaultContextmyContext进行比较,并且除了CL_CONTEXT_REFERENCE_COUNT之外,它们都匹配。这似乎并不重要(但可能确实如此)。
  2. 我可以混合上下文。但是,我将我想要使用的上下文分配给chosenContext,并在需要上下文的任何地方使用它。
  3. 似乎某些东西以某种方式使用默认上下文而不是我提供的上下文,但我无法找到位置。任何见解都将不胜感激。

    代码:

    #define CL_HPP_ENABLE_EXCEPTIONS
    #define CL_HPP_TARGET_OPENCL_VERSION 200
    
    #include <CL/cl2.hpp>
    #include <fstream>
    #include <iostream>
    
    int main()
    {
        // Get Platform and Device
        std::vector<cl::Platform> platforms;
        cl::Platform::get(&platforms);
        auto platform = platforms.front();
        std::vector<cl::Device> devices;
        platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
        auto device = devices.front();
    
        //This context doesn't work. Causes CL_INVALID_CONTEXT (-34)
        cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform(), 0};
        cl::Context myContext(device, properties);
    
        //If I stick with the default context, things work.
        cl::Context defaultContext = cl::Context::getDefault();
    
        //The choice of context here determines whether it works or not:
        // myContext -> Fails with CL_INVALID_CONTEXT (-34)
        // defaultContext -> works
        auto chosenContext = myContext;
    
        std::ifstream helloWorldFile("hello_world.cl");
        std::string src(std::istreambuf_iterator<char>(helloWorldFile), (std::istreambuf_iterator<char>()));
    
        cl::Program program(chosenContext, src);
        program.build("-cl-std=CL2.1");
    
        //Debugging code: Check to make sure that the contexts are similar
        auto myContextDevices = myContext.getInfo<CL_CONTEXT_DEVICES>();
        auto defaultContextDevices = defaultContext.getInfo<CL_CONTEXT_DEVICES>();
        auto devicesMatch = myContextDevices == defaultContextDevices; //true
    
        auto myContextProperties = myContext.getInfo<CL_CONTEXT_PROPERTIES>();
        auto defaultContextProperties = defaultContext.getInfo<CL_CONTEXT_PROPERTIES>();
        auto propertiesMatch = myContextProperties == defaultContextProperties; //true
    
        auto myContextNumDevices = myContext.getInfo<CL_CONTEXT_NUM_DEVICES>();
        auto defaultContextNumDevices = defaultContext.getInfo<CL_CONTEXT_NUM_DEVICES>();
        auto numDevicesMatch = myContextNumDevices == defaultContextNumDevices; //true
    
        auto myContextRefCount = myContext.getInfo<CL_CONTEXT_REFERENCE_COUNT>();           // 1 if defaultContext, 3 if myContext
        auto defaultContextRefCount = defaultContext.getInfo<CL_CONTEXT_REFERENCE_COUNT>(); // 4 if defaultContext, 2 if myContext
        auto refCountsMatch = myContextRefCount == defaultContextRefCount;                  // false
    
        auto contextsMatch = myContext == defaultContext; //false
        //End of debugging code
    
        //Continuing with computation
        char buf[16];
        cl::Buffer outputBuffer = cl::Buffer(CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(buf));
    
        cl::Kernel kernel(program, "HelloWorld");
        kernel.setArg(0, outputBuffer);
    
        cl::CommandQueue commandQueue(chosenContext, device);
        auto result = commandQueue.enqueueNDRangeKernel(kernel, 0, 1, 1);           //CL_SUCCESS
        commandQueue.enqueueReadBuffer(outputBuffer, CL_TRUE, 0, sizeof(buf), buf); // Execution fails here, raises cl::Error (-34)
    
        std::cout << buf;
    
        return EXIT_SUCCESS;
    }
    

    构建命令:

    g++ -g hello_world_21.cpp -IOpenCL-Headers/opencl21 -std=c++11 -lOpenCL
    

    hello_world.cl:

    __kernel void HelloWorld(__global char* output) {
        output[0] = 'H';
        output[1] = 'e';
        output[2] = 'l';
        output[3] = 'l';
        output[4] = 'o';
        output[5] = ' ';
        output[6] = 'W';
        output[7] = 'o';
        output[8] = 'r';
        output[9] = 'l';
        output[10] = 'd';
        output[11] = '!';
        output[12] = '\n';
    }
    

1 个答案:

答案 0 :(得分:1)

您仍在使用全局内存缓冲区的默认上下文,而不是使用您自己的上下文:

cl::Buffer outputBuffer = cl::Buffer(CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(buf));

只需将此行更改为以下内容即可:

cl::Buffer outputBuffer = cl::Buffer(myContext, CL_MEM_WRITE_ONLY | CL_MEM_HOST_READ_ONLY, sizeof(buf));