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.

aicpu_ext_info.cc 13 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /**
  2. * Copyright 2019-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 "hybrid/node_executor/aicpu/aicpu_ext_info.h"
  17. #include "framework/common/util.h"
  18. #include "framework/common/fmk_error_codes.h"
  19. #include "framework/common/debug/log.h"
  20. namespace ge {
  21. namespace hybrid {
  22. namespace {
  23. // if dim count is not reach kMaxShapeDims(8), use INT64_MIN to mark dim end.
  24. constexpr int64_t kDimEndFlag = INT64_MIN;
  25. }
  26. Status AicpuExtInfoHandler::Parse(const std::string &ext_info) {
  27. GELOGI("Node[%s] parse ext info start.", node_name_.c_str());
  28. if (ext_info.empty()) {
  29. GELOGE(ACL_ERROR_GE_PARAM_INVALID, "Node[%s] parse ext info failed as ext info is empty.",
  30. node_name_.c_str());
  31. return ACL_ERROR_GE_PARAM_INVALID;
  32. }
  33. ext_info_len_ = ext_info.size();
  34. ext_info_.reset(new(std::nothrow)uint8_t[ext_info_len_]);
  35. GE_CHECK_NOTNULL(ext_info_);
  36. if (memcpy_s(ext_info_.get(), ext_info_len_, ext_info.c_str(), ext_info.size()) != EOK) {
  37. GELOGE(ACL_ERROR_GE_MEMORY_OPERATE_FAILED, "[%s] Failed to coy ext info", node_name_.c_str());
  38. return ACL_ERROR_GE_MEMORY_OPERATE_FAILED;
  39. }
  40. input_shape_and_type_.clear();
  41. output_shape_and_type_.clear();
  42. auto ext_info_data = ext_info_.get();
  43. size_t offset = 0;
  44. while (offset + sizeof(AicpuExtInfo) <= ext_info_len_) {
  45. auto aicpu_ext_info = reinterpret_cast<AicpuExtInfo *>(ext_info_data + offset);
  46. GELOGD("Ext infoType=%d, infoLen=%u.", aicpu_ext_info->infoType, aicpu_ext_info->infoLen);
  47. switch (aicpu_ext_info->infoType) {
  48. case aicpu::FWKAdapter::FWK_ADPT_EXT_SHAPE_TYPE:
  49. GE_CHK_STATUS_RET(ParseExtShapeType(aicpu_ext_info), "Parse ext shape type failed.");
  50. break;
  51. case aicpu::FWKAdapter::FWK_ADPT_EXT_INPUT_SHAPE:
  52. GE_CHK_STATUS_RET(ParseExtInputShape(aicpu_ext_info), "Parse ext input shape failed.");
  53. break;
  54. case aicpu::FWKAdapter::FWK_ADPT_EXT_OUTPUT_SHAPE:
  55. GE_CHK_STATUS_RET(ParseExtOutputShape(aicpu_ext_info), "Parse ext output shape failed.");
  56. break;
  57. case aicpu::FWKAdapter::FWK_ADPT_EXT_SESSION_INFO:
  58. GE_CHK_STATUS_RET(ParseExtSessionInfo(aicpu_ext_info), "Parse ext session info failed.");
  59. break;
  60. case aicpu::FWKAdapter::FWK_ADPT_EXT_BITMAP:
  61. GE_CHK_STATUS_RET(ParseExtBitMap(aicpu_ext_info), "Parse ext bit map failed.");
  62. break;
  63. case aicpu::FWKAdapter::FWK_ADPT_EXT_UPDATE_ADDR:
  64. GE_CHK_STATUS_RET(ParseExtUpdateAddr(aicpu_ext_info), "Parse ext update_addr failed.");
  65. break;
  66. default:
  67. GELOGD("Node[%s] ignore infoType=%d, infoLen=%u.",
  68. node_name_.c_str(), aicpu_ext_info->infoType, aicpu_ext_info->infoLen);
  69. break;
  70. }
  71. offset += sizeof(AicpuExtInfo);
  72. offset += aicpu_ext_info->infoLen;
  73. }
  74. GE_CHK_BOOL_RET_STATUS(offset == ext_info_len_, ACL_ERROR_GE_PARAM_INVALID,
  75. "Node[%s] ext_info format error, parse not reach end, offset=%zu, ext_info_len=%zu.",
  76. node_name_.c_str(), offset, ext_info_len_);
  77. GELOGI("Node[%s] parse ext info end.", node_name_.c_str());
  78. return SUCCESS;
  79. }
  80. Status AicpuExtInfoHandler::ParseExtShapeType(AicpuExtInfo *aicpu_ext_info) {
  81. GE_CHK_BOOL_RET_STATUS(aicpu_ext_info->infoLen == sizeof(int32_t), ACL_ERROR_GE_PARAM_INVALID,
  82. "Node[%s] parse ext shape type failed as infoLen must be %zu but %u.",
  83. node_name_.c_str(), sizeof(int32_t), aicpu_ext_info->infoLen);
  84. auto type = reinterpret_cast<const int32_t *>(aicpu_ext_info->infoMsg);
  85. GE_CHK_BOOL_RET_STATUS(*type == unknown_type_, ACL_ERROR_GE_PARAM_INVALID,
  86. "Node[%s] parse ext shape type failed as need %d but %d.",
  87. node_name_.c_str(), unknown_type_, *type);
  88. GELOGI("Node[%s] parse ext shape type success infoLen=%u.", node_name_.c_str(), aicpu_ext_info->infoLen);
  89. return SUCCESS;
  90. }
  91. Status AicpuExtInfoHandler::ParseExtInputShape(AicpuExtInfo *aicpu_ext_info) {
  92. auto need_len = input_num_ * sizeof(AicpuShapeAndType);
  93. GE_CHK_BOOL_RET_STATUS(aicpu_ext_info->infoLen == need_len, ACL_ERROR_GE_PARAM_INVALID,
  94. "Node[%s] parse ext input shape failed as infoLen must be "
  95. "input_num[%u]*sizeof(ShapeAndType)[%zu] but %u.",
  96. node_name_.c_str(), input_num_, sizeof(AicpuShapeAndType), aicpu_ext_info->infoLen);
  97. auto input = reinterpret_cast<AicpuShapeAndType *>(aicpu_ext_info->infoMsg);
  98. for (uint32_t index = 0; index < input_num_; ++index) {
  99. input_shape_and_type_.emplace_back(&input[index]);
  100. }
  101. GELOGI("Node[%s] parse ext input shape success infoLen=%u.", node_name_.c_str(), aicpu_ext_info->infoLen);
  102. return SUCCESS;
  103. }
  104. Status AicpuExtInfoHandler::ParseExtOutputShape(AicpuExtInfo *aicpu_ext_info) {
  105. if (unknown_type_ == DEPEND_COMPUTE) {
  106. GELOGD("Node[%s] is depend compute type no need ext output shape, ignore it, infoLen=%u.",
  107. node_name_.c_str(), aicpu_ext_info->infoLen);
  108. return SUCCESS;
  109. }
  110. auto need_len = output_num_ * sizeof(AicpuShapeAndType);
  111. GE_CHK_BOOL_RET_STATUS(aicpu_ext_info->infoLen == need_len, ACL_ERROR_GE_PARAM_INVALID,
  112. "Node[%s] parse ext output shape failed as infoLen must be "
  113. "output_num[%u]*sizeof(ShapeAndType)[%zu] but %u.",
  114. node_name_.c_str(), output_num_, sizeof(AicpuShapeAndType), aicpu_ext_info->infoLen);
  115. auto output = reinterpret_cast<AicpuShapeAndType *>(aicpu_ext_info->infoMsg);
  116. for (uint32_t index = 0; index < output_num_; ++index) {
  117. output_shape_and_type_.emplace_back(&output[index]);
  118. }
  119. GELOGI("Node[%s] parse ext output shape success infoLen=%u.", node_name_.c_str(), aicpu_ext_info->infoLen);
  120. return SUCCESS;
  121. }
  122. Status AicpuExtInfoHandler::ParseExtSessionInfo(AicpuExtInfo *aicpu_ext_info) {
  123. GE_CHK_BOOL_RET_STATUS(aicpu_ext_info->infoLen == sizeof(AicpuSessionInfo), ACL_ERROR_GE_PARAM_INVALID,
  124. "Node[%s] parse ext session info failed as infoLen must be %zu but %u.",
  125. node_name_.c_str(), sizeof(SessionInfo), aicpu_ext_info->infoLen);
  126. session_info_ = reinterpret_cast<AicpuSessionInfo *>(aicpu_ext_info->infoMsg);
  127. GELOGI("Node[%s] parse session info success infoLen=%u.", node_name_.c_str(), aicpu_ext_info->infoLen);
  128. return SUCCESS;
  129. }
  130. Status AicpuExtInfoHandler::ParseExtBitMap(AicpuExtInfo *aicpu_ext_info) {
  131. GE_CHK_BOOL_RET_STATUS(aicpu_ext_info->infoLen == sizeof(uint64_t), PARAM_INVALID,
  132. "Node[%s] parse bit_map info failed as infoLen must be %zu but %u.",
  133. node_name_.c_str(), sizeof(uint64_t), aicpu_ext_info->infoLen);
  134. bit_map_ = reinterpret_cast<uint64_t *>(aicpu_ext_info->infoMsg);
  135. GELOGI("Node[%s] bit_map info success infoLen=%u.", node_name_.c_str(), aicpu_ext_info->infoLen);
  136. return SUCCESS;
  137. }
  138. Status AicpuExtInfoHandler::ParseExtUpdateAddr(AicpuExtInfo *aicpu_ext_info) {
  139. GE_CHK_BOOL_RET_STATUS(aicpu_ext_info->infoLen == sizeof(uint32_t), PARAM_INVALID,
  140. "Node[%s] parse update_addr info failed as infoLen must be %zu but %u.",
  141. node_name_.c_str(), sizeof(uint32_t), aicpu_ext_info->infoLen);
  142. update_addr_ = reinterpret_cast<uint32_t *>(aicpu_ext_info->infoMsg);
  143. GELOGI("Node[%s] update_addr info success infoLen=%u.", node_name_.c_str(), aicpu_ext_info->infoLen);
  144. return SUCCESS;
  145. }
  146. Status AicpuExtInfoHandler::UpdateExecuteMode(bool flag) {
  147. if (bit_map_ == nullptr) {
  148. GELOGD("There is no bit_map in ext_info, no need update.");
  149. return SUCCESS;
  150. }
  151. if (flag) {
  152. *(bit_map_) |= 1;
  153. } else {
  154. *(bit_map_) &= ~1;
  155. }
  156. return SUCCESS;
  157. }
  158. Status AicpuExtInfoHandler::UpdateSessionInfo(uint64_t session_id, uint64_t kernel_id, bool sess_flag) {
  159. if (session_info_ == nullptr) {
  160. GELOGD("There is no session info in ext_info, no need update.");
  161. return SUCCESS;
  162. }
  163. session_info_->sessionId = session_id;
  164. session_info_->kernelId = kernel_id;
  165. session_info_->sessFlag = sess_flag;
  166. return SUCCESS;
  167. }
  168. Status AicpuExtInfoHandler::UpdateSessionInfoSessionId(uint64_t session_id) {
  169. if (session_info_ == nullptr) {
  170. GELOGD("There is no session info in ext_info, no need update.");
  171. return SUCCESS;
  172. }
  173. session_info_->sessionId = session_id;
  174. session_info_->sessFlag = true;
  175. return SUCCESS;
  176. }
  177. Status AicpuExtInfoHandler::UpdateInputShapeAndType(uint32_t input_index, const GeTensorDesc &input_desc) {
  178. GE_CHECK_LE(input_index, input_num_);
  179. const auto &shape = input_desc.GetShape();
  180. GE_CHK_STATUS_RET(UpdateShapeAndType(shape, input_desc.GetDataType(), input_shape_and_type_[input_index]),
  181. "Node[%s] input[%u] update input shape and type failed.",
  182. node_name_.c_str(), input_index);
  183. return SUCCESS;
  184. }
  185. Status AicpuExtInfoHandler::UpdateOutputShapeAndType(uint32_t output_index, const GeTensorDesc &output_desc) {
  186. GE_CHK_BOOL_RET_STATUS((unknown_type_ != DEPEND_COMPUTE), ACL_ERROR_GE_INTERNAL_ERROR,
  187. "Node[%s] is depend compute is no need update output shape and type by ext.",
  188. node_name_.c_str());
  189. GE_CHECK_LE(output_index, output_num_);
  190. auto shape = output_desc.GetShape();
  191. // shape range need use range update shape
  192. if (unknown_type_ == DEPEND_SHAPE_RANGE) {
  193. std::vector<std::pair<int64_t, int64_t>> range;
  194. auto range_ret = output_desc.GetShapeRange(range);
  195. GE_CHK_BOOL_RET_STATUS(range_ret == GRAPH_SUCCESS, ACL_ERROR_GE_INTERNAL_ERROR,
  196. "Node[%s] is shape range type but get GetShapeRange failed, ret=%u.",
  197. node_name_.c_str(), range_ret);
  198. for (size_t k = 0; k < range.size(); ++k) {
  199. if (shape.GetDim(k) < 0 && k < range.size()) {
  200. GELOGD("Node[%s] output[%u] update dim[%zu] from %ld to range max %ld.",
  201. node_name_.c_str(), output_index, k, shape.GetDim(k), range[k].second);
  202. shape.SetDim(k, range[k].second);
  203. }
  204. }
  205. }
  206. return UpdateShapeAndType(shape, output_desc.GetDataType(), output_shape_and_type_[output_index]);
  207. }
  208. Status AicpuExtInfoHandler::GetOutputShapeAndType(uint32_t output_index, GeShape &shape, DataType &data_type) {
  209. GE_CHK_BOOL_RET_STATUS((unknown_type_ != DEPEND_COMPUTE), INTERNAL_ERROR,
  210. "Node[%s] is depend compute type can not get output shape and type by ext.",
  211. node_name_.c_str());
  212. GetShapeAndType(output_shape_and_type_[output_index], shape, data_type);
  213. return SUCCESS;
  214. }
  215. bool AicpuExtInfoHandler::IsNeedRefreshIOAddr() {
  216. return update_addr_ != nullptr && *update_addr_ != static_cast<uint32_t>(aicpu::FWKAdapter::FWK_ADPT_UPDATE_NULL);
  217. }
  218. Status AicpuExtInfoHandler::UpdateShapeAndType(const GeShape &shape, DataType data_type,
  219. AicpuShapeAndType *shape_and_type) {
  220. auto dim_num = shape.GetDimNum();
  221. if (dim_num > aicpu::FWKAdapter::kMaxShapeDims) {
  222. GELOGE(ACL_ERROR_GE_PARAM_INVALID, "Update shape and type failed, as dim_num %zu is over max shape dims %u.",
  223. dim_num, aicpu::FWKAdapter::kMaxShapeDims);
  224. return ACL_ERROR_GE_PARAM_INVALID;
  225. }
  226. size_t index = 0;
  227. for (; index < dim_num; ++index) {
  228. shape_and_type->dims[index] = shape.GetDim(index);
  229. }
  230. if (index < aicpu::FWKAdapter::kMaxShapeDims) {
  231. shape_and_type->dims[index] = kDimEndFlag;
  232. }
  233. // now only support update shape, type is not support
  234. return SUCCESS;
  235. }
  236. void AicpuExtInfoHandler::GetShapeAndType(const AicpuShapeAndType *shape_and_type,
  237. GeShape &shape,
  238. DataType &data_type) {
  239. std::vector<int64_t> dims;
  240. for (uint32_t index = 0; index < aicpu::FWKAdapter::kMaxShapeDims; ++index) {
  241. auto tmpDim = shape_and_type->dims[index];
  242. if (tmpDim == kDimEndFlag) {
  243. break;
  244. }
  245. dims.emplace_back(tmpDim);
  246. }
  247. data_type = static_cast<DataType>(shape_and_type->type);
  248. shape = GeShape(dims);
  249. }
  250. } // namespace hybrid
  251. } // namespace ge

图引擎模块(GE)是MindSpore的一个子模块,其代码由C++实现,位于前端模块ME和底层硬件之间,起到承接作用。图引擎模块以ME下发的图作为输入,然后进行一系列的深度图优化操作,最后输出一张可以在底层硬件上高效运行的图。GE针对昇腾AI处理器的硬件结构特点,做了特定的优化工作,以此来充分发挥出昇腾AI处理器的强大算力。在进行模型训练/推理时,GE会被自动调用而用户并不感知。GE主要由GE API和GE Core两部分组成,详细的架构图如下所示