ATLAS Offline Software
Loading...
Searching...
No Matches
F1X0IntegrationAlg.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#include <xrt/xrt_bo.h>
9#include <xrt/xrt_device.h>
10#include <xrt/xrt_kernel.h>
11#include <xrt/xrt_uuid.h>
12
14{
16 {
17 ATH_MSG_INFO("Running on the FPGA accelerator");
18
20
21 ATH_CHECK(m_chronoSvc.retrieve());
22
23 {
24 Athena::Chrono chrono("Platform and device initlize", m_chronoSvc.get());
26 }
27
28 {
29 Athena::Chrono chrono("CL::loadProgram", m_chronoSvc.get());
31 }
32 ATH_MSG_INFO("loading "<<m_xclbin);
33
34
35 ATH_CHECK(m_FPGAStripRDO.initialize());
36 ATH_CHECK(m_FPGAPixelRDO.initialize());
37
38 ATH_CHECK(m_FPGAStripOutput.initialize());
39 ATH_CHECK(m_FPGAPixelOutput.initialize());
40 ATH_CHECK(m_FPGAPixelRDOSize.initialize());
41 ATH_CHECK(m_FPGAStripRDOSize.initialize());
42
43 std::vector<std::string> listofCUs;
44
45 getListofCUs(listofCUs);
46
47 cl_int err = 0;
48
49 unsigned int nthreads = m_FPGAThreads.value();
50
51 if(m_FPGAThreads.value() < 1){
52 nthreads = SG::getNSlots();
53 }
54
55 // create the buffers
56 for(unsigned int i = 0; i < nthreads; i++)
57 {
58 m_acc_queues.emplace_back(m_context, m_accelerator, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err);
59
60 // Input
61 m_pixelClusterInputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_ONLY, EFTrackingTransient::PIXEL_CONTAINER_INPUT_BUF_SIZE * sizeof(uint64_t), NULL, &err));
62 m_stripClusterInputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_ONLY, EFTrackingTransient::STRIP_CONTAINER_INPUT_BUF_SIZE * sizeof(uint64_t), NULL, &err));
63
64 // Clustering
65 if (!m_doF110) {
66 m_pixelClusterOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
67 }
68 m_stripClusterOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
69 m_pixelClusterEDMOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE,EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
70 m_stripClusterEDMOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
71 // L2G
72 if (!m_doF110) {
73 m_pixelL2GOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
74 m_pixelL2GEDMOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::PIXEL_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
75 }
76 m_stripL2GOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
77 m_stripL2GEDMOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::STRIP_BLOCK_BUF_SIZE * sizeof(uint64_t), NULL, &err));
78 // EDMPrep
79 m_edmPixelOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::PIXEL_CONTAINER_BUF_SIZE * sizeof(uint32_t), NULL, &err));
80 m_edmStripOutputBufferList.push_back(cl::Buffer(m_context, CL_MEM_READ_WRITE, EFTrackingTransient::STRIP_CONTAINER_BUF_SIZE * sizeof(uint32_t), NULL, &err));
81 }
82
83 // Create kernels for each one of CUs that is inside device
84 for (const auto& cuName: listofCUs)
85 {
86 // Pixel clustering
87 if(cuName.find(m_pixelClusterKernelName.value()) != std::string::npos) m_pixelClusteringKernels.emplace_back(cl::Kernel(m_program, cuName.c_str()));
88
89 // Strip clustering
90 else if(cuName.find(m_stripClusterKernelName.value()) != std::string::npos) m_stripClusteringKernels.emplace_back(cl::Kernel(m_program, cuName.c_str()));
91
92 // Pixel L2G
93 else if(!m_doF110 && cuName.find(m_pixelL2GKernelName.value()) != std::string::npos) m_pixelL2GKernels.emplace_back(cl::Kernel(m_program, cuName.c_str()));
94
95 // Strip L2G
96 else if(cuName.find(m_stripL2GKernelName.value()) != std::string::npos) m_stripL2GKernels.emplace_back(cl::Kernel(m_program, cuName.c_str()));
97
98 // EDM prep
99 else if(cuName.find(m_pixelEdmKernelName.value()) != std::string::npos) m_pixelEdmPrepKernels.emplace_back(cl::Kernel(m_program, cuName.c_str()));
100
101 else if(cuName.find(m_stripEdmKernelName.value()) != std::string::npos) m_stripEdmPrepKernels.emplace_back(cl::Kernel(m_program, cuName.c_str()));
102 else
103 {
104 ATH_MSG_WARNING("Do not recognize kernel name: "<<cuName);
105 }
106 }
107
108 ATH_MSG_INFO(m_pixelClusterKernelName.value()<<" size: "<<m_pixelClusteringKernels.size());
109 ATH_MSG_INFO(m_stripClusterKernelName.value()<<" size: "<<m_stripClusteringKernels.size());
110 ATH_MSG_INFO(m_pixelL2GKernelName.value()<<" size: "<<m_pixelL2GKernels.size());
111 ATH_MSG_INFO(m_stripL2GKernelName.value()<<" size: "<<m_stripL2GKernels.size());
112 ATH_MSG_INFO(m_pixelEdmKernelName.value()<<" size: "<<m_pixelEdmPrepKernels.size());
113 ATH_MSG_INFO(m_stripEdmKernelName.value()<<" size: "<<m_stripEdmPrepKernels.size());
114
115 if(m_pixelClusteringKernels.size()==0){
116 ATH_MSG_FATAL("No m_pixelClusteringKernels constructed");
117 return StatusCode::FAILURE;
118 }
119
120 // monitoring
121 if ( !m_monTool.empty() ) {
122 ATH_CHECK(m_monTool.retrieve() );
123 }
124 else {
125 ATH_MSG_INFO("Monitoring tool is empty");
126 }
127
128 return StatusCode::SUCCESS;
129 }
130
131 StatusCode F1X0IntegrationAlg::execute(const EventContext &ctx) const
132 {
133 ATH_MSG_DEBUG("Executing F1X0IntegrationAlg");
134 auto mnt_timer_Total = Monitored::Timer<std::chrono::milliseconds>("TIME_Total");
135 auto monTime = Monitored::Group(m_monTool, mnt_timer_Total);
136
137 mnt_timer_Total.start();
138
139 m_numEvents++;
140
142 const std::vector<uint64_t>* pixelInput{nullptr}, *stripInput{nullptr};
143 ATH_CHECK(SG::get(pixelInput, m_FPGAPixelRDO, ctx));
144 ATH_CHECK(SG::get(stripInput, m_FPGAStripRDO, ctx));
145
146 const int* pixelInputSize{nullptr}, *stripInputSize{nullptr};
147 ATH_CHECK(SG::get(pixelInputSize, m_FPGAPixelRDOSize, ctx));
148 ATH_CHECK(SG::get(stripInputSize, m_FPGAStripRDOSize, ctx));
149
150 // logic
151 unsigned int nthreads = m_FPGAThreads.value();
152
153 if(m_FPGAThreads.value() < 1){
154 nthreads = SG::getNSlots();
155 }
156
157 size_t bufferIndex = ctx.slot() % nthreads;
158
159 // Get index for each of the kernels
160 size_t pixelClusterIndex = ctx.slot() % m_pixelClusteringKernels.size();
161 size_t stripClusterIndex = ctx.slot() % m_stripClusteringKernels.size();
162 size_t stripL2GIndex = ctx.slot() % m_stripL2GKernels.size();
163 size_t pixelL2GIndex = m_pixelL2GKernels.size() ? ctx.slot() % m_pixelL2GKernels.size() : 0;
164 size_t pixelEDMIndex = m_pixelEdmPrepKernels.size() ? ctx.slot() % m_pixelEdmPrepKernels.size() : 0;
165 size_t stripEDMIndex = m_stripEdmPrepKernels.size() ? ctx.slot() % m_stripEdmPrepKernels.size() : 0;
166
167 const cl::CommandQueue &acc_queue = m_acc_queues[bufferIndex];
168
169 cl::Kernel &pixelClusteringKernel = m_pixelClusteringKernels[pixelClusterIndex];
170 cl::Kernel &stripClusteringKernel = m_stripClusteringKernels[stripClusterIndex];
171 cl::Kernel &stripL2GKernel = m_stripL2GKernels[stripL2GIndex];
172 cl::Kernel &pixelEdmPrepKernel = m_pixelEdmPrepKernels[pixelEDMIndex];
173 cl::Kernel &stripEdmPrepKernel = m_stripEdmPrepKernels[stripEDMIndex];
174 cl::Kernel *pixelL2GKernel = nullptr;
175
176 if (!m_doF110) pixelL2GKernel = &m_pixelL2GKernels[pixelL2GIndex];
177
178 // Set kernel arguments
179 pixelClusteringKernel.setArg(0, m_pixelClusterInputBufferList[bufferIndex]);
180 if (m_doF110) {
181 pixelClusteringKernel.setArg(1, m_pixelClusterEDMOutputBufferList[bufferIndex]);
182 } else {
183 pixelClusteringKernel.setArg(1, m_pixelClusterOutputBufferList[bufferIndex]);
184 pixelClusteringKernel.setArg(2, m_pixelClusterEDMOutputBufferList[bufferIndex]);
185
186 uint32_t hit_vector_size_bytes = sizeof(uint64_t) * (*pixelInput).size();
187 uint32_t cluster_vector_size_bytes = sizeof(uint64_t) * (*pixelInput).size();
188 uint32_t edm_vector_size_bytes = sizeof(uint64_t) * (*pixelInput).size() * 8;
189
190
191 pixelClusteringKernel.setArg(3, hit_vector_size_bytes);
192 pixelClusteringKernel.setArg(4, cluster_vector_size_bytes);
193 pixelClusteringKernel.setArg(5, edm_vector_size_bytes);
194 }
195
196 stripClusteringKernel.setArg(0, m_stripClusterInputBufferList[bufferIndex]);
197 stripClusteringKernel.setArg(1, m_stripClusterOutputBufferList[bufferIndex]);
198 stripClusteringKernel.setArg(2, m_stripClusterEDMOutputBufferList[bufferIndex]);
199 stripClusteringKernel.setArg(3, static_cast<unsigned int>(*stripInputSize));
200
201 if (!m_doF110) {
202 pixelL2GKernel->setArg(0, m_pixelClusterOutputBufferList[bufferIndex]);
203 pixelL2GKernel->setArg(1, m_pixelClusterEDMOutputBufferList[bufferIndex]);
204 pixelL2GKernel->setArg(2, m_pixelL2GOutputBufferList[bufferIndex]);
205 pixelL2GKernel->setArg(3, m_pixelL2GEDMOutputBufferList[bufferIndex]);
206 }
207
208 stripL2GKernel.setArg(0, m_stripClusterOutputBufferList[bufferIndex]);
209 stripL2GKernel.setArg(1, m_stripClusterEDMOutputBufferList[bufferIndex]);
210 stripL2GKernel.setArg(2, m_stripL2GOutputBufferList[bufferIndex]);
211 stripL2GKernel.setArg(3, m_stripL2GEDMOutputBufferList[bufferIndex]);
212
213
214 pixelEdmPrepKernel.setArg(0, m_pixelClusterEDMOutputBufferList[bufferIndex]);
215 pixelEdmPrepKernel.setArg(1, m_edmPixelOutputBufferList[bufferIndex]);
216 stripEdmPrepKernel.setArg(0, m_stripL2GEDMOutputBufferList[bufferIndex]);
217 stripEdmPrepKernel.setArg(1, m_edmStripOutputBufferList[bufferIndex]);
218
219
220
221 // Start the transfers
222 cl::Event evt_write_pixel_input;
223 cl::Event evt_write_strip_input;
224
225 acc_queue.enqueueWriteBuffer(m_pixelClusterInputBufferList[bufferIndex], CL_FALSE, 0, sizeof(uint64_t) * (*pixelInput).size(), (*pixelInput).data(), NULL, &evt_write_pixel_input);
226 acc_queue.enqueueWriteBuffer(m_stripClusterInputBufferList[bufferIndex], CL_FALSE, 0, sizeof(uint64_t) * (*stripInput).size(), (*stripInput).data(), NULL, &evt_write_strip_input);
227 std::vector<cl::Event> evt_vec_pixel_input{evt_write_pixel_input};
228 std::vector<cl::Event> evt_vec_strip_input{evt_write_strip_input};
229
230
231 cl::Event evt_pixel_clustering;
232 cl::Event evt_strip_clustering;
233 cl::Event evt_strip_l2g;
234 cl::Event evt_pixel_l2g;
235 cl::Event evt_edm_prep;
236 cl::Event evt_pixel_edm_prep;
237 cl::Event evt_strip_edm_prep;
238 {
239 Athena::Chrono chrono("Kernel execution", m_chronoSvc.get());
240 acc_queue.enqueueTask(pixelClusteringKernel, &evt_vec_pixel_input, &evt_pixel_clustering);
241 acc_queue.enqueueTask(stripClusteringKernel, &evt_vec_strip_input, &evt_strip_clustering);
242
243 std::vector<cl::Event> evt_vec_strip_clustering{evt_strip_clustering};
244 if (!m_doF110)
245 {
246 std::vector<cl::Event> evt_vec_pixel_clustering{evt_pixel_clustering};
247 acc_queue.enqueueTask(*pixelL2GKernel, &evt_vec_pixel_clustering, &evt_pixel_l2g);
248 }
249 acc_queue.enqueueTask(stripL2GKernel, &evt_vec_strip_clustering, &evt_strip_l2g);
250
251 std::vector<cl::Event> evt_vec_pixelEDM;
252 if(m_doF110) evt_vec_pixelEDM.push_back(evt_pixel_clustering);
253 else evt_vec_pixelEDM.push_back(evt_pixel_l2g);
254 std::vector<cl::Event> evt_vec_strip_l2g{evt_strip_l2g};
255 acc_queue.enqueueTask(pixelEdmPrepKernel, &evt_vec_pixelEDM, &evt_pixel_edm_prep);
256 acc_queue.enqueueTask(stripEdmPrepKernel, &evt_vec_strip_l2g, &evt_strip_edm_prep);
257
258 }
259
260 cl::Event evt_pixel_cluster_output;
261 cl::Event evt_strip_cluster_output;
262
263 std::vector<cl::Event> evt_vec_pixel_edm_prep;
264 std::vector<cl::Event> evt_vec_strip_edm_prep;
265
266 evt_vec_pixel_edm_prep.push_back(evt_pixel_edm_prep);
267 evt_vec_strip_edm_prep.push_back(evt_strip_edm_prep);
268
269
270 // output handles
271
273 ATH_CHECK(FPGAPixelOutput.record(std::make_unique<std::vector<uint32_t> >(EFTrackingTransient::PIXEL_CONTAINER_BUF_SIZE, 0)));
274
276 ATH_CHECK(FPGAStripOutput.record(std::make_unique<std::vector<uint32_t> >(EFTrackingTransient::STRIP_CONTAINER_BUF_SIZE, 0)));
277
278 acc_queue.enqueueReadBuffer(m_edmPixelOutputBufferList[bufferIndex], CL_FALSE, 0, sizeof(uint32_t) * (*FPGAPixelOutput).size(), (*FPGAPixelOutput).data(), &evt_vec_pixel_edm_prep, &evt_pixel_cluster_output);
279 acc_queue.enqueueReadBuffer(m_edmStripOutputBufferList[bufferIndex], CL_FALSE, 0, sizeof(uint32_t) * (*FPGAStripOutput).size(), (*FPGAStripOutput).data(), &evt_vec_strip_edm_prep, &evt_strip_cluster_output);
280
281 std::vector<cl::Event> wait_for_reads = { evt_pixel_cluster_output, evt_strip_cluster_output };
282 cl::Event::waitForEvents(wait_for_reads);
283
284 mnt_timer_Total.stop();
285
286 if(*pixelInputSize == 6) (*FPGAPixelOutput)[0] = 0; // if no pixel input, set the first element to 0
287 if(*stripInputSize == 6) (*FPGAStripOutput)[0] = 0; // if no strip input, set the first element to 0
288
289 // calculate the time for the kernel execution
290 // get the time of writing pixel input buffer
291 cl_ulong pixel_input_time = evt_write_pixel_input.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_write_pixel_input.getProfilingInfo<CL_PROFILING_COMMAND_START>();
292 m_pixelInputTime += pixel_input_time;
293 ATH_MSG_DEBUG("Pixel input buffer write time: " << pixel_input_time / 1e6 << " ms");
294
295 // get the time of writing strip input buffer
296 cl_ulong strip_input_time = evt_write_strip_input.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_write_strip_input.getProfilingInfo<CL_PROFILING_COMMAND_START>();
297 m_stripInputTime += strip_input_time;
298 ATH_MSG_DEBUG("Strip input buffer write time: " << strip_input_time / 1e6 << " ms");
299
300 // get the time of pixel clustering
301 cl_ulong pixel_clustering_time = evt_pixel_clustering.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_pixel_clustering.getProfilingInfo<CL_PROFILING_COMMAND_START>();
302 m_pixelClusteringTime += pixel_clustering_time;
303 ATH_MSG_DEBUG("Pixel clustering time: " << pixel_clustering_time / 1e6 << " ms");
304
305 // get the time of strip clustering
306 cl_ulong strip_clustering_time = evt_strip_clustering.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_strip_clustering.getProfilingInfo<CL_PROFILING_COMMAND_START>();
307 m_stripClusteringTime += strip_clustering_time;
308 ATH_MSG_DEBUG("Strip clustering time: " << strip_clustering_time / 1e6 << " ms");
309
310 if (!m_doF110) {
311 // get the time of pixel L2G
312 cl_ulong pixel_l2g_time = evt_pixel_l2g.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_pixel_l2g.getProfilingInfo<CL_PROFILING_COMMAND_START>();
313 m_pixelL2GTime += pixel_l2g_time;
314 ATH_MSG_DEBUG("Pixel L2G time: " << pixel_l2g_time / 1e6 << " ms");
315 }
316
317 // get the time of strip L2G
318 cl_ulong strip_l2g_time = evt_strip_l2g.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_strip_l2g.getProfilingInfo<CL_PROFILING_COMMAND_START>();
319 m_stripL2GTime += strip_l2g_time;
320 ATH_MSG_DEBUG("Strip L2G time: " << strip_l2g_time / 1e6 << " ms");
321
322 // get the time of EDMPrep
323 if (m_doF110) {
324 cl_ulong pixel_edm_prep_time = evt_pixel_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_pixel_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_START>();
325 cl_ulong strip_edm_prep_time = evt_strip_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_strip_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_START>();
326
327 m_pixelEdmPrepTime += pixel_edm_prep_time;
328 ATH_MSG_DEBUG("PixelEDMPrep time: " << pixel_edm_prep_time / 1e6 << " ms");
329
330 m_stripEdmPrepTime += strip_edm_prep_time;
331 ATH_MSG_DEBUG("StripEDMPrep time: " << strip_edm_prep_time / 1e6 << " ms");
332 }
333 else {
334 cl_ulong edm_prep_time = evt_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_START>();
335
336 m_edmPrepTime += edm_prep_time;
337 ATH_MSG_DEBUG("EDMPrep time: " << edm_prep_time / 1e6 << " ms");
338 }
339
340 // get the time of the whole kernel execution
341 cl_ulong kernel_start = evt_pixel_clustering.getProfilingInfo<CL_PROFILING_COMMAND_QUEUED>();
342 cl_ulong kernel_end = m_doF110 ?
343 std::max(evt_pixel_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_END>(), evt_strip_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_END>()) :
344 evt_edm_prep.getProfilingInfo<CL_PROFILING_COMMAND_END>();
345 m_kernelTime += (kernel_end - kernel_start);
346 ATH_MSG_DEBUG("Kernel execution time: " << (kernel_end - kernel_start) / 1e6 << " ms");
347
348 // get the time of reading pixel output buffer
349 cl_ulong pixel_output_time = evt_pixel_cluster_output.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_pixel_cluster_output.getProfilingInfo<CL_PROFILING_COMMAND_START>();
350 m_pixelOutputTime += pixel_output_time;
351 ATH_MSG_DEBUG("Pixel output buffer read time: " << pixel_output_time / 1e6 << " ms");
352
353 // get the time of reading strip output buffer
354 cl_ulong strip_output_time = evt_strip_cluster_output.getProfilingInfo<CL_PROFILING_COMMAND_END>() - evt_strip_cluster_output.getProfilingInfo<CL_PROFILING_COMMAND_START>();
355 m_stripOutputTime += strip_output_time;
356 ATH_MSG_DEBUG("Strip output buffer read time: " << strip_output_time / 1e6 << " ms");
357
358 return StatusCode::SUCCESS;
359 }
360
362 {
363
364 ATH_MSG_INFO("Finalizing F1X0IntegrationAlg");
365 ATH_MSG_INFO("Number of events: " << m_numEvents);
366
367 if(m_numEvents > 0){
368 ATH_MSG_INFO("Pixel input ave time: " << m_pixelInputTime / m_numEvents / 1e6 << " ms");
369 ATH_MSG_INFO("Strip input ave time: " << m_stripInputTime / m_numEvents / 1e6 << " ms");
370 ATH_MSG_INFO("Pixel clustering ave time: " << m_pixelClusteringTime / m_numEvents / 1e6 << " ms");
371 ATH_MSG_INFO("Strip clustering ave time: " << m_stripClusteringTime / m_numEvents / 1e6 << " ms");
372 if (!m_doF110) {
373 ATH_MSG_INFO("Pixel L2G ave time: " << m_pixelL2GTime / m_numEvents / 1e6 << " ms");
374 }
375 ATH_MSG_INFO("Strip L2G ave time: " << m_stripL2GTime / m_numEvents / 1e6 << " ms");
376 if (!m_doF110) {
377 ATH_MSG_INFO("EDMPrep ave time: " << m_edmPrepTime / m_numEvents / 1e6 << " ms");
378 } else {
379 ATH_MSG_INFO("PixelEDMPrep ave time: " << m_pixelEdmPrepTime / m_numEvents / 1e6 << " ms");
380 ATH_MSG_INFO("StripEDMPrep ave time: " << m_stripEdmPrepTime / m_numEvents / 1e6 << " ms");
381 }
382 ATH_MSG_INFO("Kernel execution ave time: " << m_kernelTime / m_numEvents / 1e6 << " ms");
383 ATH_MSG_INFO("Pixel output ave time: " << m_pixelOutputTime / m_numEvents / 1e6 << " ms");
384 ATH_MSG_INFO("Strip output ave time: " << m_stripOutputTime / m_numEvents / 1e6 << " ms");
385 }
386
387 return StatusCode::SUCCESS;
388 }
389
390 void F1X0IntegrationAlg::getListofCUs(std::vector<std::string>& cuNames)
391 {
392 xrt::xclbin xrt_xclbin(m_xclbin.value());
393
394 ATH_MSG_INFO("xsa name: "<<xrt_xclbin.get_xsa_name());
395 ATH_MSG_INFO("fpga name: "<<xrt_xclbin.get_fpga_device_name());
396 ATH_MSG_INFO("uuid: "<<xrt_xclbin.get_uuid().to_string());
397
398 for (const xrt::xclbin::kernel &kernel : xrt_xclbin.get_kernels()) {
399 const std::string& kernelName = kernel.get_name();
400
401 ATH_MSG_INFO("kernelName: "<<kernelName);
402
403
404 for (const xrt::xclbin::ip &computeUnit : kernel.get_cus()) {
405 const std::string& computeUnitName = computeUnit.get_name();
406 const std::string computeUnitIsolatedName = computeUnitName.substr(kernelName.size() + 1);
407
408 const std::string computeUnitUsableName = kernelName + ":{" + computeUnitIsolatedName + "}";
409
410 ATH_MSG_INFO("CU name: "<<computeUnitUsableName);
411 cuNames.push_back(computeUnitUsableName);
412 }
413 }
414 }
415
416} // namespace EFTrackingFPGAIntegration
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(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.
Exception-safe IChronoSvc caller.
Definition Chrono.h:50
std::atomic< ulonglong > m_numEvents
Number of events processed.
Gaudi::Property< std::string > m_xclbin
Path and name of the xclbin file.
virtual StatusCode execute(const EventContext &ctx) const override final
Should be overriden by derived classes to perform meaningful work.
ToolHandle< GenericMonitoringTool > m_monTool
std::atomic< cl_ulong > m_pixelOutputTime
Time for pixel output buffer read.
SG::ReadHandleKey< std::vector< uint64_t > > m_FPGAPixelRDO
void getListofCUs(std::vector< std::string > &cuNames)
std::atomic< cl_ulong > m_stripL2GTime
Time for strip L2G.
Gaudi::Property< std::string > m_pixelClusterKernelName
Name of the pixel clustering kernel.
Gaudi::Property< std::string > m_pixelL2GKernelName
Name of the pixel L2G kernel.
std::atomic< cl_ulong > m_stripEdmPrepTime
Time for strip EDM preparation.
std::atomic< cl_ulong > m_stripClusteringTime
Time for strip clustering.
std::atomic< cl_ulong > m_pixelClusteringTime
Time for pixel clustering.
SG::WriteHandleKey< std::vector< uint32_t > > m_FPGAPixelOutput
std::atomic< cl_ulong > m_stripOutputTime
Time for strip output buffer read.
virtual StatusCode initialize() override final
Detect the OpenCL devices and prepare OpenCL context.
std::atomic< cl_ulong > m_pixelInputTime
Time for pixel input buffer write.
SG::ReadHandleKey< std::vector< uint64_t > > m_FPGAStripRDO
ServiceHandle< IChronoSvc > m_chronoSvc
Service for timing the algorithm.
std::atomic< cl_ulong > m_pixelEdmPrepTime
Time for pixel EDM preparation.
std::vector< cl::Buffer > m_stripClusterEDMOutputBufferList
Gaudi::Property< std::string > m_pixelEdmKernelName
Name of the FPGA kernel.
std::atomic< cl_ulong > m_pixelL2GTime
Time for pixel L2G.
Gaudi::Property< bool > m_doF110
Boolean to run F110 instead of F100.
Gaudi::Property< std::string > m_stripClusterKernelName
Name of the strip clustering kernel.
virtual StatusCode finalize() override final
SG::WriteHandleKey< std::vector< uint32_t > > m_FPGAStripOutput
std::vector< cl::Buffer > m_pixelClusterEDMOutputBufferList
std::atomic< cl_ulong > m_kernelTime
Time for kernel execution.
std::atomic< cl_ulong > m_stripInputTime
Time for strip input buffer write.
Gaudi::Property< std::string > m_stripL2GKernelName
Name of the strip L2G kernelS.
std::atomic< cl_ulong > m_edmPrepTime
Time for EDM preparation.
Gaudi::Property< std::string > m_stripEdmKernelName
Name of the FPGA kernel.
StatusCode loadProgram(const std::string &xclbin)
Find the xclbin file and load it into the OpenCL program object.
cl::Program m_program
Program object containing the kernel.
virtual StatusCode initialize() override
Detect the OpenCL devices and prepare OpenCL context.
cl::Context m_context
Context object for the application.
StatusCode precheck(const std::vector< Gaudi::Property< std::string > > &inputs) const
Check if the the desired Gaudi properties are set.
cl::Device m_accelerator
Device object for the accelerator card.
Group of local monitoring quantities and retain correlation when filling histograms
A monitored timer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
The class for enconding RDO to FPGA format.
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.