You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

tensorprint_utils.cc 12 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /**
  2. * Copyright 2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "utils/tensorprint_utils.h"
  17. #include <atomic>
  18. #include <fstream>
  19. #include <memory>
  20. #include <string>
  21. #include <vector>
  22. #include "ir/tensor.h"
  23. #include "pybind11/pybind11.h"
  24. #include "utils/ms_utils.h"
  25. #include "utils/shape_utils.h"
  26. #ifndef NO_DLIB
  27. #include "tdt/tsd_client.h"
  28. #include "tdt/tdt_host_interface.h"
  29. #include "tdt/data_common.h"
  30. #endif
  31. namespace py = pybind11;
  32. namespace mindspore {
  33. const char kShapeSeperator[] = ",";
  34. const char kShapeScalar[] = "[0]";
  35. const char kShapeNone[] = "[]";
  36. static std::map<std::string, TypeId> print_type_map = {
  37. {"int8_t", TypeId::kNumberTypeInt8}, {"uint8_t", TypeId::kNumberTypeUInt8},
  38. {"int16_t", TypeId::kNumberTypeInt16}, {"uint16_t", TypeId::kNumberTypeUInt16},
  39. {"int32_t", TypeId::kNumberTypeInt32}, {"uint32_t", TypeId::kNumberTypeUInt32},
  40. {"int64_t", TypeId::kNumberTypeInt64}, {"uint64_t", TypeId::kNumberTypeUInt64},
  41. {"float16", TypeId::kNumberTypeFloat16}, {"float", TypeId::kNumberTypeFloat32},
  42. {"double", TypeId::kNumberTypeFloat64}, {"bool", TypeId::kNumberTypeBool}};
  43. static std::map<std::string, size_t> type_size_map = {
  44. {"int8_t", sizeof(int8_t)}, {"uint8_t", sizeof(uint8_t)}, {"int16_t", sizeof(int16_t)},
  45. {"uint16_t", sizeof(uint16_t)}, {"int32_t", sizeof(int32_t)}, {"uint32_t", sizeof(uint32_t)},
  46. {"int64_t", sizeof(int64_t)}, {"uint64_t", sizeof(uint64_t)}, {"float16", sizeof(float) / 2},
  47. {"float", sizeof(float)}, {"double", sizeof(double)}, {"bool", sizeof(bool)}};
  48. std::string GetParseType(const std::string &tensorType_) {
  49. static const std::map<std::string, std::string> print_parse_map = {
  50. {"int8_t", "Int8"}, {"uint8_t", "Uint8"}, {"int16_t", "Int16"}, {"uint16_t", "Uint16"},
  51. {"int32_t", "Int32"}, {"uint32_t", "Uint32"}, {"int64_t", "Int64"}, {"uint64_t", "Uint64"},
  52. {"float16", "Float16"}, {"float", "Float32"}, {"double", "Float64"}, {"bool", "Bool"}};
  53. auto type_iter = print_parse_map.find(tensorType_);
  54. if (type_iter == print_parse_map.end()) {
  55. MS_LOG(EXCEPTION) << "type of tensor need to print is not support " << tensorType_;
  56. }
  57. return type_iter->second;
  58. }
  59. bool ParseTensorShape(const std::string &input_shape_str, ShapeVector *const tensor_shape, size_t *dims) {
  60. if (tensor_shape == nullptr) {
  61. return false;
  62. }
  63. MS_EXCEPTION_IF_NULL(dims);
  64. std::string shape_str = input_shape_str;
  65. if (shape_str.size() <= 2) {
  66. return false;
  67. }
  68. (void)shape_str.erase(shape_str.begin());
  69. shape_str.pop_back();
  70. shape_str += kShapeSeperator;
  71. string::size_type pos_begin = 0;
  72. string::size_type pos_end = shape_str.find(kShapeSeperator);
  73. while (pos_end != std::string::npos) {
  74. string dim_str = shape_str.substr(pos_begin, pos_end - pos_begin);
  75. tensor_shape->emplace_back(std::stoi(dim_str));
  76. (*dims) = (*dims) * std::stoul(dim_str);
  77. pos_begin = pos_end + sizeof(kShapeSeperator) - 1;
  78. pos_end = shape_str.find(kShapeSeperator, pos_begin);
  79. }
  80. return true;
  81. }
  82. bool PrintTensorToString(const char *str_data_ptr, mindspore::tensor::Tensor *const print_tensor,
  83. const size_t &memory_size) {
  84. MS_EXCEPTION_IF_NULL(str_data_ptr);
  85. MS_EXCEPTION_IF_NULL(print_tensor);
  86. auto *tensor_data_ptr = static_cast<uint8_t *>(print_tensor->data_c());
  87. MS_EXCEPTION_IF_NULL(tensor_data_ptr);
  88. auto cp_ret =
  89. memcpy_s(tensor_data_ptr, static_cast<size_t>(print_tensor->data().nbytes()), str_data_ptr, memory_size);
  90. if (cp_ret != EOK) {
  91. MS_LOG(ERROR) << "Print op Failed to copy the memory to py::tensor " << cp_ret;
  92. return false;
  93. }
  94. return true;
  95. }
  96. template <typename T>
  97. void PrintScalarToString(const char *str_data_ptr, const string &tensor_type, std::ostringstream *const buf) {
  98. MS_EXCEPTION_IF_NULL(str_data_ptr);
  99. MS_EXCEPTION_IF_NULL(buf);
  100. *buf << "Tensor(shape=[1], dtype=" << GetParseType(tensor_type) << ", value=";
  101. const T *data_ptr = reinterpret_cast<const T *>(str_data_ptr);
  102. if constexpr (std::is_same<T, int8_t>::value || std::is_same<T, uint8_t>::value) {
  103. const int int_data = static_cast<int>(*data_ptr);
  104. *buf << int_data << ")\n";
  105. } else {
  106. *buf << *data_ptr << ")\n";
  107. }
  108. }
  109. void PrintScalarToBoolString(const char *str_data_ptr, const string &tensor_type, std::ostringstream *const buf) {
  110. MS_EXCEPTION_IF_NULL(str_data_ptr);
  111. MS_EXCEPTION_IF_NULL(buf);
  112. const bool *data_ptr = reinterpret_cast<const bool *>(str_data_ptr);
  113. *buf << "Tensor(shape=[1], dtype=" << GetParseType(tensor_type) << ", value=";
  114. if (*data_ptr) {
  115. *buf << "True)\n";
  116. } else {
  117. *buf << "False)\n";
  118. }
  119. }
  120. void convertDataItem2Scalar(const char *str_data_ptr, const string &tensor_type, std::ostringstream *const buf) {
  121. MS_EXCEPTION_IF_NULL(str_data_ptr);
  122. MS_EXCEPTION_IF_NULL(buf);
  123. auto type_iter = print_type_map.find(tensor_type);
  124. auto type_id = type_iter->second;
  125. if (type_id == TypeId::kNumberTypeBool) {
  126. PrintScalarToBoolString(str_data_ptr, tensor_type, buf);
  127. } else if (type_id == TypeId::kNumberTypeInt8) {
  128. PrintScalarToString<int8_t>(str_data_ptr, tensor_type, buf);
  129. } else if (type_id == TypeId::kNumberTypeUInt8) {
  130. PrintScalarToString<uint8_t>(str_data_ptr, tensor_type, buf);
  131. } else if (type_id == TypeId::kNumberTypeInt16) {
  132. PrintScalarToString<int16_t>(str_data_ptr, tensor_type, buf);
  133. } else if (type_id == TypeId::kNumberTypeUInt16) {
  134. PrintScalarToString<uint16_t>(str_data_ptr, tensor_type, buf);
  135. } else if (type_id == TypeId::kNumberTypeInt32) {
  136. PrintScalarToString<int32_t>(str_data_ptr, tensor_type, buf);
  137. } else if (type_id == TypeId::kNumberTypeUInt32) {
  138. PrintScalarToString<uint32_t>(str_data_ptr, tensor_type, buf);
  139. } else if (type_id == TypeId::kNumberTypeInt64) {
  140. PrintScalarToString<int64_t>(str_data_ptr, tensor_type, buf);
  141. } else if (type_id == TypeId::kNumberTypeUInt64) {
  142. PrintScalarToString<uint64_t>(str_data_ptr, tensor_type, buf);
  143. } else if (type_id == TypeId::kNumberTypeFloat16) {
  144. PrintScalarToString<float16>(str_data_ptr, tensor_type, buf);
  145. } else if (type_id == TypeId::kNumberTypeFloat32) {
  146. PrintScalarToString<float>(str_data_ptr, tensor_type, buf);
  147. } else if (type_id == TypeId::kNumberTypeFloat64) {
  148. PrintScalarToString<double>(str_data_ptr, tensor_type, buf);
  149. } else {
  150. MS_LOG(EXCEPTION) << "Cannot print scalar because of unsupported data type: " << tensor_type << ".";
  151. }
  152. }
  153. bool judgeLengthValid(const size_t str_len, const string &tensor_type) {
  154. auto type_iter = type_size_map.find(tensor_type);
  155. if (type_iter == type_size_map.end()) {
  156. MS_LOG(EXCEPTION) << "type of scalar to print is not support.";
  157. }
  158. return str_len == type_iter->second;
  159. }
  160. #ifndef NO_DLIB
  161. bool ConvertDataItem2Tensor(const std::vector<tdt::DataItem> &items) {
  162. // Acquire Python GIL
  163. py::gil_scoped_acquire gil_acquire;
  164. std::ostringstream buf;
  165. bool ret_end_sequence = false;
  166. for (auto &item : items) {
  167. if (item.dataType_ == tdt::TDT_END_OF_SEQUENCE) {
  168. ret_end_sequence = true;
  169. break;
  170. }
  171. std::shared_ptr<std::string> str_data_ptr = std::static_pointer_cast<std::string>(item.dataPtr_);
  172. MS_EXCEPTION_IF_NULL(str_data_ptr);
  173. if (item.tensorShape_ == kShapeScalar || item.tensorShape_ == kShapeNone) {
  174. if (!judgeLengthValid(str_data_ptr->size(), item.tensorType_)) {
  175. MS_LOG(EXCEPTION) << "Print op receive data length is invalid.";
  176. }
  177. convertDataItem2Scalar(str_data_ptr->data(), item.tensorType_, &buf);
  178. continue;
  179. }
  180. ShapeVector tensor_shape;
  181. size_t totaldims = 1;
  182. if (!ParseTensorShape(item.tensorShape_, &tensor_shape, &totaldims)) {
  183. MS_LOG(ERROR) << "Tensor print can not parse tensor shape, receive info" << item.tensorShape_;
  184. continue;
  185. }
  186. if (item.tensorType_ == "string") {
  187. std::string data(reinterpret_cast<const char *>(str_data_ptr->c_str()), item.dataLen_);
  188. buf << data << std::endl;
  189. } else {
  190. auto type_iter = print_type_map.find(item.tensorType_);
  191. if (type_iter == print_type_map.end()) {
  192. MS_LOG(ERROR) << "type of tensor need to print is not support " << item.tensorType_;
  193. continue;
  194. }
  195. auto type_id = type_iter->second;
  196. mindspore::tensor::Tensor print_tensor(type_id, tensor_shape);
  197. auto memory_size = totaldims * type_size_map[item.tensorType_];
  198. if (PrintTensorToString(str_data_ptr->data(), &print_tensor, memory_size)) {
  199. buf << print_tensor.ToStringNoLimit() << std::endl;
  200. }
  201. }
  202. }
  203. std::cout << buf.str() << std::endl;
  204. return ret_end_sequence;
  205. }
  206. bool SaveDataItem2File(const std::vector<tdt::DataItem> &items, const std::string &print_file_path, prntpb::Print print,
  207. std::fstream *output) {
  208. bool ret_end_thread = false;
  209. for (auto &item : items) {
  210. if (item.dataType_ == tdt::TDT_END_OF_SEQUENCE) {
  211. ret_end_thread = true;
  212. break;
  213. }
  214. prntpb::Print_Value *value = print.add_value();
  215. std::shared_ptr<std::string> str_data_ptr = std::static_pointer_cast<std::string>(item.dataPtr_);
  216. MS_EXCEPTION_IF_NULL(str_data_ptr);
  217. if (item.tensorShape_ == kShapeScalar || item.tensorShape_ == kShapeNone) {
  218. if (!judgeLengthValid(str_data_ptr->size(), item.tensorType_)) {
  219. MS_LOG(ERROR) << "Print op receive data length is invalid.";
  220. ret_end_thread = true;
  221. }
  222. }
  223. ShapeVector tensor_shape;
  224. size_t totaldims = 1;
  225. if (!ParseTensorShape(item.tensorShape_, &tensor_shape, &totaldims)) {
  226. MS_LOG(ERROR) << "Tensor print can not parse tensor shape, receive info" << item.tensorShape_;
  227. ret_end_thread = true;
  228. }
  229. if (item.tensorType_ == "string") {
  230. std::string data(reinterpret_cast<const char *>(str_data_ptr->c_str()), item.dataLen_);
  231. value->set_desc(data);
  232. } else {
  233. auto parse_type = GetParseType(item.tensorType_);
  234. prntpb::TensorProto *tensor = value->mutable_tensor();
  235. if (!(item.tensorShape_ == kShapeScalar) && !(item.tensorShape_ == kShapeNone)) {
  236. for (const auto &dim : tensor_shape) {
  237. tensor->add_dims(static_cast<::google::protobuf::int64>(dim));
  238. }
  239. }
  240. tensor->set_tensor_type(parse_type);
  241. std::string data(reinterpret_cast<const char *>(str_data_ptr->c_str()), item.dataLen_);
  242. tensor->set_tensor_content(data);
  243. }
  244. if (!print.SerializeToOstream(output)) {
  245. MS_LOG(ERROR) << "Save print file:" << print_file_path << " fail.";
  246. ret_end_thread = true;
  247. break;
  248. }
  249. print.Clear();
  250. }
  251. return ret_end_thread;
  252. }
  253. void TensorPrint::operator()() {
  254. prntpb::Print print;
  255. auto ms_context = MsContext::GetInstance();
  256. MS_EXCEPTION_IF_NULL(ms_context);
  257. std::string print_file_path = ms_context->get_param<std::string>(MS_CTX_PRINT_FILE_PATH);
  258. if (print_file_path == "") {
  259. while (true) {
  260. std::vector<tdt::DataItem> bundle;
  261. if (tdt::TdtHostPopData("_npu_log", bundle) != 0) {
  262. break;
  263. }
  264. if (ConvertDataItem2Tensor(bundle)) {
  265. break;
  266. }
  267. }
  268. } else {
  269. std::fstream output(print_file_path, std::ios::out | std::ios::trunc | std::ios::binary);
  270. while (true) {
  271. std::vector<tdt::DataItem> bundle;
  272. if (tdt::TdtHostPopData("_npu_log", bundle) != 0) {
  273. break;
  274. }
  275. if (SaveDataItem2File(bundle, print_file_path, print, &output)) {
  276. break;
  277. }
  278. }
  279. output.close();
  280. std::string path_string = print_file_path;
  281. if (chmod(common::SafeCStr(path_string), S_IRUSR) == -1) {
  282. MS_LOG(ERROR) << "Modify file:" << print_file_path << " to r fail.";
  283. return;
  284. }
  285. }
  286. }
  287. #endif
  288. } // namespace mindspore