KleidiAI Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 23 / 0 / 23
Functions: 100.0% 125 / 0 / 125
Branches: 59.4% 19 / 0 / 32

test/common/cache.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 #include <tuple>
8 #include <unordered_map>
9
10 namespace kai::test {
11
12 namespace impl {
13 /// Naive combination of two hash values
14 147428 constexpr size_t hash_combine(size_t lhs, size_t rhs) noexcept {
15 147428 return lhs ^ (rhs << 3);
16 }
17
18 /// Tuple hash recursive case, combines hash of Ith hash with Ith - 1 hash.
19 /// Defaults to last element in tuple
20 template <typename Tuple, std::size_t Index = std::tuple_size<Tuple>::value - 1>
21 struct TupleHash {
22 147428 static size_t combine(const Tuple& tuple) noexcept {
23 using EType = std::tuple_element_t<Index, Tuple>;
24 147428 return hash_combine(
25
3/6
✓ Branch 0 taken 21831 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21831 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21831 times.
✗ Branch 5 not taken.
147428 std::hash<EType>{}(std::get<Index>(tuple)), // hash of current element
26 147428 TupleHash<Tuple, Index - 1>::combine(tuple) // hash of previous elements
27 );
28 }
29 };
30
31 /// TupleHash base case, returns hash of first value
32 template <typename Tuple>
33 struct TupleHash<Tuple, 0> {
34 27295 static size_t combine(const Tuple& tuple) noexcept {
35 using EType = std::tuple_element_t<0, Tuple>;
36
2/4
✓ Branch 0 taken 26649 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 646 times.
✗ Branch 3 not taken.
27295 return std::hash<EType>{}(std::get<0>(tuple));
37 }
38 };
39 } // namespace impl
40
41 struct TupleHash {
42 template <typename... Args>
43 27295 std::size_t operator()(const std::tuple<Args...>& tuple) const noexcept {
44 27295 return impl::TupleHash<std::tuple<Args...>>::combine(tuple);
45 }
46 };
47
48 /// Cached reference cache
49 ///
50 /// The user need to specialize and implement the private `generate_reference()` function, which
51 /// will then be used by the cache mechanism to generate cached reference data
52 ///
53 /// template <>
54 /// CacheData ReferenceGenerator<YourTestID, YourTestData>::generate_reference(const YourTestID& k) {
55 /// ...
56 /// }
57 ///
58 /// And then use the `getV()` helper function to retrieve test reference data
59 ///
60 /// const auto& test_data = getV<YourTestID, YourTestData>(test_id);
61 ///
62 /// Notice that current implementation can be quite memory intensive, but the positive tradeoff
63 /// is its ease of use
64 template <typename K, typename V>
65 struct ReferenceGenerator final {
66 20320 static ReferenceGenerator& getRG() {
67
6/8
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 20118 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 190 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
20320 static ReferenceGenerator rg;
68 20320 return rg;
69 }
70
71 20320 const V& get_test_reference(const K& test_id) {
72
6/10
✓ Branch 0 taken 18568 times.
✓ Branch 1 taken 1560 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18568 times.
✓ Branch 4 taken 1560 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 192 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 192 times.
38888 if (const auto itr = m_data.find(test_id); itr != end(m_data)) {
73 18568 return itr->second;
74 }
75
76
2/4
✓ Branch 0 taken 1560 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
1752 return m_data[test_id] = generate_reference(test_id);
77 20320 }
78
79 private:
80 18 ReferenceGenerator() = default;
81
82 std::unordered_map<K, V, TupleHash> m_data;
83
84 V generate_reference(const K& test_id);
85 };
86
87 /// Main accessor function for retrieving reference test values from test identifier.
88 ///
89 /// This can also be used as a shim between test data creation and usage
90 template <typename K, typename V, typename RG = ReferenceGenerator<K, V>>
91 20320 inline const V& getV(const K& k) {
92 20320 auto& rg = ReferenceGenerator<K, V>::getRG();
93 40640 return rg.get_test_reference(k);
94 20320 }
95
96 }; // namespace kai::test
97