Similar to this question, I'm trying to implement the HelloWorld example from this video by Wesley Shillingford, except this time with OpenCL 2.1. I can get it to run if I use the default context, but not if I create my own (as the video does).
When I use my own context, it produces a cl::Error (-34 = CL_INVALID_CONTEXT):
CL_INVALID_CONTEXT = the given context is invalid OpenCL context, or the context associated with certain parameters are not the same.
- I'm not sure how I could tell that the context is invalid. I've tried comparing the
defaultContext
tomyContext
, and they match of everything exceptCL_CONTEXT_REFERENCE_COUNT
. Which doesn't seem to matter (but maybe it does). - I could be mixing contexts. However, I assign the context I want to use to
chosenContext
and use that everywhere I need a context.
It seems that something is somehow using the default context instead of my supplied context, but I haven't been able to spot where. Any insights would be appreciated.
The code:
#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;
}
Build Command:
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';
}
Aucun commentaire:
Enregistrer un commentaire