attribute_adapter.hpp
1 //*****************************************************************************
2 // Copyright 2017-2021 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 #pragma once
18 
19 #include <string>
20 #include <type_traits>
21 #include <vector>
22 
23 #include "ngraph/enum_names.hpp"
24 #include "ngraph/type.hpp"
25 
26 ///
27 namespace ngraph
28 {
29  class AttributeVisitor;
30 
31  /// \brief Provides access to an attribute of type AT as a value accessor type VAT
32  template <typename VAT>
33  class ValueAccessor;
34 
35  /// \brief ValueAccessor<void> provides an accessor for values that do not have get/set methonds
36  /// via AttributeVistor.on_adapter.
37  ///
38  /// All ValueAccessors must be derived from ValueAccessor<void> so that an AttributeVisitor
39  /// only needs to implement a subset of the on_adapter methods.
40  template <>
41  class NGRAPH_API ValueAccessor<void>
42  {
43  public:
44  /// \brief type info enables identification of the value accessor, as well as is_type and
45  /// as_type.
46  virtual const DiscreteTypeInfo& get_type_info() const = 0;
47  virtual ~ValueAccessor() {}
48  };
49 
50  /// \brief Provides access to values via get/set methods from an m_value, typically from
51  /// ValueReference
52  ///
53  /// The m_buffer holds a VAT, which may be wider than the attribute AT. For example, serializers
54  /// that only
55  /// support int64_t integers would use a ValueAccessor<vector<int64_t>> to reference a
56  /// vector<int8_t> attribute. Destruction moves the value back to the attribute if it was
57  /// changed.
58  /// \tparam VAT The adapter value type; may be wider than the value being accessed.
59  template <typename VAT>
60  class ValueAccessor : public ValueAccessor<void>
61  {
62  public:
63  /// Returns the value
64  virtual const VAT& get() = 0;
65  /// Sets the value
66  virtual void set(const VAT& value) = 0;
67  };
68 
69  template <>
70  class ValueAccessor<void*> : public ValueAccessor<void>
71  {
72  public:
73  virtual void* get_ptr() = 0;
74  virtual size_t size() = 0;
75  };
76 
77  template <typename AT>
79  {
80  public:
81  DirectValueAccessor(AT& ref)
82  : m_ref(ref)
83  {
84  }
85  const AT& get() override { return m_ref; }
86  void set(const AT& value) override { m_ref = value; }
87  protected:
88  AT& m_ref;
89  };
90 
91  template <typename AT, typename VAT>
93  {
94  public:
96  : m_ref(ref)
97  , m_buffer()
98  {
99  }
100 
101  const VAT& get() override
102  {
103  if (!m_buffer_valid)
104  {
105  m_buffer = static_cast<VAT>(m_ref);
106  m_buffer_valid = true;
107  }
108  return m_buffer;
109  }
110 
111  void set(const VAT& value) override
112  {
113  m_ref = static_cast<AT>(value);
114  m_buffer_valid = false;
115  }
116 
117  protected:
118  AT& m_ref;
119  VAT m_buffer;
120  bool m_buffer_valid{false};
121  };
122 
123  template <typename A, typename B>
124  A copy_from(B& b)
125  {
126  A result(b.size());
127  for (size_t i = 0; i < b.size(); ++i)
128  {
129  result[i] =
130  static_cast<typename std::remove_reference<decltype(result[i])>::type>(b[i]);
131  }
132  return result;
133  }
134 
135  template <typename AT, typename VAT>
137  {
138  public:
140  : m_ref(ref)
141  {
142  }
143 
144  const VAT& get() override
145  {
146  if (!m_buffer_valid)
147  {
148  m_buffer = copy_from<typename std::remove_cv<VAT>::type>(m_ref);
149  m_buffer_valid = true;
150  }
151  return m_buffer;
152  }
153 
154  void set(const VAT& value) override
155  {
156  m_ref = copy_from<AT>(value);
157  m_buffer_valid = false;
158  }
159 
160  operator AT&() { return m_ref; }
161  protected:
162  AT& m_ref;
163  VAT m_buffer;
164  bool m_buffer_valid{false};
165  };
166 
167  /// \brief An AttributeAdapter "captures" an attribute as an AT& and makes it available as a
168  /// ValueAccessor<VAT>.
169  template <typename AT>
171  {
172  };
173 
174  /// \brief Access an enum via a string
175  /// \tparam AT The attribute type enum class
176  template <typename AT>
177  class EnumAttributeAdapterBase : public ValueAccessor<std::string>
178  {
179  public:
180  EnumAttributeAdapterBase(AT& value)
181  : m_ref(value)
182  {
183  }
184 
185  const std::string& get() override { return as_string(m_ref); }
186  void set(const std::string& value) override { m_ref = as_enum<AT>(value); }
187  operator AT&() { return m_ref; }
188  protected:
189  AT& m_ref;
190  };
191 
192  /// Adapters will see visitor
193  class VisitorAdapter : public ValueAccessor<void>
194  {
195  public:
196  virtual bool visit_attributes(AttributeVisitor& visitor) = 0;
197  };
198 
199  template <>
200  class NGRAPH_API AttributeAdapter<float> : public IndirectScalarValueAccessor<float, double>
201  {
202  public:
203  AttributeAdapter(float& value)
205  {
206  }
207 
208  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<float>", 0};
209  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
210  };
211 
212  /// \brief Access a double as a double
213  template <>
214  class NGRAPH_API AttributeAdapter<double> : public DirectValueAccessor<double>
215  {
216  public:
217  AttributeAdapter(double& value)
219  {
220  }
221 
222  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<double>", 0};
223  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
224  };
225 
226  /// \brief Access a string as a string
227  template <>
228  class NGRAPH_API AttributeAdapter<std::string> : public DirectValueAccessor<std::string>
229  {
230  public:
231  AttributeAdapter(std::string& value)
233  {
234  }
235 
236  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<string>", 0};
237  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
238  };
239 
240  /// \brief Access a bool as a bool
241  template <>
242  class NGRAPH_API AttributeAdapter<bool> : public DirectValueAccessor<bool>
243  {
244  public:
245  AttributeAdapter(bool& value)
247  {
248  }
249 
250  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<bool>", 0};
251  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
252  };
253 
254  /// \brief Access an int8_t and an int64_t
255  template <>
256  class NGRAPH_API AttributeAdapter<int8_t> : public IndirectScalarValueAccessor<int8_t, int64_t>
257  {
258  public:
259  AttributeAdapter(int8_t& value)
261  {
262  }
263 
264  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<int8_t>", 0};
265  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
266  };
267 
268  /// \brief Access an int16_t as an int64_t
269  template <>
270  class NGRAPH_API AttributeAdapter<int16_t>
271  : public IndirectScalarValueAccessor<int16_t, int64_t>
272  {
273  public:
274  AttributeAdapter(int16_t& value)
276  {
277  }
278 
279  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<int16_t>", 0};
280  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
281  };
282 
283  /// \brief Access an int32_t as an int64_t
284  template <>
285  class NGRAPH_API AttributeAdapter<int32_t>
286  : public IndirectScalarValueAccessor<int32_t, int64_t>
287  {
288  public:
289  AttributeAdapter(int32_t& value)
291  {
292  }
293 
294  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<int32_t>", 0};
295  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
296  };
297 
298  /// \brief Access an int64_t as an int64_t
299  template <>
300  class NGRAPH_API AttributeAdapter<int64_t> : public DirectValueAccessor<int64_t>
301  {
302  public:
303  AttributeAdapter(int64_t& value)
305  {
306  }
307 
308  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<int64_t>", 0};
309  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
310  };
311 
312  /// \brief Access a uint8_t as an int64_t
313  template <>
314  class NGRAPH_API AttributeAdapter<uint8_t>
315  : public IndirectScalarValueAccessor<uint8_t, int64_t>
316  {
317  public:
318  AttributeAdapter(uint8_t& value)
320  {
321  }
322 
323  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<uint8_t>", 0};
324  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
325  };
326 
327  /// \brief Access a uint16_t as an int64_t
328  template <>
329  class NGRAPH_API AttributeAdapter<uint16_t>
330  : public IndirectScalarValueAccessor<uint16_t, int64_t>
331  {
332  public:
333  AttributeAdapter(uint16_t& value)
335  {
336  }
337 
338  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<uint16_t>", 0};
339  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
340  };
341 
342  /// \brief Access a uint32_t as an int64_t
343  template <>
344  class NGRAPH_API AttributeAdapter<uint32_t>
345  : public IndirectScalarValueAccessor<uint32_t, int64_t>
346  {
347  public:
348  AttributeAdapter(uint32_t& value)
350  {
351  }
352 
353  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<uint32_t>", 0};
354  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
355  };
356 
357  /// \brief Access a uint64_t as an int64_t
358  template <>
359  class NGRAPH_API AttributeAdapter<uint64_t>
360  : public IndirectScalarValueAccessor<uint64_t, int64_t>
361  {
362  public:
363  AttributeAdapter(uint64_t& value)
365  {
366  }
367 
368  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<uint64_t>", 0};
369  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
370  };
371 
372 #ifdef __APPLE__
373  // size_t is one of the uint types on _WIN32
374  template <>
375  class NGRAPH_API AttributeAdapter<size_t> : public IndirectScalarValueAccessor<size_t, int64_t>
376  {
377  public:
378  AttributeAdapter(size_t& value)
379  : IndirectScalarValueAccessor<size_t, int64_t>(value)
380  {
381  }
382 
383  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<size_t>", 0};
384  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
385  };
386 
387  template <>
388  class NGRAPH_API AttributeAdapter<std::vector<size_t>>
389  : public IndirectVectorValueAccessor<std::vector<size_t>, std::vector<int64_t>>
390  {
391  public:
392  AttributeAdapter(std::vector<size_t>& value)
393  : IndirectVectorValueAccessor<std::vector<size_t>, std::vector<int64_t>>(value)
394  {
395  }
396 
397  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<size_t>>", 0};
398  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
399  };
400 #endif
401 
402  /// Note: These class bodies cannot be defined with templates because of interactions
403  /// between dllexport and templates on Windows.
404 
405  /// \brief Access a vector<int8_t>
406  template <>
407  class NGRAPH_API AttributeAdapter<std::vector<int8_t>>
408  : public DirectValueAccessor<std::vector<int8_t>>
409  {
410  public:
411  AttributeAdapter(std::vector<int8_t>& value)
413  {
414  }
415 
416  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<int8_t>>", 0};
417  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
418  };
419 
420  /// \brief Access a vector<int16_t>
421  template <>
422  class NGRAPH_API AttributeAdapter<std::vector<int16_t>>
423  : public DirectValueAccessor<std::vector<int16_t>>
424  {
425  public:
426  AttributeAdapter(std::vector<int16_t>& value)
428  {
429  }
430 
431  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<int16_t>>", 0};
432  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
433  };
434 
435  /// \brief Access a vector<int32_t>
436  template <>
437  class NGRAPH_API AttributeAdapter<std::vector<int32_t>>
438  : public DirectValueAccessor<std::vector<int32_t>>
439  {
440  public:
441  AttributeAdapter(std::vector<int32_t>& value)
443  {
444  }
445 
446  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<int32_t>>", 0};
447  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
448  };
449 
450  /// \brief Access a vector<int64_t>
451  template <>
452  class NGRAPH_API AttributeAdapter<std::vector<int64_t>>
453  : public DirectValueAccessor<std::vector<int64_t>>
454  {
455  public:
456  AttributeAdapter(std::vector<int64_t>& value)
458  {
459  }
460 
461  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<int64_t>>", 0};
462  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
463  };
464 
465  /// \brief Access a vector<uint8_t>
466  template <>
467  class NGRAPH_API AttributeAdapter<std::vector<uint8_t>>
468  : public DirectValueAccessor<std::vector<uint8_t>>
469  {
470  public:
471  AttributeAdapter(std::vector<uint8_t>& value)
473  {
474  }
475 
476  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<uint8_t>>", 0};
477  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
478  };
479 
480  /// \brief Access a vector<uint16_t>
481  template <>
482  class NGRAPH_API AttributeAdapter<std::vector<uint16_t>>
483  : public DirectValueAccessor<std::vector<uint16_t>>
484  {
485  public:
486  AttributeAdapter(std::vector<uint16_t>& value)
488  {
489  }
490 
491  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<uint16_t>>", 0};
492  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
493  };
494 
495  /// \brief Access a vector<uint32_t>
496  template <>
497  class NGRAPH_API AttributeAdapter<std::vector<uint32_t>>
498  : public DirectValueAccessor<std::vector<uint32_t>>
499  {
500  public:
501  AttributeAdapter(std::vector<uint32_t>& value)
503  {
504  }
505 
506  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<uint32_t>>", 0};
507  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
508  };
509 
510  /// \brief Access a vector<uint64_t>
511  template <>
512  class NGRAPH_API AttributeAdapter<std::vector<uint64_t>>
513  : public DirectValueAccessor<std::vector<uint64_t>>
514  {
515  public:
516  AttributeAdapter(std::vector<uint64_t>& value)
518  {
519  }
520 
521  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<uint64_t>>", 0};
522  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
523  };
524 
525  /// \brief Access a vector<float>
526  template <>
527  class NGRAPH_API AttributeAdapter<std::vector<float>>
528  : public DirectValueAccessor<std::vector<float>>
529  {
530  public:
531  AttributeAdapter(std::vector<float>& value)
533  {
534  }
535 
536  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<float>>", 0};
537  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
538  };
539 
540  /// \brief Access a vector<double>
541  template <>
542  class NGRAPH_API AttributeAdapter<std::vector<double>>
543  : public DirectValueAccessor<std::vector<double>>
544  {
545  public:
546  AttributeAdapter(std::vector<double>& value)
548  {
549  }
550 
551  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<double>>", 0};
552  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
553  };
554 
555  /// \brief Access a vector<string>
556  template <>
557  class NGRAPH_API AttributeAdapter<std::vector<std::string>>
558  : public DirectValueAccessor<std::vector<std::string>>
559  {
560  public:
561  AttributeAdapter(std::vector<std::string>& value)
563  {
564  }
565 
566  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<vector<string>>", 0};
567  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
568  };
569 }
An AttributeAdapter "captures" an attribute as an AT& and makes it available as a ValueAccessor<VAT>.
Definition: attribute_adapter.hpp:171
Visits the attributes of a node, primarily for serialization-like tasks.
Definition: attribute_visitor.hpp:71
Definition: attribute_adapter.hpp:79
void set(const AT &value) override
Sets the value.
Definition: attribute_adapter.hpp:86
const AT & get() override
Returns the value.
Definition: attribute_adapter.hpp:85
Access an enum via a string.
Definition: attribute_adapter.hpp:178
const std::string & get() override
Returns the value.
Definition: attribute_adapter.hpp:185
void set(const std::string &value) override
Sets the value.
Definition: attribute_adapter.hpp:186
Definition: attribute_adapter.hpp:93
void set(const VAT &value) override
Sets the value.
Definition: attribute_adapter.hpp:111
const VAT & get() override
Returns the value.
Definition: attribute_adapter.hpp:101
Definition: attribute_adapter.hpp:137
const VAT & get() override
Returns the value.
Definition: attribute_adapter.hpp:144
void set(const VAT &value) override
Sets the value.
Definition: attribute_adapter.hpp:154
ValueAccessor<void> provides an accessor for values that do not have get/set methonds via AttributeVi...
Definition: attribute_adapter.hpp:42
virtual const DiscreteTypeInfo & get_type_info() const =0
type info enables identification of the value accessor, as well as is_type and as_type.
Provides access to an attribute of type AT as a value accessor type VAT.
Definition: attribute_adapter.hpp:61
virtual void set(const VAT &value)=0
Sets the value.
virtual const VAT & get()=0
Returns the value.
Adapters will see visitor.
Definition: attribute_adapter.hpp:194
The Intel nGraph C++ API.
Definition: attribute_adapter.hpp:28
const std::string & as_string(Value value)
Returns the string matching the enum value.
Definition: enum_names.hpp:92
Definition: type.hpp:39