2022 {
2023 using namespace asg::msgUserCode;
2025
2026 if (!testDefinition.sysName.empty())
2027 {
2028 auto *sysTool = dynamic_cast<CP::ISystematicsTool*>(testDefinition.tool);
2029 if (!sysTool)
2030 throw std::runtime_error ("tool does not support systematics");
2031 std::cout << "applying systematic variation: " << testDefinition.sysName << std::endl;
2032 if (sysTool->applySystematicVariation (CP::SystematicSet (testDefinition.sysName)).isFailure())
2033 throw std::runtime_error ("failed to apply systematic variation: " + testDefinition.sysName);
2034 }
2036 {
2037 auto *myTool = dynamic_cast<ColumnarTool<ColumnarModeArray>*>(testDefinition.tool);
2038 if (!testDefinition.containerRenames.empty())
2040 ColumnVectorHeader columnHeader;
2041 ToolColumnVectorMap toolWrapper (columnHeader, *myTool);
2042
2045
2046 Benchmark benchmarkCall (testDefinition.name, userConfiguration.batchSize);
2047 Benchmark benchmarkCall2 (testDefinition.name + "(call2)", userConfiguration.batchSize);
2048 Benchmark benchmarkCheck (testDefinition.name + "(column check)", userConfiguration.batchSize);
2049 Benchmark benchmarkEmpty ("empty");
2050
2053 const auto startTime = std::chrono::high_resolution_clock::now();
2054 bool endLoop = false;
2055 for (; !endLoop; ++
entry)
2056 {
2057
2058
2059 benchmarkEmpty.startTimer ();
2060 benchmarkEmpty.stopTimer ();
2061
2062 ColumnVectorData columnData (&columnHeader);
2063 TestUtils::ToolWrapperData toolColumnData (&columnData, &toolWrapper);
2066 if ((entry + 1) % userConfiguration.batchSize == 0)
2067 {
2069 {
2071 column->collectColumnData ();
2072 }
2074 column->setData (toolColumnData);
2075 benchmarkCheck.startTimer ();
2076 columnData.checkData ();
2077 benchmarkCheck.stopTimer ();
2078 benchmarkCall.startTimer ();
2079 columnData.callNoCheck (*myTool);
2080 benchmarkCall.stopTimer ();
2081 if (userConfiguration.runToolTwice)
2082 {
2083 benchmarkCall2.startTimer ();
2084 columnData.callNoCheck (*myTool);
2085 benchmarkCall2.stopTimer ();
2086 }
2089 if ((std::chrono::high_resolution_clock::now() - startTime) > userConfiguration.targetTime)
2090 endLoop = true;
2092 {
2094 column->collectColumnData ();
2095 }
2096 }
2098 std::cout <<
"Total entries read: " <<
entry << std::endl;
2099 const float emptyTime = benchmarkEmpty.getEntryTime(0).value();
2100 std::cout << "Empty benchmark time: " << emptyTime << "ns" << std::endl;
2101 benchmarkEmpty.setSilence();
2102 {
2103 std::vector<TestUtils::BranchPerfData> branchPerfData;
2104 TestUtils::BranchPerfData
summary;
2109 summary.entries = std::nullopt;
2110 summary.nullEntries = std::nullopt;
2112 {
2113 branchPerfData.push_back (
column->getPerfData (emptyTime));
2114 summary.timeRead.value() += branchPerfData.back().timeRead.value_or(0);
2115 summary.timeUnpack.value() += branchPerfData.back().timeUnpack.value_or(0);
2116 summary.timeShallowCopy.value() += branchPerfData.back().timeShallowCopy.value_or(0);
2117 }
2118 std::sort (branchPerfData.begin(), branchPerfData.end(), [] (
const auto&
a,
const auto& b) {return a.name < b.name;});
2119 branchPerfData.insert (branchPerfData.end(), summary);
2120 const std::size_t nameWidth = std::max_element (branchPerfData.begin(), branchPerfData.end(), [] (
const auto&
a,
const auto& b) {return a.name.size() < b.name.size();})->name.size();
2121 std::string
header = std::format (
"{:{}} | read(ns) | unpack(ns) | size(B) | rate(MB/s) | compression | baskets | entries | null",
"branch name", nameWidth);
2122 std::cout <<
"\n" <<
header << std::endl;
2123 std::cout << std::string (
header.size(),
'-') << std::endl;
2124 for (
auto&
data : branchPerfData)
2125 {
2126 if (
data.name ==
"total")
2127 std::cout << std::string (
header.size(),
'-') << std::endl;
2128 std::cout << std::format (
"{:{}} |",
data.name, nameWidth);
2130 std::cout << std::format (
"{:>9.0f} |",
data.timeRead.value());
2131 else
2132 std::cout << " |";
2133 if (
data.timeUnpack)
2134 std::cout << std::format (
"{:>11.1f} |",
data.timeUnpack.value());
2135 else
2136 std::cout << " |";
2138 std::cout << std::format (
"{:>8.1f} |",
data.entrySize.value());
2139 else
2140 std::cout << " |";
2141 if (
data.timeRead &&
data.entrySize)
2142 std::cout << std::format (
"{:>11.1f} |", (
data.entrySize.value() / (
data.timeRead.value() * 1e-3 * 1.024 * 1.024)));
2143 else
2144 std::cout << " |";
2145 if (
data.entrySize &&
data.uncompressedSize)
2146 std::cout << std::format (
"{:>12.2f} |",
float (
data.uncompressedSize.value()) /
data.entrySize.value());
2147 else
2148 std::cout << " |";
2149 if (
data.numBaskets)
2150 std::cout << std::format (
"{:>8} |",
data.numBaskets.value());
2151 else
2152 std::cout << " |";
2154 std::cout << std::format (
"{:>8.2f} |",
static_cast<float>(
data.entries.value())/
numberOfEvents);
2155 else
2156 std::cout << " |";
2157 if (
data.nullEntries &&
data.entries)
2158 std::cout << std::format (
"{:>4.0f}%",
static_cast<float>(
data.nullEntries.value()) /
data.entries.value() * 100.0f);
2159 std::cout << std::endl;
2160 }
2161 }
2162 {
2163 std::vector<TestUtils::ToolPerfData> toolPerfData;
2164 toolPerfData.emplace_back ();
2165 toolPerfData.back().name = testDefinition.name;
2166 toolPerfData.back().timeCall = benchmarkCall.getEntryTime(emptyTime);
2167 if (userConfiguration.runToolTwice)
2168 toolPerfData.back().timeCall2 = benchmarkCall2.getEntryTime(emptyTime);
2169 toolPerfData.back().timeCheck = benchmarkCheck.getEntryTime(emptyTime);
2170 benchmarkCall.setSilence();
2171 benchmarkCall2.setSilence();
2172 benchmarkCheck.setSilence();
2173 const std::size_t nameWidth = std::max_element (toolPerfData.begin(), toolPerfData.end(), [] (
const auto&
a,
const auto& b) {return a.name.size() < b.name.size();})->name.size();
2174 std::string
header = std::format (
"{:{}} | call(ns) | call2(ns) | check(ns)",
"tool name", nameWidth);
2175 std::cout <<
"\n" <<
header << std::endl;
2176 std::cout << std::string (
header.size(),
'-') << std::endl;
2177 for (
auto&
data : toolPerfData)
2178 {
2179 std::cout << std::format (
"{:{}} |",
data.name, nameWidth);
2181 std::cout << std::format (
"{:>9.0f} |",
data.timeCall.value());
2182 else
2183 std::cout << " |";
2185 std::cout << std::format (
"{:>10.0f} |",
data.timeCall2.value());
2186 else
2187 std::cout << " |";
2189 std::cout << std::format (
"{:>10.1f}",
data.timeCheck.value());
2190 std::cout << std::endl;
2191 }
2192 }
2194 {
2195
2196#ifdef XAOD_STANDALONE
2199#else
2201#endif
2203
2204#ifdef XAOD_STANDALONE
2205 Benchmark benchmarkEmptyClear (testDefinition.name + " empty clear");
2206 Benchmark benchmarkCallClear (testDefinition.name + " call clear");
2207 Benchmark benchmarkPrepClear (testDefinition.name + " prep clear");
2208#endif
2209 Benchmark benchmarkRepeatCall (testDefinition.name + " repeat-call");
2210 Benchmark benchmarkCall (testDefinition.name + " call");
2211 Benchmark benchmarkCallCopyRecord (testDefinition.name + " call copy-record");
2212 Benchmark benchmarkCallRetrieve (testDefinition.name + " call retrieve");
2213 Benchmark benchmarkPrep (testDefinition.name + " prep");
2214 Benchmark benchmarkPrepCopyRecord (testDefinition.name + " prep copy-record");
2215 Benchmark benchmarkPrepRetrieve (testDefinition.name + " prep retrieve");
2216 Benchmark benchmarkGetEntry (testDefinition.name + " getEntry");
2217
2219#ifdef XAOD_STANDALONE
2220 std::cout << "known container keys:" << std::endl;
2222 {
2223 std::cout << std::format (
" {} -> 0x{:x}, 0x{:x} -> {}", container,
event.getHash (container), key,
event.getName (key)) << std::endl;
2224 }
2225#endif
2227 throw std::runtime_error ("ColumnarPhysLiteTest: numberOfEvents == 0");
2228 }
2230
2231
2232
2233
2234
2235
2236 const auto startTime = std::chrono::high_resolution_clock::now();
2237 for (; (std::chrono::high_resolution_clock::now() -
startTime) < userConfiguration.targetTime; ++
entry)
2238 {
2239 benchmarkGetEntry.startTimer ();
2241 benchmarkGetEntry.stopTimer ();
2242 benchmarkPrepRetrieve.startTimer ();
2243 ASSERT_SUCCESS (testDefinition.xAODToolCaller->retrieve (*testDefinition.tool->evtStore()));
2244 benchmarkPrepRetrieve.stopTimer ();
2245 benchmarkPrepCopyRecord.startTimer ();
2246 static const std::string prepPostfix = "Prep";
2247 ASSERT_SUCCESS (testDefinition.xAODToolCaller->copyRecord (*testDefinition.tool->evtStore(), prepPostfix));
2248 benchmarkPrepCopyRecord.stopTimer ();
2249 benchmarkPrep.startTimer ();
2251 benchmarkPrep.stopTimer ();
2252#ifdef XAOD_STANDALONE
2253 benchmarkPrepClear.startTimer ();
2255 benchmarkPrepClear.stopTimer ();
2256#endif
2257 benchmarkCallRetrieve.startTimer ();
2258 ASSERT_SUCCESS (testDefinition.xAODToolCaller->retrieve (*testDefinition.tool->evtStore()));
2259 benchmarkCallRetrieve.stopTimer ();
2260 benchmarkCallCopyRecord.startTimer ();
2261 static const std::string callPostfix = "Call";
2262 ASSERT_SUCCESS (testDefinition.xAODToolCaller->copyRecord (*testDefinition.tool->evtStore(), callPostfix));
2263 benchmarkCallCopyRecord.stopTimer ();
2264 benchmarkCall.startTimer ();
2266 benchmarkCall.stopTimer ();
2267 if (userConfiguration.runToolTwice)
2268 {
2269 benchmarkRepeatCall.startTimer ();
2271 benchmarkRepeatCall.stopTimer ();
2272 }
2273#ifdef XAOD_STANDALONE
2274 benchmarkCallClear.startTimer ();
2276 benchmarkCallClear.stopTimer ();
2277 benchmarkEmptyClear.startTimer ();
2279 benchmarkEmptyClear.stopTimer ();
2280#endif
2281 }
2282 std::cout <<
"Total entries read: " <<
entry << std::endl;
2284 {
2286 }
2287 }
char data[hepevt_bytes_allocation_ATLAS]
void runXaodArrayTest(const UserConfiguration &userConfiguration, const TestDefinition &testDefinition, TFile *file)
static const std::unordered_map< std::string, SG::sgkey_t > knownKeys
constexpr unsigned columnarAccessMode
void renameContainers(IColumnarTool &tool, const std::vector< std::pair< std::string, std::string > > &renames)
rename containers in the columnar tool
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
std::vector< std::shared_ptr< TestUtils::IColumnData > > usedColumns
void setupColumns(ToolColumnVectorMap &toolWrapper)
void setupKnownColumns(const TestUtils::TestDefinition &testDefinition)
static UserConfiguration fromEnvironment()
create a UserConfiguration, loading from the file pointed to by the COLUMNAR_TEST_CONFIG environment ...