File indexing completed on 2025-04-06 22:42:48
0001 #include <Eigen/Core>
0002 #include <Eigen/Dense>
0003
0004 #define CATCH_CONFIG_MAIN
0005 #include <catch.hpp>
0006
0007 #include "DataFormats/SoATemplate/interface/SoALayout.h"
0008
0009 GENERATE_SOA_LAYOUT(SoAPositionTemplate,
0010 SOA_COLUMN(float, x),
0011 SOA_COLUMN(float, y),
0012 SOA_COLUMN(float, z),
0013 SOA_SCALAR(int, detectorType))
0014
0015 using SoAPosition = SoAPositionTemplate<>;
0016 using SoAPositionView = SoAPosition::View;
0017 using SoAPositionConstView = SoAPosition::ConstView;
0018
0019 GENERATE_SOA_LAYOUT(SoAPCATemplate,
0020 SOA_COLUMN(float, eigenvalues),
0021 SOA_COLUMN(float, eigenvector_1),
0022 SOA_COLUMN(float, eigenvector_2),
0023 SOA_COLUMN(float, eigenvector_3),
0024 SOA_EIGEN_COLUMN(Eigen::Vector3d, candidateDirection))
0025
0026 using SoAPCA = SoAPCATemplate<>;
0027 using SoAPCAView = SoAPCA::View;
0028 using SoAPCAConstView = SoAPCA::ConstView;
0029
0030 GENERATE_SOA_LAYOUT(GenericSoATemplate,
0031 SOA_COLUMN(float, xPos),
0032 SOA_COLUMN(float, yPos),
0033 SOA_COLUMN(float, zPos),
0034 SOA_EIGEN_COLUMN(Eigen::Vector3d, candidateDirection))
0035
0036 using GenericSoA = GenericSoATemplate<cms::soa::CacheLineSize::IntelCPU>;
0037 using GenericSoAView = GenericSoA::View;
0038 using GenericSoAConstView = GenericSoA::ConstView;
0039
0040 TEST_CASE("SoAGenericView") {
0041
0042 const std::size_t elems = 17;
0043
0044
0045 const std::size_t positionBufferSize = SoAPosition::computeDataSize(elems);
0046 const std::size_t pcaBufferSize = SoAPCA::computeDataSize(elems);
0047
0048
0049 std::unique_ptr<std::byte, decltype(std::free) *> bufferPos{
0050 reinterpret_cast<std::byte *>(aligned_alloc(SoAPosition::alignment, positionBufferSize)), std::free};
0051
0052 std::unique_ptr<std::byte, decltype(std::free) *> bufferPCA{
0053 reinterpret_cast<std::byte *>(aligned_alloc(SoAPCA::alignment, pcaBufferSize)), std::free};
0054
0055
0056 SoAPosition position{bufferPos.get(), elems};
0057 SoAPCA pca{bufferPCA.get(), elems};
0058
0059
0060 SoAPositionView positionView{position};
0061 SoAPositionConstView positionConstView{position};
0062 SoAPCAView pcaView{pca};
0063 SoAPCAConstView pcaConstView{pca};
0064
0065
0066 for (size_t i = 0; i < elems; i++) {
0067 positionView[i] = {i * 1.0f, i * 2.0f, i * 3.0f};
0068 }
0069 positionView.detectorType() = 1;
0070
0071 float time = 0.01;
0072 for (size_t i = 0; i < elems; i++) {
0073 pcaView[i].eigenvector_1() = positionView[i].x() / time;
0074 pcaView[i].eigenvector_2() = positionView[i].y() / time;
0075 pcaView[i].eigenvector_3() = positionView[i].z() / time;
0076 pcaView[i].candidateDirection()(0) = positionView[i].x() / time;
0077 pcaView[i].candidateDirection()(1) = positionView[i].y() / time;
0078 pcaView[i].candidateDirection()(2) = positionView[i].z() / time;
0079 }
0080
0081 SECTION("Generic View") {
0082
0083 const auto posRecs = positionView.records();
0084 const auto pcaRecs = pcaView.records();
0085
0086
0087 GenericSoAView genericView(posRecs.x(), posRecs.y(), posRecs.z(), pcaRecs.candidateDirection());
0088
0089
0090 REQUIRE(genericView.metadata().addressOf_xPos() == positionView.metadata().addressOf_x());
0091 REQUIRE(genericView.metadata().addressOf_yPos() == positionView.metadata().addressOf_y());
0092 REQUIRE(genericView.metadata().addressOf_zPos() == positionView.metadata().addressOf_z());
0093 REQUIRE(genericView.metadata().addressOf_candidateDirection() == pcaView.metadata().addressOf_candidateDirection());
0094
0095
0096 genericView[3].xPos() = 0.;
0097 REQUIRE(genericView[3].xPos() == positionConstView[3].x());
0098 }
0099
0100 SECTION("Generic ConstView") {
0101
0102 const auto posRecs = positionConstView.records();
0103 const auto pcaRecs = pcaConstView.records();
0104
0105
0106 GenericSoAConstView genericConstView(posRecs.x(), posRecs.y(), posRecs.z(), pcaRecs.candidateDirection());
0107
0108
0109 REQUIRE(genericConstView.metadata().addressOf_xPos() == positionConstView.metadata().addressOf_x());
0110 REQUIRE(genericConstView.metadata().addressOf_yPos() == positionConstView.metadata().addressOf_y());
0111 REQUIRE(genericConstView.metadata().addressOf_zPos() == positionConstView.metadata().addressOf_z());
0112 REQUIRE(genericConstView.metadata().addressOf_candidateDirection() ==
0113 pcaConstView.metadata().addressOf_candidateDirection());
0114 }
0115
0116 SECTION("Generic ConstView from Views") {
0117
0118 const auto posRecs = positionView.records();
0119 const auto pcaRecs = pcaView.records();
0120
0121
0122 GenericSoAConstView genericConstView(posRecs.x(), posRecs.y(), posRecs.z(), pcaRecs.candidateDirection());
0123
0124
0125 positionView[3].x() = 0.;
0126 REQUIRE(genericConstView[3].xPos() == positionView[3].x());
0127 }
0128
0129 SECTION("Deep copy the Generic View") {
0130
0131 const std::size_t genericBufferSize = GenericSoA::computeDataSize(elems);
0132 std::unique_ptr<std::byte, decltype(std::free) *> bufferGeneric{
0133 reinterpret_cast<std::byte *>(aligned_alloc(GenericSoA::alignment, genericBufferSize)), std::free};
0134 GenericSoA genericSoA(bufferGeneric.get(), elems);
0135
0136
0137 const auto posRecs = positionView.records();
0138 const auto pcaRecs = pcaView.records();
0139 GenericSoAView genericView(posRecs.x(), posRecs.y(), posRecs.z(), pcaRecs.candidateDirection());
0140
0141
0142 genericSoA.deepCopy(genericView);
0143
0144
0145 GenericSoAView genericSoAView{genericSoA};
0146
0147
0148 REQUIRE(genericSoAView.metadata().addressOf_xPos() != positionConstView.metadata().addressOf_x());
0149 REQUIRE(genericSoAView.metadata().addressOf_yPos() != positionConstView.metadata().addressOf_y());
0150 REQUIRE(genericSoAView.metadata().addressOf_zPos() != positionConstView.metadata().addressOf_z());
0151 REQUIRE(genericSoAView.metadata().addressOf_candidateDirection() !=
0152 pcaConstView.metadata().addressOf_candidateDirection());
0153
0154
0155 REQUIRE(0 ==
0156 reinterpret_cast<uintptr_t>(genericSoAView.metadata().addressOf_xPos()) % decltype(genericSoA)::alignment);
0157 REQUIRE(0 ==
0158 reinterpret_cast<uintptr_t>(genericSoAView.metadata().addressOf_yPos()) % decltype(genericSoA)::alignment);
0159 REQUIRE(0 ==
0160 reinterpret_cast<uintptr_t>(genericSoAView.metadata().addressOf_zPos()) % decltype(genericSoA)::alignment);
0161 REQUIRE(0 == reinterpret_cast<uintptr_t>(genericSoAView.metadata().addressOf_candidateDirection()) %
0162 decltype(genericSoA)::alignment);
0163
0164
0165 REQUIRE(reinterpret_cast<std::byte *>(genericSoAView.metadata().addressOf_xPos()) +
0166 cms::soa::alignSize(elems * sizeof(float), GenericSoA::alignment) ==
0167 reinterpret_cast<std::byte *>(genericSoAView.metadata().addressOf_yPos()));
0168 REQUIRE(reinterpret_cast<std::byte *>(genericSoAView.metadata().addressOf_yPos()) +
0169 cms::soa::alignSize(elems * sizeof(float), GenericSoA::alignment) ==
0170 reinterpret_cast<std::byte *>(genericSoAView.metadata().addressOf_zPos()));
0171 REQUIRE(reinterpret_cast<std::byte *>(genericSoAView.metadata().addressOf_zPos()) +
0172 cms::soa::alignSize(elems * sizeof(float), GenericSoA::alignment) ==
0173 reinterpret_cast<std::byte *>(genericSoAView.metadata().addressOf_candidateDirection()));
0174
0175
0176 for (size_t i = 0; i < elems; i++) {
0177 REQUIRE(genericSoAView[i].xPos() == positionConstView[i].x());
0178 REQUIRE(genericSoAView[i].yPos() == positionConstView[i].y());
0179 REQUIRE(genericSoAView[i].zPos() == positionConstView[i].z());
0180 REQUIRE(genericSoAView[i].candidateDirection()(0) == pcaConstView[i].candidateDirection()(0));
0181 REQUIRE(genericSoAView[i].candidateDirection()(1) == pcaConstView[i].candidateDirection()(1));
0182 REQUIRE(genericSoAView[i].candidateDirection()(2) == pcaConstView[i].candidateDirection()(2));
0183 }
0184
0185
0186 genericSoAView[3].xPos() = 0.;
0187 REQUIRE(genericSoAView[3].xPos() != positionView[3].x());
0188 }
0189 }