ATLAS Offline Software
Loading...
Searching...
No Matches
IntegrationBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
10
12#include <fstream>
13#include <CL/cl_ext_xilinx.h>
14
15
17{
18 // Perform the usual OpenCL setup here
19 // Find device
20 std::vector<cl::Platform> platforms;
21 cl_int err = cl::Platform::get(&platforms);
22
23 if (err == CL_SUCCESS)
24 {
25 ATH_MSG_INFO("Detected OpenCL platforms: " << platforms.size());
26 }
27 else
28 {
29 ATH_MSG_ERROR("Error calling cl::Platform::get. Error code: " << err);
30 return StatusCode::FAILURE;
31 }
32
33 std::vector<cl::Device> allDevices;
34 int device_id = 0;
35
36 bool foundAccelerator = false;
37
38 // Print platform information
39 for (cl::Platform pf : platforms)
40 {
41 ATH_MSG_INFO("In initialize()");
42 ATH_MSG_INFO("---");
43 ATH_MSG_INFO("Platform name: " << pf.getInfo<CL_PLATFORM_NAME>());
44 ATH_MSG_INFO("Platform profile: " << pf.getInfo<CL_PLATFORM_PROFILE>());
45 ATH_MSG_INFO("Platform vendor: " << pf.getInfo<CL_PLATFORM_VENDOR>());
46
47 pf.getDevices(CL_DEVICE_TYPE_ALL, &allDevices);
48 ATH_MSG_INFO("There are " << allDevices.size() << " devices in this platform.");
49
50 for(auto device : allDevices)
51 {
52 // If emulation is being used, use the first device
53 if(m_doEmulation.value())
54 {
55 m_accelerator = device;
56 foundAccelerator = true;
57 break;
58 }
59
60 if (device.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_ACCELERATOR)
61 {
62 std::string deviceBDF = "";
63 device.getInfo(CL_DEVICE_PCIE_BDF, &deviceBDF);
64 // check if the user specify the BDF of the device
65 if (!m_deviceBDF.empty())
66 {
67 if (deviceBDF == m_deviceBDF)
68 {
69 ATH_MSG_INFO("Found the device with BDF: " << m_deviceBDF.value());
70 m_accelerator = device;
71 foundAccelerator = true;
72 break;
73 }
74 }
75 else
76 {
77 ATH_MSG_INFO("Using the first found accelerator card: " << device.getInfo<CL_DEVICE_NAME>());
78 m_accelerator = device;
79 foundAccelerator = true;
80 break;
81 }
82 }
83 device_id++;
84 }
85
86 if(!foundAccelerator)
87 {
88 ATH_MSG_INFO("Couldn't find an FPGA accelerator card in this platform");
89 } else {
90 break;
91 }
92 }
93
94 if(!foundAccelerator)
95 {
96 ATH_MSG_ERROR("Couldn't find an FPGA accelerator card on any platform");
97 return StatusCode::FAILURE;
98 }
99
100 ATH_MSG_INFO("Using device number " << device_id << " which is a FPGA accelerator card: " << m_accelerator.getInfo<CL_DEVICE_NAME>());
101
102 // Create context
103 m_context = cl::Context({m_accelerator});
104
105 return StatusCode::SUCCESS;
106}
107
108StatusCode IntegrationBase::execute(const EventContext &ctx) const
109{
110 ATH_MSG_DEBUG("In execute(), event slot: "<<ctx.slot());
111
112 return StatusCode::SUCCESS;
113}
114
115StatusCode IntegrationBase::loadProgram(const std::string& xclbin)
116{
117 // Open binary object in binary mode
118 std::ifstream bin_file(xclbin, std::ios_base::binary);
119 if (!bin_file)
120 {
121 ATH_MSG_ERROR("Couldn't find the xclbin file: " << xclbin);
122 return StatusCode::FAILURE;
123 }
124 // Get the size of the binary file
125 bin_file.seekg(0, bin_file.end);
126 unsigned bin_size = bin_file.tellg();
127 // Reset the reference point back to the beginning
128 bin_file.seekg(0, bin_file.beg);
129 // Create a new pointer for the binary buffer and get the set a pointer to the binary buffer
130 std::vector<char> buf(bin_size);
131 bin_file.read(buf.data(), bin_size);
132
133 // Create binary object and program object
134 cl_int err = 0;
135 std::vector<cl_int> binaryStatus;
136 cl::Program::Binaries bins{{buf.data(), bin_size}};
137 m_program = cl::Program(m_context, {m_accelerator}, bins, &binaryStatus, &err);
138
139 bin_file.close();
140
141 if (err == CL_SUCCESS && binaryStatus.at(0) == CL_SUCCESS)
142 {
143 ATH_MSG_INFO("Successfully loaded xclbin file into " << m_accelerator.getInfo<CL_DEVICE_NAME>());
144 }
145 else
146 {
147 ATH_MSG_ERROR("Error loading xclbin file (" << xclbin << ") into " << m_accelerator.getInfo<CL_DEVICE_NAME>() <<". Error code: " << err);
148 return StatusCode::FAILURE;
149 }
150
151 return StatusCode::SUCCESS;
152}
153
154StatusCode IntegrationBase::precheck(const std::vector<Gaudi::Property<std::string>>& inputs) const
155{
156 for(const auto &item : inputs)
157 {
158 if(item.empty())
159 {
160 ATH_MSG_FATAL(item.documentation()<<" is empty. Please set it to a valid value");
161 return StatusCode::FAILURE;
162 }
163 }
164
165 // Always check if bdf is set
166 if (m_deviceBDF.empty())
167 {
168 ATH_MSG_WARNING("Device BDF is not set. Using the first found accelerator card. Set property 'bdfID' to specify the BDF of the device.");
169 }
170
171 return StatusCode::SUCCESS;
172}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static const std::vector< std::string > bins
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.
Gaudi::Property< bool > m_doEmulation
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.
Gaudi::Property< std::string > m_deviceBDF
BDF ID of the accelerator card.
cl::Device m_accelerator
Device object for the accelerator card.
virtual StatusCode execute(const EventContext &ctx) const
Should be overriden by derived classes to perform meaningful work.