-
Notifications
You must be signed in to change notification settings - Fork 487
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
Changes from all commits
c4a73f1
e71387f
dfcc10e
cb9ada8
c0afb67
666640a
08b09ba
fdea9e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
|
@@ -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 | ||
|
@@ -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))) | ||
{} | ||
|
||
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) | ||
//////////////////////////////////////////////////////////////// | ||
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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()); | ||
|
@@ -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(); | ||
chvamshi-xilinx marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else | ||
throw xrt_core::error(-EINVAL, "No such profiling handle"); | ||
} | ||
catch (const xrt_core::error& ex) { | ||
xrt_core::send_exception_message(ex.what()); | ||
|
@@ -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()); | ||
|
@@ -816,5 +930,4 @@ xrtAIEStopProfiling(xrtDeviceHandle handle, int pHandle) | |
catch (const std::exception& ex) { | ||
send_exception_message(ex.what()); | ||
} | ||
return -1; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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> | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
@@ -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 | ||
|
There was a problem hiding this comment.
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 callstop()
?There was a problem hiding this comment.
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.