-
Notifications
You must be signed in to change notification settings - Fork 486
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
Conversation
d953946
to
479e00d
Compare
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.
Once event is created, we should be able to start , stop and read. Please make requested changes
{ | ||
public: | ||
|
||
event(const xrt::device& device, int option, const std::string& port1_name, const std::string& port2_name, uint32_t value); |
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.
instead of constructor taking all the variables, Can you have constructor which takes only device class
and have another member function to start the profiling.
|
||
} | ||
|
||
int get_event_handle(const std::shared_ptr<xrt::aie::event_impl>& event_ptr) { |
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.
Why is this extra function required? you can directly get handle using event_ptr->getHandle() function.
device->stop_profiling(handle); | ||
} | ||
|
||
int getHandle() const { return handle; } |
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.
naming convention.. Use get_handle instead of getHandle
static uint64_t | ||
read_profiling(xrtDeviceHandle dhdl, int phdl) | ||
static std::shared_ptr<xrt::aie::event_impl> | ||
start_profiling(xrtDeviceHandle dhdl, int option, const char *port1_name, const char *port2_name, uint32_t value) |
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.
these can be part of event_impl class functions once you make all other changes.
a621e7c
to
97ede86
Compare
if(event_hdl == invalid_handle) | ||
throw xrt_core::error(-EINVAL, "Not a valid event handle"); | ||
device->stop_profiling(event_hdl); | ||
event_hdl= invalid_handle; |
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.
indentation ..
using handle = int; | ||
static constexpr handle invalid_handle = -1; | ||
|
||
event_impl(std::shared_ptr<xrt_core::device> dev, handle hdl) |
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.
dont need to send hdl.
|
||
event:: | ||
event(const xrt::device& device) | ||
: impl(open_event(device)) |
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.
std::move
return start_profiling(handle, option, port1Name, port2Name, value); | ||
auto impl = open_event(handle); | ||
auto hdl = impl->start_profiling(option, port1Name, port2Name, value); | ||
impl->get_handle() = hdl; |
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.
dont require this line
return it->second->read_profiling(); | ||
} | ||
else | ||
throw xrt_core::error(-EINVAL, "No such event handle"); |
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.
indentation
event_cache.erase(pHandle); | ||
} | ||
else | ||
throw xrt_core::error(-EINVAL, "No such event handle"); |
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.
indentation
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::event_impl>(core_device, xrt::aie::event_impl::invalid_handle); |
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.
remove hdl from constructor
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.
Please add comments to minimum public APIs and format the public APIs properly.
34bc318
to
cc9066f
Compare
cc9066f
to
f4bfac9
Compare
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.
The public APIs are still not documented or formatted correctly; I am referring to xrt_aie.h.
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.
Quite a few requests, please review with @chvamshi-xilinx
You can pick and choose as you like, but the public API comments are most important.
* event() - Constructor from a device | ||
* | ||
* @param device | ||
* The device on which the profiling event should start |
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.
This is a bit too obfuscated. Line 175 is the first that hints at this having something to do with profiling.
The class name event
is rather generic, but I think this event is specifically for profiling. Would it be better to make that clear by moving event under namespace xrt::aie::profiling
? And if so then change start/read/stop_profiling
to just start/read/stop
?
Sorry for being picky here, but this is a public API that we can't change in the future, so we better get it right the first time.
What happens when you create an event? What is an event?
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. Thank you for the suggestion Soren. Also for clarity on the event APIs, I'm referring UG-1076
/** | ||
* start_profiling() - Start AIE performance profiling | ||
* | ||
* @param option | ||
* Profiling option | ||
* @param port1_name | ||
* Profiling port 1 name. | ||
* @param port2_name | ||
* Profiling port 2 name. | ||
* @param value | ||
* The number of bytes to trigger the profiling event. | ||
* | ||
* 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(int option, const std::string& port1_name, const std::string& port2_name, uint32_t value) const; |
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.
This will not work in a public API. What is option
? It's an int
what happens if I pass my lucky number 17
? Kidding aside, we need a class enum here. Also, the other parameters are not clear at all, what is profiling port? What does number of bytes to trigger the profiling event
mean? Is 0 bytes good? It's not useable in a public API without a lot more documentation and explanation as to what happens with out or range numbers. How do know what port names to use?
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.
I have added an enum class of profiling option. Also, the other parameters like profiling port etc are the PLIO/ GMIO ports here. I am referring (UG-1076) for implementation.
uint64_t | ||
read_profiling() const; |
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.
What does the profiling counter value represent? I am beginning to wonder who the consumer of these event APIs will be? Will it be end-user from application, or will it be internal XRT (xdp?) using this?
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.
The consumer is the end user from application. To understand the adf APIs I referred UG-1076
stop_profiling() const; | ||
|
||
private: | ||
std::shared_ptr<event_impl> impl; |
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.
If this is meant to be a public class, then maybe use core/include/xrt/detail/pimpl.h
as base class; look at other examples.
~event_impl() | ||
{} | ||
|
||
int |
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.
int | |
handle |
if (it != event_cache.end()) { | ||
return it->second->read_profiling(); | ||
} |
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.
if (it != event_cache.end()) { | |
return it->second->read_profiling(); | |
} | |
if (it != event_cache.end()) | |
return it->second->read_profiling(); |
:number-lines: 45 | ||
|
||
auto graph = xrt::graph(device, xclbin_uuid, "graph_name"); | ||
auto handle = event.start_profiling(int option, std::string& port1, std::string& port2, int value); |
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 was hoping this documentation would explain the semantics of option and value :-(
auto handle = event.start_profiling(int option, std::string& port1, std::string& port2, int value); | |
auto handle = event.start_profiling(option, std::string& port1, std::string& port2, int value); |
:number-lines: 35 | ||
|
||
event.stop_profiling(); | ||
double throughput = (double)output_size_in_bytes / (cycle_count *0.8 * 1e-3); |
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.
Why the cast?
event.stop_profiling(); | ||
double throughput = (double)output_size_in_bytes / (cycle_count *0.8 * 1e-3); | ||
//Every AIE cycle is 0.8ns in production board | ||
std::cout<<"Throughput of the graph: "<<throughput<<" MB/s"<<std::endl; |
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.
std::cout<<"Throughput of the graph: "<<throughput<<" MB/s"<<std::endl; | |
std::cout << "Throughput of the graph: " << throughput << " MB/s" << std::endl; |
|
||
event.stop_profiling(); | ||
double throughput = (double)output_size_in_bytes / (cycle_count *0.8 * 1e-3); | ||
//Every AIE cycle is 0.8ns in production board |
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.
//Every AIE cycle is 0.8ns in production board | |
// Every AIE cycle is 0.8ns in production board |
59e12e6
to
6ce5255
Compare
minor fix review suggestions minor change Signed-off-by: saumya garg <[email protected]> minor change Signed-off-by: saumya garg <[email protected]> minor change Signed-off-by: saumya garg <[email protected]>
fix Signed-off-by: saumya garg <[email protected]> fix Signed-off-by: saumya garg <[email protected]>
Signed-off-by: saumya garg <[email protected]>
Signed-off-by: saumya garg <[email protected]> doc update2 Signed-off-by: saumya garg <[email protected]>
Signed-off-by: saumya garg <[email protected]>
Signed-off-by: saumya garg <[email protected]> fix Signed-off-by: saumya garg <[email protected]>
6ce5255
to
282e04c
Compare
Signed-off-by: saumya garg <[email protected]> fix review comments Signed-off-by: saumya garg <[email protected]>
282e04c
to
08b09ba
Compare
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.
Looks a lot better now. Few more notes.
class profiling : public detail::pimpl<profiling_impl> | ||
{ | ||
public: | ||
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 }; |
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.
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 }; | |
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 | |
}; |
You would maybe want to document these?
/**
* @enum profiliing_options - ...
*
* @var enumerator
* What it does
* /
I know the enumerators are long, so maybe they explain what needs to be explained?
* 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 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.
stop() const; | ||
|
||
private: | ||
std::shared_ptr<profiling_impl> impl; |
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.
Uh, not needed now that you derived off of detail::pimpl
{ | ||
device->stop_profiling(profiling_hdl); | ||
} |
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.
Uh, in conjunction with user callling stop()
this dtor won't work. I think you need a bit more logic to the state so stop_profiling can bail if it was already called. My point earlier was that you must handle the case where user forgets to call stop()
but you must also handle the case where user does call stop()
and the handle is invalid.
Destructors cannot throw, so you must have a try/catch if the function that is called can throw.
Signed-off-by: saumya garg <[email protected]> fix review comments Signed-off-by: saumya garg <[email protected]>
8e6dca1
to
fdea9e9
Compare
@@ -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 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.
Problem solved by the commit
https://jira.xilinx.com/browse/VITIS-9706
Providing XRT support for Event APIs.
Bug / issue (if any) fixed, which PR introduced the bug, how it was discovered
None
How problem was solved, alternative solutions (if any) and why they were rejected
Implemented an Event class whose constructor xrt::aie::event is used to create event object.
The member function start_profiling() is used to start performance counters in AI Engine as per the profiling option passed as an argument.
The read_profiling() member function will return the current performance counter value associated with the event handle.
The stop_profiling() member function stops the performance profiling associated with the event handle.
Risks (if any) associated the changes in the commit
Low
What has been tested and how, request additional testing if necessary
Tested for an application that calculates throughout
Documentation impact (if any)
NA