Skip to content

Commit

Permalink
[Hexagon] RPC server/client for simulator (apache#10361)
Browse files Browse the repository at this point in the history
This is the C++ code for running Hexagon code on simulator via the
RPC mechanism. It is intended to be integrated into the current
HexagonLauncher, although the integration will require further changes
to the launcher python code.

The final goal is to be able to run the same file.py on either
hardware or simulator without needing to edit the python file, but
simply by changing the configuration of the execution platform
(i.e. something like --exectute-on=simulator as a command line or
in an environment variable). The exact details are still to be
determined.
  • Loading branch information
Krzysztof Parzyszek authored and pfk-beta committed Apr 11, 2022
1 parent 87f821a commit aa71c5f
Show file tree
Hide file tree
Showing 6 changed files with 1,776 additions and 5 deletions.
29 changes: 27 additions & 2 deletions apps/hexagon_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,31 @@ else()
endif()
file(MAKE_DIRECTORY ${HEXAGON_API_BINARY_DIR})

# Build X86 binaries:
# - tvm_rpc_x86

ExternalProject_Add(x86_tvm_runtime_rpc
SOURCE_DIR "${TVM_SOURCE_DIR}"
BUILD_COMMAND $(MAKE) runtime tvm_rpc
CMAKE_ARGS
"-DUSE_HEXAGON_TOOLCHAIN=${USE_HEXAGON_TOOLCHAIN}"
"-DCMAKE_CXX_STANDARD=14"
"-DUSE_LIBBACKTRACE=OFF"
"-DUSE_RPC=ON"
"-DUSE_CPP_RPC=ON"
"-DUSE_HEXAGON_RPC=ON"
"-DBUILD_STATIC_RUNTIME=ON"
INSTALL_COMMAND ""
BUILD_ALWAYS ON
)
ExternalProject_Get_Property(x86_tvm_runtime_rpc BINARY_DIR)
ExternalProject_Add_Step(x86_tvm_runtime_rpc copy_rpc_server
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${BINARY_DIR}/tvm_rpc
${HEXAGON_API_BINARY_DIR}/tvm_rpc_x86
DEPENDEES install
)

# Build Android binaries:
# - libtvm_runtime.so
# - tvm_rpc_android
Expand All @@ -38,7 +63,6 @@ ExternalProject_Add(android_tvm_runtime_rpc
"-DUSE_HEXAGON_ARCH=${USE_HEXAGON_ARCH}"
"-DCMAKE_CXX_STANDARD=14"
"-DUSE_LIBBACKTRACE=OFF"
"-DUSE_LLVM=OFF"
"-DUSE_RPC=ON"
"-DUSE_CPP_RPC=ON"
"-DUSE_HEXAGON_RPC=ON"
Expand Down Expand Up @@ -66,7 +90,7 @@ ExternalProject_Add_Step(android_tvm_runtime_rpc copy_rpc_server

ExternalProject_Add(hexagon_tvm_runtime_rpc
SOURCE_DIR "${TVM_SOURCE_DIR}"
BUILD_COMMAND $(MAKE) runtime
BUILD_COMMAND $(MAKE) runtime hexagon_rpc_sim
CMAKE_ARGS
"-DCMAKE_C_COMPILER=${USE_HEXAGON_TOOLCHAIN}/bin/hexagon-clang"
"-DCMAKE_CXX_COMPILER=${USE_HEXAGON_TOOLCHAIN}/bin/hexagon-clang++"
Expand All @@ -84,6 +108,7 @@ ExternalProject_Add_Step(hexagon_tvm_runtime_rpc copy_binaries
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${BINARY_DIR}/libtvm_runtime.a
${BINARY_DIR}/libhexagon_rpc_skel.so
${BINARY_DIR}/libhexagon_rpc_sim.so
${HEXAGON_API_BINARY_DIR}
DEPENDEES install
)
Expand Down
34 changes: 31 additions & 3 deletions cmake/modules/Hexagon.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,13 @@ endif()
#
# USE_HEXAGON_RPC:
# - When building for Hexagon, this will build the Hexagon endpoint of the
# RPC server: the FastRPC skel library (with TVM runtime built into it).
# RPC server: the FastRPC skel library (with TVM runtime built into it),
# and the standalone RPC server for simulator.
# - When building for Android, this will build the (intermediary) RPC server,
# including the "stub" code for the FastRPC implementation of the RPC
# channel.
# - When building for x86, this will build the host-side code that instan-
# tiates the simulator.

if(NOT BUILD_FOR_HEXAGON AND NOT BUILD_FOR_ANDROID)
set(BUILD_FOR_HOST TRUE)
Expand Down Expand Up @@ -116,6 +119,15 @@ function(add_android_paths)
link_directories(${HEXAGON_REMOTE_ROOT})
endfunction()

function(add_hexagon_wrapper_paths)
if(NOT DEFINED HEXAGON_TOOLCHAIN)
message(FATAL_ERROR "This function must be called after find_hexagon_toolchain")
endif()
include_directories(SYSTEM
"${HEXAGON_TOOLCHAIN}/include/iss"
)
link_directories("${HEXAGON_TOOLCHAIN}/lib/iss")
endfunction()

# Common sources for TVM runtime with Hexagon support
file_glob_append(RUNTIME_HEXAGON_COMMON_SRCS
Expand Down Expand Up @@ -148,12 +160,11 @@ if(USE_HEXAGON_DEVICE)
invalid_device_value_for("host")
endif()
find_hexagon_toolchain()
add_hexagon_wrapper_paths()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon/android/*.cc"
"${TVMRT_SOURCE_DIR}/hexagon/android/sim/*.cc"
)
include_directories(SYSTEM "${HEXAGON_TOOLCHAIN}/include/iss")
link_directories("${HEXAGON_TOOLCHAIN}/lib/iss")
list(APPEND TVM_RUNTIME_LINKER_LIBS "-lwrapper")

ExternalProject_Add(sim_dev
Expand Down Expand Up @@ -245,6 +256,23 @@ if(USE_HEXAGON_RPC)
target_include_directories(hexagon_rpc_skel
SYSTEM PRIVATE "${TVMRT_SOURCE_DIR}/hexagon/rpc"
)
# Add the simulator-specific RPC code into a shared library to be
# executed via run_main_on_sim.
add_library(hexagon_rpc_sim SHARED
"${TVMRT_SOURCE_DIR}/hexagon/rpc/simulator/rpc_server.cc"
)
target_link_libraries(hexagon_rpc_sim
-Wl,--whole-archive tvm_runtime -Wl,--no-whole-archive
)

elseif(BUILD_FOR_HOST)
find_hexagon_toolchain()
add_hexagon_wrapper_paths()
file_glob_append(RUNTIME_HEXAGON_SRCS
"${TVMRT_SOURCE_DIR}/hexagon/host/*.cc"
"${TVMRT_SOURCE_DIR}/hexagon/rpc/simulator/session.cc"
)
list(APPEND TVM_RUNTIME_LINKER_LIBS "-lwrapper")
endif()
endif() # USE_HEXAGON_RPC

Expand Down
2 changes: 2 additions & 0 deletions python/tvm/contrib/hexagon/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

"""Defines a Session class for Hexagon devices."""

import os
from tvm import rpc as _rpc


Expand Down Expand Up @@ -59,6 +60,7 @@ def __enter__(self):
"tvm.contrib.hexagon.create_hexagon_session",
self._session_name,
self._remote_stack_size_bytes,
os.environ.get("HEXAGON_SIM_ARGS", ""),
],
)
self.device = self._rpc.hexagon(0)
Expand Down
75 changes: 75 additions & 0 deletions src/runtime/hexagon/rpc/simulator/hexagon_sim_proto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#ifndef TVM_RUNTIME_HEXAGON_RPC_SIMULATOR_HEXAGON_SIM_PROTO_H_
#define TVM_RUNTIME_HEXAGON_RPC_SIMULATOR_HEXAGON_SIM_PROTO_H_

struct Message {
enum : uint32_t {
kNone = 0,
kAck,
kTerminate,
kReceiveStart,
kReceiveEnd,
kSendStart,
kSendEnd,
};
enum : uint32_t {
null_va = 0,
};

uint32_t code;
uint32_t len;
uint32_t va;
} __attribute__((packed));

// Protocol:
//
// Copying data from host to remote:
//
// Host >-- [ kReceiveStart, len, null_va ] --> Remote
// * Remote client prepares a buffer with at least `len` bytes.
// Host <-- [ kAck, buf_size, buf_ptr ] <-- Remote
// * Host writes `nbytes` into buffer, `nbytes` <= `len`.
// Host >-- [ kReceiveEnd, nbytes, buf_ptr ] --> Remote
// * Remote client processes the data.
// Host <-- [ kAck, ___, ___ ] <-- Remote
//
// Copying data from remote to host:
//
// Host >-- [ kSendStart, len, null_va ] --> Remote
// * Remote client returns pointer to the buffer with the data to be read.
// * There should be at least `len` bytes ready in the buffer.
// Host <-- [ kAck, buf_size, buf_ptr ] <-- Remote
// * Host reads `nbytes` from buffer, `nbytes` <= `buf_size`.
// Host >-- [ kSendEnd , nbytes, buf_ptr ] --> Remote
// * Remote client processes the data.
// Host <-- [ kAck, ___, ___ ] <-- Remote
//
// Teminating server:
//
// Host >-- [ kTerminate, ___, ___ ] --> Remote
// Host <-- [ kAck, ___, ___ ] <-- Remote
// * Host continues execution of the client.
// * Client terminates.

#define DISPATCH_FUNCTION_NAME dispatch_875b2e3a28186123
#define MESSAGE_BUFFER_NAME message_buffer_71d6a7b93c318d7e

#endif // TVM_RUNTIME_HEXAGON_RPC_SIMULATOR_HEXAGON_SIM_PROTO_H_
Loading

0 comments on commit aa71c5f

Please sign in to comment.