From 5fd2056db61c8c5ada95c58de15d0b940b553ea6 Mon Sep 17 00:00:00 2001 From: Bernhard Manfred Gruber Date: Mon, 5 Sep 2022 16:31:19 +0200 Subject: [PATCH] Add dump tests for computed mappings --- include/llama/DumpMapping.hpp | 25 ++++-- tests/common.hpp | 142 ++++++++++++++++++++++++++++++++++ tests/computedprop.cpp | 79 +------------------ tests/dump.cpp | 15 ++++ tests/proofs.cpp | 73 ----------------- 5 files changed, 177 insertions(+), 157 deletions(-) diff --git a/include/llama/DumpMapping.hpp b/include/llama/DumpMapping.hpp index 8ceb09a754..f2909b8eb9 100644 --- a/include/llama/DumpMapping.hpp +++ b/include/llama/DumpMapping.hpp @@ -236,11 +236,11 @@ namespace llama std::string svg; - const auto hasAnyComputedField = internal::hasAnyComputedField(); + constexpr auto hasAnyComputedField = internal::hasAnyComputedField(); std::array blobYOffset{}; - for(std::size_t i = 0; i < Mapping::blobCount + hasAnyComputedField; i++) + auto writeBlobHeader = [&](std::size_t i, std::size_t size, std::string_view name) { - const auto blobRows = (mapping.blobSize(i) + wrapByteCount - 1) / wrapByteCount; + const auto blobRows = (size + wrapByteCount - 1) / wrapByteCount; blobYOffset[i + 1] = blobYOffset[i] + (blobRows + 1) * byteSizeInPixel; // one row gap between blobs const auto height = blobRows * byteSizeInPixel; svg += fmt::format( @@ -252,8 +252,10 @@ namespace llama height, blobBlockWidth / 2, blobYOffset[i] + height / 2, - i < Mapping::blobCount ? "Blob: " + std::to_string(i) : "Comp."); - } + name); + }; + for(std::size_t i = 0; i < Mapping::blobCount; i++) + writeBlobHeader(i, mapping.blobSize(i), "Blob: " + std::to_string(i)); svg = fmt::format( R"( @@ -263,7 +265,7 @@ namespace llama )", blobBlockWidth + wrapByteCount * byteSizeInPixel, - blobYOffset.back() - byteSizeInPixel, + blobYOffset.back() == 0 ? 987654321 : blobYOffset.back() - byteSizeInPixel, byteSizeInPixel / 2) + svg; @@ -349,6 +351,17 @@ namespace llama svg += R"( )"; } + + if(hasAnyComputedField) + { + writeBlobHeader(Mapping::blobCount, computedSizeSoFar, "Comp."); + + // fix total SVG size + const auto i = svg.find("987654321"); + assert(i != std::string::npos); + svg.replace(i, 9, std::to_string(blobYOffset.back() - byteSizeInPixel)); + } + svg += ""; return svg; } diff --git a/tests/common.hpp b/tests/common.hpp index 276fd60efd..33ffb86dbb 100644 --- a/tests/common.hpp +++ b/tests/common.hpp @@ -163,3 +163,145 @@ void iotaCheckView(View& view) ++value; }); } + +// maps each element of the record dimension into a separate blobs. Each blob stores Modulus elements. If the array +// dimensions are larger than Modulus, elements are overwritten. +template +struct ModulusMapping : TArrayExtents +{ + using ArrayExtents = TArrayExtents; + using ArrayIndex = typename ArrayExtents::Index; + using RecordDim = TRecordDim; + static constexpr std::size_t blobCount = boost::mp11::mp_size>::value; + + LLAMA_FN_HOST_ACC_INLINE + constexpr explicit ModulusMapping(ArrayExtents extents, RecordDim = {}) : ArrayExtents(extents) + { + } + + LLAMA_FN_HOST_ACC_INLINE constexpr auto extents() const -> const ArrayExtents& + { + return *this; + } + + constexpr auto blobSize(std::size_t) const -> std::size_t + { + return Modulus * llama::sizeOf; + } + + template + constexpr auto blobNrAndOffset(ArrayIndex ai, llama::RecordCoord = {}) const + -> llama::NrAndOffset + { + const auto blob = llama::flatRecordCoord>; + const auto offset = (llama::mapping::LinearizeArrayDimsCpp{}(ai, extents()) % Modulus) + * sizeof(llama::GetType>); + return {blob, offset}; + } +}; + +// Maps everything to blob 0, offset 0 +template +struct MapEverythingToZero : TArrayExtents +{ + using ArrayExtents = TArrayExtents; + using ArrayIndex = typename ArrayExtents::Index; + using RecordDim = TRecordDim; + static constexpr std::size_t blobCount = 1; + + LLAMA_FN_HOST_ACC_INLINE + constexpr explicit MapEverythingToZero(ArrayExtents extents, RecordDim = {}) : ArrayExtents(extents) + { + } + + LLAMA_FN_HOST_ACC_INLINE constexpr auto extents() const -> const ArrayExtents& + { + return *this; + } + + constexpr auto blobSize(std::size_t) const -> std::size_t + { + return llama::product(extents()) * llama::sizeOf; + } + + template + constexpr auto blobNrAndOffset(ArrayIndex, llama::RecordCoord = {}) const + -> llama::NrAndOffset + { + return {0, 0}; + } +}; + +using Triangle = llama::Record< + llama::Field, + llama::Field, + llama::Field, + llama::Field>; + +template +struct TriangleAoSWithComputedNormal : llama::mapping::PackedAoS +{ + using Base = llama::mapping::PackedAoS; + using typename Base::ArrayIndex; + + using Base::Base; + + template + static constexpr auto isComputed(llama::RecordCoord) + { + return llama::recordCoordCommonPrefixIsSame, llama::RecordCoord<3>>; + } + + template + constexpr auto compute( + ArrayIndex ai, + llama::RecordCoord, + llama::Array& storageBlobs) const + { + auto fetch = [&](llama::NrAndOffset nrAndOffset) -> double + { return *reinterpret_cast(&storageBlobs[nrAndOffset.nr][nrAndOffset.offset]); }; + + const auto ax = fetch(Base::template blobNrAndOffset<0, 0>(ai)); + const auto ay = fetch(Base::template blobNrAndOffset<0, 1>(ai)); + const auto az = fetch(Base::template blobNrAndOffset<0, 2>(ai)); + const auto bx = fetch(Base::template blobNrAndOffset<1, 0>(ai)); + const auto by = fetch(Base::template blobNrAndOffset<1, 1>(ai)); + const auto bz = fetch(Base::template blobNrAndOffset<1, 2>(ai)); + const auto cx = fetch(Base::template blobNrAndOffset<2, 0>(ai)); + const auto cy = fetch(Base::template blobNrAndOffset<2, 1>(ai)); + const auto cz = fetch(Base::template blobNrAndOffset<2, 2>(ai)); + + const auto e1x = bx - ax; + const auto e1y = by - ay; + const auto e1z = bz - az; + const auto e2x = cx - ax; + const auto e2y = cy - ay; + const auto e2z = cz - az; + + const auto crossx = e1y * e2z - e1z * e2y; + const auto crossy = -(e1x * e2z - e1z * e2x); + const auto crossz = e1x * e2y - e1y * e2x; + + const auto length = std::sqrt(crossx * crossx + crossy * crossy + crossz * crossz); + + [[maybe_unused]] const auto normalx = crossx / length; + [[maybe_unused]] const auto normaly = crossy / length; + [[maybe_unused]] const auto normalz = crossz / length; + + using DC = llama::RecordCoord; + if constexpr(std::is_same_v>) + return normalx; + if constexpr(std::is_same_v>) + return normaly; + if constexpr(std::is_same_v>) + return normalz; + // if constexpr (std::is_same_v>) + //{ + // llama::One>> normal; + // normal(llama::RecordCoord<0>{}) = normalx; + // normal(llama::RecordCoord<1>{}) = normaly; + // normal(llama::RecordCoord<2>{}) = normalz; + // return normal; + //} + } +}; diff --git a/tests/computedprop.cpp b/tests/computedprop.cpp index 82a3142e31..e0c99dc059 100644 --- a/tests/computedprop.cpp +++ b/tests/computedprop.cpp @@ -3,87 +3,10 @@ #include #include -namespace -{ - using Triangle = llama::Record< - llama::Field, - llama::Field, - llama::Field, - llama::Field>; - - template - struct AoSWithComputedNormal : llama::mapping::PackedAoS - { - using Base = llama::mapping::PackedAoS; - using typename Base::ArrayIndex; - - using Base::Base; - - template - static constexpr auto isComputed(llama::RecordCoord) - { - return llama::recordCoordCommonPrefixIsSame, llama::RecordCoord<3>>; - } - - template - constexpr auto compute( - ArrayIndex ai, - llama::RecordCoord, - llama::Array& storageBlobs) const - { - auto fetch = [&](llama::NrAndOffset nrAndOffset) -> double - { return *reinterpret_cast(&storageBlobs[nrAndOffset.nr][nrAndOffset.offset]); }; - - const auto ax = fetch(Base::template blobNrAndOffset<0, 0>(ai)); - const auto ay = fetch(Base::template blobNrAndOffset<0, 1>(ai)); - const auto az = fetch(Base::template blobNrAndOffset<0, 2>(ai)); - const auto bx = fetch(Base::template blobNrAndOffset<1, 0>(ai)); - const auto by = fetch(Base::template blobNrAndOffset<1, 1>(ai)); - const auto bz = fetch(Base::template blobNrAndOffset<1, 2>(ai)); - const auto cx = fetch(Base::template blobNrAndOffset<2, 0>(ai)); - const auto cy = fetch(Base::template blobNrAndOffset<2, 1>(ai)); - const auto cz = fetch(Base::template blobNrAndOffset<2, 2>(ai)); - - const auto e1x = bx - ax; - const auto e1y = by - ay; - const auto e1z = bz - az; - const auto e2x = cx - ax; - const auto e2y = cy - ay; - const auto e2z = cz - az; - - const auto crossx = e1y * e2z - e1z * e2y; - const auto crossy = -(e1x * e2z - e1z * e2x); - const auto crossz = e1x * e2y - e1y * e2x; - - const auto length = std::sqrt(crossx * crossx + crossy * crossy + crossz * crossz); - - [[maybe_unused]] const auto normalx = crossx / length; - [[maybe_unused]] const auto normaly = crossy / length; - [[maybe_unused]] const auto normalz = crossz / length; - - using DC = llama::RecordCoord; - if constexpr(std::is_same_v>) - return normalx; - if constexpr(std::is_same_v>) - return normaly; - if constexpr(std::is_same_v>) - return normalz; - // if constexpr (std::is_same_v>) - //{ - // llama::One>> normal; - // normal(llama::RecordCoord<0>{}) = normalx; - // normal(llama::RecordCoord<1>{}) = normaly; - // normal(llama::RecordCoord<2>{}) = normalz; - // return normal; - //} - } - }; -} // namespace - TEST_CASE("computedprop") { auto extents = llama::ArrayExtentsDynamic{10}; - auto mapping = AoSWithComputedNormal{extents}; + auto mapping = TriangleAoSWithComputedNormal{extents}; STATIC_REQUIRE(mapping.blobCount == 1); CHECK(mapping.blobSize(0) == sizeof(double) * 10 * 12); diff --git a/tests/dump.cpp b/tests/dump.cpp index 46f213993c..118f118817 100644 --- a/tests/dump.cpp +++ b/tests/dump.cpp @@ -340,4 +340,19 @@ TEST_CASE("dump.ParticleAligned.PackedAoS") { dump(llama::mapping::PackedAoS{extents}); } + +TEST_CASE("dump.Particle.ModulusMapping.8") +{ + dump(ModulusMapping{extents}); +} + +TEST_CASE("dump.Particle.MapEverythingToZero") +{ + dump(MapEverythingToZero{extents}); +} + +TEST_CASE("dump.Triangle.TriangleAoSWithComputedNormal") +{ + dump(TriangleAoSWithComputedNormal{extents}); +} #endif diff --git a/tests/proofs.cpp b/tests/proofs.cpp index 8315c386c6..cc0e9479f8 100644 --- a/tests/proofs.cpp +++ b/tests/proofs.cpp @@ -25,40 +25,6 @@ TEST_CASE("mapsNonOverlappingly.AlignedAoS") } #endif -namespace -{ - template - struct MapEverythingToZero : TArrayExtents - { - using ArrayExtents = TArrayExtents; - using ArrayIndex = typename ArrayExtents::Index; - using RecordDim = TRecordDim; - static constexpr std::size_t blobCount = 1; - - LLAMA_FN_HOST_ACC_INLINE - constexpr explicit MapEverythingToZero(ArrayExtents extents, RecordDim = {}) : ArrayExtents(extents) - { - } - - LLAMA_FN_HOST_ACC_INLINE constexpr auto extents() const -> const ArrayExtents& - { - return *this; - } - - constexpr auto blobSize(std::size_t) const -> std::size_t - { - return llama::product(extents()) * llama::sizeOf; - } - - template - constexpr auto blobNrAndOffset(ArrayIndex, llama::RecordCoord = {}) const - -> llama::NrAndOffset - { - return {0, 0}; - } - }; -} // namespace - TEST_CASE("mapsNonOverlappingly.MapEverythingToZero") { #ifdef __cpp_constexpr_dynamic_alloc @@ -73,45 +39,6 @@ TEST_CASE("mapsNonOverlappingly.MapEverythingToZero") #endif } -namespace -{ - // maps each element of the record dimension into a separate blobs. Each blob stores Modulus elements. If the array - // dimensions are larger than Modulus, elements are overwritten. - template - struct ModulusMapping : TArrayExtents - { - using ArrayExtents = TArrayExtents; - using ArrayIndex = typename ArrayExtents::Index; - using RecordDim = TRecordDim; - static constexpr std::size_t blobCount = boost::mp11::mp_size>::value; - - LLAMA_FN_HOST_ACC_INLINE - constexpr explicit ModulusMapping(ArrayExtents extents, RecordDim = {}) : ArrayExtents(extents) - { - } - - LLAMA_FN_HOST_ACC_INLINE constexpr auto extents() const -> const ArrayExtents& - { - return *this; - } - - constexpr auto blobSize(std::size_t) const -> std::size_t - { - return Modulus * llama::sizeOf; - } - - template - constexpr auto blobNrAndOffset(ArrayIndex ai, llama::RecordCoord = {}) const - -> llama::NrAndOffset - { - const auto blob = llama::flatRecordCoord>; - const auto offset = (llama::mapping::LinearizeArrayDimsCpp{}(ai, extents()) % Modulus) - * sizeof(llama::GetType>); - return {blob, offset}; - } - }; -} // namespace - TEST_CASE("mapsNonOverlappingly.ModulusMapping") { #ifdef __cpp_constexpr_dynamic_alloc