与this question类似,我试图通过Wesley Shillingford从this video实现HelloWorld示例,除了这次使用OpenCL 2.1。如果我使用默认上下文,我可以让它运行,但如果我创建自己的(如视频那样)则不能。
当我使用自己的上下文时,它会产生一个cl :: Error(-34 = CL_INVALID_CONTEXT):
CL_INVALID_CONTEXT =给定的上下文无效OpenCL上下文,或与某些参数关联的上下文不相同。
defaultContext
与myContext
进行比较,并且除了CL_CONTEXT_REFERENCE_COUNT
之外,它们都匹配。这似乎并不重要(但可能确实如此)。chosenContext
,并在需要上下文的任何地方使用它。似乎某些东西以某种方式使用默认上下文而不是我提供的上下文,但我无法找到位置。任何见解都将不胜感激。
代码:
#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';
}
答案 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));