KleidiAI Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 18 / 0 / 18
Functions: 100.0% 9 / 0 / 9
Branches: -% 0 / 0 / 0

test/common/buffer.hpp
Line Branch Exec Source
1 //
2 // SPDX-FileCopyrightText: Copyright 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 <cstddef>
10 #include <cstdint>
11 #include <functional>
12 #include <memory>
13
14 #include "test/common/span.hpp"
15
16 namespace kai::test {
17
18 /// Buffer is a high-level abstraction for a block of memory.
19 ///
20 /// The class performs dynamic memory allocation and management in an opaque manner. The underlying memory resource can
21 /// be requested using the familiar @ref Buffer::data() method and interacted with using @ref
22 /// kai::test::read_array<T>() and @ref kai::test::write_array<T>() utilities.
23 ///
24 /// Buffer comes with protection mechanisms defined by @ref BufferProtectionPolicy. These are enabled by setting the
25 /// KAI_TEST_BUFFER_POLICY environment variable, for example:
26 /// KAI_TEST_BUFFER_POLICY=PROTECT_UNDERFLOW to enable @ref BufferProtectionPolicy::ProtectUnderflow.
27 /// KAI_TEST_BUFFER_POLICY=PROTECT_OVERFLOW to enable @ref BufferProtectionPolicy::ProtectOverflow.
28 ///
29 class Buffer {
30 // Handle to the underlying memory resource and its deleter
31 using handle = std::unique_ptr<void, std::function<void(void*)>>;
32
33 public:
34 929553 Buffer() = default;
35 explicit Buffer(size_t size);
36 Buffer(size_t size, uint8_t init_value);
37
38 Buffer(const Buffer& other) = delete;
39 948549 Buffer(Buffer&& other) noexcept = default;
40 Buffer& operator=(const Buffer& other) = delete;
41 293823 Buffer& operator=(Buffer&& other) noexcept = default;
42
43 2950667 ~Buffer() = default;
44
45 /// Gets the base memory address of the user buffer.
46 ///
47 /// @return Base memory address of the user buffer.
48 1063184133 [[nodiscard]] std::byte* data() const {
49 1063184133 return static_cast<std::byte*>(m_buffer.get()) + m_user_buffer_offset;
50 }
51
52 /// Gets a view of the data.
53 11270 operator Span<const std::byte>() const {
54 11270 return {data(), size()};
55 }
56
57 /// Gets a view of the data.
58 2656047 operator Span<std::byte>() {
59 2656047 return {data(), size()};
60 }
61
62 /// Gets a view of the data.
63 [[nodiscard]] Span<const std::byte> view() const {
64 return {data(), size()};
65 }
66
67 /// Gets a view of the data.
68 5040386 [[nodiscard]] Span<std::byte> view() {
69 5040386 return {data(), size()};
70 }
71
72 /// Gets the size of the user buffer.
73 ///
74 /// Depending on the @ref BufferProtectionPolicy policy enabled, the actual size of memory allocated may be larger.
75 /// However, this function guarantees to always provide the size of the user buffer only.
76 ///
77 /// @return Size of the user buffer in bytes.
78 11906396 [[nodiscard]] size_t size() const {
79 11906396 return m_user_buffer_size;
80 }
81
82 static constexpr const char* buffer_policy_env_name = "KAI_TEST_BUFFER_POLICY";
83
84 private:
85 /// Buffer can be protected with one of the following protection policies:
86 /// - @ref BufferProtectionPolicy::None No protection mechanisms are enabled.
87 /// - @ref BufferProtectionPolicy::ProtectUnderflow Memory equal to the size of the user buffer rounded to the
88 /// nearest whole page plus adjacent guard pages is allocated,
89 /// and the user buffer is aligned to the end of the head guard
90 /// page thus detecting whenever a buffer underflow occurs.
91 /// - @ref BufferProtectionPolicy::ProtectOverflow Same as above, but now the edge of the user buffer is aligned
92 /// to the start of the tail guard page thus detecting whenever a
93 /// buffer overflow occurs.
94 enum class BufferProtectionPolicy : uint8_t {
95 None = 0,
96 ProtectUnderflow = 1,
97 ProtectOverflow = 2,
98 };
99
100 /// Naively allocate memory.
101 void allocate();
102
103 #if defined(__linux__) || defined(__APPLE__)
104 /// Allocate memory with adjacent guard pages.
105 void allocate_with_guard_pages();
106 #endif // defined(__linux__) || defined(__APPLE__)
107
108 350105 handle m_buffer = nullptr;
109
110 350105 size_t m_user_buffer_size = 0;
111 350105 size_t m_user_buffer_offset = 0;
112
113 350105 BufferProtectionPolicy m_protection_policy = BufferProtectionPolicy::None;
114 };
115
116 } // namespace kai::test
117