element_type.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 //================================================================================================
18 // ElementType
19 //================================================================================================
20 
21 #pragma once
22 
23 #include <iostream>
24 #include <limits>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 #include "ngraph/attribute_adapter.hpp"
30 #include "ngraph/deprecated.hpp"
31 #include "ngraph/except.hpp"
32 #include "ngraph/ngraph_visibility.hpp"
33 #include "ngraph/type/bfloat16.hpp"
34 #include "ngraph/type/float16.hpp"
35 
36 namespace ngraph
37 {
38  namespace element
39  {
40  enum class Type_t
41  {
42  undefined,
43  dynamic,
44  boolean,
45  bf16,
46  f16,
47  f32,
48  f64,
49  i8,
50  i16,
51  i32,
52  i64,
53  u1,
54  u8,
55  u16,
56  u32,
57  u64
58  };
59 
60  class NGRAPH_API Type
61  {
62  public:
63  Type()
64  : m_type{element::Type_t::undefined}
65  {
66  }
67  Type(const Type&) = default;
68  constexpr Type(const Type_t t)
69  : m_type{t}
70  {
71  }
72  Type(size_t bitwidth,
73  bool is_real,
74  bool is_signed,
75  bool is_quantized,
76  const std::string& cname);
77  Type& operator=(const Type&) = default;
78  const std::string& c_type_string() const;
79  size_t size() const;
80  size_t hash() const;
81  bool is_static() const;
82  bool is_dynamic() const { return !is_static(); }
83  bool is_real() const;
84  // TODO: We may want to revisit this definition when we do a more general cleanup of
85  // element types:
86  bool is_integral() const { return !is_real(); }
87  bool is_integral_number() const;
88  bool is_signed() const;
89  bool is_quantized() const;
90  size_t bitwidth() const;
91  // The name of this type, the enum name of this type
92  const std::string& get_type_name() const;
93  friend NGRAPH_API std::ostream& operator<<(std::ostream&, const Type&);
94  static std::vector<const Type*> get_known_types();
95 
96  /// \brief Checks whether this element type is merge-compatible with `t`.
97  /// \param t The element type to compare this element type to.
98  /// \return `true` if this element type is compatible with `t`, else `false`.
99  bool compatible(const element::Type& t) const;
100 
101  /// \brief Merges two element types t1 and t2, writing the result into dst and
102  /// returning true if successful, else returning false.
103  ///
104  /// To "merge" two element types t1 and t2 is to find the least restrictive
105  /// element type t that is no more restrictive than t1 and t2, if t exists.
106  /// More simply:
107  ///
108  /// merge(dst,element::Type::dynamic,t)
109  /// writes t to dst and returns true
110  ///
111  /// merge(dst,t,element::Type::dynamic)
112  /// writes t to dst and returns true
113  ///
114  /// merge(dst,t1,t2) where t1, t2 both static and equal
115  /// writes t1 to dst and returns true
116  ///
117  /// merge(dst,t1,t2) where t1, t2 both static and unequal
118  /// does nothing to dst, and returns false
119  static bool merge(element::Type& dst, const element::Type& t1, const element::Type& t2);
120 
121  // \brief This allows switch(element_type)
122  constexpr operator Type_t() const { return m_type; }
123  private:
124  Type_t m_type{Type_t::undefined};
125  };
126 
127  typedef std::vector<Type> TypeVector;
128 
129  constexpr Type undefined(Type_t::undefined);
130  constexpr Type dynamic(Type_t::dynamic);
131  constexpr Type boolean(Type_t::boolean);
132  constexpr Type bf16(Type_t::bf16);
133  constexpr Type f16(Type_t::f16);
134  constexpr Type f32(Type_t::f32);
135  constexpr Type f64(Type_t::f64);
136  constexpr Type i8(Type_t::i8);
137  constexpr Type i16(Type_t::i16);
138  constexpr Type i32(Type_t::i32);
139  constexpr Type i64(Type_t::i64);
140  constexpr Type u1(Type_t::u1);
141  constexpr Type u8(Type_t::u8);
142  constexpr Type u16(Type_t::u16);
143  constexpr Type u32(Type_t::u32);
144  constexpr Type u64(Type_t::u64);
145 
146  template <typename T>
147  Type from()
148  {
149  throw std::invalid_argument("Unknown type");
150  }
151  template <>
152  NGRAPH_API Type from<char>();
153  template <>
154  NGRAPH_API Type from<bool>();
155  template <>
156  NGRAPH_API Type from<float>();
157  template <>
158  NGRAPH_API Type from<double>();
159  template <>
160  NGRAPH_API Type from<int8_t>();
161  template <>
162  NGRAPH_API Type from<int16_t>();
163  template <>
164  NGRAPH_API Type from<int32_t>();
165  template <>
166  NGRAPH_API Type from<int64_t>();
167  template <>
168  NGRAPH_API Type from<uint8_t>();
169  template <>
170  NGRAPH_API Type from<uint16_t>();
171  template <>
172  NGRAPH_API Type from<uint32_t>();
173  template <>
174  NGRAPH_API Type from<uint64_t>();
175  template <>
176  NGRAPH_API Type from<ngraph::bfloat16>();
177  template <>
178  NGRAPH_API Type from<ngraph::float16>();
179 
180  NGRAPH_API
181  std::ostream& operator<<(std::ostream& out, const ngraph::element::Type& obj);
182  }
183 
184  template <>
185  class NGRAPH_API AttributeAdapter<element::Type_t>
186  : public EnumAttributeAdapterBase<element::Type_t>
187  {
188  public:
189  AttributeAdapter(element::Type_t& value)
191  {
192  }
193 
194  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<element::Type_t>", 0};
195  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
196  };
197 
198  template <>
199  class NGRAPH_API AttributeAdapter<element::Type> : public ValueAccessor<std::string>
200  {
201  public:
203  : m_ref(value)
204  {
205  }
206 
207  const std::string& get() override;
208  void set(const std::string& value) override;
209 
210  static constexpr DiscreteTypeInfo type_info{"AttributeAdapter<element::Type>", 0};
211  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
212  operator element::Type&() { return m_ref; }
213  protected:
214  element::Type& m_ref;
215  };
216 
217  /// \brief Return the number of bytes in the compile-time representation of the element type.
218  size_t compiler_byte_size(element::Type_t et);
219 }
const std::string & get() override
Returns the value.
void set(const std::string &value) override
Sets the value.
An AttributeAdapter "captures" an attribute as an AT& and makes it available as a ValueAccessor<VAT>.
Definition: attribute_adapter.hpp:171
Access an enum via a string.
Definition: attribute_adapter.hpp:178
Provides access to an attribute of type AT as a value accessor type VAT.
Definition: attribute_adapter.hpp:61
Definition: element_type.hpp:61
static bool merge(element::Type &dst, const element::Type &t1, const element::Type &t2)
Merges two element types t1 and t2, writing the result into dst and returning true if successful,...
bool compatible(const element::Type &t) const
Checks whether this element type is merge-compatible with t.
The Intel nGraph C++ API.
Definition: attribute_adapter.hpp:28
size_t compiler_byte_size(element::Type_t et)
Return the number of bytes in the compile-time representation of the element type.
Definition: type.hpp:39