KleidiAI Coverage Report


Directory: ./
File: test/common/bfloat16.hpp
Date: 2025-10-20 13:18:31
Coverage Exec Excl Total
Lines: 77.3% 17 0 22
Functions: 87.5% 7 0 8
Branches: -% 0 0 0

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 3392113970 explicit BFloat16(float value) : m_data(f32_bf16_convertfn(value)) {
40 3392113970 }
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 1686405429 explicit operator float() const {
63 1686405429 float value_f32 = 0.0F;
64 1686405429 uint32_t value_u32 = static_cast<uint32_t>(m_data) << 16;
65
66 1686405429 memcpy(&value_f32, &value_u32, sizeof(float));
67
68 3372810858 return value_f32;
69 1686405429 }
70
71 private:
72 /// Equality operator.
73 3 [[nodiscard]] friend bool operator==(BFloat16 lhs, BFloat16 rhs) {
74 3 return lhs.m_data == rhs.m_data;
75 }
76
77 /// Inequality operator.
78 3 [[nodiscard]] friend bool operator!=(BFloat16 lhs, BFloat16 rhs) {
79 3 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 1399264618 static uint16_t float_to_bfloat16_round_towards_zero(float value) {
91 1399264618 uint32_t value_u32;
92
93 1399264618 memcpy(&value_u32, &value, sizeof(value));
94
95 2798529236 return value_u32 >> 16;
96 1399264618 }
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