Оболочка OpenCL C ++.Можно ли извлечь платформу и устройство из класса Context? - PullRequest
0 голосов
/ 13 декабря 2018

Я изучаю 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;
        }
    }
}

1 Ответ

0 голосов
/ 13 декабря 2018

Вы можете найти список устройств, связанных с контекстом, используя функцию clGetContextInfo(CL_CONTEXT_DEVICES) (или Context::getInfo() для C ++).Затем вы можете выполнить итерации по этим устройствам и запросить статус сборки программы или журнал сборки для каждого устройства.

Эту же функцию можно использовать для получения платформы из контекста: для CL_CONTEXT_PROPERTIES запрос вернет массивсвойств, которые должны содержать значение для CL_CONTEXT_PLATFORM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...