CIRCT 21.0.0git
Loading...
Searching...
No Matches
Xrt.cpp
Go to the documentation of this file.
1//===- Xrt.cpp - ESI XRT device backend -------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// DO NOT EDIT!
10// This file is distributed as part of an ESI package. The source for this file
11// should always be modified within CIRCT
12// (lib/dialect/ESI/runtime/cpp/lib/backends/Cosim.cpp).
13//
14//===----------------------------------------------------------------------===//
15
16#include "esi/backends/Xrt.h"
17#include "esi/Services.h"
18
19// XRT includes
20#include "experimental/xrt_bo.h"
21#include "experimental/xrt_device.h"
22#include "experimental/xrt_ip.h"
23#include "experimental/xrt_xclbin.h"
24
25#include <fstream>
26#include <iostream>
27#include <set>
28
29using namespace esi;
30using namespace esi::services;
31using namespace esi::backends::xrt;
32
33/// Parse the connection std::string and instantiate the accelerator. Connection
34/// std::string format:
35/// <xclbin>[:<device_id>]
36/// wherein <device_id> is in BDF format.
37std::unique_ptr<AcceleratorConnection>
38XrtAccelerator::connect(Context &ctxt, std::string connectionString) {
39 std::string xclbin;
40 std::string device_id;
41
42 size_t colon = connectionString.find(':');
43 if (colon == std::string::npos) {
44 xclbin = connectionString;
45 } else {
46 xclbin = connectionString.substr(0, colon);
47 device_id = connectionString.substr(colon + 1);
48 }
49
50 return make_unique<XrtAccelerator>(ctxt, xclbin, device_id);
51}
52
54 constexpr static char kernel_name[] = "esi_kernel";
55
56 Impl(std::string xclbin, std::string device_id) {
57 if (device_id.empty())
58 device = ::xrt::device(0);
59 else
60 device = ::xrt::device(device_id);
61
62 // Find memory group for the host.
63 ::xrt::xclbin xcl(xclbin);
64 std::optional<::xrt::xclbin::mem> host_mem;
65 for (auto mem : xcl.get_mems()) {
66 // The host memory is tagged with "HOST[0]". Memory type is wrong --
67 // reports as DRAM rather than host memory so we can't filter on that.
68 if (mem.get_tag().starts_with("HOST")) {
69 if (host_mem.has_value())
70 throw std::runtime_error("Multiple host memories found in xclbin");
71 else
72 host_mem = mem;
73 }
74 }
75 if (!host_mem)
76 throw std::runtime_error("No host memory found in xclbin");
77 memoryGroup = host_mem->get_index();
78
79 // Load the xclbin and instantiate the IP.
80 auto uuid = device.load_xclbin(xcl);
81 ip = ::xrt::ip(device, uuid, kernel_name);
82 }
83
84 ::xrt::device device;
85 ::xrt::ip ip;
86 int32_t memoryGroup;
87};
88
89/// Construct and connect to a cosim server.
90XrtAccelerator::XrtAccelerator(Context &ctxt, std::string xclbin,
91 std::string device_id)
92 : AcceleratorConnection(ctxt) {
93 impl = make_unique<Impl>(xclbin, device_id);
94}
96
97namespace {
98class XrtMMIO : public MMIO {
99public:
100 XrtMMIO(XrtAccelerator &conn, ::xrt::ip &ip, const HWClientDetails &clients)
101 : MMIO(conn, clients), ip(ip) {}
102
103 uint64_t read(uint32_t addr) const override {
104 auto lo = static_cast<uint64_t>(ip.read_register(addr));
105 auto hi = static_cast<uint64_t>(ip.read_register(addr + 0x4));
106 return (hi << 32) | lo;
107 }
108 void write(uint32_t addr, uint64_t data) override {
109 ip.write_register(addr, data);
110 ip.write_register(addr + 0x4, data >> 32);
111 }
112
113private:
114 ::xrt::ip &ip;
115};
116} // namespace
117
118namespace {
119/// Host memory service specialized to XRT.
120class XrtHostMem : public HostMem {
121public:
122 XrtHostMem(XrtAccelerator &conn, ::xrt::device &device, int32_t memoryGroup)
123 : HostMem(conn), device(device), memoryGroup(memoryGroup){};
124
125 struct XrtHostMemRegion : public HostMemRegion {
126 XrtHostMemRegion(::xrt::device &device, std::size_t size,
127 HostMem::Options opts, int32_t memoryGroup) {
128 bo = ::xrt::bo(device, size, ::xrt::bo::flags::host_only, memoryGroup);
129 // Map the buffer into application memory space so that the application
130 // can use it just like any memory -- no need to use bo::write.
131 ptr = bo.map();
132 }
133 virtual void *getPtr() const override { return ptr; }
134 /// On XRT platforms, the pointer which the device sees is different from
135 /// the pointer the user application sees.
136 virtual void *getDevicePtr() const override { return (void *)bo.address(); }
137 virtual std::size_t getSize() const override { return bo.size(); }
138 /// It is required to use 'sync' to flush the caches before executing any
139 /// DMA.
140 virtual void flush() override { bo.sync(XCL_BO_SYNC_BO_TO_DEVICE); }
141
142 private:
143 ::xrt::bo bo;
144 void *ptr;
145 };
146
147 std::unique_ptr<HostMemRegion>
148 allocate(std::size_t size, HostMem::Options opts) const override {
149 return std::unique_ptr<HostMemRegion>(
150 new XrtHostMemRegion(device, size, opts, memoryGroup));
151 }
152
153private:
154 ::xrt::device &device;
155 int32_t memoryGroup;
156};
157} // namespace
158
160 std::string implName,
161 const ServiceImplDetails &details,
162 const HWClientDetails &clients) {
163 if (svcType == typeid(MMIO))
164 return new XrtMMIO(*this, impl->ip, clients);
165 else if (svcType == typeid(HostMem))
166 return new XrtHostMem(*this, impl->device, impl->memoryGroup);
167 else if (svcType == typeid(SysInfo))
168 return new MMIOSysInfo(getService<MMIO>());
169 return nullptr;
170}
171
#define REGISTER_ACCELERATOR(Name, TAccelerator)
Abstract class representing a connection to an accelerator.
Definition Accelerator.h:79
virtual void disconnect()
Disconnect from the accelerator cleanly.
Context & ctxt
ESI accelerator context.
AcceleratorConnections, Accelerators, and Manifests must all share a context.
Definition Context.h:31
Connect to an ESI simulation.
Definition Xrt.h:31
XrtAccelerator(Context &, std::string xclbin, std::string kernelName)
Construct and connect to a cosim server.
Definition Xrt.cpp:90
static std::unique_ptr< AcceleratorConnection > connect(Context &, std::string connectionString)
Parse the connection std::string and instantiate the accelerator.
Definition Xrt.cpp:38
std::unique_ptr< Impl > impl
Definition Xrt.h:47
virtual Service * createService(Service::Type service, AppIDPath path, std::string implName, const ServiceImplDetails &details, const HWClientDetails &clients) override
Called by getServiceImpl exclusively.
Definition Xrt.cpp:159
Implement the SysInfo API for a standard MMIO protocol.
Definition Services.h:184
Parent class of all APIs modeled as 'services'.
Definition Services.h:46
const std::type_info & Type
Definition Services.h:48
Information about the Accelerator system.
Definition Services.h:100
Definition esi.py:1
std::map< std::string, std::any > ServiceImplDetails
Definition Common.h:98
std::vector< HWClientDetail > HWClientDetails
Definition Common.h:97
static constexpr char kernel_name[]
Definition Xrt.cpp:54
Impl(std::string xclbin, std::string device_id)
Definition Xrt.cpp:56
Options for allocating host memory.
Definition Services.h:226