Я изучаю OpenCL и уже знаю, что эту проблему можно решить, сначала правильно настроив платформу и устройство.
Я хотел бы узнать следующее.В бесплатном онлайн-курсе https://handsonopencl.github.io/ они начинают настраивать среду более удобным для меня способом.
Я сейчас на Exercise9 и должен писать программу для ядра и хоста с нуля.,Я хочу решить эту проблему таким коротким способом, который пропускает настройку платформы и устройства и вместо этого идет прямо к вызову класса Context.Вот так.
#define DEVICE CL_DEVICE_TYPE_GPU
try {
// Create a context
cl::Context context(DEVICE);
// Load source and build
cl::Program program(context, kernelSource, true);
// Get command queue
cl::CommandQueue queue(context);
// Create kernel functor
auto pi = cl::make_kernel<int>(program, "pi");
}
catch (cl::Error err) {
std::cout << "Exception" << std::endl;
std::cerr << "ERROR: " << err.what() << "(" << err_code(err.err()) << ")" << std::endl;
}
Сейчас.У меня все настроено правильно.Код C ++ компилируется, и если я предоставлю правильный kernelSource, программа также скомпилируется.
Пока все хорошо.
Проблема возникает, когда я допустил ошибку в исходном коде ядра и хотел бычтобы получить CL_PROGRAM_BUILD_LOG.Единственные вызовы, которые я нахожу, требуют, чтобы я передал cl :: device (который, очевидно, должен был существовать в какой-то момент внутри конструктора Context).Но поскольку я выбрал сокращенный маршрут, у меня нет этого под рукой за пределами конструктора.
Я знаю, что могу выполнять вызовы, по которым пропустил, и получать нужные мне значения.Но я чувствую, что это лишает вас возможности писать это в краткой форме.
Есть ли способ получить идентификатор устройства и платформы изнутри класса Context? Мой C ++ не самый сильный, но, глядя на класс, я не мог найти способ.
Есть ли какой-либо другой способ в этой оболочке или вызове, который я пропустил, который может получить журнал сборки для меня без предварительной настройки устройства и платформы?
Есть ли действительно веские причины, по которым я не должен настраивать свой код таким образом?
Единственное преимущество, которое я вижу при сканировании с помощью платформы и устройства, - это если я заинтересован в получении возможностейи сделать осознанный выбор.В данном случае это не так, поскольку я знаю, какое устройство я хочу использовать.
РЕДАКТИРОВАТЬ: добавив этот фрагмент кода, чтобы показать, как я решил свою проблему, используя context.getInfo (), предоставленный в ответе.
cl::Context context;
cl::Program program;
cl::CommandQueue queue;
try {
// Create a context
context = cl::Context(DEVICE);
// Load source and build
//program = cl::Program(context, kernelSource, true); // Don't do this. It will error with "abort() has been called
program = cl::Program(context, kernelSource);
program.build();
// Bind variables
d_sum = cl::Buffer(context, CL_MEM_WRITE_ONLY, sizeof(float) * 1);
// Get command queue
queue = cl::CommandQueue(context);
// Create kernel functor
auto clpi = cl::make_kernel<int, cl::Buffer, cl::LocalSpaceArg>(program, "pi");
// Run kernel
clpi(cl::EnqueueArgs(queue, cl::NDRange(num_steps), cl::NDRange(workgroup_size)), num_steps, d_sum, d_local_sums);
// Extract sum
cl::copy(queue, d_sum, h_sum.begin(), h_sum.end());
}
catch (cl::Error err) {
std::cout << "Exception" << std::endl;
std::cerr << "ERROR: " << err.what() << "(" << err_code(err.err()) << ")" << std::endl;
if (err.err() == CL_BUILD_PROGRAM_FAILURE)
{
for (cl::Device dev : context.getInfo<CL_CONTEXT_DEVICES>())
{
// Check the build status
cl_build_status status = program.getBuildInfo<CL_PROGRAM_BUILD_STATUS>(dev);
if (status != CL_BUILD_ERROR)
continue;
// Get the build log
std::string name = dev.getInfo<CL_DEVICE_NAME>();
std::string buildlog = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(dev);
std::cerr << "Build log for " << name << ":" << std::endl
<< buildlog << std::endl;
}
}
}