11 #include <CL/cl_ext_xilinx.h>
21 std::vector<cl::Platform> platforms;
25 for (
const cl::Platform &
platform : platforms) {
29 std::string platform_name;
31 if (platform_name !=
"Xilinx") {
37 std::vector<cl::Device> devices;
40 ATH_MSG_DEBUG(
"Found XRT/OpenCL platform '" << platform_name <<
"' with "
48 for (
const cl::Device &device : devices) {
54 std::string list_device_name;
55 ATH_CHECK(
list[0].getInfo(CL_DEVICE_NAME, &list_device_name) ==
57 if (device_name == list_device_name) {
59 list.push_back(device);
64 std::vector<cl::Device> new_list = {device};
76 return StatusCode::FAILURE;
83 return StatusCode::SUCCESS;
96 return StatusCode::FAILURE;
103 "More XCLBIN file(s) specified than "
104 "devices type available ("
109 return StatusCode::FAILURE;
116 ATH_MSG_ERROR(
"XCLBIN file does not exist: " << xclbin_path);
117 return StatusCode::FAILURE;
125 xrt::xclbin xrt_xclbin(xclbin_path);
126 xclbin_info.
path = xclbin_path;
127 xclbin_info.
xsa_name = xrt_xclbin.get_xsa_name();
129 xclbin_info.
uuid = xrt_xclbin.get_uuid().to_string();
131 for (
const xrt::xclbin::kernel &kernel : xrt_xclbin.get_kernels()) {
132 const std::string& kernelName = kernel.get_name();
138 if (!kernel.get_cus().empty()) {
143 const std::string& computeUnitName = computeUnit.get_name();
144 const std::string computeUnitIsolatedName =
145 computeUnitName.substr(kernelName.size() + 1);
147 const std::string computeUnitUsableName = kernelName +
":{" + computeUnitIsolatedName +
"}";
149 xclbin_info.
cu_names.push_back(std::move(computeUnitUsableName));
154 ATH_MSG_ERROR(
"Could not create xrt::xclbin from " << xclbin_path);
155 return StatusCode::FAILURE;
163 std::set<std::string> uuids;
164 std::set<std::string> fpga_device_names;
166 uuids.insert(
info.uuid);
167 fpga_device_names.insert(
info.fpga_device_name);
172 return StatusCode::SUCCESS;
181 cl_int
err = CL_SUCCESS;
182 std::string device_name;
183 err = device.getInfo(CL_DEVICE_NAME, &device_name);
184 if (
err != CL_SUCCESS) {
186 return std::string(
"error");
196 cl_int
err = CL_SUCCESS;
197 std::string device_bdf;
198 err = device.getInfo(CL_DEVICE_PCIE_BDF, &device_bdf);
199 if (
err != CL_SUCCESS) {
201 return std::string(
"error");
212 static std::string getPrefixUpToNthOccurrence(
const std::string &
str,
219 while (
count <
n &&
pos != std::string::npos) {
225 if (
pos == std::string::npos) {
230 return str.substr(0,
pos + 1);
243 const cl::Device &device)
const {
245 const std::string device_prefix =
247 const std::string xsa_prefix =
248 getPrefixUpToNthOccurrence(xclbin_info.
xsa_name,
'_', 2);
249 if (device_prefix == xsa_prefix) {
286 ATH_MSG_DEBUG(
"Case 1: One or multiple identical device(s), one xclbin");
289 ath_cl_context.
devices.push_back(device);
301 "Specified XCLBINs target multiple device types, but only one "
302 "device type is present");
303 return StatusCode::FAILURE;
312 "Case 2: Multiple identical devices, multiple identical xclbins");
327 "Case 3: Multiple identical devices, multiple different XCLBIN "
328 "files, but targeting the same device type");
343 ATH_MSG_DEBUG(
"Case 4: Multiple different devices, multiple xclbins");
345 for (
const std::vector<cl::Device> &device_type : si.
device_types) {
346 for (
const cl::Device &device : device_type) {
348 ath_cl_context.
devices.push_back(device);
353 for (
iter = unaffected_xclbin_infos.begin();
354 iter != unaffected_xclbin_infos.end();) {
357 iter = unaffected_xclbin_infos.erase(
iter);
378 for (
const XclbinInfo &xclbin_info : unaffected_xclbin_infos) {
382 "No compatible device found for XCLBIN: " << xclbin_info.path);
386 return StatusCode::SUCCESS;
398 cl_int
err = CL_SUCCESS;
403 ath_cl_context.context = std::make_shared<cl::Context>(
404 ath_cl_context.devices,
nullptr,
nullptr,
nullptr, &
err);
405 if (
err != CL_SUCCESS) {
407 return StatusCode::FAILURE;
413 file.open(ath_cl_context.xclbin_info.path.c_str(), std::ios::binary);
415 ATH_MSG_ERROR(
"Could not open " << ath_cl_context.xclbin_info.path
417 return StatusCode::FAILURE;
419 std::vector<char> xclbin_buffer((std::istreambuf_iterator<char>(
file)),
420 std::istreambuf_iterator<char>());
425 cl::Program::Binaries binary;
426 for (std::size_t
i = 0;
i < ath_cl_context.devices.size(); ++
i) {
427 binary.push_back({xclbin_buffer.data(), xclbin_buffer.size()});
432 ath_cl_context.program = std::make_shared<cl::Program>(
433 *ath_cl_context.context, ath_cl_context.devices, binary,
nullptr, &
err);
434 if (
err != CL_SUCCESS) {
436 return StatusCode::FAILURE;
440 std::string bdfs =
"";
441 for (
const cl::Device &device : ath_cl_context.devices) {
445 ATH_MSG_INFO(
"Loaded " << ath_cl_context.xclbin_info.path <<
" on "
446 << ath_cl_context.devices.size() <<
" "
448 <<
" device(s): " << bdfs);
451 return StatusCode::SUCCESS;
482 return StatusCode::SUCCESS;
491 return StatusCode::SUCCESS;
494 const std::vector<std::shared_ptr<xrt::device>>
497 std::vector<std::shared_ptr<xrt::device>> devices;
502 if (
std::find(ath_cl_context.xclbin_info.kernel_names.begin(),
503 ath_cl_context.xclbin_info.kernel_names.end(),
504 name) != ath_cl_context.xclbin_info.kernel_names.end()) {
505 for (
const cl::Device &device : ath_cl_context.devices) {
506 devices.push_back(std::make_shared<xrt::device>(
507 xrt::opencl::get_xrt_device(device())));
510 else if (
std::find(ath_cl_context.xclbin_info.cu_names.begin(),
511 ath_cl_context.xclbin_info.cu_names.end(),
512 name) != ath_cl_context.xclbin_info.cu_names.end()) {
513 for (
const cl::Device &device : ath_cl_context.devices) {
514 devices.push_back(std::make_shared<xrt::device>(
515 xrt::opencl::get_xrt_device(device())));
523 const std::vector<IDeviceMgmtSvc::OpenCLHandle>
525 const std::string &
name)
const {
527 std::vector<IDeviceMgmtSvc::OpenCLHandle> handles;
532 if (
std::find(ath_cl_context.xclbin_info.kernel_names.begin(),
533 ath_cl_context.xclbin_info.kernel_names.end(),
534 name) != ath_cl_context.xclbin_info.kernel_names.end()) {
536 ath_cl_context.program};
537 handles.push_back(handle);