ATLAS Offline Software
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 
5 #include "AthenaKernel/Chrono.h"
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());
22  ATH_CHECK(m_outputDataStreamKeys.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  return StatusCode::SUCCESS;
184 }
185 
186 StatusCode EFTrackingXrtAlgorithm::execute(const EventContext& ctx) const
187 {
188  ATH_CHECK(m_inputDataStreamKeys.size() == m_inputBuffers.size());
189  std::size_t inputHandleIndex = 0;
190  for (
191  const SG::ReadHandleKey<std::vector<unsigned long>>& inputDataStreamKey :
193  ) {
195  ATH_MSG_DEBUG("Writing: " << inputDataStream.name());
196  unsigned long* inputMap = m_inputBuffers.at(inputHandleIndex).map<unsigned long*>();
197 
199 
200  ATH_MSG_DEBUG("Copy " + inputDataStream.name() + " from storegate to host side map");
201  {
202  Athena::Chrono chrono(
203  "Copy " + inputDataStream.name() + " from storegate to host side map",
204  m_chronoSvc.get()
205  );
206 
207  for (std::size_t index = 0; index < inputDataStream->size(); index++) {
208  inputMap[index] = inputDataStream->at(index);
209  }
210  }
211 
212  ATH_MSG_DEBUG("Copy " + inputDataStream.name() + " from host side map to device");
213  {
214  Athena::Chrono chrono(
215  "Copy " + inputDataStream.name() + " from host side map to device",
216  m_chronoSvc.get()
217  );
218 
219  m_inputBuffers.at(inputHandleIndex).sync(XCL_BO_SYNC_BO_TO_DEVICE);
220  }
221 
222  inputHandleIndex++;
223  }
224 
226  std::size_t vSizeHandleIndex = 0;
227  for (
228  const SG::ReadHandleKey<std::vector<unsigned long>>& vSizeDataStreamKey :
230  ) {
231  SG::ReadHandle<std::vector<unsigned long>> vSizeDataStream(vSizeDataStreamKey, ctx);
232  const auto& [kernelName, storeGateKey, argumentIndex] = m_vSizeInterfaces[vSizeHandleIndex];
233  ATH_MSG_DEBUG("Setting VSize: " << kernelName << ", " << vSizeDataStream.name() << ", " << vSizeDataStream->size());
234 
235  m_runs.at(kernelName)->set_arg(argumentIndex, vSizeDataStream->size());
236  vSizeHandleIndex++;
237  }
238 
239  ATH_MSG_DEBUG("Run kernels");
240  {
241  Athena::Chrono chrono("Run kernels", m_chronoSvc.get());
242 
243  for (const auto& kernelNames : m_kernelOrder) {
244  for (const auto& kernelName : kernelNames) {
245  ATH_MSG_DEBUG("Running: " << kernelName);
246  m_runs.at(kernelName)->start();
247  }
248 
249  for (const auto& kernelName : kernelNames) {
250  ATH_MSG_DEBUG("Waiting: " << kernelName);
251  m_runs.at(kernelName)->wait();
252  }
253  }
254  }
255 
256  std::size_t outputHandleIndex = 0;
257  for (
258  const SG::WriteHandleKey<std::vector<unsigned long>>& outputDataStreamKey :
260  ) {
262  ATH_CHECK(outputDataStream.record(std::make_unique<std::vector<unsigned long>>(m_bufferSize)));
263 
264  ATH_MSG_DEBUG("Copy " + outputDataStream.name() + " from device to host side map");
265  {
266  Athena::Chrono chrono(
267  "Copy " + outputDataStream.name() + " from device to host side map",
268  m_chronoSvc.get()
269  );
270 
271  m_outputBuffers.at(outputHandleIndex).sync(XCL_BO_SYNC_BO_FROM_DEVICE);
272  }
273 
274  const unsigned long* outputMap = m_outputBuffers.at(outputHandleIndex).map<unsigned long*>();
275  ATH_MSG_DEBUG("Copy " + outputDataStream.name() + " from host side map to storegate");
276  {
277  Athena::Chrono chrono(
278  "Copy " + outputDataStream.name() + " from host side map to storegate",
279  m_chronoSvc.get()
280  );
281 
282  for (std::size_t index = 0; index < outputDataStream->size(); index++) {
283  outputDataStream->at(index) = outputMap[index];
284  }
285  }
286 
287  outputHandleIndex++;
288  }
289 
290  return StatusCode::SUCCESS;
291 }
292 
EFTrackingXrtAlgorithm::m_outputInterfaces
Gaudi::Property< std::vector< std::tuple< std::string, std::string, int > > > m_outputInterfaces
Definition: EFTrackingXrtAlgorithm.h:72
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
index
Definition: index.py:1
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
EFTrackingXrtAlgorithm::EFTrackingXrtAlgorithm
EFTrackingXrtAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Definition: EFTrackingXrtAlgorithm.cxx:9
Chrono.h
Exception-safe IChronoSvc caller.
SG::ReadHandleKey
Property holding a SG store/key/clid from which a ReadHandle is made.
Definition: StoreGate/StoreGate/ReadHandleKey.h:39
EFTrackingXrtAlgorithm::m_kernelOrder
Gaudi::Property< std::vector< std::vector< std::string > > > m_kernelOrder
Definition: EFTrackingXrtAlgorithm.h:86
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
EFTrackingXrtAlgorithm::m_vSizeInterfaces
Gaudi::Property< std::vector< std::tuple< std::string, std::string, int > > > m_vSizeInterfaces
Definition: EFTrackingXrtAlgorithm.h:65
EFTrackingXrtAlgorithm::m_kernels
std::map< std::string, std::unique_ptr< xrt::kernel > > m_kernels
Definition: EFTrackingXrtAlgorithm.h:100
SG::WriteHandleKey
Property holding a SG store/key/clid from which a WriteHandle is made.
Definition: StoreGate/StoreGate/WriteHandleKey.h:40
Athena::Chrono
Exception-safe IChronoSvc caller.
Definition: Chrono.h:50
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
EFTrackingXrtAlgorithm::m_inputDataStreamKeys
SG::ReadHandleKeyArray< std::vector< unsigned long > > m_inputDataStreamKeys
Keys to access encoded 64bit words following the EFTracking specification.
Definition: EFTrackingXrtAlgorithm.h:40
EFTrackingXrtAlgorithm::m_DeviceMgmtSvc
ServiceHandle< AthXRT::IDeviceMgmtSvc > m_DeviceMgmtSvc
Definition: EFTrackingXrtAlgorithm.h:44
EFTrackingXrtAlgorithm::m_inputInterfaces
Gaudi::Property< std::vector< std::tuple< std::string, std::string, int > > > m_inputInterfaces
Definition: EFTrackingXrtAlgorithm.h:58
EFTrackingXrtAlgorithm::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: EFTrackingXrtAlgorithm.cxx:186
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
EFTrackingXrtAlgorithm::m_vSizeDataStreamKeys
SG::ReadHandleKeyArray< std::vector< unsigned long > > m_vSizeDataStreamKeys
Definition: EFTrackingXrtAlgorithm.h:41
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
DeMoScan.index
string index
Definition: DeMoScan.py:362
EFTrackingXrtAlgorithm::m_sharedInterfaces
Gaudi::Property< std::vector< std::tuple< std::string, int, std::string, int > > > m_sharedInterfaces
Definition: EFTrackingXrtAlgorithm.h:79
EFTrackingXrtAlgorithm::initialize
StatusCode initialize() override final
Definition: EFTrackingXrtAlgorithm.cxx:15
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:130
F150_i_TestConfig.outputDataStream
outputDataStream
Definition: F150_i_TestConfig.py:109
EFTrackingXrtAlgorithm.h
EFTrackingXrtAlgorithm::m_bufferSize
Gaudi::Property< std::size_t > m_bufferSize
Definition: EFTrackingXrtAlgorithm.h:93
F150_i_TestConfig.inputDataStream
inputDataStream
Definition: F150_i_TestConfig.py:72
EFTrackingXrtAlgorithm::m_outputDataStreamKeys
SG::WriteHandleKeyArray< std::vector< unsigned long > > m_outputDataStreamKeys
Definition: EFTrackingXrtAlgorithm.h:42
EFTrackingXrtAlgorithm::m_runs
std::map< std::string, std::unique_ptr< xrt::run > > m_runs
Definition: EFTrackingXrtAlgorithm.h:101
EFTrackingXrtAlgorithm::m_chronoSvc
ServiceHandle< IChronoSvc > m_chronoSvc
Definition: EFTrackingXrtAlgorithm.h:51