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