коммит произвёл
GitHub
родитель
0a2ea9ef55
Коммит
0b4a309ff7
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace rocprofsys
|
||||
{
|
||||
inline namespace common
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct span
|
||||
{
|
||||
using value_type = T;
|
||||
|
||||
constexpr span(T* data, size_t size) noexcept
|
||||
: m_data(data)
|
||||
, m_size(size)
|
||||
{}
|
||||
|
||||
constexpr span(std::vector<T>& vec) noexcept
|
||||
: m_data(vec.data())
|
||||
, m_size(vec.size())
|
||||
{}
|
||||
|
||||
template <size_t N>
|
||||
constexpr span(std::array<T, N>& arr) noexcept
|
||||
: m_data(arr.data())
|
||||
, m_size(arr.size())
|
||||
{}
|
||||
|
||||
constexpr inline __attribute__((always_inline)) T* data() const noexcept
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
constexpr inline __attribute__((always_inline)) T* data() noexcept { return m_data; }
|
||||
constexpr inline __attribute__((always_inline)) T* begin() noexcept { return m_data; }
|
||||
constexpr inline __attribute__((always_inline)) T* end() noexcept
|
||||
{
|
||||
return m_data + m_size;
|
||||
}
|
||||
constexpr inline __attribute__((always_inline)) size_t size() const noexcept
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
constexpr inline __attribute__((always_inline)) bool empty() const noexcept
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
constexpr inline __attribute__((always_inline)) T& operator[](size_t index) noexcept
|
||||
{
|
||||
return m_data[index];
|
||||
}
|
||||
constexpr inline __attribute__((always_inline)) const T& operator[](
|
||||
size_t index) const noexcept
|
||||
{
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
private:
|
||||
T* m_data = nullptr;
|
||||
size_t m_size = 0;
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace rocprofsys
|
||||
+26
-8
@@ -21,6 +21,7 @@
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "common/span.hpp"
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
@@ -80,20 +81,37 @@ struct tuple_to_variant<std::tuple<Types...>>
|
||||
template <class...>
|
||||
using void_t = void;
|
||||
|
||||
template <typename... Types>
|
||||
struct typelist
|
||||
{
|
||||
template <typename T>
|
||||
constexpr static bool is_supported = (std::is_same_v<std::decay_t<T>, Types> || ...);
|
||||
};
|
||||
template <typename T>
|
||||
struct is_span : std::false_type
|
||||
{};
|
||||
|
||||
using supported_types = typelist<std::string_view, uint64_t, int32_t, uint32_t,
|
||||
std::vector<uint8_t>, uint8_t, int64_t, double>;
|
||||
template <typename T>
|
||||
struct is_span<span<T>> : std::true_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_span_v = is_span<T>::value;
|
||||
|
||||
template <typename T>
|
||||
struct is_vector : std::false_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct is_vector<std::vector<T>> : std::true_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_vector_v = is_vector<T>::value;
|
||||
|
||||
template <typename T>
|
||||
static constexpr bool is_string_view_v =
|
||||
std::is_same_v<std::decay_t<T>, std::string_view>;
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_supported_type_v =
|
||||
is_span_v<T> || std::is_integral_v<T> || std::is_floating_point_v<T> ||
|
||||
is_string_view_v<T> || is_vector_v<T>;
|
||||
|
||||
template <typename T>
|
||||
struct is_enum_class
|
||||
: std::bool_constant<std::is_enum_v<T> &&
|
||||
|
||||
@@ -78,13 +78,19 @@ __attribute__((always_inline)) inline constexpr size_t
|
||||
get_size(Type&& val)
|
||||
{
|
||||
using DecayedType = std::decay_t<Type>;
|
||||
static_assert(type_traits::supported_types::is_supported<DecayedType>,
|
||||
static_assert(type_traits::is_supported_type_v<DecayedType>,
|
||||
"Unsupported type in get_size");
|
||||
|
||||
if constexpr(type_traits::is_string_view_v<DecayedType> ||
|
||||
std::is_same_v<DecayedType, std::vector<uint8_t>>)
|
||||
type_traits::is_vector_v<DecayedType> ||
|
||||
type_traits::is_span_v<DecayedType>)
|
||||
{
|
||||
return val.size() + sizeof(size_t);
|
||||
using ContainerType = std::decay_t<decltype(val)>;
|
||||
const size_t item_size = sizeof(typename ContainerType::value_type);
|
||||
const size_t item_count = val.size();
|
||||
const size_t total_size = item_count * item_size;
|
||||
|
||||
return total_size + sizeof(size_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -104,18 +110,21 @@ __attribute__((always_inline)) inline void
|
||||
store_value(const Type& value, uint8_t* buffer, size_t& position)
|
||||
{
|
||||
using DecayedType = std::decay_t<Type>;
|
||||
static_assert(type_traits::supported_types::is_supported<DecayedType>,
|
||||
static_assert(type_traits::is_supported_type_v<DecayedType>,
|
||||
"Unsupported type in store_value");
|
||||
|
||||
auto* dest = buffer + position;
|
||||
|
||||
if constexpr(type_traits::is_string_view_v<DecayedType> ||
|
||||
std::is_same_v<DecayedType, std::vector<uint8_t>>)
|
||||
type_traits::is_vector_v<DecayedType> ||
|
||||
type_traits::is_span_v<DecayedType>)
|
||||
{
|
||||
const size_t elem_count = value.size();
|
||||
*reinterpret_cast<size_t*>(dest) = elem_count;
|
||||
std::memcpy(dest + sizeof(size_t), value.data(), elem_count);
|
||||
position += elem_count + sizeof(size_t);
|
||||
const size_t total_size = get_size(value);
|
||||
const size_t header_size = sizeof(size_t);
|
||||
const size_t data_size = total_size - header_size;
|
||||
*reinterpret_cast<size_t*>(dest) = data_size;
|
||||
std::memcpy(dest + sizeof(size_t), value.data(), data_size);
|
||||
position += total_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -137,7 +146,7 @@ __attribute__((always_inline)) inline static void
|
||||
parse_value(uint8_t*& data_pos, Type& arg)
|
||||
{
|
||||
using DecayedType = std::decay_t<Type>;
|
||||
static_assert(type_traits::supported_types::is_supported<DecayedType>,
|
||||
static_assert(type_traits::is_supported_type_v<DecayedType>,
|
||||
"Unsupported type in parse_value");
|
||||
|
||||
if constexpr(type_traits::is_string_view_v<DecayedType>)
|
||||
@@ -147,13 +156,17 @@ parse_value(uint8_t*& data_pos, Type& arg)
|
||||
arg = std::string_view{ reinterpret_cast<const char*>(data_pos), string_size };
|
||||
data_pos += string_size;
|
||||
}
|
||||
else if constexpr(std::is_same_v<DecayedType, std::vector<uint8_t>>)
|
||||
else if constexpr(type_traits::is_vector_v<DecayedType> ||
|
||||
type_traits::is_span_v<DecayedType>)
|
||||
{
|
||||
const size_t vector_size = *reinterpret_cast<const size_t*>(data_pos);
|
||||
using ContainerType = std::decay_t<decltype(arg)>;
|
||||
const size_t item_size = sizeof(typename ContainerType::value_type);
|
||||
const size_t total_size = *reinterpret_cast<const size_t*>(data_pos);
|
||||
data_pos += sizeof(size_t);
|
||||
arg.reserve(vector_size);
|
||||
std::copy_n(data_pos, vector_size, std::back_inserter(arg));
|
||||
data_pos += vector_size;
|
||||
arg.reserve(total_size / item_size);
|
||||
std::copy_n(reinterpret_cast<const typename ContainerType::value_type*>(data_pos),
|
||||
total_size / item_size, std::back_inserter(arg));
|
||||
data_pos += total_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+39
@@ -33,6 +33,7 @@ enum class test_type_identifier_t : uint32_t
|
||||
sample_type_1 = 1,
|
||||
sample_type_2 = 2,
|
||||
sample_type_3 = 3,
|
||||
sample_type_4 = 4,
|
||||
fragmented_space = 0xFFFF
|
||||
};
|
||||
struct test_sample_1 : public rocprofsys::trace_cache::cacheable_t
|
||||
@@ -97,6 +98,21 @@ struct test_sample_3 : public rocprofsys::trace_cache::cacheable_t
|
||||
bool operator==(const test_sample_3& other) const { return payload == other.payload; }
|
||||
};
|
||||
|
||||
struct test_sample_4 : public rocprofsys::trace_cache::cacheable_t
|
||||
{
|
||||
static constexpr test_type_identifier_t type_identifier =
|
||||
test_type_identifier_t::sample_type_4;
|
||||
|
||||
test_sample_4() = default;
|
||||
test_sample_4(std::vector<uint32_t> d)
|
||||
: data(std::move(d))
|
||||
{}
|
||||
|
||||
std::vector<uint32_t> data;
|
||||
|
||||
bool operator==(const test_sample_4& other) const { return data == other.data; }
|
||||
};
|
||||
|
||||
template <>
|
||||
inline void
|
||||
rocprofsys::trace_cache::serialize(uint8_t* buffer, const test_sample_1& item)
|
||||
@@ -165,3 +181,26 @@ rocprofsys::trace_cache::get_size(const test_sample_3& item)
|
||||
{
|
||||
return rocprofsys::trace_cache::utility::get_size(item.payload);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void
|
||||
rocprofsys::trace_cache::serialize(uint8_t* buffer, const test_sample_4& item)
|
||||
{
|
||||
rocprofsys::trace_cache::utility::store_value(buffer, item.data);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline test_sample_4
|
||||
rocprofsys::trace_cache::deserialize(uint8_t*& buffer)
|
||||
{
|
||||
test_sample_4 result;
|
||||
rocprofsys::trace_cache::utility::parse_value(buffer, result.data);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline size_t
|
||||
rocprofsys::trace_cache::get_size(const test_sample_4& item)
|
||||
{
|
||||
return rocprofsys::trace_cache::utility::get_size(item.data);
|
||||
}
|
||||
|
||||
+146
-6
@@ -77,6 +77,19 @@ struct sample_3_hash
|
||||
}
|
||||
};
|
||||
|
||||
struct sample_4_hash
|
||||
{
|
||||
size_t operator()(const test_sample_4& s) const
|
||||
{
|
||||
size_t h = 0;
|
||||
for(auto val : s.data)
|
||||
{
|
||||
h ^= std::hash<uint32_t>{}(val) + 0x9e3779b9 + (h << 6) + (h >> 2);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class integration_sample_processor_t
|
||||
@@ -114,6 +127,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void set_expected_samples_4(const std::vector<test_sample_4>& samples)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_data_mutex);
|
||||
m_expected_samples_4.clear();
|
||||
for(const auto& s : samples)
|
||||
{
|
||||
m_expected_samples_4[s]++;
|
||||
}
|
||||
}
|
||||
|
||||
void execute_sample_processing(test_type_identifier_t type_identifier,
|
||||
const rocprofsys::trace_cache::cacheable_t& value)
|
||||
{
|
||||
@@ -143,6 +166,14 @@ public:
|
||||
check_sample_3(sample);
|
||||
break;
|
||||
}
|
||||
case test_type_identifier_t::sample_type_4:
|
||||
{
|
||||
const auto& sample = static_cast<const test_sample_4&>(value);
|
||||
std::lock_guard<std::mutex> lock(m_data_mutex);
|
||||
m_sample_4_count++;
|
||||
check_sample_4(sample);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -150,11 +181,12 @@ public:
|
||||
int get_sample_1_count() const { return m_sample_1_count.load(); }
|
||||
int get_sample_2_count() const { return m_sample_2_count.load(); }
|
||||
int get_sample_3_count() const { return m_sample_3_count.load(); }
|
||||
int get_sample_4_count() const { return m_sample_4_count.load(); }
|
||||
bool all_expected_samples_found() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_data_mutex);
|
||||
return m_expected_samples_1.empty() && m_expected_samples_2.empty() &&
|
||||
m_expected_samples_3.empty();
|
||||
m_expected_samples_3.empty() && m_expected_samples_4.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -200,12 +232,28 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void check_sample_4(const test_sample_4& sample)
|
||||
{
|
||||
auto it = m_expected_samples_4.find(sample);
|
||||
EXPECT_NE(it, m_expected_samples_4.end());
|
||||
if(it != m_expected_samples_4.end())
|
||||
{
|
||||
it->second--;
|
||||
if(it->second == 0)
|
||||
{
|
||||
m_expected_samples_4.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::atomic<int> m_sample_1_count{ 0 };
|
||||
std::atomic<int> m_sample_2_count{ 0 };
|
||||
std::atomic<int> m_sample_3_count{ 0 };
|
||||
std::atomic<int> m_sample_4_count{ 0 };
|
||||
std::unordered_map<test_sample_1, int, sample_1_hash> m_expected_samples_1;
|
||||
std::unordered_map<test_sample_2, int, sample_2_hash> m_expected_samples_2;
|
||||
std::unordered_map<test_sample_3, int, sample_3_hash> m_expected_samples_3;
|
||||
std::unordered_map<test_sample_4, int, sample_4_hash> m_expected_samples_4;
|
||||
mutable std::mutex m_data_mutex;
|
||||
};
|
||||
|
||||
@@ -275,7 +323,7 @@ TEST_F(trace_cache_module_integration_test, buffer_fragmentation_handling)
|
||||
processor->set_expected_samples_3(expected_3);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
parser.load(processor);
|
||||
@@ -358,7 +406,7 @@ TEST_F(trace_cache_module_integration_test, content_validation_edge_cases)
|
||||
processor->set_expected_samples_3(expected_3);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
parser.load(processor);
|
||||
|
||||
@@ -408,7 +456,7 @@ TEST_F(trace_cache_module_integration_test, stress_test_multiple_fragmentations)
|
||||
processor->set_expected_samples_1(expected_1);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
parser.load(processor);
|
||||
|
||||
@@ -465,7 +513,7 @@ TEST_F(trace_cache_module_integration_test, performance_write_test)
|
||||
processor->set_expected_samples_1(samples);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
parser.load(processor);
|
||||
|
||||
@@ -547,10 +595,102 @@ TEST_F(trace_cache_module_integration_test, concurrent_write_read_validation)
|
||||
processor->set_expected_samples_1(expected_1);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
parser.load(processor);
|
||||
|
||||
EXPECT_EQ(processor->get_sample_1_count(), total_samples);
|
||||
EXPECT_TRUE(processor->all_expected_samples_found());
|
||||
}
|
||||
|
||||
TEST_F(trace_cache_module_integration_test, uint32_vector_element_size_handling)
|
||||
{
|
||||
std::vector<test_sample_4> expected_4;
|
||||
expected_4.reserve(100);
|
||||
|
||||
{
|
||||
rocprofsys::trace_cache::buffer_storage<
|
||||
rocprofsys::trace_cache::flush_worker_factory_t, test_type_identifier_t>
|
||||
storage(test_file_path);
|
||||
storage.start();
|
||||
|
||||
for(int i = 0; i < 100; ++i)
|
||||
{
|
||||
std::vector<uint32_t> data;
|
||||
data.reserve(10);
|
||||
for(int j = 0; j < 10; ++j)
|
||||
{
|
||||
data.push_back(static_cast<uint32_t>(i * 1000 + j));
|
||||
}
|
||||
test_sample_4 sample(data);
|
||||
expected_4.push_back(sample);
|
||||
storage.store(sample);
|
||||
}
|
||||
|
||||
storage.shutdown();
|
||||
}
|
||||
|
||||
auto processor = std::make_shared<integration_sample_processor_t>();
|
||||
processor->set_expected_samples_4(expected_4);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
parser.load(processor);
|
||||
|
||||
EXPECT_EQ(processor->get_sample_4_count(), 100);
|
||||
EXPECT_TRUE(processor->all_expected_samples_found());
|
||||
}
|
||||
|
||||
TEST_F(trace_cache_module_integration_test, mixed_vector_element_sizes)
|
||||
{
|
||||
std::vector<test_sample_3> expected_3;
|
||||
std::vector<test_sample_4> expected_4;
|
||||
expected_3.reserve(50);
|
||||
expected_4.reserve(50);
|
||||
|
||||
{
|
||||
rocprofsys::trace_cache::buffer_storage<
|
||||
rocprofsys::trace_cache::flush_worker_factory_t, test_type_identifier_t>
|
||||
storage(test_file_path);
|
||||
storage.start();
|
||||
|
||||
for(int i = 0; i < 100; ++i)
|
||||
{
|
||||
if(i % 2 == 0)
|
||||
{
|
||||
std::vector<uint8_t> payload(20, static_cast<uint8_t>(i));
|
||||
test_sample_3 sample(payload);
|
||||
expected_3.push_back(sample);
|
||||
storage.store(sample);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<uint32_t> data;
|
||||
data.reserve(5);
|
||||
for(int j = 0; j < 5; ++j)
|
||||
{
|
||||
data.push_back(static_cast<uint32_t>(i * 100 + j));
|
||||
}
|
||||
test_sample_4 sample(data);
|
||||
expected_4.push_back(sample);
|
||||
storage.store(sample);
|
||||
}
|
||||
}
|
||||
|
||||
storage.shutdown();
|
||||
}
|
||||
|
||||
auto processor = std::make_shared<integration_sample_processor_t>();
|
||||
processor->set_expected_samples_3(expected_3);
|
||||
processor->set_expected_samples_4(expected_4);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
parser.load(processor);
|
||||
|
||||
EXPECT_EQ(processor->get_sample_3_count(), 50);
|
||||
EXPECT_EQ(processor->get_sample_4_count(), 50);
|
||||
EXPECT_TRUE(processor->all_expected_samples_found());
|
||||
}
|
||||
|
||||
+220
@@ -20,10 +20,12 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "core/trace_cache/cache_type_traits.hpp"
|
||||
#include "core/trace_cache/cacheable.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -303,6 +305,224 @@ TEST_F(cacheable_test, get_size_helper_byte_array)
|
||||
EXPECT_EQ(size, value.size() + sizeof(size_t));
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, store_value_span_uint8)
|
||||
{
|
||||
std::vector<uint8_t> data = { 1, 2, 3, 4, 5 };
|
||||
rocprofsys::span<uint8_t> span_val(data);
|
||||
rocprofsys::trace_cache::utility::store_value(span_val, buffer.data(), position);
|
||||
|
||||
size_t expected_size = data.size() * sizeof(uint8_t) + sizeof(size_t);
|
||||
EXPECT_EQ(position, expected_size);
|
||||
|
||||
size_t stored_size = *reinterpret_cast<size_t*>(buffer.data());
|
||||
EXPECT_EQ(stored_size, data.size() * sizeof(uint8_t));
|
||||
|
||||
uint8_t* data_start = buffer.data() + sizeof(size_t);
|
||||
for(size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
EXPECT_EQ(data_start[i], data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, store_value_span_uint32)
|
||||
{
|
||||
std::vector<uint32_t> data = { 100, 200, 300, 400, 500 };
|
||||
rocprofsys::span<uint32_t> span_val(data);
|
||||
rocprofsys::trace_cache::utility::store_value(span_val, buffer.data(), position);
|
||||
|
||||
size_t expected_data_size = data.size() * sizeof(uint32_t);
|
||||
size_t expected_total_size = expected_data_size + sizeof(size_t);
|
||||
EXPECT_EQ(position, expected_total_size);
|
||||
|
||||
size_t stored_size = *reinterpret_cast<size_t*>(buffer.data());
|
||||
EXPECT_EQ(stored_size, expected_data_size);
|
||||
|
||||
uint32_t* data_start = reinterpret_cast<uint32_t*>(buffer.data() + sizeof(size_t));
|
||||
for(size_t i = 0; i < data.size(); ++i)
|
||||
{
|
||||
EXPECT_EQ(data_start[i], data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, store_value_empty_span)
|
||||
{
|
||||
rocprofsys::span<uint8_t> empty_span(nullptr, 0);
|
||||
rocprofsys::trace_cache::utility::store_value(empty_span, buffer.data(), position);
|
||||
|
||||
EXPECT_EQ(position, sizeof(size_t));
|
||||
size_t stored_size = *reinterpret_cast<size_t*>(buffer.data());
|
||||
EXPECT_EQ(stored_size, 0);
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, span_store_vector_parse_roundtrip)
|
||||
{
|
||||
std::vector<uint8_t> original_data = { 10, 20, 30, 40, 50 };
|
||||
rocprofsys::span<uint8_t> span_val(original_data);
|
||||
rocprofsys::trace_cache::utility::store_value(span_val, buffer.data(), position);
|
||||
|
||||
uint8_t* data_pos = buffer.data();
|
||||
std::vector<uint8_t> parsed_value;
|
||||
rocprofsys::trace_cache::utility::parse_value(data_pos, parsed_value);
|
||||
|
||||
EXPECT_EQ(parsed_value.size(), original_data.size());
|
||||
EXPECT_EQ(parsed_value, original_data);
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, span_uint32_store_vector_parse_roundtrip)
|
||||
{
|
||||
std::vector<uint32_t> original_data = { 0xDEADBEEF, 0xCAFEBABE, 0x12345678 };
|
||||
rocprofsys::span<uint32_t> span_val(original_data);
|
||||
rocprofsys::trace_cache::utility::store_value(span_val, buffer.data(), position);
|
||||
|
||||
uint8_t* data_pos = buffer.data();
|
||||
std::vector<uint32_t> parsed_value;
|
||||
rocprofsys::trace_cache::utility::parse_value(data_pos, parsed_value);
|
||||
|
||||
EXPECT_EQ(parsed_value.size(), original_data.size());
|
||||
EXPECT_EQ(parsed_value, original_data);
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, get_size_span_uint8)
|
||||
{
|
||||
std::vector<uint8_t> data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
rocprofsys::span<uint8_t> span_val(data);
|
||||
size_t size = rocprofsys::trace_cache::utility::get_size(span_val);
|
||||
EXPECT_EQ(size, data.size() * sizeof(uint8_t) + sizeof(size_t));
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, get_size_span_uint32)
|
||||
{
|
||||
std::vector<uint32_t> data = { 100, 200, 300, 400, 500 };
|
||||
rocprofsys::span<uint32_t> span_val(data);
|
||||
size_t size = rocprofsys::trace_cache::utility::get_size(span_val);
|
||||
EXPECT_EQ(size, data.size() * sizeof(uint32_t) + sizeof(size_t));
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, store_value_int_vector)
|
||||
{
|
||||
std::vector<int> value = { -100, 0, 100, 200, -200 };
|
||||
rocprofsys::trace_cache::utility::store_value(value, buffer.data(), position);
|
||||
|
||||
size_t expected_data_size = value.size() * sizeof(int);
|
||||
size_t expected_total = expected_data_size + sizeof(size_t);
|
||||
EXPECT_EQ(position, expected_total);
|
||||
|
||||
size_t stored_size = *reinterpret_cast<size_t*>(buffer.data());
|
||||
EXPECT_EQ(stored_size, expected_data_size);
|
||||
|
||||
int* data_start = reinterpret_cast<int*>(buffer.data() + sizeof(size_t));
|
||||
for(size_t i = 0; i < value.size(); ++i)
|
||||
{
|
||||
EXPECT_EQ(data_start[i], value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, parse_value_int_vector)
|
||||
{
|
||||
std::vector<int> original_value = { -100, 0, 100, 200, -200 };
|
||||
rocprofsys::trace_cache::utility::store_value(original_value, buffer.data(),
|
||||
position);
|
||||
|
||||
uint8_t* data_pos = buffer.data();
|
||||
std::vector<int> parsed_value;
|
||||
rocprofsys::trace_cache::utility::parse_value(data_pos, parsed_value);
|
||||
|
||||
EXPECT_EQ(parsed_value.size(), original_value.size());
|
||||
EXPECT_EQ(parsed_value, original_value);
|
||||
size_t expected_advance = sizeof(size_t) + original_value.size() * sizeof(int);
|
||||
EXPECT_EQ(data_pos, buffer.data() + expected_advance);
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, store_value_uint64_vector)
|
||||
{
|
||||
std::vector<uint64_t> value = { 0xFFFFFFFFFFFFFFFF, 0x0, 0x123456789ABCDEF0 };
|
||||
rocprofsys::trace_cache::utility::store_value(value, buffer.data(), position);
|
||||
|
||||
size_t expected_data_size = value.size() * sizeof(uint64_t);
|
||||
size_t expected_total = expected_data_size + sizeof(size_t);
|
||||
EXPECT_EQ(position, expected_total);
|
||||
|
||||
size_t stored_size = *reinterpret_cast<size_t*>(buffer.data());
|
||||
EXPECT_EQ(stored_size, expected_data_size);
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, parse_value_uint64_vector)
|
||||
{
|
||||
std::vector<uint64_t> original_value = { 0xFFFFFFFFFFFFFFFF, 0x0,
|
||||
0x123456789ABCDEF0 };
|
||||
rocprofsys::trace_cache::utility::store_value(original_value, buffer.data(),
|
||||
position);
|
||||
|
||||
uint8_t* data_pos = buffer.data();
|
||||
std::vector<uint64_t> parsed_value;
|
||||
rocprofsys::trace_cache::utility::parse_value(data_pos, parsed_value);
|
||||
|
||||
EXPECT_EQ(parsed_value.size(), original_value.size());
|
||||
EXPECT_EQ(parsed_value, original_value);
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, get_size_int_vector)
|
||||
{
|
||||
std::vector<int> value = { 1, 2, 3, 4, 5 };
|
||||
size_t size = rocprofsys::trace_cache::utility::get_size(value);
|
||||
EXPECT_EQ(size, value.size() * sizeof(int) + sizeof(size_t));
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, get_size_uint64_vector)
|
||||
{
|
||||
std::vector<uint64_t> value = { 1, 2, 3, 4, 5 };
|
||||
size_t size = rocprofsys::trace_cache::utility::get_size(value);
|
||||
EXPECT_EQ(size, value.size() * sizeof(uint64_t) + sizeof(size_t));
|
||||
}
|
||||
|
||||
TEST(type_traits_test, is_span_v)
|
||||
{
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_span_v<rocprofsys::span<int>>);
|
||||
EXPECT_TRUE(
|
||||
rocprofsys::trace_cache::type_traits::is_span_v<rocprofsys::span<uint8_t>>);
|
||||
EXPECT_TRUE(
|
||||
rocprofsys::trace_cache::type_traits::is_span_v<rocprofsys::span<double>>);
|
||||
|
||||
EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_span_v<int>);
|
||||
EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_span_v<std::vector<int>>);
|
||||
EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_span_v<std::string_view>);
|
||||
}
|
||||
|
||||
TEST(type_traits_test, is_vector_v)
|
||||
{
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_vector_v<std::vector<int>>);
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_vector_v<std::vector<uint8_t>>);
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_vector_v<std::vector<double>>);
|
||||
|
||||
EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_vector_v<int>);
|
||||
EXPECT_FALSE(
|
||||
rocprofsys::trace_cache::type_traits::is_vector_v<rocprofsys::span<int>>);
|
||||
EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_vector_v<std::string_view>);
|
||||
}
|
||||
|
||||
TEST(type_traits_test, is_supported_type_v)
|
||||
{
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v<int>);
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v<uint64_t>);
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v<double>);
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v<float>);
|
||||
EXPECT_TRUE(
|
||||
rocprofsys::trace_cache::type_traits::is_supported_type_v<std::string_view>);
|
||||
EXPECT_TRUE(
|
||||
rocprofsys::trace_cache::type_traits::is_supported_type_v<std::vector<int>>);
|
||||
EXPECT_TRUE(
|
||||
rocprofsys::trace_cache::type_traits::is_supported_type_v<std::vector<uint8_t>>);
|
||||
EXPECT_TRUE(
|
||||
rocprofsys::trace_cache::type_traits::is_supported_type_v<rocprofsys::span<int>>);
|
||||
EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v<
|
||||
rocprofsys::span<uint8_t>>);
|
||||
|
||||
struct custom_type
|
||||
{};
|
||||
EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_supported_type_v<custom_type>);
|
||||
EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_supported_type_v<std::string>);
|
||||
}
|
||||
|
||||
TEST_F(cacheable_test, get_buffered_storage_filename)
|
||||
{
|
||||
int ppid = 1234;
|
||||
|
||||
+34
-9
@@ -54,6 +54,12 @@ public:
|
||||
m_expected_samples_3 = samples;
|
||||
}
|
||||
|
||||
void set_expected_samples_4(const std::vector<test_sample_4>& samples)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_data_mutex);
|
||||
m_expected_samples_4 = samples;
|
||||
}
|
||||
|
||||
void execute_sample_processing(test_type_identifier_t type_identifier,
|
||||
const rocprofsys::trace_cache::cacheable_t& value)
|
||||
{
|
||||
@@ -83,6 +89,14 @@ public:
|
||||
check_sample_3(idx, sample);
|
||||
break;
|
||||
}
|
||||
case test_type_identifier_t::sample_type_4:
|
||||
{
|
||||
const auto& sample = static_cast<const test_sample_4&>(value);
|
||||
std::lock_guard<std::mutex> lock(m_data_mutex);
|
||||
size_t idx = m_sample_4_count++;
|
||||
check_sample_4(idx, sample);
|
||||
break;
|
||||
}
|
||||
default: m_unknown_count++; break;
|
||||
}
|
||||
}
|
||||
@@ -90,6 +104,7 @@ public:
|
||||
int get_sample_1_count() const { return m_sample_1_count.load(); }
|
||||
int get_sample_2_count() const { return m_sample_2_count.load(); }
|
||||
int get_sample_3_count() const { return m_sample_3_count.load(); }
|
||||
int get_sample_4_count() const { return m_sample_4_count.load(); }
|
||||
int get_unknown_count() const { return m_unknown_count.load(); }
|
||||
|
||||
private:
|
||||
@@ -117,13 +132,23 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void check_sample_4(size_t index, const test_sample_4& sample)
|
||||
{
|
||||
if(index < m_expected_samples_4.size())
|
||||
{
|
||||
EXPECT_EQ(m_expected_samples_4[index], sample);
|
||||
}
|
||||
}
|
||||
|
||||
std::atomic<int> m_sample_1_count{ 0 };
|
||||
std::atomic<int> m_sample_2_count{ 0 };
|
||||
std::atomic<int> m_sample_3_count{ 0 };
|
||||
std::atomic<int> m_sample_4_count{ 0 };
|
||||
std::atomic<int> m_unknown_count{ 0 };
|
||||
std::vector<test_sample_1> m_expected_samples_1;
|
||||
std::vector<test_sample_2> m_expected_samples_2;
|
||||
std::vector<test_sample_3> m_expected_samples_3;
|
||||
std::vector<test_sample_4> m_expected_samples_4;
|
||||
std::mutex m_data_mutex;
|
||||
};
|
||||
|
||||
@@ -196,7 +221,7 @@ TEST_F(storage_parser_test, load_empty_file)
|
||||
auto processor = std::make_shared<sample_processor_t>();
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_NO_THROW(parser.load(processor));
|
||||
@@ -219,7 +244,7 @@ TEST_F(storage_parser_test, load_single_sample_type_1)
|
||||
processor->set_expected_samples_1(samples_1);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_NO_THROW(parser.load(processor));
|
||||
@@ -246,7 +271,7 @@ TEST_F(storage_parser_test, load_multiple_sample_types)
|
||||
processor->set_expected_samples_3(samples_3);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_NO_THROW(parser.load(processor));
|
||||
@@ -314,7 +339,7 @@ TEST_F(storage_parser_test, load_file_with_zero_sized_samples)
|
||||
processor->set_expected_samples_1({ valid_sample });
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_NO_THROW(parser.load(processor));
|
||||
@@ -328,7 +353,7 @@ TEST_F(storage_parser_test, load_nonexisting_file)
|
||||
auto processor = std::make_shared<sample_processor_t>();
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser("non_existent_file.bin");
|
||||
|
||||
EXPECT_THROW(parser.load(processor), std::runtime_error);
|
||||
@@ -347,7 +372,7 @@ TEST_F(storage_parser_test, load_large_sample_data)
|
||||
processor->set_expected_samples_3(samples_3);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_NO_THROW(parser.load(processor));
|
||||
@@ -379,7 +404,7 @@ TEST_F(storage_parser_test, load_many_small_samples)
|
||||
processor->set_expected_samples_1(many_samples);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_NO_THROW(parser.load(processor));
|
||||
@@ -406,7 +431,7 @@ TEST_F(storage_parser_test, write_less_than_expected)
|
||||
auto processor = std::make_shared<sample_processor_t>();
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_THROW(parser.load(processor), std::runtime_error);
|
||||
@@ -453,7 +478,7 @@ TEST_F(storage_parser_test, read_fragmented_space)
|
||||
processor->set_expected_samples_3(samples_3);
|
||||
|
||||
rocprofsys::trace_cache::storage_parser<test_type_identifier_t, test_sample_1,
|
||||
test_sample_2, test_sample_3>
|
||||
test_sample_2, test_sample_3, test_sample_4>
|
||||
parser(test_file_path);
|
||||
|
||||
EXPECT_NO_THROW(parser.load(processor));
|
||||
|
||||
Ссылка в новой задаче
Block a user