1 | /******************************************************************************* |
2 | * Copyright 2016-2022 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 | #ifndef COMMON_ENGINE_HPP |
18 | #define COMMON_ENGINE_HPP |
19 | |
20 | #include "oneapi/dnnl/dnnl.h" |
21 | |
22 | #if DNNL_CPU_RUNTIME == DNNL_RUNTIME_THREADPOOL |
23 | #include "oneapi/dnnl/dnnl_threadpool_iface.hpp" |
24 | #endif |
25 | |
26 | #include "c_types_map.hpp" |
27 | #include "engine_id.hpp" |
28 | #include "memory.hpp" |
29 | #include "memory_storage.hpp" |
30 | #include "primitive_desc.hpp" |
31 | #include "utils.hpp" |
32 | |
33 | /** \brief An abstraction of an execution unit with shared resources |
34 | * |
35 | * Responsibilities: |
36 | * - Provide engine specific memory allocation |
37 | * - Provide engine specific primitive_desc_t creators |
38 | */ |
39 | struct dnnl_engine : public dnnl::impl::c_compatible { |
40 | dnnl_engine(dnnl::impl::engine_kind_t kind, |
41 | dnnl::impl::runtime_kind_t runtime_kind, size_t index) |
42 | : kind_(kind) |
43 | , runtime_kind_(runtime_kind) |
44 | , index_(index) |
45 | , allocator_(nullptr) // no default allocator |
46 | , counter_(1) {} |
47 | |
48 | /** get kind of the current engine */ |
49 | dnnl::impl::engine_kind_t kind() const { return kind_; } |
50 | |
51 | /** get the runtime kind of the current engine */ |
52 | dnnl::impl::runtime_kind_t runtime_kind() const { return runtime_kind_; } |
53 | |
54 | /** get index of the current engine */ |
55 | size_t index() const { return index_; } |
56 | |
57 | virtual dnnl::impl::device_id_t device_id() const = 0; |
58 | |
59 | virtual dnnl::impl::engine_id_t engine_id() const = 0; |
60 | |
61 | /** create memory storage */ |
62 | virtual dnnl::impl::status_t create_memory_storage( |
63 | dnnl::impl::memory_storage_t **storage, unsigned flags, size_t size, |
64 | void *handle) |
65 | = 0; |
66 | dnnl::impl::status_t create_memory_storage( |
67 | dnnl::impl::memory_storage_t **storage, size_t size) { |
68 | return create_memory_storage( |
69 | storage, dnnl::impl::memory_flags_t::alloc, size, nullptr); |
70 | } |
71 | |
72 | /** create stream */ |
73 | virtual dnnl::impl::status_t create_stream( |
74 | dnnl::impl::stream_t **stream, unsigned flags) |
75 | = 0; |
76 | |
77 | #if DNNL_CPU_RUNTIME == DNNL_RUNTIME_THREADPOOL |
78 | virtual dnnl::impl::status_t create_stream(dnnl::impl::stream_t **stream, |
79 | dnnl::threadpool_interop::threadpool_iface *threadpool) { |
80 | return dnnl::impl::status::invalid_arguments; |
81 | } |
82 | #endif |
83 | |
84 | virtual dnnl::impl::status_t get_service_stream( |
85 | dnnl::impl::stream_t *&stream) { |
86 | stream = nullptr; |
87 | return dnnl::impl::status::success; |
88 | } |
89 | |
90 | /* implementation section */ |
91 | |
92 | /** return the list of reorder implementations. engine guarantees to return |
93 | * a NULL-terminated list */ |
94 | virtual const dnnl::impl::impl_list_item_t *get_reorder_implementation_list( |
95 | const dnnl::impl::memory_desc_t *src_md, |
96 | const dnnl::impl::memory_desc_t *dst_md) const = 0; |
97 | |
98 | /** return the list of concat implementations. engine guarantees to return |
99 | * a NULL-terminated list */ |
100 | virtual const dnnl::impl::impl_list_item_t * |
101 | get_concat_implementation_list() const = 0; |
102 | |
103 | /** return the list of sum implementations. engine guarantees to return |
104 | * a NULL-terminated list */ |
105 | virtual const dnnl::impl::impl_list_item_t * |
106 | get_sum_implementation_list() const = 0; |
107 | |
108 | /** return the list of implementations for a given descriptor. |
109 | * engine guarantees to return a NULL-terminated list */ |
110 | |
111 | virtual const dnnl::impl::impl_list_item_t *get_implementation_list( |
112 | const dnnl::impl::op_desc_t *desc) const = 0; |
113 | |
114 | virtual dnnl::impl::status_t serialize_device( |
115 | dnnl::impl::serialization_stream_t &sstream) const { |
116 | assert(!"unexpected" ); |
117 | return dnnl::impl::status::runtime_error; |
118 | } |
119 | |
120 | virtual bool mayiuse_f16_accumulator_with_f16() const { return false; } |
121 | |
122 | /** only used in graph implementation **/ |
123 | void *get_allocator() const { return allocator_; }; |
124 | void set_allocator(void *allocator) { allocator_ = allocator; } |
125 | |
126 | void retain() { counter_++; } |
127 | |
128 | void release() { |
129 | if (--counter_ == 0) { delete this; } |
130 | } |
131 | |
132 | protected: |
133 | dnnl::impl::engine_kind_t kind_; |
134 | dnnl::impl::runtime_kind_t runtime_kind_; |
135 | size_t index_; |
136 | |
137 | /** only used in graph implementation **/ |
138 | void *allocator_; |
139 | |
140 | virtual ~dnnl_engine() = default; |
141 | |
142 | private: |
143 | std::atomic<int> counter_; |
144 | }; |
145 | |
146 | namespace dnnl { |
147 | namespace impl { |
148 | |
149 | inline runtime_kind_t get_default_runtime(engine_kind_t kind) { |
150 | #if DNNL_GPU_RUNTIME == DNNL_RUNTIME_OCL |
151 | if (kind == engine_kind::gpu) return runtime_kind::ocl; |
152 | #elif DNNL_GPU_RUNTIME == DNNL_RUNTIME_SYCL |
153 | if (kind == engine_kind::gpu) return runtime_kind::sycl; |
154 | #endif |
155 | #if DNNL_CPU_RUNTIME == DNNL_RUNTIME_SEQ |
156 | return runtime_kind::seq; |
157 | #elif DNNL_CPU_RUNTIME == DNNL_RUNTIME_OMP |
158 | return runtime_kind::omp; |
159 | #elif DNNL_CPU_RUNTIME == DNNL_RUNTIME_TBB |
160 | return runtime_kind::tbb; |
161 | #elif DNNL_CPU_RUNTIME == DNNL_RUNTIME_THREADPOOL |
162 | return runtime_kind::threadpool; |
163 | #elif DNNL_CPU_RUNTIME == DNNL_RUNTIME_SYCL |
164 | return runtime_kind::sycl; |
165 | #else |
166 | return runtime_kind::none; |
167 | #endif |
168 | } |
169 | |
170 | inline runtime_kind_t get_cpu_native_runtime() { |
171 | #if DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_SEQ |
172 | return runtime_kind::seq; |
173 | #elif DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_OMP |
174 | return runtime_kind::omp; |
175 | #elif DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_TBB |
176 | return runtime_kind::tbb; |
177 | #elif DNNL_CPU_THREADING_RUNTIME == DNNL_RUNTIME_THREADPOOL |
178 | return runtime_kind::threadpool; |
179 | #else |
180 | return runtime_kind::none; |
181 | #endif |
182 | } |
183 | |
184 | struct engine_factory_t : public c_compatible { |
185 | virtual size_t count() const = 0; |
186 | virtual status_t engine_create(engine_t **engine, size_t index) const = 0; |
187 | virtual ~engine_factory_t() = default; |
188 | }; |
189 | |
190 | struct engine_deleter_t { |
191 | void operator()(engine_t *e) const { e->release(); } |
192 | }; |
193 | |
194 | } // namespace impl |
195 | } // namespace dnnl |
196 | |
197 | #endif |
198 | |
199 | // vim: et ts=4 sw=4 cindent cino+=l0,\:4,N-s |
200 | |