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

[Hexagon] Add RPC Mechanism for Hexagon #9631

Merged
merged 15 commits into from
Dec 8, 2021

Conversation

mehrdadh
Copy link
Member

@mehrdadh mehrdadh commented Dec 1, 2021

This PR:

  • Reuses minRPC implementation for hexagon to create RPC connection from host to hexagon device which is passed through android RPC server.
  • Adds HexagonLauncher which manages file upload to Android, initiate RPC server on Android and manage RPC session to hexagon.

To use this feature you need to build TVM using these configs:

cmake -DUSE_HEXAGON_RPC=ON \
       -DUSE_ANDROID_TOOLCHAIN=/path/to/android-ndk/build/cmake/android.toolchain.cmake \
       -DANDROID_PLATFORM=android-28 \
       -DANDROID_ABI=arm64-v8a \
       -DUSE_HEXAGON_ARCH=v65|v66|v68 \
       -DUSE_HEXAGON_SDK=/path/to/Hexagon/SDK \
       -DUSE_HEXAGON_TOOLCHAIN=/path/to/Hexagon/toolchain/ \
       -DUSE_LLVM=/path/to/llvm/bin/llvm-config \
       -DUSE_CPP_RPC=ON \
       -DCMAKE_CXX_COMPILER=/path/to/clang++ \    
       -DCMAKE_CXX_FLAGS='-stdlib=libc++' ..

This will build:

  • libtvm and libtvm_runtime using hexagon LLVM andtvm_rcp for host.
  • libtvm_runtime_android.so and tvm_rpc_android for Android under build/hexagon_rpc
  • libhexagon_rpc_skel.so library which include RPC server for Hexagon under build/hexagon_rpc

cc @areusch @csullivan @adstraw

@mehrdadh mehrdadh force-pushed the hexagon/hexagon_rpc branch 2 times, most recently from 5fc7750 to 129d96a Compare December 2, 2021 03:23
@mehrdadh mehrdadh marked this pull request as ready for review December 2, 2021 03:25
@mehrdadh mehrdadh force-pushed the hexagon/hexagon_rpc branch 3 times, most recently from 38c2c50 to ef7da6e Compare December 2, 2021 22:36
Copy link
Contributor

@csullivan csullivan left a 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!

# copy android_bash template file
configure_file("${CMAKE_SOURCE_DIR}/src/runtime/hexagon/rpc/android_bash.sh.template"
${HEXAGON_RPC_OUTPUT} COPYONLY)
endif()
Copy link
Contributor

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.

Suggested change
endif()
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${HEXAGON_RPC_OUTPUT}")
endif()

Copy link
Member Author

Choose a reason for hiding this comment

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

done here: 28db608

apps/cpp_rpc/CMakeLists.txt Show resolved Hide resolved
@@ -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))
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

done: 28db608

@@ -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)
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

done: 28db608

python/tvm/contrib/hexagon/build.py Show resolved Hide resolved
read_buffer_size_bytes_);

uint32_t bytes_to_read = 0;
if ((read_buffer_size_bytes_ - read_len_bytes) < 0) {
Copy link
Contributor

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.

Copy link
Member Author

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];
Copy link
Contributor

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).

Copy link
Member Author

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;
Copy link
Contributor

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

Copy link
Member Author

Choose a reason for hiding this comment

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

can you clarify this?

Copy link
Member Author

Choose a reason for hiding this comment

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

addressed here: 31fda2b

src/runtime/hexagon/rpc/hexagon_rpc.idl Outdated Show resolved Hide resolved
Comment on lines 36 to 80
@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.",
),
]
Copy link
Contributor

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?

Copy link
Member Author

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

Copy link
Contributor

@adstraw adstraw left a 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.

Copy link
Contributor

@csullivan csullivan left a 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

@jroesch jroesch merged commit cd2fa69 into apache:main Dec 8, 2021
@mehrdadh mehrdadh mentioned this pull request Dec 8, 2021
mikepapadim pushed a commit to mikepapadim/tvm that referenced this pull request Dec 9, 2021
* 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")
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member Author

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!

ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
* 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
yangulei pushed a commit to yangulei/tvm that referenced this pull request Jan 11, 2022
* 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
yangulei pushed a commit to yangulei/tvm that referenced this pull request Jan 12, 2022
* 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
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
* 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.
Copy link
Contributor

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) {
Copy link
Contributor

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);
Copy link
Contributor

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;
Copy link
Contributor

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)
Copy link
Contributor

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} {}
Copy link
Contributor

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);
Copy link
Contributor

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).

@mehrdadh
Copy link
Member Author

@kparzysz-quic thanks for pointing out these issues. I will address these in the next PR for AOT executor.

@mehrdadh mehrdadh deleted the hexagon/hexagon_rpc branch January 28, 2022 22:52
mehrdadh added a commit to mehrdadh/tvm that referenced this pull request Feb 9, 2022
mehrdadh added a commit to mehrdadh/tvm that referenced this pull request Feb 9, 2022
kparzysz-quic pushed a commit that referenced this pull request Feb 11, 2022
ylc pushed a commit to ylc/tvm that referenced this pull request Feb 16, 2022
pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
qsqqsqqsq-intellif pushed a commit to qsqqsqqsq-intellif/tvm that referenced this pull request Apr 29, 2022
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants