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 */
39struct 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
132protected:
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
142private:
143 std::atomic<int> counter_;
144};
145
146namespace dnnl {
147namespace impl {
148
149inline 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
170inline 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
184struct 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
190struct 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