File indexing completed on 2025-05-04 22:50:31
0001 #ifndef DataFormats_SoATemplate_interface_SoALayout_h
0002 #define DataFormats_SoATemplate_interface_SoALayout_h
0003
0004
0005
0006
0007
0008
0009 #include "FWCore/Reflection/interface/reflex.h"
0010
0011 #include "SoACommon.h"
0012 #include "SoAView.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 #define _COUNT_SOA_METHODS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS, DATA) \
0061 BOOST_PP_IF(BOOST_PP_EQUAL(VALUE_TYPE, _VALUE_TYPE_METHOD), \
0062 DATA++;, \
0063 BOOST_PP_EMPTY())
0064
0065
0066 #define _COUNT_SOA_METHODS(R, DATA, TYPE_NAME) \
0067 BOOST_PP_EXPAND(_COUNT_SOA_METHODS_IMPL BOOST_PP_TUPLE_PUSH_BACK(TYPE_NAME, DATA))
0068
0069
0070 #define _COUNT_SOA_CONST_METHODS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS, DATA) \
0071 BOOST_PP_IF(BOOST_PP_EQUAL(VALUE_TYPE, _VALUE_TYPE_CONST_METHOD), \
0072 DATA++;, \
0073 BOOST_PP_EMPTY())
0074
0075
0076 #define _COUNT_SOA_CONST_METHODS(R, DATA, TYPE_NAME) \
0077 BOOST_PP_EXPAND(_COUNT_SOA_CONST_METHODS_IMPL BOOST_PP_TUPLE_PUSH_BACK(TYPE_NAME, DATA))
0078
0079
0080 #define _DECLARE_SOA_STREAM_INFO_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0081 _SWITCH_ON_TYPE( \
0082 VALUE_TYPE, \
0083 \
0084 _soa_impl_os << " Scalar " BOOST_PP_STRINGIZE(NAME) " at offset " << _soa_impl_offset \
0085 << " has size " << sizeof(CPP_TYPE) \
0086 << " and padding " << ((sizeof(CPP_TYPE) - 1) / alignment + 1) * alignment - sizeof(CPP_TYPE) \
0087 << std::endl; \
0088 _soa_impl_offset += ((sizeof(CPP_TYPE) - 1) / alignment + 1) * alignment; \
0089 , \
0090 \
0091 _soa_impl_os << " Column " BOOST_PP_STRINGIZE(NAME) " at offset " << _soa_impl_offset << " has size " \
0092 << sizeof(CPP_TYPE) * elements_ << " and padding " \
0093 << cms::soa::alignSize(elements_ * sizeof(CPP_TYPE), alignment) - (elements_ * sizeof(CPP_TYPE)) \
0094 << std::endl; \
0095 _soa_impl_offset += cms::soa::alignSize(elements_ * sizeof(CPP_TYPE), alignment); \
0096 , \
0097 \
0098 _soa_impl_os << " Eigen value " BOOST_PP_STRINGIZE(NAME) " at offset " << _soa_impl_offset << " has dimension " \
0099 << "(" << CPP_TYPE::RowsAtCompileTime << " x " << CPP_TYPE::ColsAtCompileTime << ")" \
0100 << " and per column size " \
0101 << sizeof(CPP_TYPE::Scalar) * elements_ \
0102 << " and padding " \
0103 << cms::soa::alignSize(elements_ * sizeof(CPP_TYPE::Scalar), alignment) \
0104 - (elements_ * sizeof(CPP_TYPE::Scalar)) \
0105 << std::endl; \
0106 _soa_impl_offset += cms::soa::alignSize(elements_ * sizeof(CPP_TYPE::Scalar), alignment) \
0107 * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \
0108 )
0109
0110
0111
0112 #define _DECLARE_SOA_STREAM_INFO(R, DATA, TYPE_NAME) \
0113 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0114 BOOST_PP_EMPTY(), \
0115 BOOST_PP_EXPAND(_DECLARE_SOA_STREAM_INFO_IMPL TYPE_NAME))
0116
0117
0118
0119
0120
0121
0122 #define _DEFINE_METADATA_MEMBERS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0123 _SWITCH_ON_TYPE(VALUE_TYPE, \
0124 \
0125 byte_size_type BOOST_PP_CAT(NAME, Pitch()) const { \
0126 return cms::soa::alignSize(sizeof(CPP_TYPE), ParentClass::alignment); \
0127 } \
0128 using BOOST_PP_CAT(TypeOf_, NAME) = CPP_TYPE; \
0129 constexpr static cms::soa::SoAColumnType BOOST_PP_CAT(ColumnTypeOf_, NAME) = cms::soa::SoAColumnType::scalar; \
0130 SOA_HOST_DEVICE SOA_INLINE \
0131 CPP_TYPE const* BOOST_PP_CAT(addressOf_, NAME)() const { \
0132 return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \
0133 } \
0134 using BOOST_PP_CAT(ParametersTypeOf_, NAME) = \
0135 cms::soa::SoAParameters_ColumnType<cms::soa::SoAColumnType::scalar>::DataType<CPP_TYPE>; \
0136 SOA_HOST_DEVICE SOA_INLINE \
0137 BOOST_PP_CAT(ParametersTypeOf_, NAME) BOOST_PP_CAT(parametersOf_, NAME)() const { \
0138 return BOOST_PP_CAT(ParametersTypeOf_, NAME) (parent_.BOOST_PP_CAT(NAME, _), parent_.metadata().size()); \
0139 } \
0140 SOA_HOST_DEVICE SOA_INLINE \
0141 CPP_TYPE* BOOST_PP_CAT(addressOf_, NAME)() { \
0142 return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \
0143 }, \
0144 \
0145 using BOOST_PP_CAT(ParametersTypeOf_, NAME) = \
0146 cms::soa::SoAParameters_ColumnType<cms::soa::SoAColumnType::column>::DataType<CPP_TYPE>; \
0147 SOA_HOST_DEVICE SOA_INLINE \
0148 BOOST_PP_CAT(ParametersTypeOf_, NAME) BOOST_PP_CAT(parametersOf_, NAME)() const { \
0149 return BOOST_PP_CAT(ParametersTypeOf_, NAME) (parent_.BOOST_PP_CAT(NAME, _), parent_.metadata().size()); \
0150 } \
0151 SOA_HOST_DEVICE SOA_INLINE \
0152 CPP_TYPE const* BOOST_PP_CAT(addressOf_, NAME)() const { \
0153 return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \
0154 } \
0155 SOA_HOST_DEVICE SOA_INLINE \
0156 CPP_TYPE* BOOST_PP_CAT(addressOf_, NAME)() { \
0157 return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \
0158 } \
0159 SOA_HOST_DEVICE SOA_INLINE \
0160 byte_size_type BOOST_PP_CAT(NAME, Pitch()) const { \
0161 return cms::soa::alignSize(parent_.elements_ * sizeof(CPP_TYPE), ParentClass::alignment); \
0162 } \
0163 using BOOST_PP_CAT(TypeOf_, NAME) = CPP_TYPE; \
0164 constexpr static cms::soa::SoAColumnType BOOST_PP_CAT(ColumnTypeOf_, NAME) = cms::soa::SoAColumnType::column;, \
0165 \
0166 using BOOST_PP_CAT(ParametersTypeOf_, NAME) = \
0167 cms::soa::SoAParameters_ColumnType<cms::soa::SoAColumnType::eigen>::DataType<CPP_TYPE>; \
0168 SOA_HOST_DEVICE SOA_INLINE \
0169 BOOST_PP_CAT(ParametersTypeOf_, NAME) BOOST_PP_CAT(parametersOf_, NAME)() const { \
0170 return BOOST_PP_CAT(ParametersTypeOf_, NAME) ( \
0171 parent_.BOOST_PP_CAT(NAME, _), \
0172 parent_.BOOST_PP_CAT(NAME, Stride_), \
0173 parent_.metadata().size()); \
0174 } \
0175 SOA_HOST_DEVICE SOA_INLINE \
0176 byte_size_type BOOST_PP_CAT(NAME, Pitch()) const { \
0177 return cms::soa::alignSize(parent_.elements_ * sizeof(CPP_TYPE::Scalar), ParentClass::alignment) \
0178 * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \
0179 } \
0180 using BOOST_PP_CAT(TypeOf_, NAME) = CPP_TYPE ; \
0181 constexpr static cms::soa::SoAColumnType BOOST_PP_CAT(ColumnTypeOf_, NAME) = cms::soa::SoAColumnType::eigen; \
0182 SOA_HOST_DEVICE SOA_INLINE \
0183 CPP_TYPE::Scalar const* BOOST_PP_CAT(addressOf_, NAME)() const { \
0184 return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \
0185 } \
0186 SOA_HOST_DEVICE SOA_INLINE \
0187 CPP_TYPE::Scalar* BOOST_PP_CAT(addressOf_, NAME)() { \
0188 return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \
0189 } \
0190 )
0191
0192
0193
0194 #define _DEFINE_METADATA_MEMBERS(R, DATA, TYPE_NAME) \
0195 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0196 BOOST_PP_EMPTY(), \
0197 BOOST_PP_EXPAND(_DEFINE_METADATA_MEMBERS_IMPL TYPE_NAME))
0198
0199
0200
0201 #define _DECLARE_MEMBER_TRIVIAL_CONSTRUCTION_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0202 _SWITCH_ON_TYPE(VALUE_TYPE, \
0203 \
0204 (BOOST_PP_CAT(NAME, _)(nullptr)), \
0205 \
0206 (BOOST_PP_CAT(NAME, _)(nullptr)), \
0207 \
0208 (BOOST_PP_CAT(NAME, ElementsWithPadding_)(0)) \
0209 (BOOST_PP_CAT(NAME, _)(nullptr)) \
0210 (BOOST_PP_CAT(NAME, Stride_)(0)) \
0211 )
0212
0213
0214
0215 #define _DECLARE_MEMBER_TRIVIAL_CONSTRUCTION(R, DATA, TYPE_NAME) \
0216 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0217 BOOST_PP_EMPTY(), \
0218 BOOST_PP_EXPAND(_DECLARE_MEMBER_TRIVIAL_CONSTRUCTION_IMPL TYPE_NAME))
0219
0220
0221
0222 #define _DECLARE_MEMBER_COPY_CONSTRUCTION_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0223 _SWITCH_ON_TYPE(VALUE_TYPE, \
0224 \
0225 (BOOST_PP_CAT(NAME, _){_soa_impl_other.BOOST_PP_CAT(NAME, _)}), \
0226 \
0227 (BOOST_PP_CAT(NAME, _){_soa_impl_other.BOOST_PP_CAT(NAME, _)}), \
0228 \
0229 (BOOST_PP_CAT(NAME, ElementsWithPadding_){_soa_impl_other.BOOST_PP_CAT(NAME, ElementsWithPadding_)}) \
0230 (BOOST_PP_CAT(NAME, _){_soa_impl_other.BOOST_PP_CAT(NAME, _)}) \
0231 (BOOST_PP_CAT(NAME, Stride_){_soa_impl_other.BOOST_PP_CAT(NAME, Stride_)}) \
0232 )
0233
0234
0235
0236 #define _DECLARE_MEMBER_COPY_CONSTRUCTION(R, DATA, TYPE_NAME) \
0237 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0238 BOOST_PP_EMPTY(), \
0239 BOOST_PP_EXPAND(_DECLARE_MEMBER_COPY_CONSTRUCTION_IMPL TYPE_NAME))
0240
0241
0242
0243 #define _DECLARE_MEMBER_ASSIGNMENT_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0244 _SWITCH_ON_TYPE(VALUE_TYPE, \
0245 \
0246 BOOST_PP_CAT(NAME, _) = _soa_impl_other.BOOST_PP_CAT(NAME, _);, \
0247 \
0248 BOOST_PP_CAT(NAME, _) = _soa_impl_other.BOOST_PP_CAT(NAME, _);, \
0249 \
0250 BOOST_PP_CAT(NAME, ElementsWithPadding_) = _soa_impl_other.BOOST_PP_CAT(NAME, ElementsWithPadding_); \
0251 BOOST_PP_CAT(NAME, _) = _soa_impl_other.BOOST_PP_CAT(NAME, _); \
0252 BOOST_PP_CAT(NAME, Stride_) = _soa_impl_other.BOOST_PP_CAT(NAME, Stride_); \
0253 )
0254
0255
0256
0257 #define _DECLARE_MEMBER_ASSIGNMENT(R, DATA, TYPE_NAME) \
0258 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0259 BOOST_PP_EMPTY(), \
0260 BOOST_PP_EXPAND(_DECLARE_MEMBER_ASSIGNMENT_IMPL TYPE_NAME))
0261
0262
0263
0264
0265
0266
0267 #define _DEFINE_VALUE_ELEMENT_MEMBERS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0268 _SWITCH_ON_TYPE(VALUE_TYPE, \
0269 \
0270 , \
0271 \
0272 CPP_TYPE NAME; \
0273 , \
0274 \
0275 CPP_TYPE NAME; \
0276 )
0277
0278
0279
0280 #define _DEFINE_VALUE_ELEMENT_MEMBERS(R, DATA, TYPE_NAME) \
0281 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0282 BOOST_PP_EMPTY(), \
0283 BOOST_PP_EXPAND(_DEFINE_VALUE_ELEMENT_MEMBERS_IMPL TYPE_NAME))
0284
0285
0286
0287
0288
0289
0290 #define _VALUE_ELEMENT_CTOR_ARGS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0291 _SWITCH_ON_TYPE(VALUE_TYPE, \
0292 \
0293 , \
0294 \
0295 (CPP_TYPE NAME), \
0296 \
0297 (CPP_TYPE NAME) \
0298 )
0299
0300
0301
0302 #define _VALUE_ELEMENT_CTOR_ARGS(R, DATA, TYPE_NAME) \
0303 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0304 BOOST_PP_EMPTY(), \
0305 BOOST_PP_EXPAND(_VALUE_ELEMENT_CTOR_ARGS_IMPL TYPE_NAME))
0306
0307
0308
0309
0310
0311
0312 #define _VALUE_ELEMENT_INITIALIZERS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0313 _SWITCH_ON_TYPE(VALUE_TYPE, \
0314 \
0315 , \
0316 \
0317 (NAME{NAME}), \
0318 \
0319 (NAME{NAME}) \
0320 )
0321
0322
0323
0324 #define _VALUE_ELEMENT_INITIALIZERS(R, DATA, TYPE_NAME) \
0325 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0326 BOOST_PP_EMPTY(), \
0327 BOOST_PP_EXPAND(_VALUE_ELEMENT_INITIALIZERS_IMPL TYPE_NAME))
0328
0329
0330
0331
0332
0333
0334 #define _ROOT_FREE_SOA_COLUMN_OR_SCALAR_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0335 delete[] BOOST_PP_CAT(NAME, _); \
0336 BOOST_PP_CAT(NAME, _) = nullptr;
0337
0338
0339
0340 #define _ROOT_FREE_SOA_COLUMN_OR_SCALAR(R, DATA, TYPE_NAME) \
0341 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0342 BOOST_PP_EMPTY(), \
0343 BOOST_PP_EXPAND(_ROOT_FREE_SOA_COLUMN_OR_SCALAR_IMPL TYPE_NAME))
0344
0345
0346
0347
0348
0349
0350 #define _ASSIGN_SOA_COLUMN_OR_SCALAR_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0351 _SWITCH_ON_TYPE(VALUE_TYPE, \
0352 \
0353 BOOST_PP_CAT(NAME, _) = reinterpret_cast<CPP_TYPE*>(_soa_impl_curMem); \
0354 _soa_impl_curMem += cms::soa::alignSize(sizeof(CPP_TYPE), alignment); \
0355 , \
0356 \
0357 BOOST_PP_CAT(NAME, _) = reinterpret_cast<CPP_TYPE*>(_soa_impl_curMem); \
0358 _soa_impl_curMem += cms::soa::alignSize(elements_ * sizeof(CPP_TYPE), alignment); \
0359 , \
0360 \
0361 BOOST_PP_CAT(NAME, Stride_) = cms::soa::alignSize(elements_ * sizeof(CPP_TYPE::Scalar), alignment) \
0362 / sizeof(CPP_TYPE::Scalar); \
0363 BOOST_PP_CAT(NAME, ElementsWithPadding_) = BOOST_PP_CAT(NAME, Stride_) \
0364 * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \
0365 BOOST_PP_CAT(NAME, _) = reinterpret_cast<CPP_TYPE::Scalar*>(_soa_impl_curMem); \
0366 _soa_impl_curMem += cms::soa::alignSize(elements_ * sizeof(CPP_TYPE::Scalar), alignment) \
0367 * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \
0368 ) \
0369 if constexpr (alignmentEnforcement == AlignmentEnforcement::enforced) \
0370 if (reinterpret_cast<intptr_t>(BOOST_PP_CAT(NAME, _)) % alignment) \
0371 throw std::runtime_error("In layout constructor: misaligned column: " #NAME);
0372
0373
0374
0375 #define _ASSIGN_SOA_COLUMN_OR_SCALAR(R, DATA, TYPE_NAME) \
0376 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0377 BOOST_PP_EMPTY(), \
0378 BOOST_PP_EXPAND(_ASSIGN_SOA_COLUMN_OR_SCALAR_IMPL TYPE_NAME))
0379
0380
0381
0382
0383
0384
0385 #define _ACCUMULATE_SOA_ELEMENT_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0386 _SWITCH_ON_TYPE(VALUE_TYPE, \
0387 \
0388 _soa_impl_ret += cms::soa::alignSize(sizeof(CPP_TYPE), alignment); \
0389 , \
0390 \
0391 _soa_impl_ret += cms::soa::alignSize(elements * sizeof(CPP_TYPE), alignment); \
0392 , \
0393 \
0394 _soa_impl_ret += cms::soa::alignSize(elements * sizeof(CPP_TYPE::Scalar), alignment) \
0395 * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \
0396 )
0397
0398
0399
0400 #define _ACCUMULATE_SOA_ELEMENT(R, DATA, TYPE_NAME) \
0401 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0402 BOOST_PP_EMPTY(), \
0403 BOOST_PP_EXPAND(_ACCUMULATE_SOA_ELEMENT_IMPL TYPE_NAME))
0404
0405
0406
0407
0408
0409
0410 #define _DECLARE_SOA_ACCESSOR_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0411 _SWITCH_ON_TYPE(VALUE_TYPE, \
0412 \
0413 SOA_HOST_DEVICE SOA_INLINE CPP_TYPE& NAME() { return *BOOST_PP_CAT(NAME, _); } \
0414 , \
0415 \
0416 SOA_HOST_DEVICE SOA_INLINE CPP_TYPE* NAME() { return BOOST_PP_CAT(NAME, _); } \
0417 SOA_HOST_DEVICE SOA_INLINE CPP_TYPE& NAME(size_type _soa_impl_index) { \
0418 return BOOST_PP_CAT(NAME, _)[_soa_impl_index]; \
0419 } \
0420 , \
0421 \
0422 \
0423 BOOST_PP_EMPTY() \
0424 )
0425
0426
0427
0428 #define _DECLARE_SOA_ACCESSOR(R, DATA, TYPE_NAME) \
0429 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0430 BOOST_PP_EMPTY(), \
0431 BOOST_PP_EXPAND(_DECLARE_SOA_ACCESSOR_IMPL TYPE_NAME))
0432
0433
0434
0435
0436
0437
0438 #define _DECLARE_SOA_CONST_ACCESSOR_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0439 _SWITCH_ON_TYPE(VALUE_TYPE, \
0440 \
0441 SOA_HOST_DEVICE SOA_INLINE CPP_TYPE NAME() const { return *(BOOST_PP_CAT(NAME, _)); } \
0442 , \
0443 \
0444 SOA_HOST_DEVICE SOA_INLINE CPP_TYPE const* NAME() const { return BOOST_PP_CAT(NAME, _); } \
0445 SOA_HOST_DEVICE SOA_INLINE CPP_TYPE NAME(size_type _soa_impl_index) const { \
0446 return *(BOOST_PP_CAT(NAME, _) + _soa_impl_index); \
0447 } \
0448 , \
0449 \
0450 SOA_HOST_DEVICE SOA_INLINE CPP_TYPE::Scalar const* NAME() const { return BOOST_PP_CAT(NAME, _); } \
0451 SOA_HOST_DEVICE SOA_INLINE size_type BOOST_PP_CAT(NAME, Stride)() { return BOOST_PP_CAT(NAME, Stride_); } \
0452 )
0453
0454
0455
0456 #define _DECLARE_SOA_CONST_ACCESSOR(R, DATA, TYPE_NAME) \
0457 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0458 BOOST_PP_EMPTY(), \
0459 BOOST_PP_EXPAND(_DECLARE_SOA_CONST_ACCESSOR_IMPL TYPE_NAME))
0460
0461
0462
0463
0464
0465
0466 #define _STREAMER_READ_SOA_DATA_MEMBER_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0467 _SWITCH_ON_TYPE(VALUE_TYPE, \
0468 \
0469 memcpy(BOOST_PP_CAT(NAME, _), onfile.BOOST_PP_CAT(NAME, _), sizeof(CPP_TYPE)); \
0470 , \
0471 \
0472 memcpy(BOOST_PP_CAT(NAME, _), onfile.BOOST_PP_CAT(NAME, _), sizeof(CPP_TYPE) * onfile.elements_); \
0473 , \
0474 \
0475 memcpy(BOOST_PP_CAT(NAME, _), onfile.BOOST_PP_CAT(NAME, _), \
0476 sizeof(CPP_TYPE::Scalar) * BOOST_PP_CAT(NAME, ElementsWithPadding_)); \
0477 )
0478
0479
0480
0481 #define _STREAMER_READ_SOA_DATA_MEMBER(R, DATA, TYPE_NAME) \
0482 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0483 BOOST_PP_EMPTY(), \
0484 BOOST_PP_EXPAND(_STREAMER_READ_SOA_DATA_MEMBER_IMPL TYPE_NAME))
0485
0486
0487
0488
0489
0490
0491 #define _DECLARE_SOA_DATA_MEMBER_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0492 _SWITCH_ON_TYPE(VALUE_TYPE, \
0493 \
0494 CPP_TYPE* BOOST_PP_CAT(NAME, _) EDM_REFLEX_SIZE(scalar_) = nullptr; \
0495 , \
0496 \
0497 CPP_TYPE * BOOST_PP_CAT(NAME, _) EDM_REFLEX_SIZE(elements_) = nullptr; \
0498 , \
0499 \
0500 size_type BOOST_PP_CAT(NAME, ElementsWithPadding_) = 0; \
0501 CPP_TYPE::Scalar * BOOST_PP_CAT(NAME, _) EDM_REFLEX_SIZE(BOOST_PP_CAT(NAME, ElementsWithPadding_)) = nullptr; \
0502 byte_size_type BOOST_PP_CAT(NAME, Stride_) = 0; \
0503 )
0504
0505
0506
0507 #define _DECLARE_SOA_DATA_MEMBER(R, DATA, TYPE_NAME) \
0508 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0509 BOOST_PP_EMPTY(), \
0510 BOOST_PP_EXPAND(_DECLARE_SOA_DATA_MEMBER_IMPL TYPE_NAME))
0511
0512
0513 #define _COPY_VIEW_COLUMNS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \
0514 _SWITCH_ON_TYPE( \
0515 VALUE_TYPE, \
0516 memcpy(BOOST_PP_CAT(this->metadata().addressOf_, NAME)(), \
0517 BOOST_PP_CAT(view.metadata().addressOf_, NAME)(), \
0518 sizeof(CPP_TYPE)); \
0519 , \
0520 memcpy(BOOST_PP_CAT(this->metadata().addressOf_, NAME)(), \
0521 BOOST_PP_CAT(view.metadata().addressOf_, NAME)(), \
0522 view.metadata().size() * sizeof(CPP_TYPE)); \
0523 , \
0524 for (unsigned int i = 0; i < CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; i++) { \
0525 memcpy(BOOST_PP_CAT(this->metadata().addressOf_, NAME)() + i * BOOST_PP_CAT(NAME, Stride_), \
0526 &view[0].NAME().coeff(i), \
0527 view.metadata().size() * sizeof(CPP_TYPE::Scalar)); \
0528 })
0529
0530 #define _COPY_VIEW_COLUMNS(R, DATA, TYPE_NAME) \
0531 BOOST_PP_IF(BOOST_PP_GREATER(BOOST_PP_TUPLE_ELEM(0, TYPE_NAME), _VALUE_LAST_COLUMN_TYPE), \
0532 BOOST_PP_EMPTY(), \
0533 BOOST_PP_EXPAND(_COPY_VIEW_COLUMNS_IMPL TYPE_NAME))
0534
0535 #ifdef DEBUG
0536 #define _DO_RANGECHECK true
0537 #else
0538 #define _DO_RANGECHECK false
0539 #endif
0540
0541
0542
0543
0544
0545 #define GENERATE_SOA_LAYOUT(CLASS, ...) \
0546 template <CMS_SOA_BYTE_SIZE_TYPE ALIGNMENT = cms::soa::CacheLineSize::defaultSize, \
0547 bool ALIGNMENT_ENFORCEMENT = cms::soa::AlignmentEnforcement::relaxed> \
0548 struct CLASS { \
0549 \
0550 using self_type = CLASS; \
0551 using AlignmentEnforcement = cms::soa::AlignmentEnforcement; \
0552 \
0553
0554
0555
0556 \
0557 using size_type = cms::soa::size_type; \
0558 using byte_size_type = cms::soa::byte_size_type; \
0559 constexpr static byte_size_type defaultAlignment = 128; \
0560 constexpr static byte_size_type alignment = ALIGNMENT; \
0561 constexpr static bool alignmentEnforcement = ALIGNMENT_ENFORCEMENT; \
0562 constexpr static byte_size_type conditionalAlignment = \
0563 alignmentEnforcement == cms::soa::AlignmentEnforcement::enforced ? alignment : 0; \
0564 \
0565 template <cms::soa::SoAColumnType COLUMN_TYPE, class C> \
0566 using SoAValueWithConf = cms::soa::SoAValue<COLUMN_TYPE, C, conditionalAlignment>; \
0567 \
0568 template <cms::soa::SoAColumnType COLUMN_TYPE, class C> \
0569 using SoAConstValueWithConf = cms::soa::SoAConstValue<COLUMN_TYPE, C, conditionalAlignment>; \
0570 \
0571 template <CMS_SOA_BYTE_SIZE_TYPE VIEW_ALIGNMENT = cms::soa::CacheLineSize::defaultSize, \
0572 bool VIEW_ALIGNMENT_ENFORCEMENT = cms::soa::AlignmentEnforcement::relaxed, \
0573 bool RESTRICT_QUALIFY = cms::soa::RestrictQualify::Default, \
0574 bool RANGE_CHECKING = cms::soa::RangeChecking::Default> \
0575 struct ViewTemplateFreeParams; \
0576 \
0577 \
0578 SOA_HOST_ONLY \
0579 void soaToStreamInternal(std::ostream & _soa_impl_os) const { \
0580 _soa_impl_os << #CLASS "(" << elements_ << " elements, byte alignement= " << alignment << ", @"<< mem_ <<"): " \
0581 << std::endl; \
0582 _soa_impl_os << " sizeof(" #CLASS "): " << sizeof(CLASS) << std::endl; \
0583 byte_size_type _soa_impl_offset = 0; \
0584 _ITERATE_ON_ALL(_DECLARE_SOA_STREAM_INFO, ~, __VA_ARGS__) \
0585 _soa_impl_os << "Final offset = " << _soa_impl_offset << " computeDataSize(...): " << computeDataSize(elements_) \
0586 << std::endl; \
0587 _soa_impl_os << std::endl; \
0588 } \
0589 \
0590 \
0591 static constexpr byte_size_type computeDataSize(size_type elements) { \
0592 byte_size_type _soa_impl_ret = 0; \
0593 _ITERATE_ON_ALL(_ACCUMULATE_SOA_ELEMENT, ~, __VA_ARGS__) \
0594 return _soa_impl_ret; \
0595 } \
0596 \
0597
0598
0599 \
0600 struct Metadata { \
0601 friend CLASS; \
0602 SOA_HOST_DEVICE SOA_INLINE size_type size() const { return parent_.elements_; } \
0603 SOA_HOST_DEVICE SOA_INLINE byte_size_type byteSize() const { return parent_.byteSize_; } \
0604 SOA_HOST_DEVICE SOA_INLINE byte_size_type alignment() const { return CLASS::alignment; } \
0605 SOA_HOST_DEVICE SOA_INLINE std::byte* data() { return parent_.mem_; } \
0606 SOA_HOST_DEVICE SOA_INLINE const std::byte* data() const { return parent_.mem_; } \
0607 SOA_HOST_DEVICE SOA_INLINE std::byte* nextByte() const { return parent_.mem_ + parent_.byteSize_; } \
0608 SOA_HOST_DEVICE SOA_INLINE CLASS cloneToNewAddress(std::byte* _soa_impl_addr) const { \
0609 return CLASS(_soa_impl_addr, parent_.elements_); \
0610 } \
0611 \
0612 _ITERATE_ON_ALL(_DEFINE_METADATA_MEMBERS, ~, __VA_ARGS__) \
0613 \
0614 struct value_element { \
0615 SOA_HOST_DEVICE SOA_INLINE value_element \
0616 BOOST_PP_IF( \
0617 BOOST_PP_SEQ_SIZE(_ITERATE_ON_ALL(_VALUE_ELEMENT_CTOR_ARGS, ~, __VA_ARGS__) ), \
0618 (_ITERATE_ON_ALL_COMMA(_VALUE_ELEMENT_CTOR_ARGS, ~, __VA_ARGS__)):, \
0619 ()) \
0620 BOOST_PP_TUPLE_ENUM(BOOST_PP_IF( \
0621 BOOST_PP_SEQ_SIZE(_ITERATE_ON_ALL(_VALUE_ELEMENT_CTOR_ARGS, ~, __VA_ARGS__)), \
0622 BOOST_PP_SEQ_TO_TUPLE(_ITERATE_ON_ALL(_VALUE_ELEMENT_INITIALIZERS, ~, __VA_ARGS__)), \
0623 () \
0624 ) \
0625 ) \
0626 {} \
0627 \
0628 _ITERATE_ON_ALL(_DEFINE_VALUE_ELEMENT_MEMBERS, ~, __VA_ARGS__) \
0629 }; \
0630 \
0631 Metadata& operator=(const Metadata&) = delete; \
0632 Metadata(const Metadata&) = delete; \
0633 \
0634 private: \
0635 SOA_HOST_DEVICE SOA_INLINE Metadata(const CLASS& _soa_impl_parent) : parent_(_soa_impl_parent) {} \
0636 const CLASS& parent_; \
0637 using ParentClass = CLASS; \
0638 }; \
0639 \
0640 friend Metadata; \
0641 \
0642 SOA_HOST_DEVICE SOA_INLINE const Metadata metadata() const { return Metadata(*this); } \
0643 SOA_HOST_DEVICE SOA_INLINE Metadata metadata() { return Metadata(*this); } \
0644 \
0645 \
0646 _GENERATE_SOA_TRIVIAL_CONST_VIEW(CLASS, \
0647 SOA_VIEW_LAYOUT_LIST( \
0648 SOA_VIEW_LAYOUT(BOOST_PP_CAT(CLASS, _parametrized) , BOOST_PP_CAT(instance_, CLASS))), \
0649 SOA_VIEW_VALUE_LIST(_ITERATE_ON_ALL_COMMA( \
0650 _VIEW_FIELD_FROM_LAYOUT, BOOST_PP_CAT(instance_, CLASS), __VA_ARGS__)), __VA_ARGS__) \
0651 \
0652 template <bool RESTRICT_QUALIFY, bool RANGE_CHECKING> \
0653 using ConstViewTemplate = ConstViewTemplateFreeParams<ALIGNMENT, ALIGNMENT_ENFORCEMENT, RESTRICT_QUALIFY, \
0654 RANGE_CHECKING>; \
0655 \
0656 using ConstView = ConstViewTemplate<cms::soa::RestrictQualify::Default, cms::soa::RangeChecking::Default>; \
0657 \
0658 \
0659 _GENERATE_SOA_TRIVIAL_VIEW(CLASS, \
0660 SOA_VIEW_LAYOUT_LIST( \
0661 SOA_VIEW_LAYOUT(BOOST_PP_CAT(CLASS, _parametrized), BOOST_PP_CAT(instance_, CLASS))), \
0662 SOA_VIEW_VALUE_LIST(_ITERATE_ON_ALL_COMMA( \
0663 _VIEW_FIELD_FROM_LAYOUT, BOOST_PP_CAT(instance_, CLASS), __VA_ARGS__)), \
0664 __VA_ARGS__) \
0665 \
0666 template <bool RESTRICT_QUALIFY, bool RANGE_CHECKING> \
0667 using ViewTemplate = ViewTemplateFreeParams<ALIGNMENT, ALIGNMENT_ENFORCEMENT, RESTRICT_QUALIFY, RANGE_CHECKING>; \
0668 \
0669 using View = ViewTemplate<cms::soa::RestrictQualify::Default, cms::soa::RangeChecking::Default>; \
0670 \
0671 \
0672 CLASS() \
0673 : mem_(nullptr), \
0674 elements_(0), \
0675 byteSize_(0), \
0676 _ITERATE_ON_ALL_COMMA(_DECLARE_MEMBER_TRIVIAL_CONSTRUCTION, ~, __VA_ARGS__) {} \
0677 \
0678 \
0679 SOA_HOST_ONLY CLASS(std::byte* mem, size_type elements) : mem_(mem), elements_(elements), byteSize_(0) { \
0680 organizeColumnsFromBuffer(); \
0681 } \
0682 \
0683 \
0684 SOA_HOST_ONLY CLASS(CLASS const& _soa_impl_other) \
0685 : mem_(_soa_impl_other.mem_), \
0686 elements_(_soa_impl_other.elements_), \
0687 byteSize_(_soa_impl_other.byteSize_), \
0688 _ITERATE_ON_ALL_COMMA(_DECLARE_MEMBER_COPY_CONSTRUCTION, ~, __VA_ARGS__) {} \
0689 \
0690 SOA_HOST_ONLY CLASS& operator=(CLASS const& _soa_impl_other) { \
0691 mem_ = _soa_impl_other.mem_; \
0692 elements_ = _soa_impl_other.elements_; \
0693 byteSize_ = _soa_impl_other.byteSize_; \
0694 _ITERATE_ON_ALL(_DECLARE_MEMBER_ASSIGNMENT, ~, __VA_ARGS__) \
0695 return *this; \
0696 } \
0697 \
0698 SOA_HOST_ONLY void deepCopy(ConstView const& view) { \
0699 if (elements_ < view.metadata().size()) \
0700 throw std::runtime_error( \
0701 "In "#CLASS "::deepCopy method: number of elements mismatch "); \
0702 _ITERATE_ON_ALL(_COPY_VIEW_COLUMNS, ~, __VA_ARGS__) \
0703 } \
0704 \
0705 \
0706 template <typename T> \
0707 void ROOTReadStreamer(T & onfile) { \
0708 _ITERATE_ON_ALL(_STREAMER_READ_SOA_DATA_MEMBER, ~, __VA_ARGS__) \
0709 } \
0710 \
0711 \
0712 void ROOTStreamerCleaner() { \
0713 \
0714 _ITERATE_ON_ALL(_ROOT_FREE_SOA_COLUMN_OR_SCALAR, ~, __VA_ARGS__) \
0715 } \
0716 \
0717 \
0718 template <typename T> \
0719 SOA_HOST_ONLY friend void dump(); \
0720 \
0721 private: \
0722 \
0723 void organizeColumnsFromBuffer() { \
0724 if constexpr (alignmentEnforcement == cms::soa::AlignmentEnforcement::enforced) \
0725 if (reinterpret_cast<intptr_t>(mem_) % alignment) \
0726 throw std::runtime_error("In " #CLASS "::" #CLASS ": misaligned buffer"); \
0727 auto _soa_impl_curMem = mem_; \
0728 _ITERATE_ON_ALL(_ASSIGN_SOA_COLUMN_OR_SCALAR, ~, __VA_ARGS__) \
0729 \
0730 byteSize_ = computeDataSize(elements_); \
0731 if (mem_ + byteSize_ != _soa_impl_curMem) \
0732 throw std::runtime_error("In " #CLASS "::" #CLASS ": unexpected end pointer."); \
0733 } \
0734 \
0735 \
0736 static constexpr std::pair<size_type, size_type> computeMethodsNumber() { \
0737 size_type _soa_methods_count = 0; \
0738 size_type _soa_const_methods_count = 0; \
0739 \
0740 _ITERATE_ON_ALL(_COUNT_SOA_METHODS, _soa_methods_count, __VA_ARGS__) \
0741 _ITERATE_ON_ALL(_COUNT_SOA_CONST_METHODS, _soa_const_methods_count, __VA_ARGS__) \
0742 \
0743 return {_soa_methods_count, _soa_const_methods_count}; \
0744 } \
0745 \
0746 \
0747 static_assert(computeMethodsNumber().first <= 1, \
0748 "There can be at most one SOA_METHODS macro. Please declare all your methods inside the same macro."); \
0749 \
0750 static_assert(computeMethodsNumber().second <= 1, \
0751 "There can be at most one SOA_CONST_METHODS macro. Please declare all your methods inside the same macro."); \
0752 \
0753 \
0754 std::byte* mem_ EDM_REFLEX_TRANSIENT; \
0755 size_type elements_; \
0756 size_type const scalar_ = 1; \
0757 byte_size_type byteSize_ EDM_REFLEX_TRANSIENT; \
0758 _ITERATE_ON_ALL(_DECLARE_SOA_DATA_MEMBER, ~, __VA_ARGS__) \
0759 \
0760 \
0761 \
0762 \
0763 };
0764
0765
0766 #endif