#ifndef XPU_OCL_ENGINE_IMPL_HPP
#define XPU_OCL_ENGINE_IMPL_HPP
#include <tuple>
#include <CL/cl.h>
#include "common/engine_impl.hpp"
#include "common/utils.hpp"
#include "xpu/ocl/engine_id.hpp"
#include "xpu/ocl/stream_impl.hpp"
#include "xpu/ocl/utils.hpp"
namespace dnnl {
namespace impl {
namespace xpu {
namespace ocl {
class engine_impl_t : public impl::engine_impl_t {
public:
engine_impl_t() = delete;
engine_impl_t(cl_device_id device, cl_context context, size_t index)
: impl::engine_impl_t(engine_kind::gpu, runtime_kind::ocl, index)
, device_(device)
, context_(context)
, is_user_context_(context) {}
~engine_impl_t() override = default;
status_t init() override {
cl_int err = CL_SUCCESS;
err = xpu::ocl::clGetDeviceInfo(device(), CL_DEVICE_PLATFORM,
sizeof(platform_), &platform_, nullptr);
if (err != CL_SUCCESS) {
device_ = nullptr;
context_ = nullptr;
}
OCL_CHECK(err);
err = xpu::ocl::clRetainDevice(device());
if (err != CL_SUCCESS) {
device_ = nullptr;
context_ = nullptr;
}
OCL_CHECK(err);
if (is_user_context_) {
err = xpu::ocl::clRetainContext(context());
if (err != CL_SUCCESS) context_ = nullptr;
} else {
context_ = xpu::ocl::clCreateContext(
nullptr, 1, &device_.unwrap(), nullptr, nullptr, &err);
}
OCL_CHECK(err);
CHECK(check_device(engine_kind::gpu, device(), context()));
size_t param_size = 0;
err = xpu::ocl::clGetDeviceInfo(
device_, CL_DEVICE_NAME, 0, nullptr, ¶m_size);
OCL_CHECK(err);
name_ = std::string(param_size, '\0');
err = xpu::ocl::clGetDeviceInfo(
device_, CL_DEVICE_NAME, param_size, &name_[0], ¶m_size);
OCL_CHECK(err);
err = xpu::ocl::clGetDeviceInfo(
device_, CL_DRIVER_VERSION, 0, nullptr, ¶m_size);
OCL_CHECK(err);
std::string driver_version(param_size, '\0');
err = xpu::ocl::clGetDeviceInfo(device_, CL_DRIVER_VERSION, param_size,
&driver_version[0], nullptr);
OCL_CHECK(err);
if (runtime_version_.set_from_string(&driver_version[0])
!= status::success) {
runtime_version_.major = 0;
runtime_version_.minor = 0;
runtime_version_.build = 0;
}
return status::success;
}
status_t create_memory_storage(memory_storage_t **storage, engine_t *engine,
unsigned flags, size_t size, void *handle) const override;
cl_device_id device() const { return device_; }
cl_context context() const { return context_; }
cl_platform_id platform() const { return platform_; }
engine_id_t engine_id() const override {
return engine_id_t(new xpu::ocl::engine_id_impl_t(
device(), context(), kind(), runtime_kind(), index()));
}
status_t create_stream_impl(
impl::stream_impl_t **stream_impl, unsigned flags) const override {
auto *si = new xpu::ocl::stream_impl_t(flags);
if (!si) return status::out_of_memory;
*stream_impl = si;
return status::success;
}
const std::string &name() const { return name_; }
const runtime_version_t &runtime_version() const {
return runtime_version_;
}
int get_buffer_alignment() const override { return 128; }
private:
std::string name_;
runtime_version_t runtime_version_;
xpu::ocl::wrapper_t<cl_device_id> device_;
xpu::ocl::wrapper_t<cl_context> context_;
cl_platform_id platform_ = nullptr;
bool is_user_context_;
};
#define DECLARE_COMMON_OCL_ENGINE_FUNCTIONS() \
cl_device_id device() const { \
return impl()->device(); \
} \
cl_context context() const { \
return impl()->context(); \
} \
cl_platform_id platform() const { \
return impl()->platform(); \
}
} } } }
#endif