From cf20b6a0220929a1dacaf6ef299e3de81cb61e7c Mon Sep 17 00:00:00 2001 From: Bernhard Manfred Gruber Date: Sun, 11 Feb 2024 14:21:59 +0100 Subject: [PATCH] Support a color palette for toSvg --- include/llama/DumpMapping.hpp | 44 ++++++++++++++++++++++++++++------- tests/dump.cpp | 11 +++++++-- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/include/llama/DumpMapping.hpp b/include/llama/DumpMapping.hpp index 95bb9bb7c0..90f5c94753 100644 --- a/include/llama/DumpMapping.hpp +++ b/include/llama/DumpMapping.hpp @@ -19,10 +19,10 @@ namespace llama { namespace internal { - inline auto color(std::string_view recordCoordTags) -> std::size_t + inline auto color(std::string_view recordCoordTags) -> std::uint32_t { - auto c = std::hash{}(recordCoordTags) &std::size_t{0xFFFFFF}; - c |= std::size_t{0x404040}; // ensure color per channel is at least 0x40. + auto c = static_cast(std::hash{}(recordCoordTags) &std::size_t{0xFFFFFF}); + c |= 0x404040u; // ensure color per channel is at least 0x40. return c; } @@ -82,6 +82,7 @@ namespace llama struct FieldBox { ArrayIndex arrayIndex; + std::size_t flatRecordCoord; std::string_view recordCoordTags; NrAndOffset nrAndOffset; std::size_t size; @@ -105,8 +106,14 @@ namespace llama using Mapping = typename View::Mapping; using RecordDim = typename Mapping::RecordDim; - auto emitInfo = [&](auto nrAndOffset, std::size_t size) { - infos.push_back({ai, prettyRecordCoord(rc), nrAndOffset, size}); + auto emitInfo = [&](auto nrAndOffset, std::size_t size) + { + infos.push_back( + {ai, + flatRecordCoord, + prettyRecordCoord(rc), + nrAndOffset, + size}); }; using Type = GetType; @@ -194,6 +201,7 @@ namespace llama const auto [nr, off] = mapping.blobNrAndOffset(ai, rc); infos.push_back( {ai, + flatRecordCoord, prettyRecordCoord(rc), {static_cast(nr), static_cast(off)}, sizeof(Type)}); @@ -234,9 +242,15 @@ namespace llama /// Returns an SVG image visualizing the memory layout created by the given mapping. The created memory blocks are /// wrapped after wrapByteCount bytes. + /// @param palette RGB colors as 0x00RRGGBB assigned cyclically. When empty, colors are assigned by hashing the + /// record coordinate. LLAMA_EXPORT template - auto toSvg(const Mapping& mapping, std::size_t wrapByteCount = 64, bool breakBoxes = true) -> std::string + auto toSvg( + const Mapping& mapping, + std::size_t wrapByteCount = 64, + bool breakBoxes = true, + const std::vector& palette = {}) -> std::string { constexpr auto byteSizeInPixel = 30; constexpr auto blobBlockWidth = 60; @@ -309,7 +323,12 @@ namespace llama }(); auto x = (offset % wrapByteCount) * byteSizeInPixel + blobBlockWidth; auto y = (offset / wrapByteCount) * byteSizeInPixel + blobY; - const auto fill = internal::color(info.recordCoordTags); + const auto fillColor = [&] + { + if(palette.empty()) + return internal::color(info.recordCoordTags); + return palette[info.flatRecordCoord % palette.size()]; + }(); const auto width = byteSizeInPixel * info.size; const auto nextOffset = [&] @@ -339,13 +358,13 @@ namespace llama y = 0; } svg += fmt::format( - R"( + R"( )", x, y, width, byteSizeInPixel, - fill, + fillColor, isOverlapped ? 0.3 : 1.0); for(std::size_t i = 1; i < info.size; i++) { @@ -390,6 +409,13 @@ namespace llama return svg; } + LLAMA_EXPORT + template + auto toSvg(const Mapping& mapping, const std::vector& palette) -> std::string + { + return toSvg(mapping, 64, true, palette); + } + /// Returns an HTML document visualizing the memory layout created by the given mapping. The visualization is /// resizeable. LLAMA_EXPORT diff --git a/tests/dump.cpp b/tests/dump.cpp index 9704c2318d..f1ee7402e7 100644 --- a/tests/dump.cpp +++ b/tests/dump.cpp @@ -15,13 +15,13 @@ namespace using ArrayExtents = decltype(extents); template - void dump(const Mapping& mapping) + void dump(const Mapping& mapping, const std::vector& palette = {}) { const auto outputDir = std::string{"dump"}; std::filesystem::create_directory(outputDir); // undocumented Catch feature, see: https://github.com/catchorg/Catch2/issues/510 const auto filename = outputDir + "/" + Catch::getResultCapture().getCurrentTestName(); - std::ofstream{filename + ".svg"} << llama::toSvg(mapping); + std::ofstream{filename + ".svg"} << llama::toSvg(mapping, palette); std::ofstream{filename + ".html"} << llama::toHtml(mapping); } } // namespace @@ -406,6 +406,13 @@ TEST_CASE("dump.AdePT.track") dump(llama::mapping::AoS, Track>{{}}); } +TEST_CASE("dump.AdePT.track.palette") +{ + dump( + llama::mapping::AoS, Track>{{}}, + {0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF}); +} + TEST_CASE("dump.LHCb.Custom4") { dump(LhcbCustom4{{3}});