ATLAS Offline Software
Loading...
Searching...
No Matches
EFTrackingXrtAlgorithm.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4
6
8
10 const std::string& name,
11 ISvcLocator* pSvcLocator
12) : AthReentrantAlgorithm(name, pSvcLocator)
13{}
14
16 ATH_MSG_INFO("Initializing " << name());
17
18 ATH_CHECK(m_DeviceMgmtSvc.retrieve());
19 ATH_CHECK(m_chronoSvc.retrieve());
20 ATH_CHECK(m_inputDataStreamKeys.initialize());
21 ATH_CHECK(m_vSizeDataStreamKeys.initialize());
23
24 for (const auto& [kernelName, storeGateKey, argumentIndex] : m_inputInterfaces) {
26 "Setting up " <<
27 kernelName <<
28 " to read " <<
29 storeGateKey <<
30 " into argument " <<
31 argumentIndex
32 );
33
34 const std::vector<std::shared_ptr<xrt::device>> devices =
35 m_DeviceMgmtSvc->get_xrt_devices_by_kernel_name(kernelName);
36
37 ATH_CHECK(devices.size() != 0);
38
39 if (!m_kernels.contains(kernelName)) {
40 m_kernels[kernelName] = std::make_unique<xrt::kernel>(
41 *(devices[0]),
42 (devices[0])->get_xclbin_uuid(),
43 kernelName,
44 xrt::kernel::cu_access_mode::exclusive
45 );
46 }
47
48 ATH_CHECK(m_kernels[kernelName].get() != nullptr);
49 m_inputBuffers.emplace_back(
50 *(devices[0]),
51 sizeof(unsigned long) * m_bufferSize,
52 xrt::bo::flags::normal,
53 m_kernels[kernelName]->group_id(argumentIndex)
54 );
55
56 if (!m_runs.contains(kernelName)) {
57 m_runs[kernelName] = std::make_unique<xrt::run>(*m_kernels[kernelName]);
58 }
59
60 ATH_CHECK(m_runs[kernelName].get() != nullptr);
61 m_runs[kernelName]->set_arg(argumentIndex, m_inputBuffers.back());
62 }
63
64 for (const auto& [kernelName, storeGateKey, argumentIndex] : m_vSizeInterfaces) {
66 "Setting up " <<
67 kernelName <<
68 " to get input size from " <<
69 storeGateKey <<
70 " for argument " <<
71 argumentIndex
72 );
73
74 const std::vector<std::shared_ptr<xrt::device>> devices =
75 m_DeviceMgmtSvc->get_xrt_devices_by_kernel_name(kernelName);
76
77 ATH_CHECK(devices.size() != 0);
78
79 if (!m_kernels.contains(kernelName)) {
80 m_kernels[kernelName] = std::make_unique<xrt::kernel>(
81 *(devices[0]),
82 (devices[0])->get_xclbin_uuid(),
83 kernelName,
84 xrt::kernel::cu_access_mode::exclusive
85 );
86 }
87
88 ATH_CHECK(m_kernels[kernelName].get() != nullptr);
89
90 if (!m_runs.contains(kernelName)) {
91 m_runs[kernelName] = std::make_unique<xrt::run>(*m_kernels[kernelName]);
92 }
93
94 ATH_CHECK(m_runs[kernelName].get() != nullptr);
95 }
96
97 for (const auto& [kernelName, storeGateKey, argumentIndex] : m_outputInterfaces) {
99 "Setting up " <<
100 kernelName <<
101 " to write " <<
102 storeGateKey <<
103 " from argument " <<
104 argumentIndex
105 );
106
107 const std::vector<std::shared_ptr<xrt::device>> devices =
108 m_DeviceMgmtSvc->get_xrt_devices_by_kernel_name(kernelName);
109
110 ATH_CHECK(devices.size() != 0);
111
112 if (!m_kernels.contains(kernelName)) {
113 m_kernels[kernelName] = std::make_unique<xrt::kernel>(
114 *(devices[0]),
115 devices[0]->get_xclbin_uuid(),
116 kernelName,
117 xrt::kernel::cu_access_mode::exclusive
118 );
119 }
120
121 m_outputBuffers.emplace_back(
122 *(devices[0]),
123 sizeof(unsigned long) * m_bufferSize,
124 xrt::bo::flags::normal,
125 m_kernels[kernelName]->group_id(argumentIndex)
126 );
127
128 if (!m_runs.contains(kernelName)) {
129 m_runs[kernelName] = std::make_unique<xrt::run>(*m_kernels[kernelName]);
130 }
131
132 ATH_CHECK(m_runs[kernelName].get() != nullptr);
133 m_runs[kernelName]->set_arg(argumentIndex, m_outputBuffers.back());
134 }
135
136 for (const auto& [kernelName, argumentIndex, sourceKernelName, sourceArgumentIndex] : m_sharedInterfaces) {
138 "Setting up shared buffer between " <<
139 kernelName <<
140 " argument " <<
141 argumentIndex <<
142 " and " <<
143 sourceKernelName <<
144 " argument " <<
145 sourceArgumentIndex
146 );
147
148 const std::vector<std::shared_ptr<xrt::device>> devices =
149 m_DeviceMgmtSvc->get_xrt_devices_by_kernel_name(kernelName);
150
151 ATH_CHECK(devices.size() != 0);
152
153 if (!m_kernels.contains(kernelName)) {
154 m_kernels[kernelName] = std::make_unique<xrt::kernel>(
155 *(devices[0]),
156 devices[0]->get_xclbin_uuid(),
157 kernelName,
158 xrt::kernel::cu_access_mode::exclusive
159 );
160 }
161
162 if (!m_runs.contains(kernelName)) {
163 m_runs[kernelName] = std::make_unique<xrt::run>(*m_kernels[kernelName]);
164 }
165
166 ATH_CHECK(m_runs[kernelName].get() != nullptr);
167
168 std::size_t index = 0;
169 for (const auto& [outputKernelName, outputStoreGateKey, outputArgumentIndex] : m_outputInterfaces) {
170 if (
171 outputKernelName == sourceKernelName &&
172 outputArgumentIndex == sourceArgumentIndex
173 ) {
174 m_runs[kernelName]->set_arg(argumentIndex, m_outputBuffers[index]);
175
176 break;
177 }
178
179 index++;
180 }
181 }
182
183 for (const auto& kernelNames : m_kernelOrder) {
184 for (const auto& kernelName : kernelNames) {
185 const std::vector<std::shared_ptr<xrt::device>> devices =
186 m_DeviceMgmtSvc->get_xrt_devices_by_kernel_name(kernelName);
187
188 ATH_CHECK(devices.size() != 0);
189
190 if (!m_kernels.contains(kernelName)) {
191 ATH_MSG_DEBUG("Creating kernel: " << kernelName);
192
193 m_kernels[kernelName] = std::make_unique<xrt::kernel>(
194 *(devices[0]),
195 devices[0]->get_xclbin_uuid(),
196 kernelName,
197 xrt::kernel::cu_access_mode::exclusive
198 );
199
200 if (!m_runs.contains(kernelName)) {
201 m_runs[kernelName] = std::make_unique<xrt::run>(*m_kernels[kernelName]);
202 }
203
204 ATH_CHECK(m_runs[kernelName].get() != nullptr);
205 }
206 }
207 }
208
209 return StatusCode::SUCCESS;
210}
211
212StatusCode EFTrackingXrtAlgorithm::execute(const EventContext& ctx) const
213{
214 ATH_CHECK(m_inputDataStreamKeys.size() == m_inputBuffers.size());
215 std::size_t inputHandleIndex = 0;
216 for (
217 const SG::ReadHandleKey<std::vector<unsigned long>>& inputDataStreamKey :
219 ) {
220 SG::ReadHandle<std::vector<unsigned long>> inputDataStream(inputDataStreamKey, ctx);
221 ATH_MSG_DEBUG("Writing: " << inputDataStream.name());
222 unsigned long* inputMap = m_inputBuffers.at(inputHandleIndex).map<unsigned long*>();
223
224 ATH_CHECK(inputDataStream->size() <= m_bufferSize);
225
226 ATH_MSG_DEBUG("Copy " + inputDataStream.name() + " from storegate to host side map");
227 {
228 Athena::Chrono chrono(
229 "Copy " + inputDataStream.name() + " from storegate to host side map",
230 m_chronoSvc.get()
231 );
232
233 for (std::size_t index = 0; index < inputDataStream->size(); index++) {
234 inputMap[index] = inputDataStream->at(index);
235 }
236 }
237
238 ATH_MSG_DEBUG("Copy " + inputDataStream.name() + " from host side map to device");
239 {
240 Athena::Chrono chrono(
241 "Copy " + inputDataStream.name() + " from host side map to device",
242 m_chronoSvc.get()
243 );
244
245 m_inputBuffers.at(inputHandleIndex).sync(XCL_BO_SYNC_BO_TO_DEVICE);
246 }
247
248 inputHandleIndex++;
249 }
250
252 std::size_t vSizeHandleIndex = 0;
253 for (
254 const SG::ReadHandleKey<std::vector<unsigned long>>& vSizeDataStreamKey :
256 ) {
257 SG::ReadHandle<std::vector<unsigned long>> vSizeDataStream(vSizeDataStreamKey, ctx);
258 const auto& [kernelName, storeGateKey, argumentIndex] = m_vSizeInterfaces[vSizeHandleIndex];
259 ATH_MSG_DEBUG("Setting VSize: " << kernelName << ", " << vSizeDataStream.name() << ", " << vSizeDataStream->size());
260
261 m_runs.at(kernelName)->set_arg(argumentIndex, vSizeDataStream->size());
262 vSizeHandleIndex++;
263 }
264
265 ATH_MSG_DEBUG("Run kernels");
266 {
267 Athena::Chrono chrono("Run kernels", m_chronoSvc.get());
268
269 for (const auto& kernelNames : m_kernelOrder) {
270 for (const auto& kernelName : kernelNames) {
271 ATH_MSG_DEBUG("Running: " << kernelName);
272 m_runs.at(kernelName)->start();
273 }
274
275 for (const auto& kernelName : kernelNames) {
276 ATH_MSG_DEBUG("Waiting: " << kernelName);
277 m_runs.at(kernelName)->wait();
278 }
279 }
280 }
281
282 std::size_t outputHandleIndex = 0;
283 for (
284 const SG::WriteHandleKey<std::vector<unsigned long>>& outputDataStreamKey :
286 ) {
287 SG::WriteHandle<std::vector<unsigned long>> outputDataStream(outputDataStreamKey, ctx);
288 ATH_CHECK(outputDataStream.record(std::make_unique<std::vector<unsigned long>>(m_bufferSize)));
289
290 ATH_MSG_DEBUG("Copy " + outputDataStream.name() + " from device to host side map");
291 {
292 Athena::Chrono chrono(
293 "Copy " + outputDataStream.name() + " from device to host side map",
294 m_chronoSvc.get()
295 );
296
297 m_outputBuffers.at(outputHandleIndex).sync(XCL_BO_SYNC_BO_FROM_DEVICE);
298 }
299
300 const unsigned long* outputMap = m_outputBuffers.at(outputHandleIndex).map<unsigned long*>();
301 ATH_MSG_DEBUG("Copy " + outputDataStream.name() + " from host side map to storegate");
302 {
303 Athena::Chrono chrono(
304 "Copy " + outputDataStream.name() + " from host side map to storegate",
305 m_chronoSvc.get()
306 );
307
308 for (std::size_t index = 0; index < outputDataStream->size(); index++) {
309 outputDataStream->at(index) = outputMap[index];
310 }
311 }
312
313 outputHandleIndex++;
314 }
315
316 return StatusCode::SUCCESS;
317}
318
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
Exception-safe IChronoSvc caller.
An algorithm that can be simultaneously executed in multiple threads.
Exception-safe IChronoSvc caller.
Definition Chrono.h:50
Gaudi::Property< std::vector< std::tuple< std::string, std::string, int > > > m_vSizeInterfaces
SG::ReadHandleKeyArray< std::vector< unsigned long > > m_vSizeDataStreamKeys
Gaudi::Property< std::vector< std::tuple< std::string, std::string, int > > > m_inputInterfaces
std::map< std::string, std::unique_ptr< xrt::kernel > > m_kernels
std::map< std::string, std::unique_ptr< xrt::run > > m_runs
StatusCode execute(const EventContext &ctx) const override final
Gaudi::Property< std::vector< std::vector< std::string > > > m_kernelOrder
SG::ReadHandleKeyArray< std::vector< unsigned long > > m_inputDataStreamKeys
Keys to access encoded 64bit words following the EFTracking specification.
Gaudi::Property< std::vector< std::tuple< std::string, int, std::string, int > > > m_sharedInterfaces
Gaudi::Property< std::vector< std::tuple< std::string, std::string, int > > > m_outputInterfaces
ServiceHandle< AthXRT::IDeviceMgmtSvc > m_DeviceMgmtSvc
SG::WriteHandleKeyArray< std::vector< unsigned long > > m_outputDataStreamKeys
Gaudi::Property< std::size_t > m_bufferSize
StatusCode initialize() override final
EFTrackingXrtAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
ServiceHandle< IChronoSvc > m_chronoSvc
Property holding a SG store/key/clid from which a ReadHandle is made.
const std::string & name() const
Return the StoreGate ID for the referenced object.
Property holding a SG store/key/clid from which a WriteHandle is made.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
Definition index.py:1