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

[iOS] Add tracker support into ios-rpc application #7876

Merged
merged 23 commits into from
Sep 22, 2021

Conversation

apeskov
Copy link
Contributor

@apeskov apeskov commented Apr 18, 2021

Some set of improvements for iOS RPC application. The main point of changes is in build procedure and introducing support of direct RPC connection and connection via Tracker.

Build process improvements

  • Direct linking with tvm_runtime.dylib. Previous approach using direct include of source files. Some users and developer face issues with with missed functionality because and have to manually add several more include lines. This patch make iOS PRC server linked with tvm_runtime.dylib directly to eliminate this disadvantage.
  • Enabled ARC by default
  • Disabled bitcode. The latest changes in tvm build flags introduces an -undefined,error linker flag which is not compatible with bitcode.
  • Custom DSO loader is enabled by default. A lot of person are forgetting to enable it during manual build.
  • Move TVM_LOG_CUSTOMIZE=1 define moved from sources to project level. Previous it was leading to ODR violation is some cases.
  • Custom DSO sub project pointer is up. To fix internal memory leak.

UI changes

  • Hide keyboard when editing is finished.
  • Store text fields values in app cache. No need to manually fill it each time.
  • Introduce mode selector "Tracker/Proxy/PureRPC"
  • Single button to connect/disconnect with enhanced size

RPC functional changes

  • Introduced command line flags to run server form host side. Required to implement automatic RPC server runner.

--host_url The tracker/proxy address, Default=0.0.0.0"
--host_port The tracker/proxy port, Default=9190"
--key The key used to identify the device type in tracker. Default=""
--custom_addr Custom IP Address to Report to RPC Tracker. Default=""
--immediate_connect No UI interconnection, connect to tracker immediately. Default=False
--verbose Allow to print status info to std out. Default=False
--server_mode Server mode. Can be "pure_server", "proxy" or "tracker".

  • The printing of server status into std out is added (also print information about real IP in wifi network and RPC server port). Required to check server state from host runner.
  • Split ViewController and RPC Server login into different classes
  • Avoid using internal interface of RPCEndpoint::Create. Switched to publicly available Registry::Get("rpc.CreateEventDrivenServer")
  • Make RPC server api asynchronous. RPC server is executed in separate thread. No more blocking of UI.

Note:
Arguments support and status printing are a prerequisites for implementation python based RPC Server launcher (on top of iOS-deploy and simctl tools). Will be introduced a little bit later.

apps/ios_rpc/tvmrpc/TVMRuntime.mm Outdated Show resolved Hide resolved
apps/ios_rpc/tvmrpc/TVMRuntime.mm Outdated Show resolved Hide resolved
apps/ios_rpc/tvmrpc/rpc_server.h Outdated Show resolved Hide resolved
apps/ios_rpc/tvmrpc/rpc_server.h Outdated Show resolved Hide resolved
* \param ping_period Timeout for select call waiting
*/
void AcceptConnection(TrackerClient* tracker, support::TCPSocket* conn_sock,
support::SockAddr* addr, std::string* opts, int ping_period = 2) {
Copy link
Contributor

Choose a reason for hiding this comment

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

specify units: ping_period_sec

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The same as previous comment. Copy-paste form cpp_rpc. Already removed. You may move this comment into original cpp_rpc application

support::SockAddr* addr, std::string* opts, int ping_period = 2) {

* \param opts The option string
*/
int GetTimeOutFromOpts(const std::string& opts) const {
const std::string option = "-timeout=";
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if this should also have units? -timeout-sec

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree. And already removed.

@@ -71,88 +73,19 @@ void LogMessageImpl(const std::string& file, int lineno, const std::string& mess
namespace tvm {
namespace runtime {

class NSStreamChannel final : public RPCChannel {
Copy link
Contributor

Choose a reason for hiding this comment

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

just curious why this is going away? not needed if we use standard sockets?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved into "RPCServer.mm". And now it's wrapped into PackedFunction to meet API requirements of rpc.CreateEventDrivenServer.

@apeskov apeskov force-pushed the ap/ios-rpc-with-tracker branch 3 times, most recently from fe5622e to c3765ea Compare May 31, 2021 15:35
@jwfromm
Copy link
Contributor

jwfromm commented Jun 7, 2021

@apeskov Can you address @areusch's comments? It looks like you made a lot of his recommended changes but it'd be good to make sure you're both on the same page.

@apeskov
Copy link
Contributor Author

apeskov commented Jun 14, 2021

@areusch I've tried to answer your comments. Could you please continue a review?

Some part of code you pointed previously to improve was redesigned with latest commits, specially the code which was borrowed from cpp_rpc. I hope the new one will not cause a lot of questions.

Copy link
Contributor

@areusch areusch left a comment

Choose a reason for hiding this comment

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

@apeskov thanks! a couple more questions--mainly it would be helpful for me to understand the use case around introducing the gRPC transport. it's not that i'm opposed to doing that, but I'd like to understand why we may need it since it does add some complexity.


bool immediate_connect = false;
bool verbose = false;
char server_mode = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

should that be an enum?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, it could be enum. I've changed it to use enum form RPCServer.h.

args.server_mode = 0;
} else if (server_mode == "proxy") {
args.server_mode = 1;
} else if (server_mode == "pure_server") {
Copy link
Contributor

Choose a reason for hiding this comment

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

what's the use case for gRPC?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've tried to answer in reply message.

apps/ios_rpc/tvmrpc/ViewController.mm Show resolved Hide resolved

/// Immediate server launch. No UI interaction.
/// 0 - UI interaction, 1 - automatically connect on launch
char immediate_connect;
Copy link
Contributor

Choose a reason for hiding this comment

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

why do you represent bool quantities with char? (instead of bool or uint8_t)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, bool should be used here. Will change.

Originally it was a simplest way to share API between code written on Obj-C, Obj-C++, and C++ ("BOOL" and "bool" are not so compatible). But now there is no such need.

[defaults setObject:[NSString stringWithUTF8String:g_rpc_args.host_url.c_str()]
forKey:@"tmvrpc_url"];
[defaults setInteger:g_rpc_args.host_port forKey:@"tmvrpc_port"];
[defaults setObject:[NSString stringWithUTF8String:g_rpc_args.key.c_str()] forKey:@"tmvrpc_key"];
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: tvm, here and above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

/*!
*/
- (NSData*)requestInputDataPacked {
int size;
Copy link
Contributor

Choose a reason for hiding this comment

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

prefer to use the inttypes when taking sizeof() to compute payload lengths for wire data

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree. Moved to int32_t everywhere.

switch (state_) {
case RPCServerProxyState_HandshakeToSend: {
// Send together kRPCMagic and server descriptor because of Proxy
int code = tvm::runtime::kRPCMagic;
Copy link
Contributor

Choose a reason for hiding this comment

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

inttypes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

apps/ios_rpc/tvmrpc/RPCServer.mm Show resolved Hide resolved
@apeskov
Copy link
Contributor Author

apeskov commented Jun 18, 2021

@apeskov thanks! a couple more questions--mainly it would be helpful for me to understand the use case around introducing the gRPC transport. it's not that i'm opposed to doing that, but I'd like to understand why we may need it since it does add some complexity.

Will assume that gRPC == PureRPC in terminology of this patch.

At first, I would like to note that "PureRPC" is a part of "Tracker" mode. The implementation of "Tracker" server mode is using using "PureRPC" as internal server. I've just expose it outside for person who would like to use direct connection to iOS without tracker/proxy. Removing this piece of functionality will not simplify implementation.

The main goal was to allow user and developers to work with iOS without requirements to keep tracker/proxy server. As example I have one laptop and one iOS device connected to it via USB (there are no local WiFi network at all, or it is very slow). With using PureRPC mode plus port tunnelling (via usbmux tool) I can work with such setup.

In addition to this patch I have a plan to introduce iOSRPCRunner script which will allow me to automate iOS test with quite simple code like next:

    # Will use first connected iOS device with automatic TCP port tunnelling to host
    ios_rpc_serv = RPCServerIOS.create_ios_rpc_server(key=key, mode="pure_server")    
    remote = rpc.connect(ios_rpc_serv.host, ios_rpc_serv.port, key=key)

    do_some_test_with_ios(remote)

Port tunnelling may significantly speed up work with iOS device. My local benchmarking shows 3x-4x speed depends on kind of workload (yes, wifi router matter).

Definitely, the same speed up result can be also achieved with tracker. For this purpose I've introduced flag --custom_addr, which help to use USB port tunnelling (as result host address replacing) for tracker clients. But this solution still require to have iOS device and host machine connected to one local WiFi network.

Totally, from my point of view, PureRPC is not so hard to support feature, but it can simplify/speedup my scripts in some cases :-)

@apeskov
Copy link
Contributor Author

apeskov commented Jun 18, 2021

@areusch could you please continue review. I resolved all your comments excluding two. I've tried to explain in corresponding replies why I don't want to change it. Hope it will be enough.

@areusch areusch self-assigned this Jul 2, 2021
Copy link
Contributor

@areusch areusch left a comment

Choose a reason for hiding this comment

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

@apeskov sorry i think the thing i'm confused about is: what functionality does RPCServerPure add over the existing tracker (or: why was the existing tracker not able to be run over usbmux)? perhaps it would be helpful to see an e.g. README.md explaining how to use RPCServerPure. Does it e.g. allow you to start/stop the tracker or RPC server? sorry my obj-c/iOS is not super great so I keep trying to review this but going in circles.

*/
FEventHandler CreateServerEventHandler(NSOutputStream* outputStream, std::string name,
std::string remote_key) {
const PackedFunc* event_handler_factor = Registry::Get("rpc.CreateEventDrivenServer");
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: event_handler_factory

@areusch
Copy link
Contributor

areusch commented Sep 7, 2021

@apeskov just reviving this--please address the comment

@echuraev
Copy link
Contributor

echuraev commented Sep 8, 2021

@apeskov just reviving this--please address the comment

Hello @areusch! @apeskov is busy with other activities. I'm working to finish this PR. What about your comment. I already fixed the typo, and now I'm working on adding a detailed instruction which will help to understand the new workflow and how it works.
Also, I'm going to clean up the ios_rpc application and remove old code.

apeskov and others added 23 commits September 22, 2021 09:30
Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
Also containes:
* Links with tvm_runtime.dylib
* Minor improvements from UX perspective
* Add cli args support
* Add caching for url/port/key attributes

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
Also:
- Disabled bit-code
- Enabled ARC
- Use custom DSO loader by default
- Single button to connect/disconnect
- Add verbose flag

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
Signed-off-by: Alexander Peskov <peskovnn@gmail.com>
@echuraev
Copy link
Contributor

thanks @echuraev could we rename Pure to Standalone? or happy to hear other options. I think standalone makes sense to me--that would be --server_mode standalone and that would remove the name conflict with PureRPC.

Renamed to standalone

Copy link
Contributor

@areusch areusch left a comment

Choose a reason for hiding this comment

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

LGTM thanks @apeskov !

@areusch areusch merged commit 76d0534 into apache:main Sep 22, 2021
@areusch
Copy link
Contributor

areusch commented Sep 22, 2021

and thanks @echuraev !

ylc pushed a commit to ylc/tvm that referenced this pull request Sep 29, 2021
* [IOS-RPC] Missprint in flag value

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] custom_dyld up commit id. Fix mem leak

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] build without scheme

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] Add tracker support into ios-rpc app

Also containes:
* Links with tvm_runtime.dylib
* Minor improvements from UX perspective
* Add cli args support
* Add caching for url/port/key attributes

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] lint fix

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] Uniform servers

Also:
- Disabled bit-code
- Enabled ARC
- Use custom DSO loader by default
- Single button to connect/disconnect
- Add verbose flag

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS_RPC] Min changes. Fix warnings

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] Fix review comments

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* Fix RPC connection to tracker

* Fix typo

* Fix build for local developer profile

* Add tvmrpc xcode scheme

* Revert unnecessary change

* Remove old mechanism of reloading libs

* Display ip and port for PureRPC mode

* Update tests

* Remove tvmLauncher from ios_rpc

* Add updating tvm_build_dir in init_proj script

* Update default bundle

* Update README.md for ios_rpc

* Fix lint

* Apply comments

* Rename PureRPC to Standalone

Co-authored-by: Egor Churaev <egor.churaev@gmail.com>
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
* [IOS-RPC] Missprint in flag value

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] custom_dyld up commit id. Fix mem leak

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] build without scheme

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] Add tracker support into ios-rpc app

Also containes:
* Links with tvm_runtime.dylib
* Minor improvements from UX perspective
* Add cli args support
* Add caching for url/port/key attributes

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] lint fix

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] Uniform servers

Also:
- Disabled bit-code
- Enabled ARC
- Use custom DSO loader by default
- Single button to connect/disconnect
- Add verbose flag

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS_RPC] Min changes. Fix warnings

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* [IOS-RPC] Fix review comments

Signed-off-by: Alexander Peskov <peskovnn@gmail.com>

* Fix RPC connection to tracker

* Fix typo

* Fix build for local developer profile

* Add tvmrpc xcode scheme

* Revert unnecessary change

* Remove old mechanism of reloading libs

* Display ip and port for PureRPC mode

* Update tests

* Remove tvmLauncher from ios_rpc

* Add updating tvm_build_dir in init_proj script

* Update default bundle

* Update README.md for ios_rpc

* Fix lint

* Apply comments

* Rename PureRPC to Standalone

Co-authored-by: Egor Churaev <egor.churaev@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: need update need update based on feedbacks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants