ATLAS Offline Software
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 
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 
108 StatusCode IntegrationBase::execute(const EventContext &ctx) const
109 {
110  ATH_MSG_DEBUG("In execute(), event slot: "<<ctx.slot());
111 
112  return StatusCode::SUCCESS;
113 }
114 
115 StatusCode 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 
154 StatusCode 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 }
IntegrationBase::m_accelerator
cl::Device m_accelerator
Device object for the accelerator card.
Definition: IntegrationBase.h:66
IntegrationBase::initialize
virtual StatusCode initialize() override
Detect the OpenCL devices and prepare OpenCL context.
Definition: IntegrationBase.cxx:16
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
IntegrationBase::m_context
cl::Context m_context
Context object for the application.
Definition: IntegrationBase.h:67
IntegrationBase.h
postInclude.inputs
inputs
Definition: postInclude.SortInput.py:15
PyPoolBrowser.item
item
Definition: PyPoolBrowser.py:129
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:183
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
IntegrationBase::m_deviceBDF
Gaudi::Property< std::string > m_deviceBDF
BDF ID of the accelerator card.
Definition: IntegrationBase.h:69
IntegrationBase::execute
virtual StatusCode execute(const EventContext &ctx) const
Should be overriden by derived classes to perform meaningful work.
Definition: IntegrationBase.cxx:108
plotting.yearwise_luminosity_vs_mu.bins
bins
Definition: yearwise_luminosity_vs_mu.py:30
IntegrationBase::precheck
StatusCode precheck(const std::vector< Gaudi::Property< std::string >> &inputs) const
Check if the the desired Gaudi properties are set.
Definition: IntegrationBase.cxx:154
IntegrationBase::loadProgram
StatusCode loadProgram(const std::string &xclbin)
Find the xclbin file and load it into the OpenCL program object.
Definition: IntegrationBase.cxx:115
IntegrationBase::m_doEmulation
Gaudi::Property< bool > m_doEmulation
Definition: IntegrationBase.h:70
python.output.AtlRunQueryRoot.pf
pf
Definition: AtlRunQueryRoot.py:988
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
IntegrationBase::m_program
cl::Program m_program
Program object containing the kernel.
Definition: IntegrationBase.h:68