ATLAS Offline Software
Loading...
Searching...
No Matches
EvaluateModelWithAsyncInfer.cxx
Go to the documentation of this file.
1// Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3// Local include(s).
5
6// Framework include(s).
8#include "EvaluateUtils.h"
10
11// Standard include(s)
12#include <algorithm>
13#include <ranges>
14#include <span>
15
16namespace AthOnnx {
17
19 if (m_batchSize.value() < 1) {
20 ATH_MSG_ERROR("Requested an invalid batch size: {}", m_batchSize.value());
21 return StatusCode::FAILURE;
22 }
23
24 // Fetch tools
25 ATH_CHECK(m_onnxTool.retrieve());
26
27 // read input file, and the target file for comparison.
28 std::string pixelFilePath =
30 ATH_MSG_INFO("Using pixel file: {}", pixelFilePath);
31
32 try {
36 "Total no. of samples: {}", m_input_tensor_values_notFlat.size());
37 } catch (const std::exception& e) {
38 ATH_MSG_ERROR(e.what());
39 return StatusCode::FAILURE;
40 }
41
42 if (std::size_t(m_batchSize.value()) > m_input_tensor_values_notFlat.size()) {
43 ATH_MSG_ERROR("The batch size requested ({}) is greater than the number of available "
44 "samples ({})",
45 m_batchSize.value(),
47 return StatusCode::FAILURE;
48 }
49
50 if (m_input_tensor_values_notFlat.size() % m_batchSize.value() != 0) {
51 ATH_MSG_ERROR("The number of samples ({}) is not a multiple of the requested batch size ({})",
53 m_batchSize.value());
54 return StatusCode::FAILURE;
55 }
56 return StatusCode::SUCCESS;
57}
58
60 [[maybe_unused]] const EventContext& ctx) const {
61 // We know we have at least one image, otherwise we would have errored out
62 // earlier
63 const std::size_t n_batches =
65 const auto n_rows = std::int64_t(m_input_tensor_values_notFlat[0].size());
66 const auto n_cols = std::int64_t(m_input_tensor_values_notFlat[0][0].size());
67
68 for (std::size_t batch_idx = 0; batch_idx < n_batches; ++batch_idx) {
69 // prepare inputs
70 std::vector<float> inputDataVector;
71 inputDataVector.reserve(m_batchSize.value() * n_rows * n_cols);
72 for (const std::vector<std::vector<float>>& imageData :
74 std::views::drop(batch_idx * m_batchSize.value()) |
75 std::views::take(m_batchSize.value())) {
76 std::vector<float> flatten =
78 inputDataVector.insert(inputDataVector.end(), flatten.begin(),
79 flatten.end());
80 }
81
82 std::vector<int64_t> inputShape = {m_batchSize.value(), n_rows, n_cols};
83
84 AthInfer::InputDataMap inputData;
85 inputData["flatten_input:0"] =
86 std::make_pair(inputShape, std::move(inputDataVector));
87
88 const std::int64_t n_scores = 10;
89 AthInfer::OutputDataMap outputData;
90 outputData["dense_1/Softmax:0"] = std::make_pair(
91 std::vector<int64_t>{m_batchSize, n_scores}, std::vector<float>{});
92
93 ATH_CHECK(m_onnxTool->inference(inputData, outputData));
94
95 auto const& outputScores =
96 std::get<std::vector<float>>(outputData["dense_1/Softmax:0"].second);
97
98 if (outputScores.size() != std::size_t(n_scores * m_batchSize.value())) {
99 ATH_MSG_ERROR("Got back {} scores when it should have been {} * {} = {}",
100 outputScores.size(), n_scores, m_batchSize.value(),
101 n_scores * m_batchSize.value());
102 return StatusCode::FAILURE;
103 }
104
105 for (int img_idx = 0; img_idx < m_batchSize.value(); img_idx++) {
106 std::span scores(outputScores.begin() + img_idx * n_scores,
107 outputScores.begin() + (img_idx + 1) * n_scores);
108 ATH_MSG_DEBUG("Scores for img {} of batch {}: {}",
109 img_idx, batch_idx,
111 const auto max_elem = std::ranges::max_element(scores);
112 ATH_MSG_DEBUG("Class: {} has the highest score: {} in img {} of batch {}",
113 max_elem - scores.begin(),
114 *max_elem, img_idx, batch_idx);
115 }
116 }
117 return StatusCode::SUCCESS;
118}
119
120} // namespace AthOnnx
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
std::vector< std::vector< float > > scores
size_t size() const
Number of registered mappings.
virtual StatusCode execute(const EventContext &ctx) const override
Function executing the algorithm for a single event.
Gaudi::Property< std::string > m_pixelFileName
Name of the input file to load.
std::vector< std::vector< std::vector< float > > > m_input_tensor_values_notFlat
Gaudi::Property< int > m_batchSize
Following properties needed to be consdered if the .onnx model is evaluated in batch mode.
virtual StatusCode initialize() override
Function initialising the algorithm.
ToolHandle< AthInfer::IAthInferenceTool > m_onnxTool
Tool handler for onnx inference session.
static std::string find_calib_file(const std::string &logical_file_name)
std::map< std::string, InferenceData > OutputDataMap
std::map< std::string, InferenceData > InputDataMap
std::vector< T > flattenNestedVectors(const std::vector< std::vector< T > > &features)
Definition OnnxUtils.h:24
Namespace holding all of the Onnx Runtime example code.
std::vector< std::vector< std::vector< float > > > read_mnist_pixel_notFlat(const std::string &full_path)