KleidiAI Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 20 / 0 / 20
Functions: 100.0% 6 / 0 / 6
Branches: 70.0% 7 / 0 / 10

test/common/seed.hpp
Line Branch Exec Source
1 //
2 // SPDX-FileCopyrightText: Copyright 2025-2026 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 <functional>
11 #include <random>
12 #include <sstream>
13 #include <string>
14 #include <string_view>
15 #include <unordered_map>
16
17 /// KleidiAI tests share a global seed controlled by the test harness. By default
18 /// GoogleTest passes `--gtest_random_seed`, which `global_test_seed()` exposes so
19 /// every test retrieves the same base value. Every test can then derive its own
20 /// deterministic seeds from that base value using `seed_stream(key)`, where `key`
21 /// is a string that identifies the test or test cache.
22 ///
23 /// The default granularity is a single GoogleTest *test case*: `current_test_key()`
24 /// returns a string key representing the current test case, and `seed_stream(current_test_key())`
25 /// returns a stateful generator that produces deterministic seeds for that test case.
26 ///
27 /// `seed_stream()` maintains a map from string keys to `SeedFeed` instances. Each entry
28 /// is seeded by combining the global test seed with a stable hash of the key, ensuring
29 /// that different test cases get different seed streams.
30 ///
31 /// Typical usage for a new test:
32 /// auto& feed = seed_stream(kai::test::current_test_key()); // per-test deterministic stream
33 /// const auto lhs_seed = feed(); // get a seed for lhs
34 /// const auto rhs_seed = feed(); // get a seed for rhs
35 ///
36 /// Tests that cache shared across multiple test cases can create their own key string (e.g. by
37 /// combining test parameters) and pass it to `seed_stream(key)` to ensure the cache stays
38 /// stable across runs.
39
40 namespace kai::test {
41
42 /// Get the global test seed supplied by the harness.
43 ///
44 /// @return Seed value (0 if unavailable).
45 std::uint32_t global_test_seed();
46
47 /// Get the current test key.
48 ///
49 /// @return String representing the current test key.
50 std::string current_test_key();
51
52 /// Stateful generator for deterministic test seeds.
53 class SeedFeed {
54 public:
55 /// Default constructor that initializes the seed internally.
56 SeedFeed() : m_gen(global_test_seed()) {
57 }
58
59 // Constructor with explicit seed.
60 113619 explicit SeedFeed(const std::uint32_t seed) : m_gen(seed) {
61 113619 }
62
63 /// Generate a random seed.
64 ///
65 /// @return Pseudo-random seed.
66 116240 std::uint32_t operator()() {
67 116240 return m_gen();
68 }
69
70 private:
71 std::mt19937 m_gen;
72 };
73
74 /// FNV-1a 32-bit hash function for string literals.
75 ///
76 /// @param[in] input The input string to hash.
77 ///
78 /// @return The computed hash value.
79 75195 constexpr inline std::uint32_t fnv1a_32(std::string_view input) noexcept {
80 75195 constexpr std::uint32_t kOffsetBasis = 0x811C9DC5u;
81 75195 constexpr std::uint32_t kPrime = 0x01000193u;
82
83 75195 std::uint32_t hash = kOffsetBasis;
84
2/2
✓ Branch 0 taken 75195 times.
✓ Branch 1 taken 15185019 times.
15260214 for (unsigned char byte : input) {
85 15185019 hash ^= static_cast<std::uint32_t>(byte);
86 15185019 hash *= kPrime;
87 15185019 }
88 150390 return hash;
89 75195 }
90
91 /// Get the seed stream for a specified key.
92 ///
93 /// @param[in] key The key to get the seed stream for.
94 ///
95 /// @return The seed stream associated with the key.
96 75195 inline SeedFeed& seed_stream(std::string_view key) {
97 // Create static map of seed feeds.
98 // NB: Tests are single-threaded, so no need for synchronization.
99
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 75192 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
75195 static std::unordered_map<std::string, SeedFeed> feeds;
100
101 // Combine global test seed with key-specific hash to create a unique seed.
102 // NB: Cannot use std::hash because it is not stable across different standard libraries or versions.
103 75195 const auto seed = global_test_seed() ^ fnv1a_32(key);
104
105 // Insert or retrieve the seed feed for the given key.
106
2/4
✓ Branch 0 taken 75195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25079 times.
✗ Branch 3 not taken.
75195 auto [it, _] = feeds.try_emplace(std::string(key), seed);
107 150390 return it->second;
108 75195 }
109
110 } // namespace kai::test
111