Skip to content

Commit 69d321a

Browse files
authored
[core] Add f8e8m0 element type, float8_e8m0 type and std::numeric_limits<float8_e8m0> (openvinotoolkit#24951)
### Details: - Add new element into OpenVINO f8e8m0 - Add new type float8_e8m0 - Add std::numeric_limits for the new type float8_e8m0 ### Tickets: - [*CVS-141560*](https://jira.devtools.intel.com/browse/CVS-141560) - [*CVS-141562*](https://jira.devtools.intel.com/browse/CVS-141562)
1 parent 15f8503 commit 69d321a

File tree

18 files changed

+723
-11
lines changed

18 files changed

+723
-11
lines changed

cmake/developer_package/ncc_naming_style/openvino.style

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# custom OpenVINO values
22
CppMethod: '^(operator\W+|[a-z_\d]+|signaling_NaN|quiet_NaN|OPENVINO_OP)$'
3-
ClassName: '^([A-Z][\w]+|b?float16|float8_e4m3|float8_e5m2|float4_e2m1|numeric_limits|ngraph_error|stopwatch|unsupported_op)$'
3+
ClassName: '^([A-Z][\w]+|b?float16|float8_e4m3|float8_e5m2|float4_e2m1|float8_e8m0|numeric_limits|ngraph_error|stopwatch|unsupported_op)$'
44
StructName: '^([A-Z][\w]+|element_type_traits|hash|oi_pair|stat)$'
55
FunctionName: '^(operator\W+|[a-z_\d]+)|PrintTo$'
66
Namespace: '^([a-z\d_]*|InferenceEngine)$'
@@ -18,7 +18,7 @@ VariableReference: '^\w+$'
1818

1919
EnumName: '^[A-Z][\w]+$'
2020
# excepts element_type
21-
EnumConstantName: '^([A-Z\d_]+|undefined|dynamic|boolean|bf16|f16|f32|f64|i4|i8|i16|i32|i64|u1|u2|u3|u4|u6|u8|u16|u32|u64|nf4|f8e4m3|f8e5m2|f4e2m1|string|asymmetric|align_corners|round_prefer_floor|round_prefer_ceil|floor|ceil|simple|nearest|linear|linear_onnx|cubic|area|scales|sizes|half_pixel|tf_half_pixel_for_nn|pytorch_half_pixel|asymetric)$'
21+
EnumConstantName: '^([A-Z\d_]+|undefined|dynamic|boolean|bf16|f16|f32|f64|i4|i8|i16|i32|i64|u1|u2|u3|u4|u6|u8|u16|u32|u64|nf4|f8e4m3|f8e5m2|f4e2m1|f8e8m0|string|asymmetric|align_corners|round_prefer_floor|round_prefer_ceil|floor|ceil|simple|nearest|linear|linear_onnx|cubic|area|scales|sizes|half_pixel|tf_half_pixel_for_nn|pytorch_half_pixel|asymetric)$'
2222
# TODO: align
2323
UsingDeclaration: '^.*$'
2424
TypedefName: '^.*$'

src/bindings/c/docs/api_overview.md

+2
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ typedef enum {
207207
208208
F4E2M1, //!< f4e2m1 element type
209209
210+
F8E8M0, //!< f8e8m0 element type
211+
210212
} ov_element_type_e;
211213
```
212214

src/bindings/c/include/openvino/c/ov_common.h

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ typedef enum {
195195
F8E5M3, //!< f8e5m2 element type
196196
STRING, //!< string element type
197197
F4E2M1, //!< f4e2m1 element type
198+
F8E8M0, //!< f8e8m0 element type
198199
} ov_element_type_e;
199200

200201
/**

src/bindings/c/src/ov_tensor.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ const std::map<ov_element_type_e, ov::element::Type> element_type_map = {
3131
{ov_element_type_e::F8E4M3, ov::element::f8e4m3},
3232
{ov_element_type_e::F8E5M3, ov::element::f8e5m2},
3333
{ov_element_type_e::STRING, ov::element::string},
34-
{ov_element_type_e::F4E2M1, ov::element::f4e2m1}};
34+
{ov_element_type_e::F4E2M1, ov::element::f4e2m1},
35+
{ov_element_type_e::F8E8M0, ov::element::f8e8m0},
36+
};
3537

3638
ov_element_type_e find_ov_element_type_e(ov::element::Type type) {
3739
for (auto iter = element_type_map.begin(); iter != element_type_map.end(); iter++) {

src/bindings/python/src/pyopenvino/core/common.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const std::map<ov::element::Type, py::dtype>& ov_type_to_dtype() {
2929
{ov::element::u4, py::dtype("uint8")}, {ov::element::nf4, py::dtype("uint8")},
3030
{ov::element::i4, py::dtype("int8")}, {ov::element::f8e4m3, py::dtype("uint8")},
3131
{ov::element::f8e5m2, py::dtype("uint8")}, {ov::element::string, py::dtype("bytes_")},
32-
{ov::element::f4e2m1, py::dtype("uint8")},
32+
{ov::element::f4e2m1, py::dtype("uint8")}, {ov::element::f8e8m0, py::dtype("uint8")},
3333
};
3434
return ov_type_to_dtype_mapping;
3535
}

src/bindings/python/src/pyopenvino/graph/types/element_type.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ void regclass_graph_Type(py::module m) {
5454
type.attr("f8e5m2") = ov::element::f8e5m2;
5555
type.attr("string") = ov::element::string;
5656
type.attr("f4e2m1") = ov::element::f4e2m1;
57+
type.attr("f8e8m0") = ov::element::f8e8m0;
5758

5859
type.def("__hash__", &ov::element::Type::hash);
5960
type.def("__repr__", [](const ov::element::Type& self) {

src/core/include/openvino/core/type/element_type.hpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "openvino/core/type/float4_e2m1.hpp"
2424
#include "openvino/core/type/float8_e4m3.hpp"
2525
#include "openvino/core/type/float8_e5m2.hpp"
26+
#include "openvino/core/type/float8_e8m0.hpp"
2627

2728
/**
2829
* @defgroup ov_element_cpp_api Element types
@@ -61,7 +62,8 @@ enum class Type_t {
6162
f8e4m3, //!< f8e4m3 element type
6263
f8e5m2, //!< f8e5m2 element type
6364
string, //!< string element type
64-
f4e2m1 //!< f4e2m1 element type
65+
f4e2m1, //!< f4e2m1 element type
66+
f8e8m0, //!< f8e8m0 element type
6567
};
6668

6769
/// \brief Base class to define element type
@@ -214,6 +216,9 @@ constexpr Type string(Type_t::string);
214216
/// \brief f4e2m1 element type
215217
/// \ingroup ov_element_cpp_api
216218
constexpr Type f4e2m1(Type_t::f4e2m1);
219+
/// \brief f8e8m0 element type
220+
/// \ingroup ov_element_cpp_api
221+
constexpr Type f8e8m0(Type_t::f8e8m0);
217222

218223
template <typename T>
219224
Type from() {
@@ -255,6 +260,8 @@ template <>
255260
OPENVINO_API Type from<std::string>();
256261
template <>
257262
OPENVINO_API Type from<ov::float4_e2m1>();
263+
template <>
264+
OPENVINO_API Type from<ov::float8_e8m0>();
258265

259266
OPENVINO_API Type fundamental_type_for(const Type& type);
260267

src/core/include/openvino/core/type/element_type_traits.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,10 @@ template <>
132132
struct element_type_traits<element::Type_t::f4e2m1> {
133133
using value_type = ov::float4_e2m1;
134134
};
135+
136+
template <>
137+
struct element_type_traits<element::Type_t::f8e8m0> {
138+
using value_type = ov::float8_e8m0;
139+
};
140+
135141
} // namespace ov
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
// Copyright (C) 2018-2024 Intel Corporation
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
5+
#pragma once
6+
7+
#include <cmath>
8+
#include <iostream>
9+
#include <limits>
10+
#include <memory>
11+
#include <string>
12+
#include <vector>
13+
14+
#include "openvino/core/core_visibility.hpp"
15+
16+
namespace ov {
17+
18+
/**
19+
* @brief Class to represent the f8e8m0 type.
20+
*/
21+
class OPENVINO_API float8_e8m0 {
22+
public:
23+
float8_e8m0() = default;
24+
float8_e8m0(const float value);
25+
26+
template <typename I>
27+
explicit float8_e8m0(I value) : float8_e8m0{static_cast<float>(value)} {}
28+
29+
template <typename T>
30+
bool operator==(const T& other) const;
31+
template <typename T>
32+
bool operator!=(const T& other) const {
33+
return !(*this == other);
34+
}
35+
36+
template <typename T>
37+
bool operator<(const T& other) const;
38+
template <typename T>
39+
bool operator<=(const T& other) const;
40+
template <typename T>
41+
bool operator>(const T& other) const;
42+
template <typename T>
43+
bool operator>=(const T& other) const;
44+
template <typename T>
45+
float8_e8m0 operator+(const T& other) const;
46+
template <typename T>
47+
float8_e8m0 operator+=(const T& other);
48+
template <typename T>
49+
float8_e8m0 operator-(const T& other) const;
50+
template <typename T>
51+
float8_e8m0 operator-=(const T& other);
52+
template <typename T>
53+
float8_e8m0 operator*(const T& other) const;
54+
template <typename T>
55+
float8_e8m0 operator*=(const T& other);
56+
template <typename T>
57+
float8_e8m0 operator/(const T& other) const;
58+
template <typename T>
59+
float8_e8m0 operator/=(const T& other);
60+
61+
operator float() const;
62+
63+
static constexpr float8_e8m0 from_bits(uint8_t bits) {
64+
return float8_e8m0(bits, true);
65+
}
66+
67+
uint8_t to_bits() const;
68+
69+
friend std::ostream& operator<<(std::ostream& out, const float8_e8m0& obj) {
70+
out << static_cast<float>(obj);
71+
return out;
72+
}
73+
74+
private:
75+
constexpr float8_e8m0(const uint8_t x, bool) : m_value{x} {}
76+
77+
uint8_t m_value{};
78+
};
79+
80+
#if defined(_MSC_VER)
81+
# pragma warning(push)
82+
# pragma warning(disable : 4756)
83+
#endif
84+
template <typename T>
85+
bool float8_e8m0::operator==(const T& other) const {
86+
#if defined(__GNUC__)
87+
# pragma GCC diagnostic push
88+
# pragma GCC diagnostic ignored "-Wfloat-equal"
89+
#endif
90+
return (static_cast<float>(*this) == static_cast<float>(other));
91+
#if defined(__GNUC__)
92+
# pragma GCC diagnostic pop
93+
#endif
94+
}
95+
96+
template <typename T>
97+
bool float8_e8m0::operator<(const T& other) const {
98+
return (static_cast<float>(*this) < static_cast<float>(other));
99+
}
100+
101+
template <typename T>
102+
bool float8_e8m0::operator<=(const T& other) const {
103+
return (static_cast<float>(*this) <= static_cast<float>(other));
104+
}
105+
106+
template <typename T>
107+
bool float8_e8m0::operator>(const T& other) const {
108+
return (static_cast<float>(*this) > static_cast<float>(other));
109+
}
110+
111+
template <typename T>
112+
bool float8_e8m0::operator>=(const T& other) const {
113+
return (static_cast<float>(*this) >= static_cast<float>(other));
114+
}
115+
116+
template <typename T>
117+
float8_e8m0 float8_e8m0::operator+(const T& other) const {
118+
return {static_cast<float>(*this) + static_cast<float>(other)};
119+
}
120+
121+
template <typename T>
122+
float8_e8m0 float8_e8m0::operator+=(const T& other) {
123+
return *this = *this + other;
124+
}
125+
126+
template <typename T>
127+
float8_e8m0 float8_e8m0::operator-(const T& other) const {
128+
return {static_cast<float>(*this) - static_cast<float>(other)};
129+
}
130+
131+
template <typename T>
132+
float8_e8m0 float8_e8m0::operator-=(const T& other) {
133+
return *this = *this - other;
134+
}
135+
136+
template <typename T>
137+
float8_e8m0 float8_e8m0::operator*(const T& other) const {
138+
return {static_cast<float>(*this) * static_cast<float>(other)};
139+
}
140+
141+
template <typename T>
142+
float8_e8m0 float8_e8m0::operator*=(const T& other) {
143+
return *this = *this * other;
144+
}
145+
146+
template <typename T>
147+
float8_e8m0 float8_e8m0::operator/(const T& other) const {
148+
return {static_cast<float>(*this) / static_cast<float>(other)};
149+
}
150+
151+
template <typename T>
152+
float8_e8m0 float8_e8m0::operator/=(const T& other) {
153+
return *this = *this / other;
154+
}
155+
#if defined(_MSC_VER)
156+
# pragma warning(pop)
157+
#endif
158+
} // namespace ov
159+
160+
namespace std {
161+
template <>
162+
class numeric_limits<ov::float8_e8m0> {
163+
public:
164+
static constexpr bool is_specialized = true;
165+
static constexpr ov::float8_e8m0 min() noexcept {
166+
return ov::float8_e8m0::from_bits(0b00000000u);
167+
}
168+
static constexpr ov::float8_e8m0 max() noexcept {
169+
return ov::float8_e8m0::from_bits(0b11111110u);
170+
}
171+
static constexpr ov::float8_e8m0 lowest() noexcept {
172+
return ov::float8_e8m0::from_bits(0b00000000u);
173+
}
174+
static constexpr int digits = 1;
175+
static constexpr int digits10 = 0;
176+
177+
static constexpr bool is_signed = false;
178+
static constexpr bool is_integer = false;
179+
static constexpr bool is_exact = false;
180+
181+
static constexpr int radix = 2;
182+
183+
static constexpr ov::float8_e8m0 epsilon() noexcept {
184+
return ov::float8_e8m0::from_bits(0b00000001u);
185+
}
186+
static constexpr ov::float8_e8m0 round_error() noexcept {
187+
return ov::float8_e8m0::from_bits(0b01111110u);
188+
}
189+
190+
static constexpr int min_exponent = -126;
191+
static constexpr int min_exponent10 = -38;
192+
static constexpr int max_exponent = 128;
193+
static constexpr int max_exponent10 = 38;
194+
195+
static constexpr bool has_infinity = false;
196+
static constexpr bool has_quiet_NaN = true;
197+
static constexpr bool has_signaling_NaN = false;
198+
199+
static constexpr float_denorm_style has_denorm = denorm_absent;
200+
static constexpr bool has_denorm_loss = false;
201+
202+
static constexpr ov::float8_e8m0 infinity() noexcept {
203+
return ov::float8_e8m0::from_bits(0); // no infinity
204+
}
205+
static constexpr ov::float8_e8m0 quiet_NaN() noexcept {
206+
return ov::float8_e8m0::from_bits(0b11111111);
207+
}
208+
static constexpr ov::float8_e8m0 signaling_NaN() noexcept {
209+
return ov::float8_e8m0::from_bits(0); // no signaling NaN
210+
}
211+
static constexpr bool is_iec559 = false;
212+
static constexpr bool is_bounded = false;
213+
static constexpr bool is_modulo = false;
214+
static constexpr bool traps = false;
215+
static constexpr bool tinyness_before = false;
216+
static constexpr float_round_style round_style = round_to_nearest;
217+
};
218+
} // namespace std

src/core/include/openvino/op/constant.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class OPENVINO_API Constant : public Op {
159159
case Type_t::f4e2m1:
160160
fill_lp_data<Type_t::f4e2m1>(value);
161161
break;
162+
case Type_t::f8e8m0:
162163
case Type_t::undefined:
163164
case Type_t::dynamic:
164165
OPENVINO_THROW("unsupported type");
@@ -720,6 +721,7 @@ class OPENVINO_API Constant : public Op {
720721
case Type_t::f4e2m1:
721722
write_lp_buffer<Type_t::f4e2m1>(source);
722723
break;
724+
case Type_t::f8e8m0:
723725
case Type_t::undefined:
724726
case Type_t::dynamic:
725727
OPENVINO_THROW("unsupported type");

src/core/src/pass/serialize.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ std::string get_precision_name(const ov::element::Type& elem_type) {
769769
return "STRING";
770770
case ::ov::element::Type_t::f4e2m1:
771771
return "F4E2M1";
772+
case ::ov::element::Type_t::f8e8m0:
773+
return "F8E8M0";
772774
default:
773775
OPENVINO_THROW("Unsupported precision: ", elem_type);
774776
}

src/core/src/pass/visualize_tree.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ static std::string get_value(const std::shared_ptr<ov::op::v0::Constant>& consta
458458
case ov::element::Type_t::f8e4m3:
459459
case ov::element::Type_t::f8e5m2:
460460
case ov::element::Type_t::f4e2m1:
461+
case ov::element::Type_t::f8e8m0:
461462
ss << constant->get_output_element_type(0).get_type_name() << " value";
462463
break;
463464
case ov::element::Type_t::bf16:

0 commit comments

Comments
 (0)