Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VITIS-9706: xrt support for adf event apis #7926

Merged
merged 8 commits into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 135 additions & 22 deletions src/runtime_src/core/common/api/aie/xrt_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,64 @@ class graph_impl

}

namespace xrt { namespace aie {

class profiling_impl
{
private:
std::shared_ptr<xrt_core::device> device;
int profiling_hdl;

public:
using handle = int;
static constexpr handle invalid_handle = -1;

profiling_impl(std::shared_ptr<xrt_core::device> dev)
: device(std::move(dev)),
profiling_hdl(invalid_handle)
{}

~profiling_impl()
{
try {
device->stop_profiling(profiling_hdl);
}
catch(...) {
// do nothing
}
}

handle
start_profiling(int option, const std::string& port1_name, const std::string& port2_name, uint32_t value)
{
profiling_hdl = device->start_profiling(option, port1_name.c_str(), port2_name.c_str(), value);
return profiling_hdl;
}

uint64_t
read_profiling()
{
if (profiling_hdl == invalid_handle)
throw xrt_core::error(-EINVAL, "Not a valid profiling handle");

return device->read_profiling(profiling_hdl);

}

void
stop_profiling()
{
if (profiling_hdl == invalid_handle)
throw xrt_core::error(-EINVAL, "Not a valid profiling handle");

device->stop_profiling(profiling_hdl);
profiling_hdl = invalid_handle;
}

};

}}

namespace {

// C-API Graph handles are inserted to this map.
Expand Down Expand Up @@ -189,25 +247,23 @@ wait_gmio(xrtDeviceHandle dhdl, const char *gmio_name)
device->wait_gmio(gmio_name);
}

static int
start_profiling(xrtDeviceHandle dhdl, int option, const char *port1_name, const char *port2_name, uint32_t value)
{
auto device = xrt_core::device_int::get_core_device(dhdl);
return device->start_profiling(option, port1_name, port2_name, value);
}
// C-API Profiling handles are inserted to this map.
static std::map<int, std::shared_ptr<xrt::aie::profiling_impl>> profiling_cache;

static uint64_t
read_profiling(xrtDeviceHandle dhdl, int phdl)
static std::shared_ptr<xrt::aie::profiling_impl>
create_profiling_event(xrtDeviceHandle dhdl)
{
auto device = xrt_core::device_int::get_core_device(dhdl);
return device->read_profiling(phdl);
auto core_device = xrt_core::device_int::get_core_device(dhdl);
auto phdl = std::make_shared<xrt::aie::profiling_impl>(core_device);
return phdl;
}

static void
stop_profiling(xrtDeviceHandle dhdl, int phdl)
static std::shared_ptr<xrt::aie::profiling_impl>
create_profiling_event(const xrt::device& device)
{
auto device = xrt_core::device_int::get_core_device(dhdl);
return device->stop_profiling(phdl);
auto core_device = device.get_handle();
auto phdl = std::make_shared<xrt::aie::profiling_impl>(core_device);
return phdl;
}

inline void
Expand Down Expand Up @@ -321,6 +377,46 @@ read_port(const std::string& port_name, void* value, size_t bytes)

} // namespace xrt

////////////////////////////////////////////////////////////////
// xrt_aie_profiling C++ API implmentations (xrt_aie.h)
////////////////////////////////////////////////////////////////
namespace xrt { namespace aie {

profiling::
profiling(const xrt::device& device)
: detail::pimpl<profiling_impl>(std::move(create_profiling_event(device)))
{}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this class class should define a destructor to clean up the resources acquired by start() if someone did not call stop()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. Thanks for the suggestion Soren.

int
profiling::
start(xrt::aie::profiling::profiling_option option, const std::string& port1_name, const std::string& port2_name, uint32_t value) const
{
int opt = static_cast<int>(option);
return xdp::native::profiling_wrapper("xrt::aie::profiling::start", [this, opt, &port1_name, &port2_name, value] {
return get_handle()->start_profiling(opt, port1_name, port2_name, value);
});
}

uint64_t
profiling::
read() const
{
return xdp::native::profiling_wrapper("xrt::aie::profiling::read", [this] {
return get_handle()->read_profiling();
});
}

void
profiling::
stop() const
{
xdp::native::profiling_wrapper("xrt::aie::profiling::stop", [this] {
return get_handle()->stop_profiling();
});
}

}} //namespace aie, xrt

////////////////////////////////////////////////////////////////
// xrt_aie API implementations (xrt_aie.h, xrt_graph.h)
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -755,7 +851,16 @@ int
xrtAIEStartProfiling(xrtDeviceHandle handle, int option, const char *port1Name, const char *port2Name, uint32_t value)
{
try {
return start_profiling(handle, option, port1Name, port2Name, value);
auto event = create_profiling_event(handle);
if (option < 0 || option > 3)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic numbers, can you replace this with proper enums? You can fix it in next PR.

throw xrt_core::error(-EINVAL, "Not a valid profiling option");
auto hdl = event->start_profiling(option, port1Name, port2Name, value);
if (hdl != xrt::aie::profiling_impl::invalid_handle) {
profiling_cache[hdl] = event;
return hdl;
}
else
throw xrt_core::error(-EINVAL, "Not a valid profiling handle");
}
catch (const xrt_core::error& ex) {
xrt_core::send_exception_message(ex.what());
Expand All @@ -777,10 +882,14 @@ xrtAIEStartProfiling(xrtDeviceHandle handle, int option, const char *port1Name,
* Return: The performance counter value, or appropriate error number.
*/
uint64_t
xrtAIEReadProfiling(xrtDeviceHandle handle, int pHandle)
xrtAIEReadProfiling(int pHandle)
{
try {
return read_profiling(handle, pHandle);
auto it = profiling_cache.find(pHandle);
if (it != profiling_cache.end())
return it->second->read_profiling();
else
throw xrt_core::error(-EINVAL, "No such profiling handle");
}
catch (const xrt_core::error& ex) {
xrt_core::send_exception_message(ex.what());
Expand All @@ -802,12 +911,17 @@ xrtAIEReadProfiling(xrtDeviceHandle handle, int pHandle)
*
* Return: 0 on success, or appropriate error number.
*/
int
xrtAIEStopProfiling(xrtDeviceHandle handle, int pHandle)
void
xrtAIEStopProfiling(int pHandle)
{
try {
stop_profiling(handle, pHandle);
return 0;
auto it = profiling_cache.find(pHandle);
if (it != profiling_cache.end()) {
it->second->stop_profiling();
profiling_cache.erase(pHandle);
}
else
throw xrt_core::error(-EINVAL, "No such profiling handle");
}
catch (const xrt_core::error& ex) {
xrt_core::send_exception_message(ex.what());
Expand All @@ -816,5 +930,4 @@ xrtAIEStopProfiling(xrtDeviceHandle handle, int pHandle)
catch (const std::exception& ex) {
send_exception_message(ex.what());
}
return -1;
}
2 changes: 1 addition & 1 deletion src/runtime_src/core/common/ishim.h
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ struct shim : public DeviceType
stop_profiling(int phdl) override
{
if (auto ret = xclStopProfiling(DeviceType::get_device_handle(), phdl))
throw system_error(ret, "fail to wait gmio");
throw system_error(ret, "failed to stop profiling");
}

void
Expand Down
122 changes: 122 additions & 0 deletions src/runtime_src/core/include/xrt/xrt_aie.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "xrt/xrt_bo.h"
#include "xrt/xrt_device.h"
#include "xrt/xrt_graph.h"
#include "xrt/detail/pimpl.h"

#ifdef __cplusplus
# include <cstdint>
Expand Down Expand Up @@ -163,6 +164,86 @@ class bo : public xrt::bo
}
};

class profiling_impl;
class profiling : public detail::pimpl<profiling_impl>
{
public:

/**
* @enum profiliing_options - contains the enumerated options for performance
* profiling using PLIO and GMIO objects.
*
* @var io_total_stream_running_to_idle_cycles
* Total clock cycles in between the stream running event and the stream
* idle event of the stream port in the interface tile.
* @var io_stream_start_to_bytes_transferred_cycles
* The clock cycles in between the first stream running event to the event that
* the specified bytes are transferred through the stream port in the interface tile.
* @var io_stream_start_difference_cycles
* The clock cycles elapsed between the first stream running events of
* the two platform I/O objects.
* @var io_stream_running_event_count
* Number of stream running events
*
* Please refer UG1079 for more details.
*/
enum class profiling_option : int
{
io_total_stream_running_to_idle_cycles = 0,
io_stream_start_to_bytes_transferred_cycles = 1,
io_stream_start_difference_cycles = 2,
io_stream_running_event_count = 3
};

profiling() = default;

/**
* event() - Constructor from a device
*
* @param device
* The device on which the profiling should start
*
*/
explicit
profiling(const xrt::device& device);

/**
* start() - Start AIE performance profiling
*
* @param option
* Profiling option
* @param port1_name
* PLIO/GMIO port 1 name.
* @param port2_name
* PLIO/GMIO port 2 name.
* @param value
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is in some user guide. Without providing the hyperlink, you could reference UGxxxx for more detail. Without the UG, I would be baffled on the meaning of these parameters.

* The number of bytes to trigger the profiling event.
*
* Please refer UG1079 for more details.
*
* This function configures the performance counters in AI Engine by given
* port names and value. The port names and value will have different
* meanings on different options.
*/
int
start(profiling_option option, const std::string& port1_name, const std::string& port2_name, uint32_t value) const;

/**
* read() - Read the current performance counter value
* associated with the profiling handle
*/
uint64_t
read() const;

/**
* stop() - Stop the current performance profiling
* associated with the profiling handle and
* release the corresponding hardware resources.
*/
void
stop() const;
};

}} // aie, xrt

/// @cond
Expand Down Expand Up @@ -256,6 +337,47 @@ xrtSyncBOAIE(xrtDeviceHandle handle, xrtBufferHandle bohdl, const char *gmioName
int
xrtResetAIEArray(xrtDeviceHandle handle);

/**
* xrtAIEStartProfiling() - Start AIE performance profiling
*
* @handle: Handle to the device
* @option: Profiling option.
* @port1Name: PLIO/GMIO port 1 name
* @port2Name: PLIO/GMIO port 2 name
* @value: The number of bytes to trigger the profiling event
*
* Return: An integer profiling handle on success,
* or appropriate error number.
*
* This function configures the performance counters in AI Engine by given
* port names and value. The port names and value will have different
* meanings on different options.
*/
int
xrtAIEStartProfiling(xrtDeviceHandle handle, int option, const char *port1Name, const char *port2Name, uint32_t value);

/**
* xrtAIEReadProfiling() - Read the current performance counter value
* associated with the profiling handle.
*
* @pHandle: Profiling handle.
*
* Return: The performance counter value, or appropriate error number.
*/
uint64_t
xrtAIEReadProfiling(int pHandle);

/**
* xrtAIEStopProfiling() - Stop the current performance profiling
* associated with the profiling handle and
* release the corresponding hardware resources.
*
* @pHandle: Profiling handle.
*
* Return: 0 on success, or appropriate error number.
*/
void
xrtAIEStopProfiling(int pHandle);
/// @endcond

#ifdef __cplusplus
Expand Down
Loading
Loading