Exemple #1
0
    platform_manager::platform_manager()
    {
        cl_uint n = 0;
        cl_int err = ::clGetPlatformIDs(0, NULL, &n);
        OCLM_THROW_IF_EXCEPTION(err, "clGetPlatformIDs");

        std::vector<cl_platform_id> platform_ids(n);

        err = ::clGetPlatformIDs(n, &platform_ids[0], NULL);
        OCLM_THROW_IF_EXCEPTION(err, "clGetPlatformIDs");

        platforms.resize(n);
        std::copy(platform_ids.begin(), platform_ids.end(), platforms.begin());

        default_platform = platforms[0];
        default_device = default_platform.devices[0];
    }
int main() {
    cl_int error_code = CL_SUCCESS;

    try {
        // find Intel platform
        cl_uint num_platforms = 0;
        error_code = clGetPlatformIDs(0, nullptr, &num_platforms);
        HANDLE_CL_ERROR(clGetPlatformIDs)
        std::unique_ptr<cl_platform_id[]> platform_ids(
                new cl_platform_id[static_cast<const std::size_t>(num_platforms)]);
        error_code = clGetPlatformIDs(num_platforms, platform_ids.get(), nullptr);
        HANDLE_CL_ERROR(clGetPlatformIDs)
        cl_platform_id platform = nullptr;
        for (std::size_t i = 0; i != static_cast<const std::size_t>(num_platforms); ++i) {
            std::size_t platform_name_size = 0;
            error_code = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME, 0, nullptr, &platform_name_size);
            HANDLE_CL_ERROR(clGetPlatformInfo)
            std::unique_ptr<char[]> platform_name(new char[platform_name_size]);
            error_code = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_NAME,
                                           platform_name_size, platform_name.get(), nullptr);
            HANDLE_CL_ERROR(clGetPlatformInfo)
            if (std::strcmp(beignet_platform_name, platform_name.get()) == 0) {
                platform = platform_ids[i];
                std::cout << "Platform: " << platform_name.get() << std::endl;
                break;
            }
        }
        if (platform == nullptr) {
            throw std::runtime_error(std::string("Couldn't find platform with name: ") + beignet_platform_name);
        }

        // find Intel GPU
        cl_device_id device = nullptr;
        error_code = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, nullptr);
        HANDLE_CL_ERROR(clGetDeviceIDs)
        std::size_t device_name_size = 0;
        error_code = clGetDeviceInfo(device, CL_DEVICE_NAME, 0, nullptr, &device_name_size);
        HANDLE_CL_ERROR(clGetDeviceInfo)
        std::unique_ptr<char[]> device_name(new char[device_name_size]);
        error_code = clGetDeviceInfo(device, CL_DEVICE_NAME, device_name_size, device_name.get(), nullptr);
        HANDLE_CL_ERROR(clGetDeviceInfo)
        std::cout << "Device: " << device_name.get() << std::endl;

        // create OpenCL context, command queue, program and kernel
        const auto context = clCreateContext(nullptr, 1, &device, nullptr, nullptr, &error_code);
        HANDLE_CL_ERROR(clCreateContext)
        const auto command_queue = clCreateCommandQueue(context, device, 0, &error_code);
        HANDLE_CL_ERROR(clCreateCommandQueue)

        const char *source_strings[1];
        source_strings[0] = kernel_source;
        const std::size_t source_size = std::strlen(kernel_source);
        const auto program = clCreateProgramWithSource(context, 1, source_strings, &source_size, &error_code);
        HANDLE_CL_ERROR(clCreateProgramWithSource)
        error_code = clBuildProgram(program, 1, &device, "", nullptr, nullptr);
        HANDLE_CL_ERROR(clBuildProgram)
        const auto kernel = clCreateKernel(program, "print_hello", &error_code);
        HANDLE_CL_ERROR(clCreateKernel)

        // enqueue kernel and set event completion handler
        cl_event event;
        std::size_t global_work_size = 1;
        error_code = clEnqueueNDRangeKernel(command_queue, kernel, 1, nullptr, &global_work_size, nullptr,
                                            0, nullptr, &event);
        HANDLE_CL_ERROR(clEnqueueNDRangeKernel)

        error_code = clSetEventCallback(event, CL_COMPLETE, [](cl_event, cl_int, void *) {
            std::cout << "OpenCL callback" << std::endl;
            // Notify the waiting thread that the kernel is completed
            {
                std::lock_guard<std::mutex> cond_lock(cond_mutex);
                kernel_complete = true;
            }
            cond_var.notify_one();
        }, nullptr);
        HANDLE_CL_ERROR(clSetEventCallback)

        error_code = clFlush(command_queue);
        HANDLE_CL_ERROR(clFlush)

        // simulate work
        std::this_thread::sleep_for(std::chrono::seconds(1));

        // do work, dependent on kernel completion
        {
            std::unique_lock<std::mutex> cond_lock(cond_mutex);
            while (!kernel_complete) {
                if (cond_var.wait_for(cond_lock, std::chrono::seconds(5)) == std::cv_status::timeout) {
                    std::cout << "WARNING: A 5 second timeout has been reached on the condition variable.\n"
                            "         This may be a deadlock." << std::endl;
                }
            }
        }
        // When using Beignet, this will never be called as a deadlock will occur.
        std::cout << "Doing work, dependent on the kernel's completion" << std::endl;
    } catch (const std::exception &e) {
        std::cout << "Error: " << e.what() << std::endl;
    } catch (...) {
        std::cout << "Unknown error" << std::endl;
    }
}