KleidiAI Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 17 / 0 / 17
Functions: 87.5% 7 / 0 / 8
Branches: -% 0 / 0 / 0

test/common/bfloat16.hpp
Line Branch Exec Source
1 //
2 // SPDX-FileCopyrightText: Copyright 2024-2025 Arm Limited and/or its affiliates <open-source-office@arm.com>
3 //
4 // SPDX-License-Identifier: Apache-2.0
5 //
6
7 #pragma once
8
9 #include <cstdint>
10 #include <cstring>
11 #include <iosfwd>
12 #include <type_traits>
13
14 #include "test/common/cpu_info.hpp"
15 #include "test/common/type_traits.hpp"
16
17 extern "C" {
18
19 /// Converts single-precision floating-point to half-precision brain floating-point.
20 ///
21 /// @params[in] value The single-precision floating-point value.
22 ///
23 /// @return The half-precision brain floating-point value reinterpreted as 16-bit unsigned integer.
24 uint16_t kai_test_float_to_bfloat16_bfcvt(float value);
25
26 } // extern "C"
27 namespace kai::test {
28
29 /// Half-precision brain floating-point.
30 template <bool hardware_support>
31 class BFloat16 {
32 public:
33 /// Constructor.
34 BFloat16() = default;
35
36 using p_F32BF16convert = uint16_t (*)(float);
37
38 /// Creates a new object from the specified numeric value.
39 2577025376 explicit BFloat16(float value) : m_data(f32_bf16_convertfn(value)) {
40 2577025376 }
41
42 /// Creates a new half-precision brain floating-point value from the raw data.
43 ///
44 /// @param[in] data The binary representation of the floating-point value.
45 ///
46 /// @return The half-precision brain floating-point value.
47 static constexpr BFloat16 from_binary(uint16_t data) {
48 BFloat16 value{};
49 value.m_data = data;
50 return value;
51 }
52
53 /// Assigns to the specified numeric value which will be converted to `bfloat16_t`.
54 template <typename T, std::enable_if_t<is_arithmetic<T>, bool> = true>
55 BFloat16& operator=(T value) {
56 const auto value_f32 = static_cast<float>(value);
57 m_data = f32_bf16_convertfn(value_f32);
58 return *this;
59 }
60
61 /// Converts to single-precision floating-point.
62 5538378904 explicit operator float() const {
63 5538378904 float value_f32 = 0.0F;
64 5538378904 uint32_t value_u32 = static_cast<uint32_t>(m_data) << 16;
65
66 5538378904 memcpy(&value_f32, &value_u32, sizeof(float));
67
68 45634516 return value_f32;
69 5538378904 }
70
71 private:
72 /// Equality operator.
73 6 [[nodiscard]] friend bool operator==(BFloat16 lhs, BFloat16 rhs) {
74 6 return lhs.m_data == rhs.m_data;
75 }
76
77 /// Inequality operator.
78 6 [[nodiscard]] friend bool operator!=(BFloat16 lhs, BFloat16 rhs) {
79 6 return lhs.m_data != rhs.m_data;
80 }
81
82 /// Writes the value to the output stream.
83 ///
84 /// @param[in] os Output stream to be written to.
85 /// @param[in] value Value to be written.
86 ///
87 /// @return The output stream.
88 friend std::ostream& operator<<(std::ostream& os, BFloat16<> value);
89
90 3974096996 static uint16_t float_to_bfloat16_round_towards_zero(float value) {
91 3974096996 uint32_t value_u32;
92
93 3974096996 memcpy(&value_u32, &value, sizeof(value));
94
95 3608713764 return value_u32 >> 16;
96 3974096996 }
97
98 inline static p_F32BF16convert f32_bf16_convertfn = (hardware_support && cpu_has_bf16())
99 ? &kai_test_float_to_bfloat16_bfcvt
100 : &float_to_bfloat16_round_towards_zero;
101
102 uint16_t m_data;
103 };
104
105 } // namespace kai::test
106