1 /*******************************************************************************
2 * Copyright 2020-2021 Intel Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16
17 #include <CL/sycl/backend/opencl.hpp>
18
19 #include "sycl/sycl_device_info.hpp"
20 #include "sycl/sycl_gpu_engine.hpp"
21 #include "sycl/sycl_utils.hpp"
22
23 #include "gpu/ocl/ocl_engine.hpp"
24 #include "gpu/ocl/ocl_gpu_detect.hpp"
25 #include "gpu/ocl/ocl_utils.hpp"
26
27 #include "cpu/platform.hpp"
28
29 namespace dnnl {
30 namespace impl {
31 namespace sycl {
32
init_arch(engine_t * engine)33 status_t sycl_device_info_t::init_arch(engine_t *engine) {
34 auto &device
35 = utils::downcast<const sycl_engine_base_t *>(engine)->device();
36
37 // skip cpu engines
38 if (!device.is_gpu()) return status::success;
39
40 // skip other vendors
41 const int intel_vendor_id = 0x8086;
42 auto vendor_id = device.get_info<cl::sycl::info::device::vendor_id>();
43 if (vendor_id != intel_vendor_id) return status::success;
44
45 // try to detect gpu by device name first
46 gpu_arch_ = gpu::ocl::detect_gpu_arch_by_device_name(name());
47 if (gpu_arch_ != gpu::compute::gpu_arch_t::unknown) return status::success;
48
49 // if failed, use slower method
50 backend_t be = get_sycl_backend(device);
51 if (be == backend_t::opencl) {
52 cl_int err = CL_SUCCESS;
53
54 auto ocl_dev_wrapper = gpu::ocl::make_ocl_wrapper(device.get());
55
56 auto ocl_dev = ocl_dev_wrapper.get();
57 auto ocl_ctx_wrapper = gpu::ocl::make_ocl_wrapper(
58 clCreateContext(nullptr, 1, &ocl_dev, nullptr, nullptr, &err));
59 OCL_CHECK(err);
60
61 gpu_arch_ = gpu::ocl::detect_gpu_arch(ocl_dev_wrapper, ocl_ctx_wrapper);
62 } else if (be == backend_t::level0) {
63 // TODO: add support for L0 binary ngen check
64 // XXX: query from ocl_engine for now
65 gpu::ocl::ocl_engine_factory_t f(engine_kind::gpu);
66
67 engine_t *engine;
68 CHECK(f.engine_create(&engine, 0));
69
70 std::unique_ptr<gpu::compute::compute_engine_t, engine_deleter_t>
71 compute_engine(
72 utils::downcast<gpu::compute::compute_engine_t *>(
73 engine));
74
75 auto *dev_info = compute_engine->device_info();
76 gpu_arch_ = dev_info->gpu_arch();
77 } else {
78 assert(!"not_expected");
79 }
80
81 return status::success;
82 }
83
init_device_name(engine_t * engine)84 status_t sycl_device_info_t::init_device_name(engine_t *engine) {
85 auto &device
86 = utils::downcast<const sycl_engine_base_t *>(engine)->device();
87 name_ = device.get_info<cl::sycl::info::device::name>();
88 return status::success;
89 }
90
init_runtime_version(engine_t * engine)91 status_t sycl_device_info_t::init_runtime_version(engine_t *engine) {
92 auto &device
93 = utils::downcast<const sycl_engine_base_t *>(engine)->device();
94 auto driver_version
95 = device.get_info<cl::sycl::info::device::driver_version>();
96
97 if (runtime_version_.set_from_string(driver_version.c_str())
98 != status::success) {
99 runtime_version_.major = 0;
100 runtime_version_.minor = 0;
101 runtime_version_.build = 0;
102 }
103
104 return status::success;
105 }
106
init_extensions(engine_t * engine)107 status_t sycl_device_info_t::init_extensions(engine_t *engine) {
108 using namespace gpu::compute;
109
110 auto &device
111 = utils::downcast<const sycl_engine_base_t *>(engine)->device();
112 std::string extension_string;
113 for (uint64_t i_ext = 1; i_ext < (uint64_t)device_ext_t::last;
114 i_ext <<= 1) {
115 const char *s_ext = ext2cl_str((device_ext_t)i_ext);
116 if (s_ext && device.has_extension(s_ext)) {
117 extension_string += std::string(s_ext) + " ";
118 extensions_ |= i_ext;
119 }
120 }
121
122 // Handle future extensions, not yet supported by the DPC++ API
123 extensions_ |= (uint64_t)get_future_extensions(gpu_arch());
124
125 return status::success;
126 }
127
init_attributes(engine_t * engine)128 status_t sycl_device_info_t::init_attributes(engine_t *engine) {
129 auto &device
130 = utils::downcast<const sycl_engine_base_t *>(engine)->device();
131 eu_count_ = device.get_info<cl::sycl::info::device::max_compute_units>();
132 return status::success;
133 }
134
135 } // namespace sycl
136 } // namespace impl
137 } // namespace dnnl
138