HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
kernel_def_builder.h
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License.
3 
4 #pragma once
5 
6 #include <limits.h>
7 #include <memory>
8 #include <optional>
9 #include <string>
10 #include <unordered_map>
11 #include <vector>
12 
13 #include "core/common/common.h"
16 #include "core/graph/basic_types.h"
17 
18 namespace onnxruntime {
20 
21 typedef std::map<size_t, OrtMemType> MemTypeMap;
22 
23 class KernelDef {
24  private:
25  // note that input/output might be on CPU implicitly when the node is from CPU execution provider
26  constexpr static inline bool MemTypeOnCpuExplicitly(OrtMemType mem_type) {
27  return mem_type == OrtMemTypeCPUInput || mem_type == OrtMemTypeCPUOutput;
28  }
29 
30  public:
31  explicit KernelDef() = default;
32 
33  const std::string& OpName() const {
34  return op_name_;
35  }
36 
37  const std::string& Domain() const {
38  return op_domain_;
39  }
40 
41  void SinceVersion(/*out*/ int* start, /*out*/ int* end) const {
42  *start = op_since_version_start_;
43  *end = op_since_version_end_;
44  }
45 
46 #ifdef onnxruntime_PYBIND_EXPORT_OPSCHEMA
47  const std::pair<int, int> SinceVersion() const {
48  return std::pair<int, int>(op_since_version_start_, op_since_version_end_);
49  }
50 #endif
51 
53  return provider_type_;
54  }
55 
56  // type constraints with types supported in this build
57  const std::unordered_map<std::string, std::vector<MLDataType>>& TypeConstraints() const {
58  return type_constraints_;
59  }
60 
61  const std::vector<std::pair<int, int>>& MayInplace() const {
62  return inplace_map_;
63  }
64 
65  const std::vector<std::pair<int, int>>& Alias() const {
66  return alias_map_;
67  }
68 
69  const std::optional<std::pair<int, int>>& VariadicAlias() const {
70  return variadic_alias_offsets_;
71  }
72 
73  OrtMemType InputMemoryType(size_t input_index) const {
74  auto it = input_memory_type_args_.find(input_index);
75  if (it == input_memory_type_args_.end())
76  return default_inputs_mem_type_;
77  return it->second;
78  }
79 
80  bool IsInputOnCpu(size_t input_index) const { return MemTypeOnCpuExplicitly(InputMemoryType(input_index)); }
81 
82  bool IsOutputOnCpu(size_t output_index) const { return MemTypeOnCpuExplicitly(OutputMemoryType(output_index)); }
83 
84  bool AllocateInputsContiguously() const { return allocate_inputs_contiguously_; }
85 
86  bool HasExternalOutputs() const { return external_outputs_; }
87 
88 #ifdef ENABLE_STRIDED_TENSORS
89  const std::vector<int>& MayStridedInput() const { return may_strided_inputs_; }
90  const std::vector<std::pair<int, int>>& MayStridedOutput() const { return may_strided_output_map_; }
91 #endif
92 
93  OrtMemType OutputMemoryType(size_t output_index) const {
94  auto it = output_memory_type_args_.find(output_index);
95  if (it == output_memory_type_args_.end())
96  return default_outputs_mem_type_;
97  return it->second;
98  }
99 
100  int ExecQueueId() const {
101  return exec_queue_id_;
102  }
103 
104  bool IsConflict(const KernelDef& other) const;
105 
106  private:
107  friend class KernelDefBuilder;
108 
109  // The operator name supported by <*this> kernel..
110  std::string op_name_;
111 
112  // The operator since_version range supported by <*this> kernel.
113  // A kernel could support an operator definition between <op_since_version_start>
114  // and <op_since_version_end> (inclusive).
115  int op_since_version_start_ = 1;
116  int op_since_version_end_ = INT_MAX;
117 
118  // The operator domain supported by <*this> kernel.
119  // Default to 'onnxruntime::kOnnxDomain'.
120  // Please note the behavior of std::string("") and std::string() are different
121  std::string op_domain_;
122 
123  // The type of the execution provider.
124  std::string provider_type_;
125 
126  // The data types that are supported in this build (enabled) for inputs/outputs.
127  // Key is input/output/type constraint name defined in op schema, Value is supported types.
128  std::unordered_map<std::string, std::vector<MLDataType>> type_constraints_;
129 
130  // An element <i, j> means that output j reuses the memory of input i.
131  std::vector<std::pair<int, int>> inplace_map_;
132 
133  // An element <i, j> means that output j is an alias of input i.
134  std::vector<std::pair<int, int>> alias_map_;
135 
136  // This variable stores <input_offset, output_offset> for the variadic alias mapping
137  // output 'i + output_offset' is an alias of input 'i + input_offset' for all i >= 0
138  std::optional<std::pair<int, int>> variadic_alias_offsets_;
139 
140  // Require input tensors to be allocated contiguously.
141  bool allocate_inputs_contiguously_ = false;
142 
143  // Whether the outputs are from external.
144  bool external_outputs_ = false;
145 
146 #ifdef ENABLE_STRIDED_TENSORS
147  // An element i means i-th input can be strided tensor.
148  std::vector<int> may_strided_inputs_;
149 
150  // An element <i, j> means j-th output can be a strided tensor, which share the data from i-th input.
151  std::vector<std::pair<int, int>> may_strided_output_map_;
152 #endif
153 
154  // The memory types of inputs/outputs of this kernel
155  MemTypeMap input_memory_type_args_;
156  MemTypeMap output_memory_type_args_;
157 
158  // execution command queue id, 0 for default queue in execution provider
159  int exec_queue_id_ = 0;
160  // Default memory type for all inputs
161  OrtMemType default_inputs_mem_type_{OrtMemTypeDefault};
162  // Default memory type for all outputs
163  OrtMemType default_outputs_mem_type_{OrtMemTypeDefault};
164 };
165 
167  public:
168  static std::unique_ptr<KernelDefBuilder> Create() { return std::make_unique<KernelDefBuilder>(); }
169 
170  explicit KernelDefBuilder()
171  : kernel_def_(std::make_unique<KernelDef>()) {}
172 
173  KernelDefBuilder& SetName(const std::string& op_name);
174  KernelDefBuilder& SetName(const char* op_name);
175 
176  KernelDefBuilder& SetDomain(const std::string& domain);
177  KernelDefBuilder& SetDomain(const char* domain);
178 
179  /**
180  This kernel supports operator definition since <since_version> (to latest).
181  */
182  KernelDefBuilder& SinceVersion(int since_version) {
183  kernel_def_->op_since_version_start_ = since_version;
184  return *this;
185  }
186 
187  /**
188  The start and end version should be set accordingly per version range for
189  each domain registered in OpSchemaRegistry::DomainToVersionRange in
190  \onnxruntime\onnxruntime\core\graph\op.h as below.
191  Key: domain. Value: <lowest version, highest version> pair.
192  std::unordered_map<std::string, std::pair<int, int>> map_;
193  */
194  KernelDefBuilder& SinceVersion(int since_version_start, int since_version_end) {
195  kernel_def_->op_since_version_start_ = since_version_start;
196  kernel_def_->op_since_version_end_ = since_version_end;
197  return *this;
198  }
199 
200  /**
201  The execution provider type of the kernel.
202  */
203  KernelDefBuilder& Provider(ProviderType provider_type);
204  KernelDefBuilder& Provider(const char* provider_type);
205 
206  /**
207  Specify the set of types that this kernel supports. A further restriction
208  of the set of types specified in the op schema.
209 
210  @param arg_name The arg name can be either op formal parameter name, say "X", or type
211  argument name specified in op schema, say "T".
212  @param types The types that are supported in this build.
213  */
214  KernelDefBuilder& TypeConstraint(const std::string& arg_name, std::vector<MLDataType> types);
215  KernelDefBuilder& TypeConstraint(const char* arg_name, std::vector<MLDataType> types);
216 
217  /**
218  Like TypeConstraint but supports just a single type.
219  */
221  KernelDefBuilder& TypeConstraint(const char* arg_name, MLDataType type);
222 
223  /**
224  Inplace mapping from inputs to outputs allowed.
225  It means that uplayer runtime could do memory in-place optimization
226  as it will not impact the correctness of this kernel.
227  */
228  KernelDefBuilder& MayInplace(const std::vector<std::pair<int, int>>& inplaces);
229  KernelDefBuilder& MayInplace(int input_index, int output_index);
230 
231  /**
232  Alias mapping from inputs to outputs. Different from Inplace that the
233  content of the tensor is not changed. This is to take care of operators
234  such as Identity and Reshape.
235  */
236  KernelDefBuilder& Alias(const std::vector<std::pair<int, int>>& aliases);
237  KernelDefBuilder& Alias(int input_index, int output_index);
238 
239  /**
240  Apply variadic number of alias mapping from inputs to outputs.
241  This is effectively applying Alias(i + input_offset, i + output_offset) for i >= 0
242  */
243  KernelDefBuilder& VariadicAlias(int input_offset, int output_offset);
244 
245  /**
246  Specify that this kernel requires input tensors to be allocated
247  contiguously. This allows kernels to execute as a single large
248  computation, rather than numerous smaller computations.
249  */
251  kernel_def_->allocate_inputs_contiguously_ = true;
252  return *this;
253  }
254 
255  /**
256  Specify that this kernel's output buffers are passed from external,
257  i.e. not created or managed by ORT's memory allocator.
258  */
260  kernel_def_->external_outputs_ = true;
261  return *this;
262  }
263 
264 #ifdef ENABLE_STRIDED_TENSORS
265  /**
266  Specify that the input_index-th input can be strided tensor.
267  */
268  KernelDefBuilder& MayStridedInput(int input_index);
269 
270  /**
271  Specify that the output_index-th output can be strided tensor, and share the data
272  from input_index-th input.
273  */
274  KernelDefBuilder& MayStridedOutput(int input_index, int output_index);
275 #endif
276 
277  /**
278  Specify that this kernel requires an input arg
279  in certain memory type (instead of the default, device memory).
280  */
282  kernel_def_->input_memory_type_args_.insert(std::make_pair(input_index, type));
283  return *this;
284  }
285 
286  /**
287  Specify that this kernel requires input arguments
288  in certain memory type (instead of the default, device memory).
289  */
290  KernelDefBuilder& InputMemoryType(OrtMemType type, const std::vector<int>& input_indexes) {
291  for (auto input_index : input_indexes) {
292  kernel_def_->input_memory_type_args_.insert(std::make_pair(input_index, type));
293  }
294  return *this;
295  }
296 
297  /**
298  Specify that this kernel provides an output arg
299  in certain memory type (instead of the default, device memory).
300  */
302  kernel_def_->output_memory_type_args_.insert(std::make_pair(output_index, type));
303  return *this;
304  }
305 
306  /**
307  Specify that this kernel provides an output arguments
308  in certain memory type (instead of the default, device memory).
309  */
310  KernelDefBuilder& OutputMemoryType(OrtMemType type, const std::vector<int>& output_indexes) {
311  for (auto output_index : output_indexes) {
312  kernel_def_->output_memory_type_args_.insert(std::make_pair(output_index, type));
313  }
314  return *this;
315  }
316 
317  /**
318  Specify that this kernel runs on which execution queue in the provider
319  */
320  KernelDefBuilder& ExecQueueId(int queue_id) {
321  kernel_def_->exec_queue_id_ = queue_id;
322  return *this;
323  }
324 
325  /**
326  Specify the default inputs memory type, if not specified, it is DefaultMemory
327  */
329  kernel_def_->default_inputs_mem_type_ = mem_type;
330  return *this;
331  }
332 
333  /**
334  Specify the default outputs memory type, if not specified, it is DefaultMemory
335  */
337  kernel_def_->default_outputs_mem_type_ = mem_type;
338  return *this;
339  }
340 
341  /**
342  Return the kernel definition, passing ownership of the KernelDef to the caller
343  */
344  std::unique_ptr<KernelDef> Build() {
345  return std::move(kernel_def_);
346  }
347 
348  private:
349  // we own the KernelDef until Build() is called.
350  std::unique_ptr<KernelDef> kernel_def_;
351 };
352 
353 } // namespace onnxruntime
KernelDefBuilder & Provider(ProviderType provider_type)
static std::unique_ptr< KernelDefBuilder > Create()
KernelDefBuilder & Alias(const std::vector< std::pair< int, int >> &aliases)
const std::string & ProviderType
Definition: basic_types.h:35
Base class for MLDataType.
Definition: data_types.h:81
KernelDefBuilder & ExternalOutputs()
const std::vector< std::pair< int, int > > & MayInplace() const
GLuint start
Definition: glcorearb.h:475
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
OrtMemType InputMemoryType(size_t input_index) const
const std::string & Domain() const
const std::vector< std::pair< int, int > > & Alias() const
bool HasExternalOutputs() const
KernelDefBuilder & SetDomain(const std::string &domain)
onnxruntime::ProviderType Provider() const
KernelDefBuilder & ExecQueueId(int queue_id)
KernelDefBuilder & VariadicAlias(int input_offset, int output_offset)
CPU accessible memory outputted by non-CPU execution provider, i.e. CUDA_PINNED.
bool AllocateInputsContiguously() const
bool IsConflict(const KernelDef &other) const
void SinceVersion(int *start, int *end) const
KernelDefBuilder & OutputMemoryType(OrtMemType type, const std::vector< int > &output_indexes)
KernelDefBuilder & SetDefaultOutputMemoryType(OrtMemType mem_type)
The default allocator for execution provider.
KernelDefBuilder & AllocateInputsContiguously()
KernelDefBuilder & SetName(const std::string &op_name)
GLuint GLuint end
Definition: glcorearb.h:475
const std::unordered_map< std::string, std::vector< MLDataType > > & TypeConstraints() const
KernelDefBuilder & SinceVersion(int since_version)
bool IsOutputOnCpu(size_t output_index) const
std::map< size_t, OrtMemType > MemTypeMap
KernelDefBuilder & TypeConstraint(const std::string &arg_name, std::vector< MLDataType > types)
Any CPU memory used by non-CPU execution provider.
const std::string & OpName() const
OrtMemType OutputMemoryType(size_t output_index) const
KernelDefBuilder & MayInplace(const std::vector< std::pair< int, int >> &inplaces)
KernelDefBuilder & InputMemoryType(OrtMemType type, int input_index)
KernelDefBuilder & InputMemoryType(OrtMemType type, const std::vector< int > &input_indexes)
std::unique_ptr< KernelDef > Build()
KernelDefBuilder & SetDefaultInputsMemoryType(OrtMemType mem_type)
GLsizei GLenum GLenum * types
Definition: glcorearb.h:2542
type
Definition: core.h:1059
const std::optional< std::pair< int, int > > & VariadicAlias() const
KernelDefBuilder & OutputMemoryType(OrtMemType type, int output_index)
KernelDefBuilder & SinceVersion(int since_version_start, int since_version_end)
OrtMemType
Memory types for allocated memory, execution provider specific types should be extended in each provi...
bool IsInputOnCpu(size_t input_index) const