31 #ifndef XAOD_STANDALONE
44 #include <gtest/gtest.h>
58 const unsigned int batchSize = 1000;
65 std::chrono::time_point<std::chrono::high_resolution_clock>
m_start;
74 Benchmark (
const std::string& val_name)
81 std::cout <<
m_name <<
": " << std::chrono::duration<std::uint64_t,std::nano> (
m_ticks) /
m_count << std::endl;
84 auto getTotalTime ()
const
102 namespace PhysliteTestHelpers
106 static const std::unordered_map<std::string,SG::sgkey_t> knownKeys =
108 {
"AnalysisMuons", 0x3a6b126f},
109 {
"AnalysisElectrons", 0x3902fec0},
110 {
"AnalysisPhotons", 0x35d1472f},
111 {
"AnalysisJets", 0x1afd1919},
112 {
"egammaClusters", 0x15788d1f},
113 {
"GSFConversionVertices", 0x1f3e85c9},
114 {
"InDetTrackParticles", 0x1d3890db},
115 {
"CombinedMuonTrackParticles", 0x340d9196},
116 {
"ExtrapolatedMuonTrackParticles", 0x14e35e9f},
117 {
"GSFTrackParticles", 0x2e42db0b},
118 {
"InDetForwardTrackParticles", 0x143c6846},
119 {
"MuonSpectrometerTrackParticles", 0x3993c8f3},
163 else if (
columnName.find (
".") != std::string::npos)
164 throw std::runtime_error (
"branch name does not contain AuxDyn or Aux: " +
m_branchName);
177 throw std::runtime_error (
"branch name does not contain AuxDyn or Aux: " +
m_branchName);
184 throw std::runtime_error (
"failed to get branch: " +
m_branchName);
195 throw std::runtime_error (
"branch not connected: " +
m_branchName);
199 throw std::runtime_error (
"got nullptr reading data for branch: " +
m_branchName);
232 else if (
columnName.find (
".") != std::string::npos)
233 throw std::runtime_error (
"branch name does not contain AuxDyn or Aux: " +
m_branchName);
246 throw std::runtime_error (
"branch name does not contain AuxDyn or Aux: " +
m_branchName);
253 throw std::runtime_error (
"failed to get branch: " +
m_branchName);
262 throw std::runtime_error (
"branch not connected: " +
m_branchName);
300 std::array<ColumnarOffsetType, 2>
data = {0, 0};
307 virtual bool connect (TTree * , std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& , std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
345 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
350 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& , std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
353 if (
iter == requestedColumns.end())
356 requestedColumns.erase (
iter);
370 benchmark.startTimer ();
372 benchmark.stopTimer ();
373 benchmarkUnpack.startTimer ();
374 outData.push_back (branchData);
375 benchmarkUnpack.stopTimer ();
389 const std::vector<ColumnarOffsetType>* offsetColumn =
nullptr;
390 std::vector<ColumnarOffsetType> offsets = {0};
396 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
402 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
405 if (
iter == requestedColumns.end())
412 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
414 requestedColumns.erase (
iter);
416 if (
auto offsetIter = offsetColumns.find (
outputColumns.at(1).name); offsetIter != offsetColumns.end())
417 offsetColumn = offsetIter->second;
422 if (
iter != requestedColumns.end())
424 requestedColumns.erase (
iter);
434 offsets.push_back (0);
440 benchmark.startTimer ();
442 benchmark.stopTimer ();
443 benchmarkUnpack.startTimer ();
444 outData.insert (outData.end(), branchData.begin(), branchData.end());
445 offsets.push_back (outData.size());
446 benchmarkUnpack.stopTimer ();
457 if (offsetColumn->size() != offsets.size())
458 throw std::runtime_error (
"offset column not filled yet: " +
outputColumns.at(1).name);
459 if (offsetColumn->back() != offsets.back())
460 throw std::runtime_error (
"offset column does not match: " +
outputColumns.at(1).name);
469 const std::vector<ColumnarOffsetType>* offsetColumn =
nullptr;
473 : defaultValue (val_defaultValue)
478 virtual bool connect (TTree * , std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
481 if (
iter == requestedColumns.end())
487 const auto offsetName =
iter->second.offsetName;
488 if (offsetName.empty())
489 throw std::runtime_error (
"missing offset column for: " +
outputColumns.at(0).name);
491 requestedColumns.erase (
iter);
493 if (
auto offsetIter = offsetColumns.find (offsetName); offsetIter != offsetColumns.end())
494 offsetColumn = offsetIter->second;
496 throw std::runtime_error (
"missing offset column for: " +
outputColumns.at(0).name);
507 outData.resize (offsetColumn->back(), defaultValue);
521 std::vector<ColumnarOffsetType> offsets = {0};
527 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
533 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& , std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
536 if (
iter == requestedColumns.end())
543 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
545 requestedColumns.erase (
iter);
548 if (
iter == requestedColumns.end())
550 requestedColumns.erase (
iter);
559 offsets.push_back (0);
564 benchmark.startTimer ();
566 benchmark.stopTimer ();
567 benchmarkUnpack.startTimer ();
568 for (
auto&
data : branchData)
570 columnData.insert (columnData.end(),
data.begin(),
data.end());
571 offsets.push_back (columnData.size());
573 benchmarkUnpack.stopTimer ();
590 std::vector<ColumnarOffsetType> offsets = {0};
592 const std::vector<ColumnarOffsetType>* targetOffsetColumn =
nullptr;
599 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
605 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
608 if (
iter == requestedColumns.end())
615 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
617 targetContainerName =
iter->second.linkToName;
618 if (
auto keyIter = knownKeys.find (targetContainerName); keyIter != knownKeys.end())
619 targetKey = keyIter->second;
620 if (
auto offsetIter = offsetColumns.find (
iter->second.linkToName); offsetIter != offsetColumns.end())
621 targetOffsetColumn = offsetIter->second;
623 throw std::runtime_error (
"missing offset column: " +
iter->second.linkToName);
625 requestedColumns.erase (
iter);
628 if (
iter == requestedColumns.end())
630 requestedColumns.erase (
iter);
639 offsets.push_back (0);
644 benchmark.startTimer ();
646 benchmark.stopTimer ();
647 benchmarkUnpack.startTimer ();
648 if (targetOffsetColumn->size() < 2)
649 throw std::runtime_error (
"target offset column not yet filled for: " +
outputColumns.at(0).name);
650 for (
auto&
data : branchData)
652 for (
auto& element :
data)
654 if (element.isDefault() || (element.key() == 0 && element.index() == 0))
658 columnData.push_back (element.index() + targetOffsetColumn->at (targetOffsetColumn->size()-2));
659 if (element.key() != targetKey)
663 targetKey = element.key();
664 std::cout <<
"assume target key for " << targetContainerName <<
" is " << std::hex << targetKey << std::dec << std::endl;
667 throw std::runtime_error(
668 std::format(
"target key mismatch: {:x} != {:x} for {} with element index {}",
669 element.key(), targetKey,
outputColumns.at(0).name, element.index())
675 offsets.push_back (columnData.size());
677 benchmarkUnpack.stopTimer ();
694 std::vector<ColumnarOffsetType> outerOffsets = {0};
695 std::vector<ColumnarOffsetType> innerOffsets = {0};
701 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
708 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& , std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
711 if (
iter == requestedColumns.end())
718 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
720 requestedColumns.erase (
iter);
723 if (
iter == requestedColumns.end())
728 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(2).name);
730 requestedColumns.erase (
iter);
733 if (
iter == requestedColumns.end())
736 requestedColumns.erase (
iter);
743 innerOffsets.clear();
744 innerOffsets.push_back (0);
745 outerOffsets.clear();
746 outerOffsets.push_back (0);
751 benchmark.startTimer ();
753 benchmark.stopTimer ();
754 benchmarkUnpack.startTimer ();
755 for (
auto& outerData : branchData)
757 for (
auto& innerData : outerData)
759 columnData.insert (columnData.end(), innerData.begin(), innerData.end());
760 innerOffsets.push_back (columnData.size());
762 outerOffsets.push_back (innerOffsets.size()-1);
764 benchmarkUnpack.stopTimer ();
772 tool.setColumn (
outputColumns.at(1).name, innerOffsets.size(), innerOffsets.data());
774 tool.setColumn (
outputColumns.at(2).name, outerOffsets.size(), outerOffsets.data());
783 const std::vector<ColumnarOffsetType>* offsetColumn =
nullptr;
784 std::vector<ColumnarOffsetType> offsets = {0};
786 const std::vector<ColumnarOffsetType>* targetOffsetColumn =
nullptr;
793 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
799 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
802 if (
iter == requestedColumns.end())
809 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
811 targetContainerName =
iter->second.linkToName;
812 if (
auto keyIter = knownKeys.find (targetContainerName); keyIter != knownKeys.end())
813 targetKey = keyIter->second;
814 if (
auto targetOffsetIter = offsetColumns.find (
iter->second.linkToName); targetOffsetIter != offsetColumns.end())
815 targetOffsetColumn = targetOffsetIter->second;
817 throw std::runtime_error (
"missing offset column: " +
iter->second.linkToName);
819 requestedColumns.erase (
iter);
821 if (
auto offsetIter = offsetColumns.find (
outputColumns.at(1).name); offsetIter != offsetColumns.end())
822 offsetColumn = offsetIter->second;
827 if (
iter != requestedColumns.end())
830 requestedColumns.erase (
iter);
840 offsets.push_back (0);
845 benchmark.startTimer ();
847 benchmark.stopTimer ();
848 benchmarkUnpack.startTimer ();
849 if (targetOffsetColumn->size() < 2)
850 throw std::runtime_error (
"target offset column not yet filled for: " +
outputColumns.at(0).name);
851 for (
auto& element : branchData)
853 if (element.isDefault())
857 columnData.push_back (element.index() + targetOffsetColumn->at (targetOffsetColumn->size()-2));
858 if (element.key() != targetKey)
862 targetKey = element.key();
863 std::cout <<
"assume target key for " << targetContainerName <<
" is " << std::hex << targetKey << std::dec << std::endl;
871 offsets.push_back (columnData.size());
874 if (offsetColumn->size() != offsets.size())
875 throw std::runtime_error (
"offset column not filled yet: " +
outputColumns.at(1).name);
876 if (offsetColumn->back() != offsets.back())
877 throw std::runtime_error (
"offset column does not match: " +
outputColumns.at(1).name);
879 benchmarkUnpack.stopTimer ();
898 const std::vector<ColumnarOffsetType>* offsetColumn =
nullptr;
899 std::vector<ColumnarOffsetType> offsets = {0};
908 : branchReaderSize (val_branchName), branchReaderKey (val_branchName +
".m_persKey"), branchReaderIndex (val_branchName +
".m_persIndex"), benchmarkUnpack (branchReaderSize.columnName()+
"(unpack)"), benchmark (branchReaderSize.columnName())
915 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
918 if (
iter == requestedColumns.end())
927 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
929 auto linkContainers =
iter->second.variantLinkContainers;
930 if (linkContainers.empty())
932 if (
iter->second.linkToName.empty())
933 throw std::runtime_error (
"missing link container for: " +
outputColumns.at(0).name);
934 linkContainers.push_back (
iter->second.linkToName);
937 if (!
iter->second.linkToName.empty())
938 throw std::runtime_error (
"link container and variant link containers both set for: " +
outputColumns.at(0).name);
940 for (
const auto& container : linkContainers)
942 if (
auto keyIter = knownKeys.find (container); keyIter != knownKeys.end())
943 targetKeys.push_back (keyIter->second);
945 throw std::runtime_error (
"no key known for link container: " + container);
946 if (
auto targetOffsetIter = offsetColumns.find (container); targetOffsetIter != offsetColumns.end())
947 targetOffsetColumns.push_back (targetOffsetIter->second);
949 throw std::runtime_error (
"missing offset column: " + container);
950 keyColumnData.push_back (keyColumnData.size());
952 requestedColumns.erase (
iter);
954 if (
auto offsetIter = offsetColumns.find (
outputColumns.at(1).name); offsetIter != offsetColumns.end())
955 offsetColumn = offsetIter->second;
960 if (
iter != requestedColumns.end())
963 requestedColumns.erase (
iter);
967 if (
iter != requestedColumns.end())
970 requestedColumns.erase (
iter);
980 offsets.push_back (0);
985 benchmark.startTimer ();
986 std::size_t branchDataSize = branchReaderSize.
getEntry (
entry);
987 auto branchDataKey = branchReaderKey.
getEntry (
entry, branchDataSize);
988 auto branchDataIndex = branchReaderIndex.
getEntry (
entry, branchDataSize);
989 benchmark.stopTimer ();
990 benchmarkUnpack.startTimer ();
991 for (
auto& targetOffsetColumn : targetOffsetColumns)
993 if (targetOffsetColumn->size() <= offsets.size())
994 throw std::runtime_error (
"target offset column not yet filled for: " +
outputColumns.at(0).name);
998 if (branchDataIndex[
index] ==
static_cast<UInt_t
>(-1))
1003 if (
auto keyIter =
std::find(targetKeys.begin(), targetKeys.end(), branchDataKey[
index]); keyIter != targetKeys.end())
1006 }
else if (targetKeys.empty())
1008 targetKeys.push_back (branchDataKey[
index]);
1010 std::cout <<
"assume target key for " <<
outputColumns.at(0).name <<
" is " << std::hex << branchDataKey[
index] << std::dec << std::endl;
1013 std::ostringstream
error;
1014 error <<
"target key mismatch: read " << std::hex << branchDataKey[
index];
1015 error <<
", expected one of";
1016 for (
const auto&
key : targetKeys)
1019 throw std::runtime_error (std::move (
error).
str());
1021 auto& targetOffsetColumn = *targetOffsetColumns.at(keyIndex);
1022 auto targetOffset = targetOffsetColumn.at (offsets.size()-1);
1025 if (
linkIndex >= targetOffsetColumn.at(offsets.size()))
1026 throw std::runtime_error (
std::format (
"index out of range for link: {} >= {} (base index {})",
outputColumns.at(0).name,
linkIndex, targetOffsetColumn.at(offsets.size()), targetOffset));
1027 columnData.push_back (CM::mergeLinkKeyIndex (keyIndex, branchDataIndex[
index] + targetOffset));
1030 offsets.push_back (columnData.size());
1033 if (offsetColumn->size() != offsets.size())
1034 throw std::runtime_error (
"offset column not filled yet: " +
outputColumns.at(1).name);
1035 if (offsetColumn->back() != offsets.back())
1036 throw std::runtime_error (
"offset column does not match: " +
outputColumns.at(1).name);
1038 benchmarkUnpack.stopTimer ();
1044 tool.setColumn (
outputColumns.at(0).name, columnData.size(), columnData.data());
1048 tool.setColumn (
outputColumns.at(2).name, keyColumnData.size(), keyColumnData.data());
1052 template<
typename T>
1057 std::vector<ColumnarOffsetType> offsets = {0};
1066 bool checkUnknownKeys =
false;
1067 std::unordered_map<SG::sgkey_t,std::unordered_set<std::string>>
unknownKeys;
1070 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
1082 for (
auto& [
key, forbiddenContainer] : unknownKeys)
1084 std::cout <<
"unknown key: " << std::hex <<
key << std::dec <<
", allowed containers:";
1087 if (forbiddenContainer.find (container) == forbiddenContainer.end())
1088 std::cout <<
" " << container;
1090 std::cout << std::endl;
1094 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
1097 if (
iter == requestedColumns.end())
1104 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
1106 if (
containers.empty() ||
iter->second.variantLinkKeyColumn.empty())
1107 throw std::runtime_error (
"no variant link containers for: " +
outputColumns.at(0).name);
1109 throw std::runtime_error (
"variant link key column mismatch: " +
iter->second.variantLinkKeyColumn +
" != " +
outputColumns.at(2).name);
1111 for ([[maybe_unused]]
auto& container :
containers)
1113 keysColumn.push_back (keysColumn.size()+1);
1114 containerOffsets.push_back (offsetColumns.at (container));
1115 if (
auto iter = knownKeys.find (container);
iter != knownKeys.end())
1117 containerKeys.push_back (
iter->second);
1120 checkUnknownKeys =
true;
1121 containerKeys.push_back (0
u);
1125 requestedColumns.erase (
iter);
1128 if (
iter != requestedColumns.end())
1131 requestedColumns.erase (
iter);
1135 if (
iter != requestedColumns.end())
1138 requestedColumns.erase (
iter);
1147 offsets.push_back (0);
1152 benchmark.startTimer ();
1154 benchmark.stopTimer ();
1155 benchmarkUnpack.startTimer ();
1156 for (
auto&
data : branchData)
1158 for (
auto& element :
data)
1160 if (element.isDefault())
1168 if (element.key() == containerKeys[
i])
1170 if (containerOffsets[
i]->back() <= element.index())
1172 key = keysColumn[
i];
1173 if (containerOffsets[
i]->
size() < 2)
1174 throw std::runtime_error (
"container offset not yet filled for: " +
containers[
i]);
1175 index = containerOffsets[
i]->at (containerOffsets[
i]->
size()-2) + element.index();
1179 if (
key == 0xff && checkUnknownKeys)
1184 auto& forbiddenContainers = unknownKeys[element.key()];
1187 if (containerOffsets[
i]->back() <= containerOffsets[
i]->at (containerOffsets[
i]->
size()-2) + element.index())
1191 columnData.push_back (CM::mergeLinkKeyIndex (
key,
index));
1194 offsets.push_back (columnData.size());
1196 benchmarkUnpack.stopTimer ();
1202 tool.setColumn (
outputColumns.at(0).name, columnData.size(), columnData.data());
1206 tool.setColumn (
outputColumns.at(2).name, keysColumn.size(), keysColumn.data());
1213 std::vector<ColumnarOffsetType> offsets = {0};
1220 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
"(unpack)"), benchmark (branchReader.columnName())
1227 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& , std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
1230 if (
iter == requestedColumns.end())
1237 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
1239 requestedColumns.erase (
iter);
1242 if (
iter == requestedColumns.end())
1247 requestedColumns.erase (
iter);
1250 if (
iter != requestedColumns.end())
1253 requestedColumns.erase (
iter);
1262 offsets.push_back (0);
1263 columnHashData.clear();
1268 benchmark.startTimer ();
1270 benchmark.stopTimer ();
1271 benchmarkUnpack.startTimer ();
1272 for (
auto&
data : branchData)
1274 columnData.insert (columnData.end(),
data.begin(),
data.end());
1275 offsets.push_back (columnData.size());
1276 columnHashData.push_back (std::hash<std::string> () (
data));
1278 benchmarkUnpack.stopTimer ();
1284 tool.setColumn (
outputColumns.at(0).name, columnData.size(), columnData.data());
1288 tool.setColumn (
outputColumns.at(2).name, columnHashData.size(), columnHashData.data());
1295 const std::vector<ColumnarOffsetType>* offsetColumns =
nullptr;
1296 std::vector<ColumnarOffsetType> offsets = {0};
1297 std::vector<ColumnarOffsetType> namesOffsets = {0};
1302 : termNames (std::move (val_termNames))
1304 outputColumns.push_back ({.name = val_columnName, .isOffset =
true});
1305 outputColumns.push_back ({.name = val_columnName +
".name.data"});
1306 outputColumns.push_back ({.name = val_columnName +
".name.offset", .isOffset =
true});
1307 outputColumns.push_back ({.name = val_columnName +
".nameHash"});
1310 virtual bool connect (TTree * , std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
1313 iter != requestedColumns.end())
1314 requestedColumns.erase (
iter);
1320 iter != requestedColumns.end())
1323 requestedColumns.erase (
iter);
1327 iter != requestedColumns.end())
1330 requestedColumns.erase (
iter);
1334 iter != requestedColumns.end())
1337 requestedColumns.erase (
iter);
1340 if (
auto offsetIter = offsetColumns.find (
outputColumns.at(0).name); offsetIter != offsetColumns.end())
1341 throw std::runtime_error (
"duplicate size column: " +
outputColumns.at(0).name);
1350 offsets.push_back (0);
1352 namesOffsets.clear ();
1353 namesOffsets.push_back (0);
1359 for (
const auto& termName : termNames)
1361 namesData.insert (namesData.end(), termName.begin(), termName.end());
1362 namesOffsets.push_back (namesData.size());
1363 namesHash.push_back (std::hash<std::string> () (termName));
1365 offsets.push_back (namesHash.size());
1375 tool.setColumn (
outputColumns.at(2).name, namesOffsets.size(), namesOffsets.data());
1384 std::vector<ColumnarOffsetType> offsets = {0};
1390 : branchReader (val_branchName), benchmarkUnpack (branchReader.columnName()+
".samplingPattern(fallback)(unpack)"), benchmark (branchReader.columnName() +
".samplingPattern(fallback)")
1396 virtual bool connect (TTree *
tree, std::unordered_map<std::string,
const std::vector<ColumnarOffsetType>*>& , std::unordered_map<std::string,ColumnInfo>& requestedColumns)
override
1399 if (
iter == requestedColumns.end())
1406 throw std::runtime_error (
"offset name mismatch: " +
iter->second.offsetName +
" != " +
outputColumns.at(1).name);
1408 requestedColumns.erase (
iter);
1411 if (
iter == requestedColumns.end())
1416 requestedColumns.erase (
iter);
1424 offsets.push_back (0);
1429 benchmark.startTimer ();
1431 benchmark.stopTimer ();
1432 benchmarkUnpack.startTimer ();
1433 for (
auto data : branchData)
1435 columnData.push_back (
data->samplingPattern());
1437 offsets.push_back (columnData.size());
1438 benchmarkUnpack.stopTimer ();
1444 tool.setColumn (
outputColumns.at(0).name, columnData.size(), columnData.data());
1455 static std::once_flag
flag;
1456 std::call_once (
flag, [] ()
1458 #ifdef XAOD_STANDALONE
1467 throw std::runtime_error (
"missing ASG_TEST_FILE_LITE_MC");
1470 throw std::runtime_error (
"failed to open file");
1471 tree =
dynamic_cast<TTree*
> (
file->Get (
"CollectionTree"));
1473 throw std::runtime_error (
"failed to open tree");
1480 static std::atomic<unsigned>
index = 0;
1492 using namespace PhysliteTestHelpers;
1494 knownColumns.push_back (std::make_shared<ColumnDataEventCount> ());
1496 tree->SetMakeClass (1);
1498 std::unordered_map<std::string,TBranch*>
branches;
1500 TIter branchIter (
tree->GetListOfBranches());
1501 TObject *
obj =
nullptr;
1502 while ((
obj = branchIter()))
1504 TBranch *
branch =
nullptr;
1505 if ((
branch =
dynamic_cast<TBranch*
>(
obj)))
1508 TIter subBranchIter (
branch->GetListOfBranches());
1509 while ((
obj = subBranchIter()))
1511 if (
auto subBranch =
dynamic_cast<TBranch*
>(
obj))
1512 branches.emplace (subBranch->GetName(), subBranch);
1520 if (
name.find (
"AuxDyn.") != std::string::npos ||
1521 name.find (
"Aux.") != std::string::npos)
1523 TClass *branchClass =
nullptr;
1524 EDataType branchType {};
1525 branch->GetExpectedType (branchClass, branchType);
1526 if (branchClass ==
nullptr)
1531 knownColumns.push_back (std::make_shared<ColumnDataScalar<std::int32_t>> (
branch->GetName()));
1534 knownColumns.push_back (std::make_shared<ColumnDataScalar<std::uint32_t>> (
branch->GetName()));
1537 knownColumns.push_back (std::make_shared<ColumnDataScalar<std::uint64_t>> (
branch->GetName()));
1540 knownColumns.push_back (std::make_shared<ColumnDataScalar<std::uint64_t>> (
branch->GetName()));
1543 knownColumns.push_back (std::make_shared<ColumnDataScalar<float>> (
branch->GetName()));
1551 if (*branchClass->GetTypeInfo() ==
typeid(std::vector<float>))
1553 knownColumns.push_back (std::make_shared<ColumnDataVector<float>> (
branch->GetName()));
1554 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<char>))
1556 knownColumns.push_back (std::make_shared<ColumnDataVector<char>> (
branch->GetName()));
1557 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::int8_t>))
1559 knownColumns.push_back (std::make_shared<ColumnDataVector<std::int8_t>> (
branch->GetName()));
1560 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::uint8_t>))
1562 knownColumns.push_back (std::make_shared<ColumnDataVector<std::uint8_t>> (
branch->GetName()));
1563 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::int16_t>))
1565 knownColumns.push_back (std::make_shared<ColumnDataVector<std::int16_t>> (
branch->GetName()));
1566 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::uint16_t>))
1568 knownColumns.push_back (std::make_shared<ColumnDataVector<std::uint16_t>> (
branch->GetName()));
1569 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::int32_t>))
1571 knownColumns.push_back (std::make_shared<ColumnDataVector<std::int32_t>> (
branch->GetName()));
1572 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::uint32_t>))
1574 knownColumns.push_back (std::make_shared<ColumnDataVector<std::uint32_t>> (
branch->GetName()));
1575 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::int64_t>))
1577 knownColumns.push_back (std::make_shared<ColumnDataVector<std::int64_t>> (
branch->GetName()));
1578 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::uint64_t>))
1580 knownColumns.push_back (std::make_shared<ColumnDataVector<std::uint64_t>> (
branch->GetName()));
1581 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::vector<float>>))
1583 knownColumns.push_back (std::make_shared<ColumnDataVectorVector<float>> (
branch->GetName()));
1584 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::vector<std::int32_t>>))
1586 knownColumns.push_back (std::make_shared<ColumnDataVectorVector<std::int32_t>> (
branch->GetName()));
1587 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::vector<std::uint64_t>>))
1589 knownColumns.push_back (std::make_shared<ColumnDataVectorVector<std::uint64_t>> (
branch->GetName()));
1590 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::vector<std::vector<std::size_t>>>))
1592 knownColumns.push_back (std::make_shared<ColumnDataVectorVectorVector<std::size_t>> (
branch->GetName()));
1593 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::vector<std::vector<unsigned char>>>))
1595 knownColumns.push_back (std::make_shared<ColumnDataVectorVectorVector<unsigned char>> (
branch->GetName()));
1596 }
else if (*branchClass->GetTypeInfo() ==
typeid(std::vector<std::string>))
1598 knownColumns.push_back (std::make_shared<ColumnDataMetNames> (
branch->GetName()));
1610 knownColumns.push_back (std::make_shared<ColumnDataSamplingPattern> (
"egammaClusters"));
1615 knownColumns.push_back (std::make_shared<ColumnDataVectorVectorLink<xAOD::CaloClusterContainer>> (
"AnalysisElectronsAuxDyn.caloClusterLinks"));
1616 knownColumns.push_back (std::make_shared<ColumnDataVectorVectorLink<xAOD::CaloClusterContainer>> (
"AnalysisPhotonsAuxDyn.caloClusterLinks"));
1617 knownColumns.push_back (std::make_shared<ColumnDataVectorVectorLink<xAOD::VertexContainer>> (
"AnalysisPhotonsAuxDyn.vertexLinks"));
1618 knownColumns.push_back (std::make_shared<ColumnDataVectorSplitLink<xAOD::TrackParticleContainer>> (
"AnalysisMuonsAuxDyn.inDetTrackParticleLink"));
1619 knownColumns.push_back (std::make_shared<ColumnDataVectorSplitLink<xAOD::TrackParticleContainer>> (
"AnalysisMuonsAuxDyn.combinedTrackParticleLink"));
1620 knownColumns.push_back (std::make_shared<ColumnDataVectorSplitLink<xAOD::TrackParticleContainer>> (
"AnalysisMuonsAuxDyn.extrapolatedMuonSpectrometerTrackParticleLink"));
1621 knownColumns.push_back (std::make_shared<ColumnDataVectorVectorLink<xAOD::TrackParticleContainer>> (
"GSFConversionVerticesAuxDyn.trackParticleLinks"));
1622 knownColumns.push_back (std::make_shared<ColumnDataVectorLink<xAOD::JetContainer>>(
"METAssoc_AnalysisMETAux.jetLink"));
1623 knownColumns.push_back (std::make_shared<ColumnDataVectorVectorVariantLink<xAOD::IParticleContainer>>(
"METAssoc_AnalysisMETAux.objectLinks"));
1627 knownColumns.push_back (std::make_shared<ColumnDataOutputMet> (
"OutputMET", std::vector<std::string>{
"Muons",
"RefJet",
"MuonEloss",
"PVSoftTrk"}));
1631 knownColumns.push_back (std::make_shared<ColumnDataOutVector<std::uint16_t>> (
"AnalysisMuons.objectType",
xAOD::Type::Muon));
1633 knownColumns.push_back (std::make_shared<ColumnDataOutVector<std::uint16_t>> (
"AnalysisJets.objectType",
xAOD::Type::Jet));
1638 knownColumns.push_back (std::make_shared<ColumnDataOutVector<float>> (
"AnalysisMuons.MetObjectWeight", 0));
1639 knownColumns.push_back (std::make_shared<ColumnDataOutVector<float>> (
"AnalysisJets.MetObjectWeight", 0));
1640 knownColumns.push_back (std::make_shared<ColumnDataOutVector<float>> (
"AnalysisJets.MetObjectWeightSoft", 0));
1641 knownColumns.push_back (std::make_shared<ColumnDataOutVector<MissingETBase::Types::bitmask_t>> (
"METAssoc_AnalysisMET.useObjectFlags", 0));
1646 using namespace asg::msgUserCode;
1648 std::unordered_map<std::string,ColumnInfo> requestedColumns;
1653 std::cout <<
"requested columns: " <<
name << std::endl;
1655 for (
auto&
column : knownColumns)
1657 if (
column->connect (
tree, offsetColumns, requestedColumns))
1658 usedColumns.push_back (
column);
1661 std::set<std::string> unclaimedColumns;
1662 for (
auto&
column : requestedColumns)
1664 if (!
column.second.isOptional)
1665 unclaimedColumns.insert (
column.first);
1667 std::cout <<
"optional column not claimed: " <<
column.first << std::endl;
1669 std::erase_if (unclaimedColumns, [&] (
auto& columnName)
1671 const auto&
info = requestedColumns.at (columnName);
1674 auto offsetIter = std::find_if (usedColumns.begin(), usedColumns.end(), [&] (
const std::shared_ptr<PhysliteTestHelpers::IColumnData>&
column)
1676 for (auto& output : column->outputColumns)
1678 if (output.name == info.offsetName)
1683 if (offsetIter == usedColumns.end())
1685 std::shared_ptr<PhysliteTestHelpers::IColumnData> myColumn;
1686 if (*
info.type ==
typeid(
float))
1688 else if (*
info.type ==
typeid(
char))
1696 ANA_MSG_WARNING (
"unhandled column type: " << info.name <<
" " << info.type->name());
1699 knownColumns.push_back (myColumn);
1700 if (!myColumn->connect (
tree, offsetColumns, requestedColumns))
1702 ANA_MSG_WARNING (
"failed to connect dynamic output column: " << info.name);
1705 usedColumns.push_back (myColumn);
1708 if (!unclaimedColumns.empty())
1710 std::string
message =
"columns not claimed:";
1711 for (
auto&
column : unclaimedColumns)
1713 throw std::runtime_error (
message);
1719 using namespace asg::msgUserCode;
1725 throw std::runtime_error (
"tool does not support systematics");
1726 std::cout <<
"applying systematic variation: " <<
sysName << std::endl;
1728 throw std::runtime_error (
"failed to apply systematic variation: " +
sysName);
1733 if (!containerRenames.empty())
1737 setupKnownColumns ();
1738 setupColumns (toolWrapper);
1740 Benchmark benchmark (
name);
1742 const std::vector<ColumnarOffsetType>* offsetColumn =
nullptr;
1743 if (!container.empty())
1745 auto iter = offsetColumns.find (container);
1746 if (
iter == offsetColumns.end())
1747 throw std::runtime_error (
"missing size column: " + container);
1748 offsetColumn =
iter->second;
1751 const auto numberOfEvents =
tree->GetEntries();
1754 for (; benchmark.getTotalTime() < targetTime; ++
entry)
1757 for (
auto&
column : usedColumns)
1761 if (
entry + 1 == numberOfEvents)
1762 std::cout <<
"average size: " <<
float (
totalSize + offsetColumn->back()) / numberOfEvents << std::endl;
1764 if ((
entry + 1) % batchSize == 0)
1768 for (
auto&
column : usedColumns)
1769 column->setData (columnData);
1770 benchmark.startTimer ();
1772 benchmark.stopTimer ();
1773 for (
auto&
column : usedColumns)
1777 std::cout <<
"Total entries read: " <<
entry << std::endl;
1781 #ifdef XAOD_STANDALONE
1789 #ifdef XAOD_STANDALONE
1790 Benchmark benchmarkEmptyClear (
name +
" empty clear");
1791 Benchmark benchmarkCallClear (
name +
" call clear");
1792 Benchmark benchmarkPrepClear (
name +
" prep clear");
1794 Benchmark benchmarkCall (
name +
" call");
1795 Benchmark benchmarkPrep (
name +
" prep");
1796 Benchmark benchmarkGetEntry (
name +
" getEntry");
1798 const auto numberOfEvents =
event.getEntries();
1799 #ifdef XAOD_STANDALONE
1800 std::cout <<
"known container keys:" << std::endl;
1801 for (
auto& [container,
key] : columnar::PhysliteTestHelpers::knownKeys)
1803 std::cout <<
std::format (
" {} -> 0x{:x}, 0x{:x} -> {}", container,
event.getHash (container),
key,
event.getName (
key)) << std::endl;
1806 if (numberOfEvents == 0){
1807 throw std::runtime_error (
"ColumnarPhysLiteTest: numberOfEvents == 0");
1818 for (; benchmarkCall.getTotalTime() < targetTime && benchmarkPrep.getTotalTime() + benchmarkGetEntry.getTotalTime() < 20 * targetTime; ++
entry)
1820 benchmarkGetEntry.startTimer ();
1821 event.getEntry (
entry % numberOfEvents);
1822 benchmarkGetEntry.stopTimer ();
1824 args.inputContainer = container;
1825 args.outputContainer = container +
"Copy1";
1826 args.isPrepCall =
true;
1827 benchmarkPrep.startTimer ();
1829 benchmarkPrep.stopTimer ();
1830 args.outputContainer = container +
"Copy2";
1831 args.isPrepCall =
false;
1832 #ifdef XAOD_STANDALONE
1833 benchmarkPrepClear.startTimer ();
1835 benchmarkPrepClear.stopTimer ();
1837 benchmarkCall.startTimer ();
1839 benchmarkCall.stopTimer ();
1840 #ifdef XAOD_STANDALONE
1841 benchmarkCallClear.startTimer ();
1843 benchmarkCallClear.stopTimer ();
1844 benchmarkEmptyClear.startTimer ();
1846 benchmarkEmptyClear.stopTimer ();
1849 std::cout <<
"Total entries read: " <<
entry << std::endl;