-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
[Hexagon] Add RPC Mechanism for Hexagon #9631
Conversation
5fc7750
to
129d96a
Compare
38c2c50
to
ef7da6e
Compare
2f0bd36
to
6f2eec9
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.
What a wonderful consolidation of effort for bringing all the TVM runtimes to Hexagon. The simplicity of the FastRPC interface and resulting enabled featureset speak for themselves. Truly incredible work @mehrdadh, thank you!
cmake/modules/Hexagon.cmake
Outdated
# copy android_bash template file | ||
configure_file("${CMAKE_SOURCE_DIR}/src/runtime/hexagon/rpc/android_bash.sh.template" | ||
${HEXAGON_RPC_OUTPUT} COPYONLY) | ||
endif() |
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.
Clean up artifacts, e.g.
endif() | |
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${HEXAGON_RPC_OUTPUT}") | |
endif() |
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.
done here: 28db608
cmake/modules/Hexagon.cmake
Outdated
@@ -217,16 +317,20 @@ if(USE_HEXAGON_DEVICE STREQUAL "${PICK_SIM}") | |||
"-DHEXAGON_ARCH=${USE_HEXAGON_ARCH}" | |||
INSTALL_COMMAND "true" | |||
) | |||
elseif(USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}") | |||
elseif((USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}") OR (USE_HEXAGON_RPC AND BUILD_FOR_ANDROID)) |
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.
Can we decouple the (USE_HEXAGON_DEVICE STREQUAL "${PICK_HW}")
and (USE_HEXAGON_RPC AND BUILD_FOR_ANDROID)
cases into separate conditionals? It's a bit tricky to follow the flow and easy to make an error in the build for one or the other flows unintentionally when grouping them together like 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.
done: 28db608
cmake/modules/Hexagon.cmake
Outdated
@@ -240,11 +344,36 @@ if (USE_HEXAGON_DEVICE STREQUAL "${PICK_NONE}") | |||
file(GLOB RUNTIME_HEXAGON_SRCS src/runtime/hexagon/hexagon/*.cc) | |||
elseif(BUILD_FOR_ANDROID AND HEXAGON_SDK_PATH_DEFINED) | |||
list(APPEND RUNTIME_HEXAGON_SRCS src/runtime/hexagon/proxy_rpc/device_api.cc) | |||
else() | |||
elseif(USE_HEXAGON_RPC) |
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.
See comment ⬆️ about breaking out not reusing the USE_HEXAGON_DEVICE block. It will also be easier to delete the USE_HEXAGON_DEVICE flow down the line if they are decoupled.
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.
done: 28db608
read_buffer_size_bytes_); | ||
|
||
uint32_t bytes_to_read = 0; | ||
if ((read_buffer_size_bytes_ - read_len_bytes) < 0) { |
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.
read_buffer_size_bytes_ can be uninitialized if SetReadBuffer is not called.
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 initialized it at the constructor as you suggested in previous comment.
static tvm::runtime::hexagon::HexagonRPCServer* g_hexagon_rpc_server = nullptr; | ||
|
||
static AEEResult hexagon_rpc_server_init() { | ||
uint8_t* receive_buffer = new uint8_t[TVM_HEXAGON_RPC_BUFF_SIZE_BYTES]; |
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.
Nothing as far as I can tell is protecting against overflowing the receive_buffer TVM_HEXAGON_RPC_BUFF_SIZE_BYTES, we don't bass the receive_buffer_size to the iohandler (via the server).
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 added check for buffer size and passed the size to IOHandler:
31fda2b
} // namespace runtime | ||
} // namespace tvm | ||
|
||
static tvm::runtime::hexagon::HexagonRPCServer* g_hexagon_rpc_server = nullptr; |
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.
Use an anonymous function to return the static global and init on first 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.
can you clarify 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.
addressed here: 31fda2b
@tvm.testing.fixture | ||
def tvm_tracker_host(): | ||
return os.environ["TVM_TRACKER_HOST"] | ||
|
||
|
||
@tvm.testing.fixture | ||
def tvm_tracker_port(): | ||
return int(os.environ["TVM_TRACKER_PORT"]) | ||
|
||
|
||
def _compose(args, decs): | ||
"""Helper to apply multiple markers""" | ||
if len(args) > 0: | ||
f = args[0] | ||
for d in reversed(decs): | ||
f = d(f) | ||
return f | ||
return decs | ||
|
||
|
||
def requires_rpc_tracker(*args): | ||
"""Mark a test as requiring an RPC tracker to exist in | ||
the host environment to run.""" | ||
_requires_rpc_tracker = [ | ||
*tvm.testing.requires_rpc(), | ||
pytest.mark.skipif( | ||
os.environ.get("TVM_TRACKER_HOST") == None, | ||
reason="Missing environment variable, TVM_TRACKER_HOST", | ||
), | ||
pytest.mark.skipif( | ||
os.environ.get("TVM_TRACKER_PORT") == None, | ||
reason="Missing environment variable, TVM_TRACKER_PORT", | ||
), | ||
] | ||
|
||
return _compose(args, _requires_rpc_tracker) | ||
|
||
|
||
def requires_hexagon_toolchain(*args): | ||
_requires_hexagon_toolchain = [ | ||
pytest.mark.skipif( | ||
os.environ.get("HEXAGON_TOOLCHAIN") == None, | ||
reason="HEXAGON_TOOLCHAIN environment variable is required to run this test.", | ||
), | ||
] |
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 are defined also in test_hexagon/proxy_rpc/
for the sake of common code can you put these in test_hexagon/conftest.py
?
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.
Refactored conftest files here: aa61967
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 partial review to note that I tested out this PR using the README and was able to get it running. LGTM from a usability / documentation point of view.
d4feb90
to
8216120
Compare
8216120
to
a7ee1a9
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 great to me! Only (non-blocking) nitpicks/TODOs
269b2a8
to
532bf1b
Compare
* Add Hexagon RPC * removed android remote and updated Readme * Add check for workspace size * Make libtvm_runtime consistent for Android * Remove root access * Fix some docstrings * Make stack remote size as parameter * add documentation * Refactor test conftest * clang format * Decoupled USE_HEXAGON_RPC * fix creation of test base directory on android * Address global variable * Fix format and Cleanup cmake * Fix build for other targets
COMMAND ${QAIC_EXE} ${QAIC_FLAGS} "${HEXAGON_RPC_DIR}/${RPC_IDL}" -o ${HEXAGON_RPC_DIR} | ||
MAIN_DEPENDENCY "${HEXAGON_RPC_DIR}/${RPC_IDL}" | ||
) | ||
file(GLOB HEXAGON_RPC_CPP "${HEXAGON_RPC_DIR}/android/*.cc") |
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 unconditionally add all files from that directory to the runtime target. If USE_HEXAGON_RPC
is not set, it will cause link errors.
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.
@kparzysz-quic thanks for pointing out. This could break if USE_HEXAGON_SDK
and BUILD_FOR_ANDROID
are enabled and USE_HEXAGON_RPC
not enabled. So we should fix this. I suggest that we fix this with a cleanup of Hexagon.cmake once we agreed on using hexagon RPC and decided to deprecate hexagon proxy rpc
and apps/hexagon_launcher
.
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.
@kparzysz-quic happy to hear your suggestion on this. thanks!
* Add Hexagon RPC * removed android remote and updated Readme * Add check for workspace size * Make libtvm_runtime consistent for Android * Remove root access * Fix some docstrings * Make stack remote size as parameter * add documentation * Refactor test conftest * clang format * Decoupled USE_HEXAGON_RPC * fix creation of test base directory on android * Address global variable * Fix format and Cleanup cmake * Fix build for other targets
* Add Hexagon RPC * removed android remote and updated Readme * Add check for workspace size * Make libtvm_runtime consistent for Android * Remove root access * Fix some docstrings * Make stack remote size as parameter * add documentation * Refactor test conftest * clang format * Decoupled USE_HEXAGON_RPC * fix creation of test base directory on android * Address global variable * Fix format and Cleanup cmake * Fix build for other targets
* Add Hexagon RPC * removed android remote and updated Readme * Add check for workspace size * Make libtvm_runtime consistent for Android * Remove root access * Fix some docstrings * Make stack remote size as parameter * add documentation * Refactor test conftest * clang format * Decoupled USE_HEXAGON_RPC * fix creation of test base directory on android * Address global variable * Fix format and Cleanup cmake * Fix build for other targets
* Add Hexagon RPC * removed android remote and updated Readme * Add check for workspace size * Make libtvm_runtime consistent for Android * Remove root access * Fix some docstrings * Make stack remote size as parameter * add documentation * Refactor test conftest * clang format * Decoupled USE_HEXAGON_RPC * fix creation of test base directory on android * Address global variable * Fix format and Cleanup cmake * Fix build for other targets
} | ||
|
||
/*! | ||
* \brief Get pointer to the buffer that a packet has been written to. |
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 function doesn't "get any pointers", it copies (part of) the write buffer to the specified address.
read_buffer_index_); | ||
|
||
uint32_t bytes_to_read = 0; | ||
if ((read_buffer_index_ - read_len_bytes) < 0) { |
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 shouldn't be subtracting unsigned numbers, just comparing them.
read_buffer_index_ -= bytes_to_read; | ||
if (bytes_to_read != read_len_bytes) { | ||
HEXAGON_PRINT(ERROR, "Error bytes_to_read (%d) < read_len_bytes (%d).", bytes_to_read, | ||
read_len_bytes); |
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's an error to read less than read_len_bytes
, then why is the code above trying to handle this?
if (data_size_bytes > read_buffer_size_bytes_) { | ||
return AEE_EFAILED; | ||
} | ||
read_buffer_ = data; |
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 loses the initial read buffer, which is never deallocated.
*/ | ||
class HexagonIOHandler { | ||
public: | ||
explicit HexagonIOHandler(uint8_t* read_buffer, size_t read_buffer_size_bytes) |
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 read_buffer
is not used for anything.
explicit HexagonIOHandler(uint8_t* read_buffer, size_t read_buffer_size_bytes) | ||
: read_buffer_{read_buffer}, | ||
read_buffer_size_bytes_{read_buffer_size_bytes}, | ||
read_buffer_index_{0} {} |
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 order here should follow the order of declarations below.
namespace { | ||
tvm::runtime::hexagon::HexagonRPCServer* get_hexagon_rpc_server() { | ||
static tvm::runtime::hexagon::HexagonRPCServer g_hexagon_rpc_server( | ||
new uint8_t[TVM_HEXAGON_RPC_BUFF_SIZE_BYTES], TVM_HEXAGON_RPC_BUFF_SIZE_BYTES); |
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 allocation is lost the first time the server tries to read something (see SetReadBuffer
).
@kparzysz-quic thanks for pointing out these issues. I will address these in the next PR for AOT executor. |
* Add Hexagon RPC * removed android remote and updated Readme * Add check for workspace size * Make libtvm_runtime consistent for Android * Remove root access * Fix some docstrings * Make stack remote size as parameter * add documentation * Refactor test conftest * clang format * Decoupled USE_HEXAGON_RPC * fix creation of test base directory on android * Address global variable * Fix format and Cleanup cmake * Fix build for other targets
This PR:
To use this feature you need to build TVM using these configs:
This will build:
libtvm
andlibtvm_runtime
using hexagon LLVM andtvm_rcp
for host.libtvm_runtime_android.so
andtvm_rpc_android
for Android underbuild/hexagon_rpc
libhexagon_rpc_skel.so
library which include RPC server for Hexagon underbuild/hexagon_rpc
cc @areusch @csullivan @adstraw