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_interfaces.h"
33#include "rpc_reference.h"
34
35namespace tvm {
36namespace runtime {
37
38void Logger::LogTVMValue(int tcode, TVMValue value) {
39 switch (tcode) {
40 case kDLInt: {
41 LogValue<int64_t>("(int64)", value.v_int64);
42 break;
43 }
44 case kDLUInt: {
45 LogValue<uint64_t>("(uint64)", value.v_int64);
46 break;
47 }
48 case kDLFloat: {
49 LogValue<float>("(float)", value.v_float64);
50 break;
51 }
52 case kTVMDataType: {
53 LogDLData("DLDataType(code,bits,lane)", &value.v_type);
54 break;
55 }
56 case kDLDevice: {
57 LogDLDevice("DLDevice(type,id)", &value.v_device);
58 break;
59 }
60 case kTVMPackedFuncHandle: {
61 LogValue<void*>("(PackedFuncHandle)", value.v_handle);
62 break;
63 }
64 case kTVMModuleHandle: {
65 LogValue<void*>("(ModuleHandle)", value.v_handle);
66 break;
67 }
68 case kTVMOpaqueHandle: {
69 LogValue<void*>("(OpaqueHandle)", value.v_handle);
70 break;
71 }
72 case kTVMDLTensorHandle: {
73 LogValue<void*>("(TensorHandle)", value.v_handle);
74 break;
75 }
76 case kTVMNDArrayHandle: {
77 LogValue<void*>("kTVMNDArrayHandle", value.v_handle);
78 break;
79 }
80 case kTVMNullptr: {
81 Log("Nullptr");
82 break;
83 }
84 case kTVMStr: {
85 Log("\"");
86 Log(value.v_str);
87 Log("\"");
88 break;
89 }
90 case kTVMBytes: {
91 TVMByteArray* bytes = static_cast<TVMByteArray*>(value.v_handle);
92 int len = bytes->size;
93 LogValue<int64_t>("(Bytes) [size]: ", len);
94 if (PRINT_BYTES) {
95 Log(", [Values]:");
96 Log(" { ");
97 if (len > 0) {
98 LogValue<uint64_t>("", (uint8_t)bytes->data[0]);
99 }
100 for (int j = 1; j < len; j++) LogValue<uint64_t>(" - ", (uint8_t)bytes->data[j]);
101 Log(" } ");
102 }
103 break;
104 }
105 default: {
106 Log("ERROR-kUnknownTypeCode)");
107 break;
108 }
109 }
110 Log("; ");
111}
112
113void Logger::OutputLog() {
114 LOG(INFO) << os_.str();
115 os_.str(std::string());
116}
117
118void MinRPCReturnsWithLog::ReturnVoid() {
119 next_->ReturnVoid();
120 logger_->Log("-> ReturnVoid");
121 logger_->OutputLog();
122}
123
124void MinRPCReturnsWithLog::ReturnHandle(void* handle) {
125 next_->ReturnHandle(handle);
126 if (code_ == RPCCode::kGetGlobalFunc) {
127 RegisterHandleName(handle);
128 }
129 logger_->LogValue<void*>("-> ReturnHandle: ", handle);
130 logger_->OutputLog();
131}
132
133void MinRPCReturnsWithLog::ReturnException(const char* msg) {
134 next_->ReturnException(msg);
135 logger_->Log("-> Exception: ");
136 logger_->Log(msg);
137 logger_->OutputLog();
138}
139
140void MinRPCReturnsWithLog::ReturnPackedSeq(const TVMValue* arg_values, const int* type_codes,
141 int num_args) {
142 next_->ReturnPackedSeq(arg_values, type_codes, num_args);
143 ProcessValues(arg_values, type_codes, num_args);
144 logger_->OutputLog();
145}
146
147void MinRPCReturnsWithLog::ReturnCopyFromRemote(uint8_t* data_ptr, uint64_t num_bytes) {
148 next_->ReturnCopyFromRemote(data_ptr, num_bytes);
149 logger_->LogValue<uint64_t>("-> CopyFromRemote: ", num_bytes);
150 logger_->LogValue<void*>(", ", static_cast<void*>(data_ptr));
151 logger_->OutputLog();
152}
153
154void MinRPCReturnsWithLog::ReturnLastTVMError() {
155 const char* err = TVMGetLastError();
156 ReturnException(err);
157}
158
159void MinRPCReturnsWithLog::ThrowError(RPCServerStatus code, RPCCode info) {
160 next_->ThrowError(code, info);
161 logger_->Log("-> ERROR: ");
162 logger_->Log(RPCServerStatusToString(code));
163 logger_->OutputLog();
164}
165
166void MinRPCReturnsWithLog::ProcessValues(const TVMValue* values, const int* tcodes, int num_args) {
167 if (tcodes != nullptr) {
168 logger_->Log("-> [");
169 for (int i = 0; i < num_args; ++i) {
170 logger_->LogTVMValue(tcodes[i], values[i]);
171
172 if (tcodes[i] == kTVMOpaqueHandle) {
173 RegisterHandleName(values[i].v_handle);
174 }
175 }
176 logger_->Log("]");
177 }
178}
179
180void MinRPCReturnsWithLog::ResetHandleName(RPCCode code) {
181 code_ = code;
182 handle_name_.clear();
183}
184
185void MinRPCReturnsWithLog::UpdateHandleName(const char* name) {
186 if (handle_name_.length() != 0) {
187 handle_name_.append("::");
188 }
189 handle_name_.append(name);
190}
191
192void MinRPCReturnsWithLog::GetHandleName(void* handle) {
193 if (handle_descriptions_.find(handle) != handle_descriptions_.end()) {
194 handle_name_.append(handle_descriptions_[handle]);
195 logger_->LogHandleName(handle_name_);
196 }
197}
198
199void MinRPCReturnsWithLog::ReleaseHandleName(void* handle) {
200 if (handle_descriptions_.find(handle) != handle_descriptions_.end()) {
201 logger_->LogHandleName(handle_descriptions_[handle]);
202 handle_descriptions_.erase(handle);
203 }
204}
205
206void MinRPCReturnsWithLog::RegisterHandleName(void* handle) {
207 handle_descriptions_[handle] = handle_name_;
208}
209
210void MinRPCExecuteWithLog::InitServer(int num_args) {
211 SetRPCCode(RPCCode::kInitServer);
212 logger_->Log("Init Server");
213 next_->InitServer(num_args);
214}
215
216void MinRPCExecuteWithLog::NormalCallFunc(uint64_t call_handle, TVMValue* values, int* tcodes,
217 int num_args) {
218 SetRPCCode(RPCCode::kCallFunc);
219 logger_->LogValue<void*>("call_handle: ", reinterpret_cast<void*>(call_handle));
220 ret_handler_->GetHandleName(reinterpret_cast<void*>(call_handle));
221 if (num_args > 0) {
222 logger_->Log(", ");
223 }
224 ProcessValues(values, tcodes, num_args);
225 next_->NormalCallFunc(call_handle, values, tcodes, num_args);
226}
227
228void MinRPCExecuteWithLog::CopyFromRemote(DLTensor* arr, uint64_t num_bytes, uint8_t* temp_data) {
229 SetRPCCode(RPCCode::kCopyFromRemote);
230 logger_->LogValue<void*>("data_handle: ", static_cast<void*>(arr->data));
231 logger_->LogDLDevice(", DLDevice(type,id):", &(arr->device));
232 logger_->LogValue<int64_t>(", ndim: ", arr->ndim);
233 logger_->LogDLData(", DLDataType(code,bits,lane): ", &(arr->dtype));
234 logger_->LogValue<uint64_t>(", num_bytes:", num_bytes);
235 next_->CopyFromRemote(arr, num_bytes, temp_data);
236}
237
238int MinRPCExecuteWithLog::CopyToRemote(DLTensor* arr, uint64_t num_bytes, uint8_t* data_ptr) {
239 SetRPCCode(RPCCode::kCopyToRemote);
240 logger_->LogValue<void*>("data_handle: ", static_cast<void*>(arr->data));
241 logger_->LogDLDevice(", DLDevice(type,id):", &(arr->device));
242 logger_->LogValue<int64_t>(", ndim: ", arr->ndim);
243 logger_->LogDLData(", DLDataType(code,bits,lane): ", &(arr->dtype));
244 logger_->LogValue<uint64_t>(", byte_offset: ", arr->byte_offset);
245 return next_->CopyToRemote(arr, num_bytes, data_ptr);
246}
247
248void MinRPCExecuteWithLog::SysCallFunc(RPCCode code, TVMValue* values, int* tcodes, int num_args) {
249 SetRPCCode(code);
250 if ((code) == RPCCode::kFreeHandle) {
251 if ((num_args == 2) && (tcodes[0] == kTVMOpaqueHandle) && (tcodes[1] == kDLInt)) {
252 logger_->LogValue<void*>("handle: ", static_cast<void*>(values[0].v_handle));
253 if (values[1].v_int64 == kTVMModuleHandle || values[1].v_int64 == kTVMPackedFuncHandle) {
254 ret_handler_->ReleaseHandleName(static_cast<void*>(values[0].v_handle));
255 }
256 }
257 } else {
258 ProcessValues(values, tcodes, num_args);
259 }
260 next_->SysCallFunc(code, values, tcodes, num_args);
261}
262
263void MinRPCExecuteWithLog::ThrowError(RPCServerStatus code, RPCCode info) {
264 logger_->Log("-> Error\n");
265 next_->ThrowError(code, info);
266}
267
268void MinRPCExecuteWithLog::ProcessValues(TVMValue* values, int* tcodes, int num_args) {
269 if (tcodes != nullptr) {
270 logger_->Log("[");
271 for (int i = 0; i < num_args; ++i) {
272 logger_->LogTVMValue(tcodes[i], values[i]);
273
274 if (tcodes[i] == kTVMStr) {
275 if (strlen(values[i].v_str) > 0) {
276 ret_handler_->UpdateHandleName(values[i].v_str);
277 }
278 }
279 }
280 logger_->Log("]");
281 }
282}
283
284void MinRPCExecuteWithLog::SetRPCCode(RPCCode code) {
285 logger_->Log(RPCCodeToString(code));
286 logger_->Log(", ");
287 ret_handler_->ResetHandleName(code);
288}
289
290} // namespace runtime
291} // namespace tvm
292