diff --git a/projects/rocprofiler-systems/source/lib/common/span.hpp b/projects/rocprofiler-systems/source/lib/common/span.hpp new file mode 100644 index 0000000000..8bfd09f3fe --- /dev/null +++ b/projects/rocprofiler-systems/source/lib/common/span.hpp @@ -0,0 +1,66 @@ +#pragma once +#include +#include +#include + +namespace rocprofsys +{ +inline namespace common +{ + +template +struct span +{ + using value_type = T; + + constexpr span(T* data, size_t size) noexcept + : m_data(data) + , m_size(size) + {} + + constexpr span(std::vector& vec) noexcept + : m_data(vec.data()) + , m_size(vec.size()) + {} + + template + constexpr span(std::array& 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 diff --git a/projects/rocprofiler-systems/source/lib/core/trace_cache/cache_type_traits.hpp b/projects/rocprofiler-systems/source/lib/core/trace_cache/cache_type_traits.hpp index 405e3cc363..f3a1b087e0 100644 --- a/projects/rocprofiler-systems/source/lib/core/trace_cache/cache_type_traits.hpp +++ b/projects/rocprofiler-systems/source/lib/core/trace_cache/cache_type_traits.hpp @@ -21,6 +21,7 @@ // SOFTWARE. #pragma once +#include "common/span.hpp" #include #include #include @@ -80,20 +81,37 @@ struct tuple_to_variant> template using void_t = void; -template -struct typelist -{ - template - constexpr static bool is_supported = (std::is_same_v, Types> || ...); -}; +template +struct is_span : std::false_type +{}; -using supported_types = typelist, uint8_t, int64_t, double>; +template +struct is_span> : std::true_type +{}; + +template +inline constexpr bool is_span_v = is_span::value; + +template +struct is_vector : std::false_type +{}; + +template +struct is_vector> : std::true_type +{}; + +template +inline constexpr bool is_vector_v = is_vector::value; template static constexpr bool is_string_view_v = std::is_same_v, std::string_view>; +template +inline constexpr bool is_supported_type_v = + is_span_v || std::is_integral_v || std::is_floating_point_v || + is_string_view_v || is_vector_v; + template struct is_enum_class : std::bool_constant && diff --git a/projects/rocprofiler-systems/source/lib/core/trace_cache/cacheable.hpp b/projects/rocprofiler-systems/source/lib/core/trace_cache/cacheable.hpp index 710e64f573..23977aa462 100644 --- a/projects/rocprofiler-systems/source/lib/core/trace_cache/cacheable.hpp +++ b/projects/rocprofiler-systems/source/lib/core/trace_cache/cacheable.hpp @@ -78,13 +78,19 @@ __attribute__((always_inline)) inline constexpr size_t get_size(Type&& val) { using DecayedType = std::decay_t; - static_assert(type_traits::supported_types::is_supported, + static_assert(type_traits::is_supported_type_v, "Unsupported type in get_size"); if constexpr(type_traits::is_string_view_v || - std::is_same_v>) + type_traits::is_vector_v || + type_traits::is_span_v) { - return val.size() + sizeof(size_t); + using ContainerType = std::decay_t; + 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; - static_assert(type_traits::supported_types::is_supported, + static_assert(type_traits::is_supported_type_v, "Unsupported type in store_value"); auto* dest = buffer + position; if constexpr(type_traits::is_string_view_v || - std::is_same_v>) + type_traits::is_vector_v || + type_traits::is_span_v) { - const size_t elem_count = value.size(); - *reinterpret_cast(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(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; - static_assert(type_traits::supported_types::is_supported, + static_assert(type_traits::is_supported_type_v, "Unsupported type in parse_value"); if constexpr(type_traits::is_string_view_v) @@ -147,13 +156,17 @@ parse_value(uint8_t*& data_pos, Type& arg) arg = std::string_view{ reinterpret_cast(data_pos), string_size }; data_pos += string_size; } - else if constexpr(std::is_same_v>) + else if constexpr(type_traits::is_vector_v || + type_traits::is_span_v) { - const size_t vector_size = *reinterpret_cast(data_pos); + using ContainerType = std::decay_t; + const size_t item_size = sizeof(typename ContainerType::value_type); + const size_t total_size = *reinterpret_cast(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(data_pos), + total_size / item_size, std::back_inserter(arg)); + data_pos += total_size; } else { diff --git a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/mocked_types.hpp b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/mocked_types.hpp index eaea4f4b7c..12e02209a0 100644 --- a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/mocked_types.hpp +++ b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/mocked_types.hpp @@ -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 d) + : data(std::move(d)) + {} + + std::vector 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); +} diff --git a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cache_integration.cpp b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cache_integration.cpp index 6b616a6d70..e4f6877bde 100644 --- a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cache_integration.cpp +++ b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cache_integration.cpp @@ -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{}(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& samples) + { + std::lock_guard 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(value); + std::lock_guard 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 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 m_sample_1_count{ 0 }; std::atomic m_sample_2_count{ 0 }; std::atomic m_sample_3_count{ 0 }; + std::atomic m_sample_4_count{ 0 }; std::unordered_map m_expected_samples_1; std::unordered_map m_expected_samples_2; std::unordered_map m_expected_samples_3; + std::unordered_map 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_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_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_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_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_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 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 data; + data.reserve(10); + for(int j = 0; j < 10; ++j) + { + data.push_back(static_cast(i * 1000 + j)); + } + test_sample_4 sample(data); + expected_4.push_back(sample); + storage.store(sample); + } + + storage.shutdown(); + } + + auto processor = std::make_shared(); + processor->set_expected_samples_4(expected_4); + + rocprofsys::trace_cache::storage_parser + 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 expected_3; + std::vector 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 payload(20, static_cast(i)); + test_sample_3 sample(payload); + expected_3.push_back(sample); + storage.store(sample); + } + else + { + std::vector data; + data.reserve(5); + for(int j = 0; j < 5; ++j) + { + data.push_back(static_cast(i * 100 + j)); + } + test_sample_4 sample(data); + expected_4.push_back(sample); + storage.store(sample); + } + } + + storage.shutdown(); + } + + auto processor = std::make_shared(); + processor->set_expected_samples_3(expected_3); + processor->set_expected_samples_4(expected_4); + + rocprofsys::trace_cache::storage_parser + 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()); +} diff --git a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cacheable.cpp b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cacheable.cpp index cfe1267e59..1187b67de7 100644 --- a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cacheable.cpp +++ b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_cacheable.cpp @@ -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 #include +#include #include #include #include @@ -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 data = { 1, 2, 3, 4, 5 }; + rocprofsys::span 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(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 data = { 100, 200, 300, 400, 500 }; + rocprofsys::span 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(buffer.data()); + EXPECT_EQ(stored_size, expected_data_size); + + uint32_t* data_start = reinterpret_cast(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 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(buffer.data()); + EXPECT_EQ(stored_size, 0); +} + +TEST_F(cacheable_test, span_store_vector_parse_roundtrip) +{ + std::vector original_data = { 10, 20, 30, 40, 50 }; + rocprofsys::span span_val(original_data); + rocprofsys::trace_cache::utility::store_value(span_val, buffer.data(), position); + + uint8_t* data_pos = buffer.data(); + std::vector 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 original_data = { 0xDEADBEEF, 0xCAFEBABE, 0x12345678 }; + rocprofsys::span span_val(original_data); + rocprofsys::trace_cache::utility::store_value(span_val, buffer.data(), position); + + uint8_t* data_pos = buffer.data(); + std::vector 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 data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + rocprofsys::span 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 data = { 100, 200, 300, 400, 500 }; + rocprofsys::span 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 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(buffer.data()); + EXPECT_EQ(stored_size, expected_data_size); + + int* data_start = reinterpret_cast(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 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 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 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(buffer.data()); + EXPECT_EQ(stored_size, expected_data_size); +} + +TEST_F(cacheable_test, parse_value_uint64_vector) +{ + std::vector original_value = { 0xFFFFFFFFFFFFFFFF, 0x0, + 0x123456789ABCDEF0 }; + rocprofsys::trace_cache::utility::store_value(original_value, buffer.data(), + position); + + uint8_t* data_pos = buffer.data(); + std::vector 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 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 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>); + EXPECT_TRUE( + rocprofsys::trace_cache::type_traits::is_span_v>); + EXPECT_TRUE( + rocprofsys::trace_cache::type_traits::is_span_v>); + + EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_span_v); + EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_span_v>); + EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_span_v); +} + +TEST(type_traits_test, is_vector_v) +{ + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_vector_v>); + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_vector_v>); + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_vector_v>); + + EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_vector_v); + EXPECT_FALSE( + rocprofsys::trace_cache::type_traits::is_vector_v>); + EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_vector_v); +} + +TEST(type_traits_test, is_supported_type_v) +{ + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v); + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v); + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v); + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v); + EXPECT_TRUE( + rocprofsys::trace_cache::type_traits::is_supported_type_v); + EXPECT_TRUE( + rocprofsys::trace_cache::type_traits::is_supported_type_v>); + EXPECT_TRUE( + rocprofsys::trace_cache::type_traits::is_supported_type_v>); + EXPECT_TRUE( + rocprofsys::trace_cache::type_traits::is_supported_type_v>); + EXPECT_TRUE(rocprofsys::trace_cache::type_traits::is_supported_type_v< + rocprofsys::span>); + + struct custom_type + {}; + EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_supported_type_v); + EXPECT_FALSE(rocprofsys::trace_cache::type_traits::is_supported_type_v); +} + TEST_F(cacheable_test, get_buffered_storage_filename) { int ppid = 1234; diff --git a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_storage_parser.cpp b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_storage_parser.cpp index 9eadd1d979..788203261e 100644 --- a/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_storage_parser.cpp +++ b/projects/rocprofiler-systems/source/lib/core/trace_cache/tests/test_storage_parser.cpp @@ -54,6 +54,12 @@ public: m_expected_samples_3 = samples; } + void set_expected_samples_4(const std::vector& samples) + { + std::lock_guard 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(value); + std::lock_guard 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 m_sample_1_count{ 0 }; std::atomic m_sample_2_count{ 0 }; std::atomic m_sample_3_count{ 0 }; + std::atomic m_sample_4_count{ 0 }; std::atomic m_unknown_count{ 0 }; std::vector m_expected_samples_1; std::vector m_expected_samples_2; std::vector m_expected_samples_3; + std::vector 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(); rocprofsys::trace_cache::storage_parser + 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_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_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_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(); rocprofsys::trace_cache::storage_parser + 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_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_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(); rocprofsys::trace_cache::storage_parser + 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_sample_2, test_sample_3, test_sample_4> parser(test_file_path); EXPECT_NO_THROW(parser.load(processor));