Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-06 04:26:43

0001 #include <memory>
0002 #include <tuple>
0003 
0004 #define CATCH_CONFIG_MAIN
0005 #include <catch.hpp>
0006 
0007 #include "DataFormats/SoATemplate/interface/SoALayout.h"
0008 
0009 // clang-format off
0010 GENERATE_SOA_LAYOUT(SimpleLayoutTemplate,
0011   SOA_COLUMN(float, x),
0012   SOA_COLUMN(float, y),
0013   SOA_COLUMN(float, z),
0014   SOA_COLUMN(float, t))
0015 // clang-format on
0016 
0017 using SimpleLayout = SimpleLayoutTemplate<>;
0018 
0019 TEST_CASE("SoATemplate") {
0020   // number of elements
0021   const std::size_t slSize = 10;
0022   // size in bytes
0023   const std::size_t slBufferSize = SimpleLayout::computeDataSize(slSize);
0024   // memory buffer aligned according to the layout requirements
0025   std::unique_ptr<std::byte, decltype(std::free) *> slBuffer{
0026       reinterpret_cast<std::byte *>(aligned_alloc(SimpleLayout::alignment, slBufferSize)), std::free};
0027   // SoA layout
0028   SimpleLayout sl{slBuffer.get(), slSize};
0029 
0030   SECTION("Row wide copies, row") {
0031     SimpleLayout::View slv{sl};
0032     SimpleLayout::ConstView slcv{sl};
0033     auto slv0 = slv[0];
0034     slv0.x() = 1;
0035     slv0.y() = 2;
0036     slv0.z() = 3;
0037     slv0.t() = 5;
0038     // Fill up
0039     for (SimpleLayout::View::size_type i = 1; i < slv.metadata().size(); ++i) {
0040       auto slvi = slv[i];
0041       slvi = slv[i - 1];
0042       auto slvix = slvi.x();
0043       slvi.x() += slvi.y();
0044       slvi.y() += slvi.z();
0045       slvi.z() += slvi.t();
0046       slvi.t() += slvix;
0047     }
0048     // Verification and const view access
0049     float x = 1, y = 2, z = 3, t = 5;
0050     for (SimpleLayout::View::size_type i = 0; i < slv.metadata().size(); ++i) {
0051       auto slvi = slv[i];
0052       auto slcvi = slcv[i];
0053       REQUIRE(slvi.x() == x);
0054       REQUIRE(slvi.y() == y);
0055       REQUIRE(slvi.z() == z);
0056       REQUIRE(slvi.t() == t);
0057       REQUIRE(slcvi.x() == x);
0058       REQUIRE(slcvi.y() == y);
0059       REQUIRE(slcvi.z() == z);
0060       REQUIRE(slcvi.t() == t);
0061       auto tx = x;
0062       x += y;
0063       y += z;
0064       z += t;
0065       t += tx;
0066     }
0067   }
0068 
0069   SECTION("Row initializer, const view access, restrict disabling") {
0070     // With two views, we are creating (artificially) aliasing and should warn the compiler by turning restrict qualifiers off.
0071     using View = SimpleLayout::ViewTemplate<cms::soa::RestrictQualify::disabled, cms::soa::RangeChecking::Default>;
0072     using ConstView =
0073         SimpleLayout::ConstViewTemplate<cms::soa::RestrictQualify::disabled, cms::soa::RangeChecking::Default>;
0074     View slv{sl};
0075     ConstView slcv{sl};
0076     auto slv0 = slv[0];
0077     slv0 = {7, 11, 13, 17};
0078     // Fill up
0079     for (SimpleLayout::View::size_type i = 1; i < slv.metadata().size(); ++i) {
0080       auto slvi = slv[i];
0081       // Copy the const view
0082       slvi = slcv[i - 1];
0083       auto slvix = slvi.x();
0084       slvi.x() += slvi.y();
0085       slvi.y() += slvi.z();
0086       slvi.z() += slvi.t();
0087       slvi.t() += slvix;
0088     }
0089     // Verification and const view access
0090     auto [x, y, z, t] = std::make_tuple(7.0, 11.0, 13.0, 17.0);
0091     for (SimpleLayout::View::size_type i = 0; i < slv.metadata().size(); ++i) {
0092       auto slvi = slv[i];
0093       auto slcvi = slcv[i];
0094       REQUIRE(slvi.x() == x);
0095       REQUIRE(slvi.y() == y);
0096       REQUIRE(slvi.z() == z);
0097       REQUIRE(slvi.t() == t);
0098       REQUIRE(slcvi.x() == x);
0099       REQUIRE(slcvi.y() == y);
0100       REQUIRE(slcvi.z() == z);
0101       REQUIRE(slcvi.t() == t);
0102       auto tx = x;
0103       x += y;
0104       y += z;
0105       z += t;
0106       t += tx;
0107     }
0108   }
0109 
0110   SECTION("Range checking View") {
0111     // Enable range checking
0112     using View = SimpleLayout::ViewTemplate<cms::soa::RestrictQualify::Default, cms::soa::RangeChecking::enabled>;
0113     View slv{sl};
0114     int underflow = -1;
0115     int overflow = slv.metadata().size();
0116     // Check for under-and overflow in the row accessor
0117     REQUIRE_THROWS_AS(slv[underflow], std::out_of_range);
0118     REQUIRE_THROWS_AS(slv[overflow], std::out_of_range);
0119     // Check for under-and overflow in the element accessors
0120     REQUIRE_THROWS_AS(slv.x(underflow), std::out_of_range);
0121     REQUIRE_THROWS_AS(slv.x(overflow), std::out_of_range);
0122   }
0123 
0124   SECTION("Range checking ConstView") {
0125     // Enable range checking
0126     using ConstView =
0127         SimpleLayout::ConstViewTemplate<cms::soa::RestrictQualify::Default, cms::soa::RangeChecking::enabled>;
0128     ConstView slcv{sl};
0129     int underflow = -1;
0130     int overflow = slcv.metadata().size();
0131     // Check for under-and overflow in the row accessor
0132     REQUIRE_THROWS_AS(slcv[underflow], std::out_of_range);
0133     REQUIRE_THROWS_AS(slcv[overflow], std::out_of_range);
0134     // Check for under-and overflow in the element accessors
0135     REQUIRE_THROWS_AS(slcv.x(underflow), std::out_of_range);
0136     REQUIRE_THROWS_AS(slcv.x(overflow), std::out_of_range);
0137   }
0138 }