ArmNN
 21.08
BackendOptions.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include "BackendId.hpp"
9 #include <cassert>
10 
11 namespace armnn
12 {
13 
14 struct BackendOptions;
15 using NetworkOptions = std::vector<BackendOptions>;
16 
17 using ModelOptions = std::vector<BackendOptions>;
19 
20 /// Struct for the users to pass backend specific options
22 {
23 private:
24  template<typename T>
25  struct CheckAllowed
26  {
27  static const bool value = std::is_same<T, int>::value ||
28  std::is_same<T, unsigned int>::value ||
29  std::is_same<T, float>::value ||
30  std::is_same<T, bool>::value ||
31  std::is_same<T, std::string>::value ||
32  std::is_same<T, const char*>::value;
33  };
34 public:
35 
36  /// Very basic type safe variant
37  class Var
38  {
39 
40  public:
41  /// Constructors
42  explicit Var(int i) : m_Vals(i), m_Type(VarTypes::Integer) {};
43  explicit Var(unsigned int u) : m_Vals(u), m_Type(VarTypes::UnsignedInteger) {};
44  explicit Var(float f) : m_Vals(f), m_Type(VarTypes::Float) {};
45  explicit Var(bool b) : m_Vals(b), m_Type(VarTypes::Boolean) {};
46  explicit Var(const char* s) : m_Vals(s), m_Type(VarTypes::String) {};
47  explicit Var(std::string s) : m_Vals(s), m_Type(VarTypes::String) {};
48 
49  /// Disallow implicit conversions from types not explicitly allowed below.
50  template<typename DisallowedType>
51  Var(DisallowedType)
52  {
53  static_assert(CheckAllowed<DisallowedType>::value, "Type is not allowed for Var<DisallowedType>.");
54  assert(false && "Unreachable code");
55  }
56 
57  /// Copy Construct
58  Var(const Var& other)
59  : m_Type(other.m_Type)
60  {
61  switch(m_Type)
62  {
63  case VarTypes::String:
64  {
65  new (&m_Vals.s) std::string(other.m_Vals.s);
66  break;
67  }
68  default:
69  {
70  DoOp(other, [](auto& a, auto& b)
71  {
72  a = b;
73  });
74  break;
75  }
76  }
77  }
78 
79  /// Copy operator
80  Var& operator=(const Var& other)
81  {
82  // Destroy existing string
83  if (m_Type == VarTypes::String)
84  {
85  Destruct(m_Vals.s);
86  }
87 
88  m_Type = other.m_Type;
89  switch(m_Type)
90  {
91  case VarTypes::String:
92  {
93 
94  new (&m_Vals.s) std::string(other.m_Vals.s);
95  break;
96  }
97  default:
98  {
99  DoOp(other, [](auto& a, auto& b)
100  {
101  a = b;
102  });
103  break;
104  }
105  }
106 
107  return *this;
108  };
109 
110  /// Type getters
111  bool IsBool() const { return m_Type == VarTypes::Boolean; }
112  bool IsInt() const { return m_Type == VarTypes::Integer; }
113  bool IsUnsignedInt() const { return m_Type == VarTypes::UnsignedInteger; }
114  bool IsFloat() const { return m_Type == VarTypes::Float; }
115  bool IsString() const { return m_Type == VarTypes::String; }
116 
117  /// Value getters
118  bool AsBool() const { assert(IsBool()); return m_Vals.b; }
119  int AsInt() const { assert(IsInt()); return m_Vals.i; }
120  unsigned int AsUnsignedInt() const { assert(IsUnsignedInt()); return m_Vals.u; }
121  float AsFloat() const { assert(IsFloat()); return m_Vals.f; }
122  std::string AsString() const { assert(IsString()); return m_Vals.s; }
123 
124  /// Destructor
126  {
127  DoOp(*this, [this](auto& a, auto&)
128  {
129  Destruct(a);
130  });
131  }
132  private:
133  template<typename Func>
134  void DoOp(const Var& other, Func func)
135  {
136  if (other.IsBool())
137  {
138  func(m_Vals.b, other.m_Vals.b);
139  }
140  else if (other.IsInt())
141  {
142  func(m_Vals.i, other.m_Vals.i);
143  }
144  else if (other.IsUnsignedInt())
145  {
146  func(m_Vals.u, other.m_Vals.u);
147  }
148  else if (other.IsFloat())
149  {
150  func(m_Vals.f, other.m_Vals.f);
151  }
152  else if (other.IsString())
153  {
154  func(m_Vals.s, other.m_Vals.s);
155  }
156  }
157 
158  template<typename Destructable>
159  void Destruct(Destructable& d)
160  {
161  if (std::is_destructible<Destructable>::value)
162  {
163  d.~Destructable();
164  }
165  }
166 
167  private:
168  /// Types which can be stored
169  enum class VarTypes
170  {
171  Boolean,
172  Integer,
173  Float,
174  String,
175  UnsignedInteger
176  };
177 
178  /// Union of potential type values.
179  union Vals
180  {
181  int i;
182  unsigned int u;
183  float f;
184  bool b;
185  std::string s;
186 
187  Vals(){}
188  ~Vals(){}
189 
190  explicit Vals(int i) : i(i) {};
191  explicit Vals(unsigned int u) : u(u) {};
192  explicit Vals(float f) : f(f) {};
193  explicit Vals(bool b) : b(b) {};
194  explicit Vals(const char* s) : s(std::string(s)) {}
195  explicit Vals(std::string s) : s(s) {}
196  };
197 
198  Vals m_Vals;
199  VarTypes m_Type;
200  };
201 
203  {
204  public:
205  BackendOption(std::string name, bool value)
206  : m_Name(name), m_Value(value)
207  {}
208  BackendOption(std::string name, int value)
209  : m_Name(name), m_Value(value)
210  {}
211  BackendOption(std::string name, unsigned int value)
212  : m_Name(name), m_Value(value)
213  {}
214  BackendOption(std::string name, float value)
215  : m_Name(name), m_Value(value)
216  {}
217  BackendOption(std::string name, std::string value)
218  : m_Name(name), m_Value(value)
219  {}
220  BackendOption(std::string name, const char* value)
221  : m_Name(name), m_Value(value)
222  {}
223 
224  template<typename DisallowedType>
225  BackendOption(std::string, DisallowedType)
226  : m_Value(0)
227  {
228  static_assert(CheckAllowed<DisallowedType>::value, "Type is not allowed for BackendOption.");
229  assert(false && "Unreachable code");
230  }
231 
232  BackendOption(const BackendOption& other) = default;
233  BackendOption(BackendOption&& other) = default;
234  BackendOption& operator=(const BackendOption& other) = default;
235  BackendOption& operator=(BackendOption&& other) = default;
236  ~BackendOption() = default;
237 
238  std::string GetName() const { return m_Name; }
239  Var GetValue() const { return m_Value; }
240 
241  private:
242  std::string m_Name; ///< Name of the option
243  Var m_Value; ///< Value of the option. (Bool, int, Float, String)
244  };
245 
246  explicit BackendOptions(BackendId backend)
247  : m_TargetBackend(backend)
248  {}
249 
250  BackendOptions(BackendId backend, std::initializer_list<BackendOption> options)
251  : m_TargetBackend(backend)
252  , m_Options(options)
253  {}
254 
255  BackendOptions(const BackendOptions& other) = default;
256  BackendOptions(BackendOptions&& other) = default;
257  BackendOptions& operator=(const BackendOptions& other) = default;
258  BackendOptions& operator=(BackendOptions&& other) = default;
259 
260  void AddOption(BackendOption&& option)
261  {
262  m_Options.push_back(option);
263  }
264 
265  void AddOption(const BackendOption& option)
266  {
267  m_Options.push_back(option);
268  }
269 
270  const BackendId& GetBackendId() const noexcept { return m_TargetBackend; }
271  size_t GetOptionCount() const noexcept { return m_Options.size(); }
272  const BackendOption& GetOption(size_t idx) const { return m_Options[idx]; }
273 
274 private:
275  /// The id for the backend to which the options should be passed.
276  BackendId m_TargetBackend;
277 
278  /// The array of options to pass to the backend context
279  std::vector<BackendOption> m_Options;
280 };
281 
282 
283 template <typename F>
284 void ParseOptions(const std::vector<BackendOptions>& options, BackendId backend, F f)
285 {
286  for (auto optionsGroup : options)
287  {
288  if (optionsGroup.GetBackendId() == backend)
289  {
290  for (size_t i=0; i < optionsGroup.GetOptionCount(); i++)
291  {
292  const BackendOptions::BackendOption option = optionsGroup.GetOption(i);
293  f(option.GetName(), option.GetValue());
294  }
295  }
296  }
297 }
298 
299 } //namespace armnn
const BackendOption & GetOption(size_t idx) const
BackendOptions(BackendId backend, std::initializer_list< BackendOption > options)
Very basic type safe variant.
BackendOption(std::string name, bool value)
Var(const Var &other)
Copy Construct.
BackendOption(std::string name, unsigned int value)
void ParseOptions(const std::vector< BackendOptions > &options, BackendId backend, F f)
std::vector< BackendOptions > ModelOptions
std::vector< BackendOptions > NetworkOptions
Copyright (c) 2021 ARM Limited and Contributors.
BackendOptions(BackendId backend)
size_t GetOptionCount() const noexcept
Var(int i)
Constructors.
void AddOption(BackendOption &&option)
Var & operator=(const Var &other)
Copy operator.
BackendOption(std::string name, int value)
std::string AsString() const
Var(DisallowedType)
Disallow implicit conversions from types not explicitly allowed below.
BackendOptions & operator=(const BackendOptions &other)=default
unsigned int AsUnsignedInt() const
Struct for the users to pass backend specific options.
void AddOption(const BackendOption &option)
bool AsBool() const
Value getters.
bool IsBool() const
Type getters.
BackendOption(std::string name, float value)
BackendOption(std::string name, const char *value)
BackendOption(std::string, DisallowedType)
const BackendId & GetBackendId() const noexcept
BackendOption(std::string name, std::string value)