ATLAS Offline Software
Loading...
Searching...
No Matches
F1X0XRTIntegrationAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include <xrt/xrt_bo.h>
10#include <xrt/xrt_device.h>
11#include <xrt/xrt_kernel.h>
12#include <xrt/xrt_uuid.h>
13
14#include <algorithm>
15#include <chrono>
16#include <cmath>
17
19{
20
21// small helper for ns accounting
22static inline uint64_t ns_between(const std::chrono::steady_clock::time_point& a,
23 const std::chrono::steady_clock::time_point& b)
24{
25 return static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(b - a).count());
26}
27
29{
30 ATH_MSG_INFO("Running on the FPGA accelerator (XRT native)");
31
33 ATH_CHECK(m_chronoSvc.retrieve());
34
35 // Open device and load xclbin
36 {
37 Athena::Chrono chrono("XRT::device open", m_chronoSvc.get());
38 // TODO: expose as configurable if you need a different board index
39 m_xrtDevice = xrt::device(0);
40 }
41 {
42 Athena::Chrono chrono("XRT::load_xclbin", m_chronoSvc.get());
43 xrt::xclbin xb(m_xclbin.value());
44 m_xrtUuid = m_xrtDevice.load_xclbin(xb);
45 }
46 ATH_MSG_INFO("loading " << m_xclbin);
47
48 ATH_CHECK(m_FPGAStripRDO.initialize());
49 ATH_CHECK(m_FPGAPixelRDO.initialize());
50 ATH_CHECK(m_FPGAStripOutput.initialize());
51 ATH_CHECK(m_FPGAPixelOutput.initialize());
52 ATH_CHECK(m_FPGAPixelRDOSize.initialize());
53 ATH_CHECK(m_FPGAStripRDOSize.initialize());
54
55 // Enumerate CUs
56 std::vector<std::string> listofCUs;
57 getListofCUs(listofCUs);
58
59 // Create kernels (per CU)
60 for (const auto& cuName : listofCUs) {
61 try {
62 if (cuName.find(m_pixelClusterKernelName.value()) != std::string::npos)
63 m_pixelClusteringKernels.emplace_back(xrt::kernel{m_xrtDevice, m_xrtUuid, cuName.c_str()});
64 else if (cuName.find(m_stripClusterKernelName.value()) != std::string::npos)
65 m_stripClusteringKernels.emplace_back(xrt::kernel{m_xrtDevice, m_xrtUuid, cuName.c_str()});
66 else if (!m_doF110 && cuName.find(m_pixelL2GKernelName.value()) != std::string::npos)
67 m_pixelL2GKernels.emplace_back(xrt::kernel{m_xrtDevice, m_xrtUuid, cuName.c_str()});
68 else if (cuName.find(m_stripL2GKernelName.value()) != std::string::npos)
69 m_stripL2GKernels.emplace_back(xrt::kernel{m_xrtDevice, m_xrtUuid, cuName.c_str()});
70 else if (cuName.find(m_pixelEdmKernelName.value()) != std::string::npos)
71 m_pixelEdmPrepKernels.emplace_back(xrt::kernel{m_xrtDevice, m_xrtUuid, cuName.c_str()});
72 else if (cuName.find(m_stripEdmKernelName.value()) != std::string::npos)
73 m_stripEdmPrepKernels.emplace_back(xrt::kernel{m_xrtDevice, m_xrtUuid, cuName.c_str()});
74 else
75 ATH_MSG_WARNING("Do not recognize kernel name: " << cuName);
76 } catch (const std::exception& e) {
77 ATH_MSG_ERROR("Failed to create kernel for CU '" << cuName << "': " << e.what());
78 return StatusCode::FAILURE;
79 }
80 }
81
82 ATH_MSG_INFO(m_pixelClusterKernelName.value() << " size: " << m_pixelClusteringKernels.size());
83 ATH_MSG_INFO(m_stripClusterKernelName.value() << " size: " << m_stripClusteringKernels.size());
84 ATH_MSG_INFO(m_pixelL2GKernelName.value() << " size: " << m_pixelL2GKernels.size());
85 ATH_MSG_INFO(m_stripL2GKernelName.value() << " size: " << m_stripL2GKernels.size());
86 ATH_MSG_INFO(m_pixelEdmKernelName.value() << " size: " << m_pixelEdmPrepKernels.size());
87 ATH_MSG_INFO(m_stripEdmKernelName.value() << " size: " << m_stripEdmPrepKernels.size());
88
89 // ---------------------------------------------------------------------------
90 // Allocate BOs per "thread" (slot). Bind each BO to the bank inferred from
91 // the kernel's group_id(argument_index). If kernel vector is empty, fall back to bank 0.
92 // ---------------------------------------------------------------------------
93 unsigned int nthreads = (m_FPGAThreads.value() < 1) ? SG::getNSlots() : m_FPGAThreads.value();
94
95 auto choose = [](const std::vector<xrt::kernel>& ks) -> const xrt::kernel* {
96 return ks.empty() ? nullptr : &ks.front();
97 };
98
99 const xrt::kernel* kPC = choose(m_pixelClusteringKernels);
100 const xrt::kernel* kSC = choose(m_stripClusteringKernels);
101 const xrt::kernel* kPL2G = choose(m_pixelL2GKernels);
102 const xrt::kernel* kSL2G = choose(m_stripL2GKernels);
103 const xrt::kernel* kPEDM = choose(m_pixelEdmPrepKernels);
104 const xrt::kernel* kSEDM = choose(m_stripEdmPrepKernels);
105
106 auto gid = [](const xrt::kernel* k, unsigned arg_index)->unsigned {
107 return k ? k->group_id(arg_index) : 0;
108 };
109
110 for (unsigned i = 0; i < nthreads; ++i) {
111 // Inputs
112 m_pixelClusterInputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::PIXEL_CONTAINER_INPUT_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kPC, 0)});
113 m_stripClusterInputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::STRIP_CONTAINER_INPUT_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kSC, 0)});
114
115 // Clustering outputs
116 if (!m_doF110) m_pixelClusterOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t),xrt::bo::flags::normal, gid(kPC, 1)});
117
118 m_stripClusterOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kSC, 1)});
119
120 // Pixel clustering EDM output: arg index depends on F110 usage
121 m_pixelClusterEDMOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kPC, m_doF110 ? 1u : 2u)});
122
123 m_stripClusterEDMOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kSC, 2)});
124
125 // L2G outputs
126 if (!m_doF110) {
127 m_pixelL2GOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kPL2G, 2)});
128 m_pixelL2GEDMOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t),xrt::bo::flags::normal, gid(kPL2G, 3)});
129 }
130 m_stripL2GOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kSL2G, 2)});
131 m_stripL2GEDMOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), xrt::bo::flags::normal, gid(kSL2G, 3)});
132
133 // Final EDM containers (outputs)
134 // PixelEDM(arg1) and StripEDM(arg1) are the output BOs
135 m_edmPixelOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::PIXEL_CONTAINER_BUF_SIZE * sizeof(uint32_t), xrt::bo::flags::normal, gid(kPEDM, 1)});
136 m_edmStripOutputBOList.emplace_back(xrt::bo{m_xrtDevice, EFTrackingTransient::STRIP_CONTAINER_BUF_SIZE * sizeof(uint32_t), xrt::bo::flags::normal, gid(kSEDM, 1)});
137 }
138
139 return StatusCode::SUCCESS;
140}
141
142StatusCode F1X0XRTIntegrationAlg::execute(const EventContext &ctx) const
143{
144 ATH_MSG_DEBUG("Executing F1X0XRTIntegrationAlg (XRT)");
145 m_numEvents++;
146
147 // Inputs
148 const std::vector<uint64_t>* pixelInput{nullptr};
149 const std::vector<uint64_t>* stripInput{nullptr};
150 ATH_CHECK(SG::get(pixelInput, m_FPGAPixelRDO, ctx));
151 ATH_CHECK(SG::get(stripInput, m_FPGAStripRDO, ctx));
152
153 const int* pixelInputSize{nullptr}, *stripInputSize{nullptr};
154 ATH_CHECK(SG::get(pixelInputSize, m_FPGAPixelRDOSize, ctx));
155 ATH_CHECK(SG::get(stripInputSize, m_FPGAStripRDOSize, ctx));
156
157
158 // Thread/buffer index
159 unsigned int nthreads = (m_FPGAThreads.value() < 1) ? SG::getNSlots() : m_FPGAThreads.value();
160 const size_t bufferIndex = ctx.slot() % nthreads;
161
162 // Kernel indices
163 const size_t pixelClusterIndex = ctx.slot() % m_pixelClusteringKernels.size();
164 const size_t stripClusterIndex = ctx.slot() % m_stripClusteringKernels.size();
165 const size_t stripL2GIndex = ctx.slot() % m_stripL2GKernels.size();
166 const size_t pixelL2GIndex = m_pixelL2GKernels.empty() ? 0 : (ctx.slot() % m_pixelL2GKernels.size());
167 const size_t pixelEDMIndex = m_pixelEdmPrepKernels.empty() ? 0 : (ctx.slot() % m_pixelEdmPrepKernels.size());
168 const size_t stripEDMIndex = m_stripEdmPrepKernels.empty() ? 0 : (ctx.slot() % m_stripEdmPrepKernels.size());
169
170 ATH_MSG_INFO("Thread number " << ctx.slot()
171 << " running on buffer " << bufferIndex
172 << " pixelClusterIndex: " << pixelClusterIndex
173 << " stripClusterIndex: " << stripClusterIndex
174 << " stripL2GIndex: " << stripL2GIndex
175 << " pixelL2GIndex: " << pixelL2GIndex
176 << " pixelEDMIndex: " << pixelEDMIndex
177 << " stripEDMIndex: " << stripEDMIndex);
178
179 // BO aliases
180 auto& bo_pix_in = m_pixelClusterInputBOList[bufferIndex];
181 auto& bo_str_in = m_stripClusterInputBOList[bufferIndex];
182
183 xrt::bo* bo_pix_cl_out = (!m_doF110) ? &m_pixelClusterOutputBOList[bufferIndex] : nullptr;
184 auto& bo_pix_cl_edm = m_pixelClusterEDMOutputBOList[bufferIndex];
185
186 auto& bo_str_cl = m_stripClusterOutputBOList[bufferIndex];
187 auto& bo_str_cl_edm = m_stripClusterEDMOutputBOList[bufferIndex];
188
189 xrt::bo* bo_pix_l2g_out = (!m_doF110) ? &m_pixelL2GOutputBOList[bufferIndex] : nullptr;
190 xrt::bo* bo_pix_l2g_edm = (!m_doF110) ? &m_pixelL2GEDMOutputBOList[bufferIndex] : nullptr;
191
192 auto& bo_str_l2g_out = m_stripL2GOutputBOList[bufferIndex];
193 auto& bo_str_l2g_edm = m_stripL2GEDMOutputBOList[bufferIndex];
194
195 auto& bo_pix_edm_cont = m_edmPixelOutputBOList[bufferIndex];
196 auto& bo_str_edm_cont = m_edmStripOutputBOList[bufferIndex];
197
198 // Write inputs (and time them)
199 const auto t_wi0 = std::chrono::steady_clock::now();
200 bo_pix_in.write(pixelInput->data(), pixelInput->size() * sizeof(uint64_t), 0);
201 bo_pix_in.sync(XCL_BO_SYNC_BO_TO_DEVICE);
202 const auto t_wi1 = std::chrono::steady_clock::now();
203 m_pixelInputTime += ns_between(t_wi0, t_wi1);
204 ATH_MSG_DEBUG("Pixel input buffer write time: " << (ns_between(t_wi0, t_wi1) / 1e6) << " ms");
205
206 const auto t_wi2 = std::chrono::steady_clock::now();
207 bo_str_in.write(stripInput->data(), stripInput->size() * sizeof(uint64_t), 0);
208 bo_str_in.sync(XCL_BO_SYNC_BO_TO_DEVICE);
209 const auto t_wi3 = std::chrono::steady_clock::now();
210 m_stripInputTime += ns_between(t_wi2, t_wi3);
211 ATH_MSG_DEBUG("Strip input buffer write time: " << (ns_between(t_wi2, t_wi3) / 1e6) << " ms");
212
213 // Launch kernels
214 const auto t_k0 = std::chrono::steady_clock::now();
215
216 // Pixel clustering
217 auto& k_pix_cl = m_pixelClusteringKernels[pixelClusterIndex];
218 xrt::run r_pix_cl{k_pix_cl};
219 r_pix_cl.set_arg(0, bo_pix_in);
220 if (m_doF110) {
221 r_pix_cl.set_arg(1, bo_pix_cl_edm);
222 } else {
223 r_pix_cl.set_arg(1, *bo_pix_cl_out);
224 r_pix_cl.set_arg(2, bo_pix_cl_edm);
225
226 // extra size args (bytes), rounded to 256 elements
227 int rounded = static_cast<int>(std::ceil(static_cast<double>(*pixelInputSize) / 256.0)) * 256;
228 uint32_t hit_bytes = static_cast<uint32_t>(sizeof(uint64_t) * rounded);
229 uint32_t cluster_bytes = static_cast<uint32_t>(sizeof(uint64_t) * rounded);
230 uint32_t edm_bytes = static_cast<uint32_t>(sizeof(uint64_t) * rounded * 8);
231 r_pix_cl.set_arg(3, hit_bytes);
232 r_pix_cl.set_arg(4, cluster_bytes);
233 r_pix_cl.set_arg(5, edm_bytes);
234 }
235 const auto t_pc_start = std::chrono::steady_clock::now();
236 r_pix_cl.start();
237 // Strip clustering
238 auto& k_str_cl = m_stripClusteringKernels[stripClusterIndex];
239 xrt::run r_str_cl{k_str_cl};
240 r_str_cl.set_arg(0, bo_str_in);
241 r_str_cl.set_arg(1, bo_str_cl);
242 r_str_cl.set_arg(2, bo_str_cl_edm);
243 r_str_cl.set_arg(3, static_cast<unsigned int>(*stripInputSize));
244 const auto t_sc_start = std::chrono::steady_clock::now();
245 r_str_cl.start();
246
247 r_pix_cl.wait();
248 const auto t_pc_done = std::chrono::steady_clock::now();
249 m_pixelClusteringTime += ns_between(t_pc_start, t_pc_done);
250 ATH_MSG_DEBUG("Pixel clustering time: " << (ns_between(t_pc_start, t_pc_done) / 1e6) << " ms");
251
252 r_str_cl.wait();
253 const auto t_sc_done = std::chrono::steady_clock::now();
254 m_stripClusteringTime += ns_between(t_sc_start, t_sc_done);
255 ATH_MSG_DEBUG("Strip clustering time: " << (ns_between(t_sc_start, t_sc_done) / 1e6) << " ms");
256
257 // Pixel L2G (only for F100)
258 std::chrono::steady_clock::time_point t_pl2g_done = t_pc_done;
259 if (!m_doF110) {
260 auto& k_pix_l2g = m_pixelL2GKernels[pixelL2GIndex];
261 xrt::run r_pix_l2g{k_pix_l2g};
262 r_pix_l2g.set_arg(0, *bo_pix_cl_out);
263 r_pix_l2g.set_arg(1, bo_pix_cl_edm);
264 r_pix_l2g.set_arg(2, *bo_pix_l2g_out);
265 r_pix_l2g.set_arg(3, *bo_pix_l2g_edm);
266 const auto t_pl2g_start = std::chrono::steady_clock::now();
267 r_pix_l2g.start();
268 r_pix_l2g.wait();
269 t_pl2g_done = std::chrono::steady_clock::now();
270 m_pixelL2GTime += ns_between(t_pl2g_start, t_pl2g_done);
271 ATH_MSG_DEBUG("Pixel L2G time: " << (ns_between(t_pl2g_start, t_pl2g_done) / 1e6) << " ms");
272 }
273
274 // Strip L2G
275 auto& k_str_l2g = m_stripL2GKernels[stripL2GIndex];
276 xrt::run r_str_l2g{k_str_l2g};
277 r_str_l2g.set_arg(0, bo_str_cl);
278 r_str_l2g.set_arg(1, bo_str_cl_edm);
279 r_str_l2g.set_arg(2, bo_str_l2g_out);
280 r_str_l2g.set_arg(3, bo_str_l2g_edm);
281 const auto t_sl2g_start = std::chrono::steady_clock::now();
282 r_str_l2g.start();
283 r_str_l2g.wait();
284 const auto t_sl2g_done = std::chrono::steady_clock::now();
285 m_stripL2GTime += ns_between(t_sl2g_start, t_sl2g_done);
286 ATH_MSG_DEBUG("Strip L2G time: " << (ns_between(t_sl2g_start, t_sl2g_done) / 1e6) << " ms");
287
288 // EDM Prep (always use PixelEDM and StripEDM kernels)
289 auto& k_pedm = m_pixelEdmPrepKernels[pixelEDMIndex];
290 auto& k_sedm = m_stripEdmPrepKernels[stripEDMIndex];
291
292 xrt::run r_pedm{k_pedm};
293 r_pedm.set_arg(0, bo_pix_cl_edm);
294 r_pedm.set_arg(1, bo_pix_edm_cont);
295
296 xrt::run r_sedm{k_sedm};
297 r_sedm.set_arg(0, bo_str_l2g_edm);
298 r_sedm.set_arg(1, bo_str_edm_cont);
299
300 // Respect dependencies:
301 // - PixelEDM depends on pixel clustering (F110) or pixel L2G (F100)
302 // - StripEDM depends on strip L2G
303 const auto t_pedm_start = std::chrono::steady_clock::now();
304 r_pedm.start();
305
306 const auto t_sedm_start = std::chrono::steady_clock::now();
307 // already waited for r_str_l2g
308 r_sedm.start();
309
310 r_pedm.wait();
311 const auto t_pedm_done = std::chrono::steady_clock::now();
312 m_pixelEdmPrepTime += ns_between(t_pedm_start, t_pedm_done);
313 ATH_MSG_DEBUG("PixelEDMPrep time: " << (ns_between(t_pedm_start, t_pedm_done) / 1e6) << " ms");
314
315 r_sedm.wait();
316 const auto t_sedm_done = std::chrono::steady_clock::now();
317 m_stripEdmPrepTime += ns_between(t_sedm_start, t_sedm_done);
318 ATH_MSG_DEBUG("StripEDMPrep time: " << (ns_between(t_sedm_start, t_sedm_done) / 1e6) << " ms");
319
320 // Kernel window = [first start, last end]
321 const auto t_kend = std::max(t_pedm_done, t_sedm_done);
322 m_kernelTime += ns_between(t_k0, t_kend);
323 ATH_MSG_DEBUG("Kernel execution time: " << (ns_between(t_k0, t_kend) / 1e6) << " ms");
324
325 // Output handles and readbacks
327 ATH_CHECK(FPGAPixelOutput.record(std::make_unique<std::vector<uint32_t>>(EFTrackingTransient::PIXEL_CONTAINER_BUF_SIZE, 0)));
328
330 ATH_CHECK(FPGAStripOutput.record(std::make_unique<std::vector<uint32_t>>(EFTrackingTransient::STRIP_CONTAINER_BUF_SIZE, 0)));
331
332 const auto t_ro0 = std::chrono::steady_clock::now();
333 bo_pix_edm_cont.sync(XCL_BO_SYNC_BO_FROM_DEVICE);
334 bo_pix_edm_cont.read(FPGAPixelOutput->data(), FPGAPixelOutput->size() * sizeof(uint64_t), 0);
335 const auto t_ro1 = std::chrono::steady_clock::now();
336 m_pixelOutputTime += ns_between(t_ro0, t_ro1);
337 ATH_MSG_DEBUG("Pixel output buffer read time: " << (ns_between(t_ro0, t_ro1) / 1e6) << " ms");
338
339 const auto t_ro2 = std::chrono::steady_clock::now();
340 bo_str_edm_cont.sync(XCL_BO_SYNC_BO_FROM_DEVICE);
341 bo_str_edm_cont.read(FPGAStripOutput->data(), FPGAStripOutput->size() * sizeof(uint64_t), 0);
342 const auto t_ro3 = std::chrono::steady_clock::now();
343 m_stripOutputTime += ns_between(t_ro2, t_ro3);
344 ATH_MSG_DEBUG("Strip output buffer read time: " << (ns_between(t_ro2, t_ro3) / 1e6) << " ms");
345
346
347 if(*pixelInputSize == 6) (*FPGAPixelOutput)[0] = 0; // if no pixel input, set the first element to 0
348 if(*stripInputSize == 6) (*FPGAStripOutput)[0] = 0; // if no strip input, set the first element to 0
349
350 return StatusCode::SUCCESS;
351}
352
354{
355 ATH_MSG_INFO("Finalizing F1X0XRTIntegrationAlg");
356 ATH_MSG_INFO("Number of events: " << m_numEvents);
357
358 if (m_numEvents > 0) {
359 ATH_MSG_INFO("Pixel input ave time: " << m_pixelInputTime / m_numEvents / 1e6 << " ms");
360 ATH_MSG_INFO("Strip input ave time: " << m_stripInputTime / m_numEvents / 1e6 << " ms");
361 ATH_MSG_INFO("Pixel clustering ave time: " << m_pixelClusteringTime / m_numEvents / 1e6 << " ms");
362 ATH_MSG_INFO("Strip clustering ave time: " << m_stripClusteringTime / m_numEvents / 1e6 << " ms");
363 if (!m_doF110) {
364 ATH_MSG_INFO("Pixel L2G ave time: " << m_pixelL2GTime / m_numEvents / 1e6 << " ms");
365 }
366 ATH_MSG_INFO("Strip L2G ave time: " << m_stripL2GTime / m_numEvents / 1e6 << " ms");
367 ATH_MSG_INFO("PixelEDMPrep ave time: " << m_pixelEdmPrepTime / m_numEvents / 1e6 << " ms");
368 ATH_MSG_INFO("StripEDMPrep ave time: " << m_stripEdmPrepTime / m_numEvents / 1e6 << " ms");
369 ATH_MSG_INFO("Kernel execution ave time: " << m_kernelTime / m_numEvents / 1e6 << " ms");
370 ATH_MSG_INFO("Pixel output ave time: " << m_pixelOutputTime / m_numEvents / 1e6 << " ms");
371 ATH_MSG_INFO("Strip output ave time: " << m_stripOutputTime / m_numEvents / 1e6 << " ms");
372 }
373
374 return StatusCode::SUCCESS;
375}
376
377void F1X0XRTIntegrationAlg::getListofCUs(std::vector<std::string>& cuNames)
378{
379 xrt::xclbin xrt_xclbin(m_xclbin.value());
380
381 ATH_MSG_INFO("xsa name: " << xrt_xclbin.get_xsa_name());
382 ATH_MSG_INFO("fpga name: " << xrt_xclbin.get_fpga_device_name());
383 ATH_MSG_INFO("uuid: " << xrt_xclbin.get_uuid().to_string());
384
385 for (const xrt::xclbin::kernel &kernel : xrt_xclbin.get_kernels()) {
386 const std::string& kernelName = kernel.get_name();
387 ATH_MSG_INFO("kernelName: " << kernelName);
388 for (const xrt::xclbin::ip &computeUnit : kernel.get_cus()) {
389 const std::string& computeUnitName = computeUnit.get_name();
390 const std::string computeUnitIsolatedName = computeUnitName.substr(kernelName.size() + 1);
391 const std::string computeUnitUsableName = kernelName + ":{" + computeUnitIsolatedName + "}";
392 ATH_MSG_INFO("CU name: " << computeUnitUsableName);
393 cuNames.push_back(computeUnitUsableName);
394 }
395 }
396}
397
398} // namespace EFTrackingFPGAIntegration
Acts::GeometryIdentifier gid
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Maintain a set of objects, one per slot.
Exception-safe IChronoSvc caller.
static Double_t a
Exception-safe IChronoSvc caller.
Definition Chrono.h:50
std::atomic< uint64_t > m_pixelEdmPrepTime
Time for pixel EDM preparation (F110)
std::atomic< uint64_t > m_stripClusteringTime
Time for strip clustering.
ServiceHandle< IChronoSvc > m_chronoSvc
Service for timing the algorithm.
std::atomic< uint64_t > m_pixelOutputTime
Time for pixel output buffer read.
virtual StatusCode execute(const EventContext &ctx) const override final
Should be overriden by derived classes to perform meaningful work.
SG::WriteHandleKey< std::vector< uint32_t > > m_FPGAStripOutput
SG::ReadHandleKey< std::vector< uint64_t > > m_FPGAPixelRDO
std::atomic< uint64_t > m_numEvents
Number of events processed.
std::atomic< uint64_t > m_pixelInputTime
Time for pixel input buffer write.
Gaudi::Property< bool > m_doF110
Boolean to run F110 instead of F100.
std::atomic< uint64_t > m_stripEdmPrepTime
Time for strip EDM preparation (F110)
SG::WriteHandleKey< std::vector< uint32_t > > m_FPGAPixelOutput
SG::ReadHandleKey< std::vector< uint64_t > > m_FPGAStripRDO
std::atomic< uint64_t > m_stripOutputTime
Time for strip output buffer read.
void getListofCUs(std::vector< std::string > &cuNames)
std::atomic< uint64_t > m_stripL2GTime
Time for strip L2G.
Gaudi::Property< std::string > m_xclbin
Path and name of the xclbin file.
std::atomic< uint64_t > m_stripInputTime
Time for strip input buffer write.
std::atomic< uint64_t > m_pixelClusteringTime
Time for pixel clustering.
std::atomic< uint64_t > m_pixelL2GTime
Time for pixel L2G (F100)
virtual StatusCode initialize() override final
Detect the OpenCL devices and prepare OpenCL context.
std::atomic< uint64_t > m_kernelTime
Time window covering kernel execution.
StatusCode precheck(const std::vector< Gaudi::Property< std::string > > &inputs) const
Check if the the desired Gaudi properties are set.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
The class for enconding RDO to FPGA format.
static uint64_t ns_between(const std::chrono::steady_clock::time_point &a, const std::chrono::steady_clock::time_point &b)
constexpr unsigned long PIXEL_CONTAINER_INPUT_BUF_SIZE
constexpr uint32_t STRIP_CONTAINER_BUF_SIZE
constexpr unsigned long STRIP_CONTAINER_INPUT_BUF_SIZE
constexpr uint32_t STRIP_BLOCK_BUF_SIZE
constexpr uint32_t PIXEL_BLOCK_BUF_SIZE
constexpr uint32_t PIXEL_CONTAINER_BUF_SIZE
size_t getNSlots()
Return the number of event slots.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.