Skip to content

Commit

Permalink
Final hwctx integration (#6736)
Browse files Browse the repository at this point in the history
  • Loading branch information
stsoe committed May 28, 2022
1 parent be3256c commit 922a610
Show file tree
Hide file tree
Showing 25 changed files with 384 additions and 407 deletions.
24 changes: 5 additions & 19 deletions src/runtime_src/core/common/api/context_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@ using namespace std::chrono_literals;

namespace {

// Transition only, to be removed
static bool
is_shared(xrt::hw_context::qos qos)
{
switch (qos) {
case xrt::hw_context::qos::exclusive:
return false;
case xrt::hw_context::qos::shared:
return true;
default:
throw std::runtime_error("unexpected access mode for kernel");
}
}

} // namespace

namespace xrt_core { namespace context_mgr {
Expand Down Expand Up @@ -112,17 +98,17 @@ class device_context_mgr
open(const xrt::hw_context& hwctx, const std::string& ipname)
{
std::unique_lock<std::mutex> ul(m_mutex);
auto ctxhdl = xrt_core::hw_context_int::get_xcl_handle(hwctx);
auto ctxhdl = static_cast<xcl_hwctx_handle>(hwctx);
auto [ipidx, ctx] = get_ipidx_ctx(ctxhdl, ipname);
while (ctx && ctx->test(ctxidx(ipidx))) {
if (m_cv.wait_for(ul, 100ms) == std::cv_status::timeout)
throw std::runtime_error("aquiring cu context timed out");
}
m_device->open_context(ctxhdl, hwctx.get_xclbin_uuid(), ipname, is_shared(hwctx.get_qos()));
ipidx = m_device->open_cu_context(hwctx, ipname);

// Successful context creation means CU idx is now known
// Successful context creation means CU idx is valid now
if (!ctx)
std::tie(ipidx, ctx) = get_ipidx_ctx(ctxhdl, ipname);
ctx = get_ctx(ipidx);

if (!ctx)
throw std::runtime_error("Unexpected ctx error");
Expand All @@ -142,7 +128,7 @@ class device_context_mgr
auto ctx = get_ctx(ipidx);
if (!ctx->test(idx))
throw std::runtime_error("ctx " + std::to_string(ipidx.index) + " not open");
m_device->close_context(hwctx.get_xclbin_uuid(), ipidx.index);
m_device->close_cu_context(hwctx, ipidx);
ctx->reset(idx);
m_cv.notify_all();
}
Expand Down
8 changes: 3 additions & 5 deletions src/runtime_src/core/common/api/hw_context_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@

// This file defines implementation extensions to the XRT XCLBIN APIs.
#include "core/include/experimental/xrt_hw_context.h"

#include <cstdint>

// Provide access to xrt::xclbin data that is not directly exposed
// to end users via xrt::xclbin. These functions are used by
// XRT core implementation.
namespace xrt_core { namespace hw_context_int {

// get_xcl_handle() - Driver handle index
// Retrieve the driver handle index associated with the context
xcl_hwctx_handle
get_xcl_handle(const xrt::hw_context& ctx);
// Get the core_device from this context
std::shared_ptr<xrt_core::device>
get_core_device(const xrt::hw_context& ctx);

// Get a raw pointer to the core device associated with
// the hw context
Expand Down
15 changes: 11 additions & 4 deletions src/runtime_src/core/common/api/xrt_hw_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
// core/include/experimental/xrt_queue.h
#define XRT_API_SOURCE // exporting xrt_hwcontext.h
#define XCL_DRIVER_DLL_EXPORT // exporting xrt_xclbin.h
#define XRT_CORE_COMMON_SOURCE // in same dll as core_common
#define XRT_CORE_COMMON_SOURCE // in same dll as coreutil
#include "core/include/experimental/xrt_hw_context.h"
#include "hw_context_int.h"

#include "core/common/device.h"

Expand Down Expand Up @@ -122,10 +123,10 @@ class hw_context_impl
////////////////////////////////////////////////////////////////
namespace xrt_core { namespace hw_context_int {

xcl_hwctx_handle
get_xcl_handle(const xrt::hw_context& hwctx)
std::shared_ptr<xrt_core::device>
get_core_device(const xrt::hw_context& hwctx)
{
return hwctx.get_handle()->get_xcl_handle();
return hwctx.get_handle()->get_core_device();
}

xrt_core::device*
Expand Down Expand Up @@ -180,4 +181,10 @@ get_qos() const
return get_handle()->get_qos();
}

hw_context::
operator xcl_hwctx_handle() const
{
return get_handle()->get_xcl_handle();
}

} // xrt
104 changes: 62 additions & 42 deletions src/runtime_src/core/common/api/xrt_ip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
// This file implements XRT IP APIs as declared in
// core/include/experimental/xrt_ip.h
#define XCL_DRIVER_DLL_EXPORT // exporting xrt_ip.h
#define XRT_CORE_COMMON_SOURCE // in same dll as core_common
#define XRT_CORE_COMMON_SOURCE // in same dll as coreutil
#define XRT_API_SOURCE // in same dll as coreutil
#include "core/include/experimental/xrt_ip.h"
#include "core/include/experimental/xrt_xclbin.h"

#include "core/common/api/hw_context_int.h"
#include "core/common/api/native_profile.h"

#include "core/common/device.h"
Expand Down Expand Up @@ -61,6 +64,17 @@ has_reg_read_write()
#endif
}

// Determine the QoS value to use when constructing xrt::hw_context in
// legacy constructor. The default is exclusive context, but if
// xrt.ini:get_rw_shared() is set then access should be shared.
static xrt::hw_context::qos
hwctx_qos()
{
return (xrt_core::config::get_rw_shared())
? xrt::hw_context::qos::shared
: xrt::hw_context::qos::exclusive;
}

} // namespace

namespace xrt {
Expand Down Expand Up @@ -131,43 +145,37 @@ class ip_impl
// context is closed.
struct ip_context
{
std::shared_ptr<xrt_core::device> device;
xrt::uuid xclbin_uuid; //
xrt_core::cuidx_type idx; // index of ip per driver, for open context
xrt::xclbin::ip ip;
uint64_t size; // address range of ip

ip_context(std::shared_ptr<xrt_core::device> dev, xrt::uuid xid, const std::string& nm)
: device(std::move(dev))
, xclbin_uuid(std::move(xid))
std::shared_ptr<xrt_core::device> m_device;
xrt::hw_context m_hwctx;
xrt_core::cuidx_type m_idx; // index of ip per driver, for open context
xrt::xclbin::ip m_ip;
uint64_t m_size; // address range of ip

ip_context(xrt::hw_context xhwctx, const std::string& nm)
: m_device(xrt_core::hw_context_int::get_core_device(xhwctx))
, m_hwctx(std::move(xhwctx))
{
std::string ipnm = nm;
auto pos1 = ipnm.find(":{");
if (pos1 != std::string::npos && ipnm.rfind('}') == nm.size() - 1)
ipnm.erase(pos1 + 1, 1).pop_back();

auto xclbin = device->get_xclbin(xclbin_uuid);
ip = xclbin.get_ip(ipnm);
auto xclbin = m_hwctx.get_xclbin();
m_ip = xclbin.get_ip(ipnm);

if (!ip)
if (!m_ip)
throw xrt_core::error(EINVAL, "No IP matching '" + nm + "'");

// default to first matching slot
auto slot = device->get_slots(xclbin_uuid).front();

// address range
size = ip.get_size();
m_size = m_ip.get_size();

// context, driver allows shared context per xrt.ini
device->open_context(slot, xclbin_uuid, ipnm, xrt_core::config::get_rw_shared());

// idx is guaranteed valid only after context creation
idx = device->get_cuidx(slot, ipnm);
m_idx = m_device->open_cu_context(m_hwctx, ipnm);
}

~ip_context()
{
device->close_context(xclbin_uuid.get(), idx.index);
m_device->close_cu_context(m_hwctx, m_idx);
}

ip_context(const ip_context&) = delete;
Expand All @@ -178,29 +186,29 @@ class ip_impl
unsigned int
get_idx() const
{
return idx.index;
return m_idx.index;
}

uint64_t
get_address() const
{
return ip.get_base_address();
return m_ip.get_base_address();
}

uint64_t
get_size() const
{
return size;
return m_size;
}
};

unsigned int
get_cuidx_or_error(size_t offset) const
{
if ((offset + sizeof(uint32_t)) > ipctx.get_size())
if ((offset + sizeof(uint32_t)) > m_ipctx.get_size())
throw std::out_of_range("Cannot read or write outside kernel register space");

return ipctx.get_idx();
return m_ipctx.get_idx();
}

static uint32_t
Expand All @@ -211,10 +219,10 @@ class ip_impl
}

private:
std::shared_ptr<xrt_core::device> device; // shared ownership
std::weak_ptr<ip::interrupt_impl> interrupt; // interrupt if active
ip_context ipctx;
uint32_t uid; // internal unique id for debug
std::shared_ptr<xrt_core::device> m_device; // shared ownership
std::weak_ptr<ip::interrupt_impl> m_interrupt; // interrupt if active
ip_context m_ipctx;
uint32_t m_uid; // internal unique id for debug

public:
// ip_impl - constructor
Expand All @@ -223,9 +231,17 @@ class ip_impl
// @xid: uuid of xclbin to mine for kernel meta data
// @nm: name identifying an ip in IP_LAYOUT of xclbin
ip_impl(std::shared_ptr<xrt_core::device> dev, const xrt::uuid& xid, const std::string& nm)
: device(std::move(dev)) // share ownership
, ipctx(device, xid, nm)
, uid(create_uid())
: m_device(std::move(dev)) // share ownership
, m_ipctx(xrt::hw_context{xrt::device{m_device}, xid, hwctx_qos()}, nm)
, m_uid(create_uid())
{
XRT_DEBUGF("ip_impl::ip_impl(%d)\n" , uid);
}

ip_impl(const xrt::hw_context& hwctx, const std::string& nm)
: m_device(xrt_core::hw_context_int::get_core_device(hwctx)) // share ownership
, m_ipctx(hwctx, nm)
, m_uid(create_uid())
{
XRT_DEBUGF("ip_impl::ip_impl(%d)\n" , uid);
}
Expand All @@ -246,9 +262,9 @@ class ip_impl
auto idx = get_cuidx_or_error(offset);
uint32_t value = 0;
if (has_reg_read_write())
device->reg_read(idx, offset, &value);
m_device->reg_read(idx, offset, &value);
else
device->xread(XCL_ADDR_KERNEL_CTRL, ipctx.get_address() + offset, &value, 4);
m_device->xread(XCL_ADDR_KERNEL_CTRL, m_ipctx.get_address() + offset, &value, 4);
return value;
}

Expand All @@ -257,23 +273,22 @@ class ip_impl
{
auto idx = get_cuidx_or_error(offset);
if (has_reg_read_write())
device->reg_write(idx, offset, data);
m_device->reg_write(idx, offset, data);
else
device->xwrite(XCL_ADDR_KERNEL_CTRL, ipctx.get_address() + offset, &data, 4);
m_device->xwrite(XCL_ADDR_KERNEL_CTRL, m_ipctx.get_address() + offset, &data, 4);
}

std::shared_ptr<ip::interrupt_impl>
get_interrupt()
{
auto intr = interrupt.lock();
auto intr = m_interrupt.lock();
if (!intr)
// NOLINTNEXTLINE(modernize-make-shared) used in weak_ptr
interrupt = intr = std::shared_ptr<ip::interrupt_impl>(new ip::interrupt_impl(device, ipctx.get_idx()));
m_interrupt = intr = std::shared_ptr<ip::interrupt_impl>(new ip::interrupt_impl(m_device, m_ipctx.get_idx()));

return intr;
}

};
}; // ip_impl

} // namespace xrt

Expand All @@ -295,6 +310,11 @@ ip(const xrt::device& device, const xrt::uuid& xclbin_id, const std::string& nam
: detail::pimpl<ip_impl>(std::make_shared<ip_impl>(device.get_handle(), xclbin_id, name))
{}

ip::
ip(const xrt::hw_context& ctx, const std::string& name)
: detail::pimpl<ip_impl>(std::make_shared<ip_impl>(ctx, name))
{}

void
ip::
write_register(uint32_t offset, uint32_t data)
Expand Down
4 changes: 2 additions & 2 deletions src/runtime_src/core/common/api/xrt_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ class ip_context
static std::mutex mutex;
static std::map<xrt_core::device*, ctx_to_ips> dev2ips;
auto device = xrt_core::hw_context_int::get_core_device_raw(hwctx);
auto ctxhdl = xrt_core::hw_context_int::get_xcl_handle(hwctx);
auto ctxhdl = static_cast<xcl_hwctx_handle>(hwctx);
std::lock_guard<std::mutex> lk(mutex);
auto& ctx2ips = dev2ips[device]; // hwctx handle -> [ip_context]*
auto& ips = ctx2ips[ctxhdl]; // ipname -> ip_context
Expand Down Expand Up @@ -584,7 +584,7 @@ class ip_context
slot_id
get_slot() const
{
return xrt_core::hw_context_int::get_xcl_handle(m_hwctx);
return static_cast<xcl_hwctx_handle>(m_hwctx);
}

// Check if arg is connected to specified memory bank
Expand Down
3 changes: 2 additions & 1 deletion src/runtime_src/core/common/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// Copyright (C) 2019-2022 Xilinx, Inc. All rights reserved.
// Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved.
#define XCL_DRIVER_DLL_EXPORT // in same dll as exported xrt apis
#define XRT_CORE_COMMON_SOURCE // in same dll as core_common
#define XRT_CORE_COMMON_SOURCE // in same dll as coreutil
#define XRT_API_SOURCE // in same dll as coreutil
#include "device.h"
#include "config_reader.h"
#include "debug.h"
Expand Down

0 comments on commit 922a610

Please sign in to comment.