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