Skip to content

Commit 3935e6b

Browse files
committed
Implemented rpc logging
1 parent f841b63 commit 3935e6b

File tree

11 files changed

+1342
-263
lines changed

11 files changed

+1342
-263
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ list(APPEND COMPILER_SRCS "src/target/datatype/myfloat/myfloat.cc")
317317
tvm_file_glob(GLOB RUNTIME_SRCS
318318
src/runtime/*.cc
319319
src/runtime/vm/*.cc
320+
src/runtime/minrpc/*.cc
320321
)
321322

322323
if(BUILD_FOR_HEXAGON)

python/tvm/rpc/client.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ def request_and_run(self, key, func, priority=1, session_timeout=0, max_retry=2)
459459
)
460460

461461

462-
def connect(url, port, key="", session_timeout=0, session_constructor_args=None):
462+
def connect(url, port, key="", session_timeout=0, session_constructor_args=None, **kwargs):
463463
"""Connect to RPC Server
464464
465465
Parameters
@@ -483,6 +483,9 @@ def connect(url, port, key="", session_timeout=0, session_constructor_args=None)
483483
The first element of the list is always a string specifying the name of
484484
the session constructor, the following args are the positional args to that function.
485485
486+
**kwargs: optional
487+
enable_logging flag to enable/disable logging. Logging is disabled by default.
488+
486489
Returns
487490
-------
488491
sess : RPCSession
@@ -505,7 +508,7 @@ def connect(url, port, key="", session_timeout=0, session_constructor_args=None)
505508
client_via_proxy = rpc.connect(
506509
proxy_server_url, proxy_server_port, proxy_server_key,
507510
session_constructor_args=[
508-
"rpc.Connect", internal_url, internal_port, internal_key])
511+
"rpc.Connect", internal_url, internal_port, internal_key, enable_logging])
509512
510513
"""
511514
try:
@@ -514,7 +517,10 @@ def connect(url, port, key="", session_timeout=0, session_constructor_args=None)
514517
session_constructor_args = session_constructor_args if session_constructor_args else []
515518
if not isinstance(session_constructor_args, (list, tuple)):
516519
raise TypeError("Expect the session constructor to be a list or tuple")
517-
sess = _ffi_api.Connect(url, port, key, *session_constructor_args)
520+
enable_logging = False
521+
if kwargs is not None and "enable_logging" in kwargs:
522+
enable_logging = kwargs["enable_logging"]
523+
sess = _ffi_api.Connect(url, port, key, enable_logging, *session_constructor_args)
518524
except NameError:
519525
raise RuntimeError("Please compile with USE_RPC=1")
520526
return RPCSession(sess)

src/runtime/minrpc/minrpc_intrfc.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#ifndef TVM_RUNTIME_MINRPC_MINRPC_INTRFC_H_
21+
#define TVM_RUNTIME_MINRPC_MINRPC_INTRFC_H_
22+
23+
#include <tvm/runtime/c_runtime_api.h>
24+
25+
#include "rpc_reference.h"
26+
27+
namespace tvm {
28+
namespace runtime {
29+
30+
/*!
31+
* \brief Return interface used in ExecInterface to generate and sent the responses.
32+
*/
33+
class ReturnInterface {
34+
public:
35+
virtual ~ReturnInterface() {}
36+
virtual void ReturnVoid() = 0;
37+
virtual void ReturnHandle(void* handle) = 0;
38+
virtual void ReturnException(const char* msg) = 0;
39+
virtual void ReturnPackedSeq(const TVMValue* arg_values, const int* type_codes, int num_args) = 0;
40+
virtual void ReturnCopyAck(uint64_t* num_bytes, uint8_t** data_ptr) = 0;
41+
virtual void ReturnLastTVMError() = 0;
42+
virtual void ThrowError(RPCServerStatus code, RPCCode info = RPCCode::kNone) = 0;
43+
};
44+
45+
/*!
46+
* \brief Execute interface used in MinRPCServer to process different received commands
47+
*/
48+
class ExecInterface {
49+
public:
50+
virtual ~ExecInterface() {}
51+
virtual void ExecInitServer(int* _num_args) = 0;
52+
virtual void ExecNormalCallFunc(uint64_t* _call_handle, TVMValue** _values, int** _tcodes,
53+
int* _num_args) = 0;
54+
virtual void ExecCopyFromRemote(DLTensor** _arr, uint64_t* _num_bytes, uint8_t** _data_ptr) = 0;
55+
virtual int ExecCopyToRemote(DLTensor** _arr, uint64_t* _num_bytes, uint8_t** _data_ptr) = 0;
56+
virtual void ExecSyscallFunc(RPCCode* _code, TVMValue** _values, int** _tcodes,
57+
int* _num_args) = 0;
58+
virtual void ThrowError(RPCServerStatus code, RPCCode info = RPCCode::kNone) = 0;
59+
virtual ReturnInterface* getReturnInterface() = 0;
60+
};
61+
62+
} // namespace runtime
63+
} // namespace tvm
64+
#endif // TVM_RUNTIME_MINRPC_MINRPC_INTRFC_H_
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "minrpc_logger.h"
21+
22+
#include <string.h>
23+
#include <time.h>
24+
#include <tvm/runtime/c_runtime_api.h>
25+
#include <tvm/runtime/logging.h>
26+
27+
#include <functional>
28+
#include <iostream>
29+
#include <sstream>
30+
#include <unordered_map>
31+
32+
#include "minrpc_intrfc.h"
33+
#include "rpc_reference.h"
34+
35+
namespace tvm {
36+
namespace runtime {
37+
38+
std::stringstream Logger::LogTime() {
39+
char buf[100];
40+
time_t t;
41+
struct tm *timeptr, result, temp;
42+
std::stringstream ss;
43+
44+
t = time(NULL);
45+
timeptr = localtime_r(&t, &temp);
46+
strftime(buf, sizeof(buf), "%a %m/%d/%Y %r", timeptr);
47+
48+
if (strptime(buf, "%a %m/%d/%Y %r", &result) == NULL) {
49+
ss << "TIME UNKNOWN, ";
50+
} else {
51+
ss << result.tm_hour << ":" << result.tm_min << ":" << result.tm_sec << ", ";
52+
}
53+
return ss;
54+
}
55+
56+
void Logger::OutputLog() {
57+
LOG(INFO) << os_.str();
58+
this->os_.str(std::string());
59+
}
60+
61+
MinRPCReturnsWithLog::MinRPCReturnsWithLog(ReturnInterface* next) : next_(next), logger_() {}
62+
63+
MinRPCReturnsWithLog::~MinRPCReturnsWithLog() {}
64+
65+
void MinRPCReturnsWithLog::ReturnVoid() {
66+
next_->ReturnVoid();
67+
logger->LogString("-> ReturnVoid");
68+
logger->OutputLog();
69+
}
70+
71+
void MinRPCReturnsWithLog::ReturnHandle(void* handle) {
72+
next_->ReturnHandle(handle);
73+
if (this->code == RPCCode::kGetGlobalFunc) {
74+
this->registerHandleName(handle);
75+
}
76+
logger->LogVal<void*>("-> ReturnHandle: ", handle);
77+
logger->OutputLog();
78+
}
79+
80+
void MinRPCReturnsWithLog::ReturnException(const char* msg) {
81+
next_->ReturnException(msg);
82+
logger->LogString("-> Exception: ");
83+
logger->LogString(msg);
84+
logger->OutputLog();
85+
}
86+
87+
void MinRPCReturnsWithLog::ReturnPackedSeq(const TVMValue* arg_values, const int* type_codes,
88+
int num_args) {
89+
next_->ReturnPackedSeq(arg_values, type_codes, num_args);
90+
processValues(&arg_values, &type_codes, &num_args);
91+
logger->OutputLog();
92+
}
93+
94+
void MinRPCReturnsWithLog::ReturnCopyAck(uint64_t* num_bytes, uint8_t** data_ptr) {
95+
next_->ReturnCopyAck(num_bytes, data_ptr);
96+
logger->LogVal<uint64_t>("-> CopyAck: ", *num_bytes);
97+
logger->LogVal<void*>(", ", reinterpret_cast<void*>(*data_ptr));
98+
logger->OutputLog();
99+
}
100+
101+
void MinRPCReturnsWithLog::ReturnLastTVMError() {
102+
const char* err = TVMGetLastError();
103+
this->ReturnException(err);
104+
}
105+
106+
void MinRPCReturnsWithLog::ThrowError(RPCServerStatus code, RPCCode info = RPCCode::kNone) {
107+
next_->ThrowError(code, info);
108+
logger->LogString("-> ERROR");
109+
logger->OutputLog();
110+
}
111+
112+
void MinRPCReturnsWithLog::processValues(const TVMValue** values, const int** tcodes,
113+
int* num_args) {
114+
if (*tcodes != nullptr) {
115+
logger->LogString("-> [");
116+
for (int i = 0; i < *num_args; ++i) {
117+
logger->LogTVMValue((*tcodes)[i], (*values)[i]);
118+
119+
if ((*tcodes)[i] == kTVMOpaqueHandle) {
120+
this->registerHandleName((*values)[i].v_handle);
121+
}
122+
}
123+
logger->LogString("]");
124+
}
125+
}
126+
127+
void MinRPCReturnsWithLog::resetCurrHandleName(RPCCode code) {
128+
this->code = code;
129+
logger->LogString(RPCCodeToString(code));
130+
logger->LogString(", ");
131+
this->CurrHandleName.clear();
132+
}
133+
134+
void MinRPCReturnsWithLog::updateCurrHandleName(const char* name) {
135+
if (this->CurrHandleName.length() != 0) {
136+
this->CurrHandleName.append("::");
137+
}
138+
this->CurrHandleName.append(name);
139+
}
140+
141+
void MinRPCReturnsWithLog::getHandleName(void* handle) {
142+
if (array_tracker.find(handle) != array_tracker.end()) {
143+
CurrHandleName.append(array_tracker[handle]);
144+
logger->LogHandleName(CurrHandleName);
145+
}
146+
}
147+
148+
void MinRPCReturnsWithLog::releaseHandleName(void* handle) {
149+
if (array_tracker.find(handle) != array_tracker.end()) {
150+
logger->LogHandleName(array_tracker[handle]);
151+
array_tracker.erase(handle);
152+
}
153+
}
154+
155+
Logger* MinRPCReturnsWithLog::getLogger() { return this->logger; }
156+
157+
void MinRPCReturnsWithLog::registerHandleName(void* handle) {
158+
const std::string newString = CurrHandleName;
159+
array_tracker[handle] = newString;
160+
}
161+
162+
MinRPCExecuteWithLog::MinRPCExecuteWithLog(ExecInterface* next) : next_(next) {
163+
this->ret_ = reinterpret_cast<MinRPCReturnsWithLog*>(next_->getReturnInterface());
164+
this->logger = ret_->getLogger();
165+
}
166+
167+
MinRPCExecuteWithLog::~MinRPCExecuteWithLog() {}
168+
169+
void MinRPCExecuteWithLog::ExecInitServer(int* _num_args) {
170+
setRPCCode(RPCCode::kInitServer);
171+
logger->LogString("Init Server");
172+
next_->ExecInitServer(_num_args);
173+
}
174+
175+
void MinRPCExecuteWithLog::ExecNormalCallFunc(uint64_t* call_handle, TVMValue** values,
176+
int** tcodes, int* num_args) {
177+
setRPCCode(RPCCode::kCallFunc);
178+
logger->LogVal<void*>("call_handle: ", reinterpret_cast<void*>(*call_handle));
179+
ret_->getHandleName(reinterpret_cast<void*>(*call_handle));
180+
if (*num_args > 0) {
181+
logger->LogString(", ");
182+
}
183+
this->processValues(values, tcodes, num_args);
184+
next_->ExecNormalCallFunc(call_handle, values, tcodes, num_args);
185+
}
186+
187+
void MinRPCExecuteWithLog::ExecCopyFromRemote(DLTensor** arr, uint64_t* num_bytes,
188+
uint8_t** temp_data) {
189+
setRPCCode(RPCCode::kCopyFromRemote);
190+
logger->LogVal<void*>("data_handle: ", reinterpret_cast<void*>((*arr)->data));
191+
logger->LogDLDevice(", DLDevice(type,id):", &(*arr)->device);
192+
logger->LogVal<int64_t>(", ndim: ", (*arr)->ndim);
193+
logger->LogDLData(", DLDataType(code,bits,lane): ", &(*arr)->dtype);
194+
logger->LogVal<uint64_t>(", num_bytes:", *num_bytes);
195+
next_->ExecCopyFromRemote(arr, num_bytes, temp_data);
196+
}
197+
198+
int MinRPCExecuteWithLog::ExecCopyToRemote(DLTensor** arr, uint64_t* _num_bytes,
199+
uint8_t** _data_ptr) {
200+
setRPCCode(RPCCode::kCopyToRemote);
201+
logger->LogVal<void*>("data_handle: ", reinterpret_cast<void*>((*arr)->data));
202+
logger->LogDLDevice(", DLDevice(type,id):", &(*arr)->device);
203+
logger->LogVal<int64_t>(", ndim: ", (*arr)->ndim);
204+
logger->LogDLData(", DLDataType(code,bits,lane): ", &(*arr)->dtype);
205+
logger->LogVal<uint64_t>(", byte_offset: ", (*arr)->byte_offset);
206+
return next_->ExecCopyToRemote(arr, _num_bytes, _data_ptr);
207+
}
208+
209+
void MinRPCExecuteWithLog::ExecSyscallFunc(RPCCode* code, TVMValue** values, int** tcodes,
210+
int* num_args) {
211+
setRPCCode(*code);
212+
if ((*code) == RPCCode::kFreeHandle) {
213+
if (((*num_args) == 2) && ((*tcodes)[0] == kTVMOpaqueHandle) && ((*tcodes)[1] == kDLInt)) {
214+
logger->LogVal<void*>("handle: ", reinterpret_cast<void*>((*values)[0].v_handle));
215+
if ((*values)[1].v_int64 == kTVMModuleHandle ||
216+
(*values)[1].v_int64 == kTVMPackedFuncHandle) {
217+
ret_->releaseHandleName(reinterpret_cast<void*>((*values)[0].v_handle));
218+
}
219+
}
220+
} else {
221+
this->processValues(values, tcodes, num_args);
222+
}
223+
next_->ExecSyscallFunc(code, values, tcodes, num_args);
224+
}
225+
226+
void MinRPCExecuteWithLog::ThrowError(RPCServerStatus code, RPCCode info = RPCCode::kNone) {
227+
logger->LogString("-> Error\n");
228+
next_->ThrowError(code, info);
229+
}
230+
231+
ReturnInterface* MinRPCExecuteWithLog::getReturnInterface() { return next_->getReturnInterface(); }
232+
233+
void MinRPCExecuteWithLog::processValues(TVMValue** values, int** tcodes, int* num_args) {
234+
if (*tcodes != nullptr) {
235+
logger->LogString("[");
236+
for (int i = 0; i < *num_args; ++i) {
237+
logger->LogTVMValue((*tcodes)[i], (*values)[i]);
238+
239+
if ((*tcodes)[i] == kTVMStr) {
240+
if (strlen((*values)[i].v_str) > 0) {
241+
ret_->updateCurrHandleName((*values)[i].v_str);
242+
}
243+
}
244+
}
245+
logger->LogString("]");
246+
}
247+
}
248+
249+
void MinRPCExecuteWithLog::setRPCCode(RPCCode code) { ret_->resetCurrHandleName(code); }
250+
251+
} // namespace runtime
252+
} // namespace tvm

0 commit comments

Comments
 (0)