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