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.

ge_aipp_op.cc 47 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
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  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 "graph/preprocess/insert_op/ge_aipp_op.h"
  17. #include <memory>
  18. #include <set>
  19. #include <string>
  20. #include <utility>
  21. #include <vector>
  22. #include "graph/preprocess/insert_op/base_insert_op.h"
  23. #include "common/dynamic_aipp.h"
  24. #include "common/ge/ge_util.h"
  25. #include "framework/common/util.h"
  26. #include "common/util/error_manager/error_manager.h"
  27. #include "external/graph/operator_factory.h"
  28. #include "framework/common/debug/ge_log.h"
  29. #include "framework/common/ge_inner_error_codes.h"
  30. #include "framework/common/op/ge_op_utils.h"
  31. #include "framework/common/types.h"
  32. #include "framework/omg/omg_inner_types.h"
  33. #include "graph/debug/ge_attr_define.h"
  34. #include "graph/optimize/common/params.h"
  35. #include "graph/utils/graph_utils.h"
  36. #include "graph/utils/node_utils.h"
  37. #include "graph/utils/op_desc_utils.h"
  38. #include "graph/utils/tensor_utils.h"
  39. #include "graph/utils/type_utils.h"
  40. #include "proto/insert_op.pb.h"
  41. #include "graph/common/local_context.h"
  42. #define SAVE_AIPP_ATTR(KEY, SAVE_TYPE) \
  43. do { \
  44. (void)aipp_attrs.SetAttr(#KEY, GeAttrValue::CreateFrom<SAVE_TYPE>(aipp_params_->KEY())); \
  45. } while (0)
  46. #define SAVE_AIPP_ATTR_LIST(KEY, SAVE_TYPE) \
  47. do { \
  48. if (aipp_params_->KEY##_size() > 0) { \
  49. (void)aipp_attrs.SetAttr(#KEY, GeAttrValue::CreateFrom<SAVE_TYPE>(aipp_params_->KEY(0))); \
  50. } \
  51. } while (0)
  52. namespace {
  53. const int32_t DEFAULT_MATRIX_R0C0_YUV2RGB = 298;
  54. const int32_t DEFAULT_MATRIX_R0C1_YUV2RGB = 0;
  55. const int32_t DEFAULT_MATRIX_R0C2_YUV2RGB = 409;
  56. const int32_t DEFAULT_MATRIX_R1C0_YUV2RGB = 298;
  57. const int32_t DEFAULT_MATRIX_R1C1_YUV2RGB = -100;
  58. const int32_t DEFAULT_MATRIX_R1C2_YUV2RGB = -208;
  59. const int32_t DEFAULT_MATRIX_R2C0_YUV2RGB = 298;
  60. const int32_t DEFAULT_MATRIX_R2C1_YUV2RGB = 516;
  61. const int32_t DEFAULT_MATRIX_R2C2_YUV2RGB = 0;
  62. const int32_t DEFAULT_MATRIX_R0C0_RGB2YUV = 66;
  63. const int32_t DEFAULT_MATRIX_R0C1_RGB2YUV = 129;
  64. const int32_t DEFAULT_MATRIX_R0C2_RGB2YUV = 25;
  65. const int32_t DEFAULT_MATRIX_R1C0_RGB2YUV = -38;
  66. const int32_t DEFAULT_MATRIX_R1C1_RGB2YUV = -74;
  67. const int32_t DEFAULT_MATRIX_R1C2_RGB2YUV = 112;
  68. const int32_t DEFAULT_MATRIX_R2C0_RGB2YUV = 112;
  69. const int32_t DEFAULT_MATRIX_R2C1_RGB2YUV = -94;
  70. const int32_t DEFAULT_MATRIX_R2C2_RGB2YUV = -18;
  71. const int32_t DEFAULT_OUTPUT_BIAS_0 = 16;
  72. const int32_t DEFAULT_OUTPUT_BIAS_1 = 128;
  73. const int32_t DEFAULT_OUTPUT_BIAS_2 = 128;
  74. const int32_t DEFAULT_INPUT_BIAS_0 = 16;
  75. const int32_t DEFAULT_INPUT_BIAS_1 = 128;
  76. const int32_t DEFAULT_INPUT_BIAS_2 = 128;
  77. const float DEFAULT_VAR_RECI_CHN = 1.0;
  78. } // namespace
  79. namespace ge {
  80. namespace {
  81. const char *const kMbatchSwitchnName = "mbatch-switch-name";
  82. const char *const kAippConfigPath = "aipp_config_path";
  83. const char *const kCurrentAippIndex = "current_aipp_index";
  84. const char *const kDynamicAippData = "ascend_dynamic_aipp_data";
  85. const uint64_t kMinTransferShape = 3;
  86. const int kAippImageInputIndex = 0;
  87. const int kAippParamsInputIndex = 1;
  88. const int kAippDataOutputIndex = 0;
  89. const int64_t kDynamicDim = -1;
  90. // the `format` must one NCHW or NHWC
  91. Status GetDataDimN(const ge::NodePtr &data_node, ge::Format format, int64_t &batch) {
  92. auto output_desc = NodeUtils::GetOutputDesc(*data_node, 0);
  93. auto shape = output_desc.GetShape().GetDims();
  94. if (shape.size() == kMinTransferShape) {
  95. batch = 1;
  96. return SUCCESS;
  97. }
  98. if (shape.size() == DIM_DEFAULT_SIZE) {
  99. switch (format) {
  100. case FORMAT_NCHW:
  101. batch = shape[NCHW_DIM_N];
  102. return SUCCESS;
  103. case FORMAT_NHWC:
  104. batch = shape[NHWC_DIM_N];
  105. return SUCCESS;
  106. default:
  107. REPORT_INPUT_ERROR("E10001", std::vector<std::string>({"parameter", "value", "reason"}),
  108. std::vector<std::string>({
  109. data_node->GetName() + " format",
  110. TypeUtils::FormatToSerialString(format),
  111. "only format " + TypeUtils::FormatToSerialString(FORMAT_NCHW) + " and " +
  112. TypeUtils::FormatToSerialString(FORMAT_NHWC) +
  113. " supported which dynamic aipp is linked"}));
  114. GELOGE(PARAM_INVALID, "[Check][Param] Not support data format:%s, node:%s",
  115. TypeUtils::FormatToSerialString(format).c_str(), data_node->GetName().c_str());
  116. return PARAM_INVALID;
  117. }
  118. }
  119. string errormsg = "its shape size must be in range[3,4] which dynamic aipp is linked, "
  120. "maybe this input is not suitable for dynamic aipp";
  121. ErrorManager::GetInstance().ATCReportErrMessage("E10001", {"parameter", "value", "reason"},
  122. {data_node->GetName() + " shape size",
  123. to_string(shape.size()), errormsg});
  124. GELOGE(PARAM_INVALID, "[Check][Param] The shape size of this node [%s] "
  125. "which linked dynamic aipp must be in range[3, 4], but is %zu",
  126. data_node->GetName().c_str(), shape.size());
  127. return PARAM_INVALID;
  128. }
  129. // the batch_count must be more than 0
  130. int64_t CalcMaxSize(int64_t batch_count) {
  131. batch_count--;
  132. if (batch_count > 0) {
  133. if (INT64_MAX / batch_count < static_cast<int64_t>(sizeof(kAippDynamicBatchPara))) {
  134. return -1;
  135. }
  136. }
  137. int64_t size = batch_count * sizeof(kAippDynamicBatchPara);
  138. if (INT64_MAX - static_cast<int64_t>(sizeof(kAippDynamicPara)) < size) {
  139. return -1;
  140. }
  141. return size + sizeof(kAippDynamicPara);
  142. }
  143. Format GetAndCheckFormat() {
  144. switch (GetLocalOmgContext().format) {
  145. case domi::DOMI_TENSOR_NCHW:
  146. return FORMAT_NCHW;
  147. case domi::DOMI_TENSOR_NHWC:
  148. return FORMAT_NHWC;
  149. default:
  150. GELOGE(PARAM_INVALID, "[Check][Param] Unexpected format found %d",
  151. static_cast<int>(GetLocalOmgContext().format));
  152. return FORMAT_ND;
  153. }
  154. }
  155. } // namespace
  156. Status AippOp::Init(domi::AippOpParams *aipp_params) {
  157. aipp_params_ = new (std::nothrow) domi::AippOpParams();
  158. if (aipp_params_ == nullptr) {
  159. REPORT_CALL_ERROR("E19999", "New AippOpParams failed");
  160. GELOGE(FAILED, "[New][AippOpParams] failed");
  161. return FAILED;
  162. }
  163. aipp_params_->CopyFrom(*aipp_params);
  164. return SUCCESS;
  165. }
  166. AippOp::~AippOp() {
  167. if (aipp_params_ != nullptr) {
  168. delete aipp_params_;
  169. aipp_params_ = nullptr;
  170. }
  171. }
  172. Status AippOp::InsertAippToGraph(ComputeGraphPtr &graph, std::string &aippConfigPath, const uint32_t index) {
  173. GE_CHECK_NOTNULL(graph);
  174. NodePtr target_input = nullptr;
  175. std::vector<std::pair<OutDataAnchorPtr, InDataAnchorPtr>> target_edges;
  176. if (this->ConvertRelatedInputNameToRank() != SUCCESS) {
  177. GELOGE(FAILED, "[Call][ConvertRelatedInputNameToRank] failed.");
  178. return FAILED;
  179. }
  180. GE_CHK_STATUS_RET(this->GetTargetPosition(graph, target_input, target_edges), "[Get][TargetPosition] failed");
  181. std::map<OutDataAnchorPtr, NodePtr> out_anchors_to_aipp;
  182. for (auto &out_in_anchors : target_edges) {
  183. auto iter = out_anchors_to_aipp.find(out_in_anchors.first);
  184. if (iter == out_anchors_to_aipp.end()) {
  185. auto aipp = CreateAipp(out_in_anchors.first, aippConfigPath, index);
  186. GE_CHECK_NOTNULL(aipp);
  187. out_anchors_to_aipp[out_in_anchors.first] = aipp;
  188. auto ret = GraphUtils::InsertNodeBetweenDataAnchors(out_in_anchors.first, out_in_anchors.second, aipp);
  189. if (ret != GRAPH_SUCCESS) {
  190. REPORT_CALL_ERROR("E19999", "Insert aipp:%s(%s) node between op:%s(%s) and op:%s:%s failed",
  191. aipp->GetName().c_str(), aipp->GetType().c_str(),
  192. out_in_anchors.first->GetOwnerNode()->GetName().c_str(),
  193. out_in_anchors.first->GetOwnerNode()->GetType().c_str(),
  194. out_in_anchors.second->GetOwnerNode()->GetName().c_str(),
  195. out_in_anchors.second->GetOwnerNode()->GetType().c_str());
  196. GELOGE(INTERNAL_ERROR, "[Insert][Node] %s(%s) between op:%s(%s) and op:%s:%s failed",
  197. aipp->GetName().c_str(), aipp->GetType().c_str(),
  198. out_in_anchors.first->GetOwnerNode()->GetName().c_str(),
  199. out_in_anchors.first->GetOwnerNode()->GetType().c_str(),
  200. out_in_anchors.second->GetOwnerNode()->GetName().c_str(),
  201. out_in_anchors.second->GetOwnerNode()->GetType().c_str());
  202. return INTERNAL_ERROR;
  203. }
  204. // add aipp data if needed
  205. if (GetAippMode() == domi::AippOpParams::dynamic) {
  206. ret = CreateAippData(aipp);
  207. if (ret != SUCCESS) {
  208. GELOGE(INTERNAL_ERROR, "[Create][AippData] for aipp %s data %s failed", aipp->GetName().c_str(),
  209. out_in_anchors.first->GetOwnerNode()->GetName().c_str());
  210. return INTERNAL_ERROR;
  211. }
  212. }
  213. GELOGI("Create aipp %s and insert it to the graph", aipp->GetName().c_str());
  214. } else {
  215. out_in_anchors.second->UnlinkAll();
  216. auto &aipp = iter->second;
  217. auto ret = out_in_anchors.second->LinkFrom(aipp->GetOutDataAnchor(0));
  218. if (ret != GRAPH_SUCCESS) {
  219. REPORT_CALL_ERROR("E19999", "link aipp:%s(%s) to peer op:%s(%s) failed",
  220. aipp->GetName().c_str(), aipp->GetType().c_str(),
  221. out_in_anchors.second->GetOwnerNode()->GetName().c_str(),
  222. out_in_anchors.second->GetOwnerNode()->GetType().c_str());
  223. GELOGE(INTERNAL_ERROR, "[Call][LinkFrom] Failed to link aipp %s to the peer node %s", aipp->GetName().c_str(),
  224. out_in_anchors.second->GetOwnerNode()->GetName().c_str());
  225. return INTERNAL_ERROR;
  226. }
  227. }
  228. }
  229. return SUCCESS;
  230. }
  231. NodePtr AippOp::CreateAipp(const OutDataAnchorPtr &out_anchor,
  232. const std::string &aippConfigPath, const uint32_t &index) {
  233. const auto &node = out_anchor->GetOwnerNode();
  234. std::string current_name = node->GetName() + "_" + std::to_string(out_anchor->GetIdx()) + "_huawei_aipp";
  235. auto aipp_opdesc_ptr = MakeShared<OpDesc>(current_name, AIPP);
  236. if (aipp_opdesc_ptr == nullptr) {
  237. REPORT_CALL_ERROR("E19999", "New OpDesc failed");
  238. GELOGE(OUT_OF_MEMORY, "[New][OpDesc] failed, name %s", current_name.c_str());
  239. return nullptr;
  240. }
  241. // Update attributes
  242. if (AddAippAttrbutes(aipp_opdesc_ptr, aippConfigPath, index) != SUCCESS) {
  243. return nullptr;
  244. }
  245. // Update input desc, the output desc will be flushed when InferShape
  246. auto node_desc = out_anchor->GetOwnerNode()->GetOpDesc();
  247. if (node_desc == nullptr) {
  248. return nullptr;
  249. }
  250. auto opdesc_src_data = node_desc->GetOutputDesc(out_anchor->GetIdx());
  251. if (opdesc_src_data.GetDataType() != DT_FLOAT) {
  252. GELOGW("The datatype of data node %s is not FP32", node_desc->GetName().c_str());
  253. opdesc_src_data.SetDataType(DT_FLOAT);
  254. }
  255. // We must get the TensorDesc from the output anchor on the Data node,
  256. // and update the TensorDesc to the input anchor on the Aipp node.
  257. // Because the InferShape function for the Aipp node needs the input tensor format,
  258. // but the InferFormat process before InferShape can not infer the format
  259. // if the tensor on the Aipp has an unknown shape
  260. if (aipp_opdesc_ptr->UpdateInputDesc(kAippImageInputIndex, opdesc_src_data) != GRAPH_SUCCESS) {
  261. REPORT_CALL_ERROR("E19999", "Update the output desc from node:%s(%s) to aipp:%s(%s) failed",
  262. node_desc->GetName().c_str(), node_desc->GetType().c_str(),
  263. aipp_opdesc_ptr->GetName().c_str(), aipp_opdesc_ptr->GetType().c_str());
  264. GELOGE(INTERNAL_ERROR, "[Call][UpdateInputDesc] Failed to update the output desc from node %s to aipp %s",
  265. node_desc->GetName().c_str(), aipp_opdesc_ptr->GetName().c_str());
  266. return nullptr;
  267. }
  268. return node->GetOwnerComputeGraph()->AddNode(aipp_opdesc_ptr);
  269. }
  270. Status AippOp::AddAippAttrbutes(const OpDescPtr &op_desc, const std::string &aipp_cfg_path, const uint32_t &index) {
  271. GeAttrValue::NAMED_ATTRS aipp_attr;
  272. ConvertParamToAttr(aipp_attr);
  273. GE_CHK_BOOL_RET_STATUS(AttrUtils::SetNamedAttrs(op_desc, ATTR_NAME_AIPP, aipp_attr),
  274. INTERNAL_ERROR, "[Set][NamedAttrs] %s for aipp node:%s failed", ATTR_NAME_AIPP.c_str(),
  275. op_desc->GetName().c_str());
  276. GE_CHK_BOOL_RET_STATUS(AttrUtils::SetStr(op_desc, kAippConfigPath, aipp_cfg_path),
  277. INTERNAL_ERROR, "[Set][Attr] config file path for aipp node:%s failed",
  278. op_desc->GetName().c_str());
  279. std::vector<std::string> empty_names;
  280. GE_CHK_BOOL_RET_STATUS(AttrUtils::SetListStr(op_desc, ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES, empty_names),
  281. INTERNAL_ERROR, "[Set][Attr] %s for aipp node:%s failed",
  282. ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES.c_str(), op_desc->GetName().c_str());
  283. GE_CHK_BOOL_RET_STATUS(AttrUtils::SetInt(op_desc, kCurrentAippIndex, index),
  284. INTERNAL_ERROR, "[Set][Attr] %s for aipp node:%s failed", kCurrentAippIndex,
  285. op_desc->GetName().c_str());
  286. // add input/output desc
  287. GeTensorDesc tensor;
  288. GE_CHK_GRAPH_STATUS_RET(op_desc->AddInputDesc("images", tensor),
  289. "[Add][InputDesc] images for aipp node:%s failed", op_desc->GetName().c_str());
  290. if (GetAippMode() == domi::AippOpParams::dynamic) {
  291. GE_CHK_GRAPH_STATUS_RET(op_desc->AddOptionalInputDesc("params", tensor),
  292. "[Call][AddOptionalInputDesc] Failed to add params for aipp node:%s",
  293. op_desc->GetName().c_str());
  294. }
  295. GE_CHK_GRAPH_STATUS_RET(op_desc->AddOutputDesc("features", tensor),
  296. "[Add][OutputDesc] features for aipp node:%s failed", op_desc->GetName().c_str());
  297. return SUCCESS;
  298. }
  299. domi::AippOpParams::AippMode AippOp::GetAippMode() { return aipp_params_->aipp_mode(); }
  300. NodePtr AippOp::FindDataByIndex(const ComputeGraphPtr &graph, int rank) {
  301. int64_t data_index = 0;
  302. for (auto &node : graph->GetDirectNode()) {
  303. if (node->GetType() != DATA) {
  304. continue;
  305. }
  306. // For functional multi batch, Skip Data for index.
  307. if (node->GetOpDesc()->HasAttr(ATTR_INSERT_BY_MBATCH)) {
  308. continue;
  309. }
  310. // There is no `index` attribute on the `Data` node when compile in inference scene
  311. // so we can only use the order of all `Data` nodes to infer the data index
  312. if (data_index++ != rank) {
  313. continue;
  314. }
  315. return node;
  316. }
  317. string error_msg = "Can not find the data node by aipp parameter related_input_rank " + to_string(rank);
  318. GE_ERRORLOG_AND_ERRORMSG(PARAM_INVALID, error_msg.c_str());
  319. return nullptr;
  320. }
  321. Status AippOp::GetAndCheckTarget(const ComputeGraphPtr &graph, int rank, NodePtr &target,
  322. std::set<uint32_t> &edge_indexes) {
  323. auto data_node = FindDataByIndex(graph, rank);
  324. if (data_node == nullptr) {
  325. GELOGE(PARAM_INVALID, "[Call][FindDataByIndex] Get target input node for rank %d failed", rank);
  326. return PARAM_INVALID;
  327. }
  328. data_node_linked_aipp = data_node;
  329. auto data_opdesc = data_node->GetOpDesc();
  330. GE_CHECK_NOTNULL(data_opdesc);
  331. string set_dt_str;
  332. if (ge::AttrUtils::GetStr(data_opdesc, ATTR_ATC_USER_DEFINE_DATATYPE, set_dt_str)) {
  333. ErrorManager::GetInstance().ATCReportErrMessage("E10034", {"opname"}, {data_opdesc->GetName()});
  334. GELOGE(INTERNAL_ERROR,
  335. "[Get][Attr] This input op [%s] is linked to aipp, can not be set to fp16, "
  336. "please check your atc parameter --insert_op_conf, --input_fp16_nodes.",
  337. data_opdesc->GetName().c_str());
  338. return PARAM_INVALID;
  339. }
  340. // add dynamic or static attr memsage to data
  341. if (GetAippMode() == domi::AippOpParams::static_) {
  342. (void)AttrUtils::SetStr(data_opdesc, ATTR_DATA_RELATED_AIPP_MODE, "static_aipp");
  343. } else if (GetAippMode() == domi::AippOpParams::dynamic) {
  344. (void)AttrUtils::SetStr(data_opdesc, ATTR_DATA_RELATED_AIPP_MODE, "dynamic_aipp");
  345. }
  346. // In scenario AIPP+CONV2D+POOLING, keep the aipp info to Data, since AIPP disappear after subgraph optimize
  347. GeAttrValue::NAMED_ATTRS aipp_attr;
  348. ConvertParamToAttr(aipp_attr);
  349. if (!AttrUtils::SetNamedAttrs(data_opdesc, ATTR_NAME_AIPP, aipp_attr)) {
  350. REPORT_INNER_ERROR("E19999", "Set Attr:%s for op:%s(%s) failed", ATTR_NAME_AIPP.c_str(),
  351. data_opdesc->GetName().c_str(), data_opdesc->GetType().c_str());
  352. GELOGE(INTERNAL_ERROR, "[Set][Attr] %s for op:%s(%s) failed", ATTR_NAME_AIPP.c_str(),
  353. data_opdesc->GetName().c_str(), data_opdesc->GetType().c_str());
  354. return INTERNAL_ERROR;
  355. }
  356. if (aipp_params_->input_edge_idx_size() > 0) {
  357. for (auto edge_index : aipp_params_->input_edge_idx()) {
  358. edge_indexes.insert(edge_index);
  359. }
  360. }
  361. if (!edge_indexes.empty() && (*edge_indexes.rbegin() >= data_node->GetOutDataNodes().size())) {
  362. string error_msg = "The aipp parameter input_edge_idx[" + std::to_string(*edge_indexes.rbegin()) +
  363. "] should be smaller than the target input[" +
  364. std::to_string(data_node->GetOutDataNodes().size()) +"]'s outnodes.";
  365. GE_ERRORLOG_AND_ERRORMSG(PARAM_INVALID, error_msg.c_str());
  366. return PARAM_INVALID;
  367. }
  368. target = data_node;
  369. return GetStaticTargetNode(graph, data_node, target);
  370. }
  371. Status AippOp::GetStaticTargetNode(const ComputeGraphPtr &graph, NodePtr &data_node, NodePtr &target) {
  372. if (GetAippMode() != domi::AippOpParams::static_) {
  373. return SUCCESS;
  374. }
  375. std::string related_node_name;
  376. if (AttrUtils::GetStr(data_node->GetOpDesc(), kMbatchSwitchnName, related_node_name)) {
  377. if (related_node_name.empty()) {
  378. REPORT_INNER_ERROR("E19999", "The data node %s has switchn node flag, but the value of attr:%s is empty, "
  379. "check invalid", data_node->GetName().c_str(),
  380. kMbatchSwitchnName);
  381. GELOGE(INTERNAL_ERROR, "[Check][Param] The data node %s has switchn node flag, but the value of attr:%s is empty",
  382. data_node->GetName().c_str(), kMbatchSwitchnName);
  383. return INTERNAL_ERROR;
  384. }
  385. auto switchn = graph->FindNode(related_node_name);
  386. if (switchn == nullptr) {
  387. REPORT_INNER_ERROR("E19999", "The data node %s has switchn node %s, but can not find it on the graph, "
  388. "check invalid", data_node->GetName().c_str(), related_node_name.c_str());
  389. GELOGE(INTERNAL_ERROR, "[Check][Param] The data node %s has switchn node %s, but can not find it on the graph",
  390. data_node->GetName().c_str(), related_node_name.c_str());
  391. return INTERNAL_ERROR;
  392. }
  393. target = switchn;
  394. GELOGI("Multi-batch/image size and static aipp for data %s, "
  395. "the aipp node will be insert after %s instead of origin data node",
  396. data_node->GetName().c_str(), switchn->GetName().c_str());
  397. return SUCCESS;
  398. }
  399. const auto out_anchor = data_node->GetOutDataAnchor(0);
  400. for (const auto &in_anchor : out_anchor->GetPeerInDataAnchors()) {
  401. if (in_anchor == nullptr) {
  402. continue;
  403. }
  404. const auto &case_node = in_anchor->GetOwnerNode();
  405. if (case_node->GetType() == CASE) {
  406. target = case_node;
  407. return SUCCESS;
  408. }
  409. }
  410. return SUCCESS;
  411. }
  412. Status AippOp::ConvertRelatedInputNameToRank() {
  413. GE_CHECK_NOTNULL(aipp_params_);
  414. string related_input_name = aipp_params_->related_input_name();
  415. if (related_input_name.empty()) {
  416. return SUCCESS;
  417. }
  418. std::vector<std::string> data_top_names = domi::GetContext().data_top_names;
  419. GELOGI("Convert name to rank start: data size[%zu]", data_top_names.size());
  420. uint32_t index = 0;
  421. bool convert_flag = false;
  422. for (const auto &data_top_name : data_top_names) {
  423. if (related_input_name == data_top_name) {
  424. aipp_params_->set_related_input_rank(index);
  425. convert_flag = true;
  426. GELOGI("AippOp: rank: %u, top name: %s.", index, data_top_name.c_str());
  427. break;
  428. }
  429. index++;
  430. }
  431. if (!convert_flag) {
  432. string error_msg = "Top name " + related_input_name + "convert rank failed, Please"
  433. " ensure top name in aipp config is the top name of data node.";
  434. GELOGE(PARAM_INVALID, "[Check][InputParam]%s", error_msg.c_str());
  435. REPORT_INPUT_ERROR("E10052", std::vector<std::string>({"reason"}), std::vector<std::string>({error_msg}));
  436. return PARAM_INVALID;
  437. }
  438. return SUCCESS;
  439. }
  440. Status AippOp::GetTargetPosition(ComputeGraphPtr graph, NodePtr &target_input,
  441. std::vector<std::pair<OutDataAnchorPtr, InDataAnchorPtr>> &target_edges) {
  442. GE_CHECK_NOTNULL(graph);
  443. GE_CHECK_NOTNULL(aipp_params_);
  444. std::set<uint32_t> edge_indexes;
  445. const uint32_t related_input_rank = aipp_params_->related_input_rank();
  446. auto ret = GetAndCheckTarget(graph, related_input_rank, target_input, edge_indexes);
  447. if (ret != SUCCESS) {
  448. GELOGE(ret, "[Get][TargetInputNode] for rank %u failed", related_input_rank);
  449. return ret;
  450. }
  451. target_edges.clear();
  452. if (target_input->GetType() != CASE) {
  453. for (OutDataAnchorPtr &src_out : target_input->GetAllOutDataAnchors()) {
  454. auto dst_ins = src_out->GetPeerInDataAnchors();
  455. for (uint32_t i = 0; i < dst_ins.size(); ++i) {
  456. auto dst_in = dst_ins.at(i);
  457. if (edge_indexes.empty() || edge_indexes.count(i) > 0) {
  458. target_edges.emplace_back(src_out, dst_in);
  459. }
  460. }
  461. }
  462. } else {
  463. const auto &func_desc = target_input->GetOpDesc();
  464. for (const auto &name : func_desc->GetSubgraphInstanceNames()) {
  465. const auto &subgraph = graph->GetSubgraph(name);
  466. if (subgraph == nullptr) {
  467. REPORT_INNER_ERROR("E19999", "Subgraph:%s of op:%s(%s) not find in graph:%s, check invalid",
  468. name.c_str(), func_desc->GetName().c_str(), func_desc->GetType().c_str(),
  469. graph->GetName().c_str());
  470. GELOGE(GE_GRAPH_EMPTY_SUBGRAPH, "[Get][Subgraph] failed, Subgraph:%s of op:%s(%s) not find in graph:%s",
  471. name.c_str(), func_desc->GetName().c_str(), func_desc->GetType().c_str(), graph->GetName().c_str());
  472. return GE_GRAPH_EMPTY_SUBGRAPH;
  473. }
  474. auto data_node = FindDataByIndex(subgraph, related_input_rank);
  475. if (data_node == nullptr) {
  476. GELOGE(PARAM_INVALID, "[Get][TargetInputNode] for rank %d failed", related_input_rank);
  477. return PARAM_INVALID;
  478. }
  479. for (OutDataAnchorPtr &src_out : data_node->GetAllOutDataAnchors()) {
  480. auto dst_ins = src_out->GetPeerInDataAnchors();
  481. for (uint32_t i = 0; i < dst_ins.size(); ++i) {
  482. auto dst_in = dst_ins.at(i);
  483. if (edge_indexes.empty() || edge_indexes.count(i) > 0) {
  484. target_edges.emplace_back(src_out, dst_in);
  485. }
  486. }
  487. }
  488. }
  489. }
  490. return SUCCESS;
  491. }
  492. Status AippOp::SetDefaultParams() {
  493. GE_CHECK_NOTNULL(aipp_params_);
  494. const domi::AippOpParams::AippMode aipp_mode = aipp_params_->aipp_mode();
  495. if (aipp_mode == domi::AippOpParams::static_) {
  496. if (aipp_params_->csc_switch()) {
  497. SetCscDefaultValue();
  498. }
  499. SetDtcDefaultValue();
  500. GELOGI("parse aipp params:input_format:%s, csc_switch:%d.",
  501. domi::AippOpParams::InputFormat_Name(aipp_params_->input_format()).c_str(), aipp_params_->csc_switch());
  502. GELOGI("parse aipp params:mean_chn_0:%d, mean_chn_1:%d, mean_chn_2:%d, mean_chn_3:%d.", aipp_params_->mean_chn_0(),
  503. aipp_params_->mean_chn_1(), aipp_params_->mean_chn_2(), aipp_params_->mean_chn_3());
  504. GELOGI("parse aipp params:min_chn_0:%f, min_chn_1:%f, min_chn_2:%f.", aipp_params_->min_chn_0(),
  505. aipp_params_->min_chn_1(), aipp_params_->min_chn_2());
  506. GE_IF_BOOL_EXEC(!aipp_params_->crop(), aipp_params_->set_load_start_pos_h(0); aipp_params_->set_load_start_pos_w(0);
  507. aipp_params_->set_crop_size_h(0); aipp_params_->set_crop_size_w(0););
  508. GE_IF_BOOL_EXEC(!aipp_params_->resize(), aipp_params_->set_resize_output_h(0);
  509. aipp_params_->set_resize_output_w(0););
  510. GE_IF_BOOL_EXEC(!aipp_params_->padding(), aipp_params_->set_left_padding_size(0);
  511. aipp_params_->set_right_padding_size(0); aipp_params_->set_top_padding_size(0);
  512. aipp_params_->set_bottom_padding_size(0););
  513. }
  514. return SUCCESS;
  515. }
  516. Status AippOp::ValidateParams() {
  517. GE_CHECK_NOTNULL(aipp_params_);
  518. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->aipp_mode() != domi::AippOpParams::undefined, PARAM_INVALID,
  519. "When insert AIPP op, aipp_mode must be configured as static or dynamic ");
  520. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->var_reci_chn_0_size() <= 1, PARAM_INVALID,
  521. "The parameter var_reci_chn_0 can not be configed repeatedly");
  522. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->var_reci_chn_1_size() <= 1, PARAM_INVALID,
  523. "The parameter var_reci_chn_1 can not be configed repeatedly");
  524. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->var_reci_chn_2_size() <= 1, PARAM_INVALID,
  525. "The parameter var_reci_chn_2 can not be configed repeatedly");
  526. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->var_reci_chn_3_size() <= 1, PARAM_INVALID,
  527. "The parameter var_reci_chn_3 can not be configed repeatedly");
  528. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r0c0_size() <= 1, PARAM_INVALID,
  529. "The parameter matrix_r0c0 can not be configed repeatedly");
  530. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r0c1_size() <= 1, PARAM_INVALID,
  531. "The parameter matrix_r0c1 can not be configed repeatedly");
  532. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r0c2_size() <= 1, PARAM_INVALID,
  533. "The parameter matrix_r0c2 can not be configed repeatedly");
  534. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r1c0_size() <= 1, PARAM_INVALID,
  535. "The parameter matrix_r1c0 can not be configed repeatedly");
  536. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r1c1_size() <= 1, PARAM_INVALID,
  537. "The parameter matrix_r1c1 can not be configed repeatedly");
  538. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r1c2_size() <= 1, PARAM_INVALID,
  539. "The parameter matrix_r1c2 can not be configed repeatedly");
  540. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r2c0_size() <= 1, PARAM_INVALID,
  541. "The parameter matrix_r2c0 can not be configed repeatedly");
  542. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r2c1_size() <= 1, PARAM_INVALID,
  543. "The parameter matrix_r2c1 can not be configed repeatedly");
  544. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->matrix_r2c2_size() <= 1, PARAM_INVALID,
  545. "The parameter matrix_r2c2 can not be configed repeatedly");
  546. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->output_bias_0_size() <= 1, PARAM_INVALID,
  547. "The parameter output_bias_0 can not be configed repeatedly");
  548. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->output_bias_1_size() <= 1, PARAM_INVALID,
  549. "The parameter output_bias_1 can not be configed repeatedly");
  550. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->output_bias_2_size() <= 1, PARAM_INVALID,
  551. "The parameter output_bias_2 can not be configed repeatedly");
  552. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->input_bias_0_size() <= 1, PARAM_INVALID,
  553. "The parameter input_bias_0 can not be configed repeatedly");
  554. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->input_bias_1_size() <= 1, PARAM_INVALID,
  555. "The parameter input_bias_1 can not be configed repeatedly");
  556. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->input_bias_2_size() <= 1, PARAM_INVALID,
  557. "The parameter input_bias_2 can not be configed repeatedly");
  558. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->input_edge_idx_size() <= 1, PARAM_INVALID,
  559. "The parameter input_edge_idx can not be configed repeatedly");
  560. const domi::AippOpParams::AippMode aipp_mode = aipp_params_->aipp_mode();
  561. if (aipp_mode == domi::AippOpParams::dynamic) {
  562. GE_CHK_LOG_AND_ERRORMSG(
  563. aipp_params_->max_src_image_size() > 0, PARAM_INVALID,
  564. "For dynamic AIPP params, max_src_image_size must be set which number should be greater than 0");
  565. } else {
  566. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->input_format() != domi::AippOpParams::UNDEFINED, PARAM_INVALID,
  567. "Input format of AIPP conf is undefined");
  568. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->src_image_size_w() >= 0, PARAM_INVALID,
  569. "Src_image_size_w must not be configed smaller than 0");
  570. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->src_image_size_h() >= 0, PARAM_INVALID,
  571. "Src_image_size_h must not be configed smaller than 0");
  572. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->load_start_pos_w() >= 0, PARAM_INVALID,
  573. "Load_start_pos_w must not be configed smaller than 0");
  574. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->load_start_pos_h() >= 0, PARAM_INVALID,
  575. "Load_start_pos_h must not be configed smaller than 0");
  576. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->crop_size_w() >= 0, PARAM_INVALID,
  577. "Crop_size_w must not be configed smaller than 0");
  578. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->resize_output_w() >= 0, PARAM_INVALID,
  579. "Resize_output_w must not be configed smaller than 0");
  580. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->resize_output_h() >= 0, PARAM_INVALID,
  581. "Resize_output_h must not be configed smaller than 0");
  582. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->left_padding_size() >= 0, PARAM_INVALID,
  583. "Left_padding_size must not be configed smaller than 0");
  584. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->right_padding_size() >= 0, PARAM_INVALID,
  585. "Right_padding_size must not be configed smaller than 0");
  586. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->top_padding_size() >= 0, PARAM_INVALID,
  587. "Top_padding_size must not be configed smaller than 0");
  588. GE_CHK_LOG_AND_ERRORMSG(aipp_params_->bottom_padding_size() >= 0, PARAM_INVALID,
  589. "Bottom_padding_size must not be configed smaller than 0");
  590. }
  591. return SUCCESS;
  592. }
  593. void AippOp::SetCscDefaultValue() {
  594. GE_CHECK_NOTNULL_JUST_RETURN(aipp_params_);
  595. if (aipp_params_->input_format() == domi::AippOpParams::YUV420SP_U8) {
  596. CHECK_FALSE_EXEC(aipp_params_->matrix_r0c0_size() > 0, aipp_params_->add_matrix_r0c0(DEFAULT_MATRIX_R2C0_YUV2RGB));
  597. CHECK_FALSE_EXEC(aipp_params_->matrix_r0c1_size() > 0, aipp_params_->add_matrix_r0c1(DEFAULT_MATRIX_R2C1_YUV2RGB));
  598. CHECK_FALSE_EXEC(aipp_params_->matrix_r0c2_size() > 0, aipp_params_->add_matrix_r0c2(DEFAULT_MATRIX_R2C2_YUV2RGB));
  599. CHECK_FALSE_EXEC(aipp_params_->matrix_r1c0_size() > 0, aipp_params_->add_matrix_r1c0(DEFAULT_MATRIX_R1C0_YUV2RGB));
  600. CHECK_FALSE_EXEC(aipp_params_->matrix_r1c1_size() > 0, aipp_params_->add_matrix_r1c1(DEFAULT_MATRIX_R1C1_YUV2RGB));
  601. CHECK_FALSE_EXEC(aipp_params_->matrix_r1c2_size() > 0, aipp_params_->add_matrix_r1c2(DEFAULT_MATRIX_R1C2_YUV2RGB));
  602. CHECK_FALSE_EXEC(aipp_params_->matrix_r2c0_size() > 0, aipp_params_->add_matrix_r2c0(DEFAULT_MATRIX_R0C0_YUV2RGB));
  603. CHECK_FALSE_EXEC(aipp_params_->matrix_r2c1_size() > 0, aipp_params_->add_matrix_r2c1(DEFAULT_MATRIX_R0C1_YUV2RGB));
  604. CHECK_FALSE_EXEC(aipp_params_->matrix_r2c2_size() > 0, aipp_params_->add_matrix_r2c2(DEFAULT_MATRIX_R0C2_YUV2RGB));
  605. } else {
  606. CHECK_FALSE_EXEC(aipp_params_->matrix_r0c0_size() > 0, aipp_params_->add_matrix_r0c0(DEFAULT_MATRIX_R0C0_RGB2YUV));
  607. CHECK_FALSE_EXEC(aipp_params_->matrix_r0c1_size() > 0, aipp_params_->add_matrix_r0c1(DEFAULT_MATRIX_R0C1_RGB2YUV));
  608. CHECK_FALSE_EXEC(aipp_params_->matrix_r0c2_size() > 0, aipp_params_->add_matrix_r0c2(DEFAULT_MATRIX_R0C2_RGB2YUV));
  609. CHECK_FALSE_EXEC(aipp_params_->matrix_r1c0_size() > 0, aipp_params_->add_matrix_r1c0(DEFAULT_MATRIX_R1C0_RGB2YUV));
  610. CHECK_FALSE_EXEC(aipp_params_->matrix_r1c1_size() > 0, aipp_params_->add_matrix_r1c1(DEFAULT_MATRIX_R1C1_RGB2YUV));
  611. CHECK_FALSE_EXEC(aipp_params_->matrix_r1c2_size() > 0, aipp_params_->add_matrix_r1c2(DEFAULT_MATRIX_R1C2_RGB2YUV));
  612. CHECK_FALSE_EXEC(aipp_params_->matrix_r2c0_size() > 0, aipp_params_->add_matrix_r2c0(DEFAULT_MATRIX_R2C0_RGB2YUV));
  613. CHECK_FALSE_EXEC(aipp_params_->matrix_r2c1_size() > 0, aipp_params_->add_matrix_r2c1(DEFAULT_MATRIX_R2C1_RGB2YUV));
  614. CHECK_FALSE_EXEC(aipp_params_->matrix_r2c2_size() > 0, aipp_params_->add_matrix_r2c2(DEFAULT_MATRIX_R2C2_RGB2YUV));
  615. }
  616. CHECK_FALSE_EXEC(aipp_params_->input_bias_0_size() > 0, aipp_params_->add_input_bias_0(DEFAULT_INPUT_BIAS_0));
  617. CHECK_FALSE_EXEC(aipp_params_->input_bias_1_size() > 0, aipp_params_->add_input_bias_1(DEFAULT_INPUT_BIAS_1));
  618. CHECK_FALSE_EXEC(aipp_params_->input_bias_2_size() > 0, aipp_params_->add_input_bias_2(DEFAULT_INPUT_BIAS_2));
  619. CHECK_FALSE_EXEC(aipp_params_->output_bias_0_size() > 0, aipp_params_->add_output_bias_0(DEFAULT_OUTPUT_BIAS_0));
  620. CHECK_FALSE_EXEC(aipp_params_->output_bias_1_size() > 0, aipp_params_->add_output_bias_1(DEFAULT_OUTPUT_BIAS_1));
  621. CHECK_FALSE_EXEC(aipp_params_->output_bias_2_size() > 0, aipp_params_->add_output_bias_2(DEFAULT_OUTPUT_BIAS_2));
  622. }
  623. void AippOp::SetDtcDefaultValue() {
  624. GE_CHECK_NOTNULL_JUST_RETURN(aipp_params_);
  625. CHECK_FALSE_EXEC(aipp_params_->var_reci_chn_0_size() > 0, aipp_params_->add_var_reci_chn_0(DEFAULT_VAR_RECI_CHN));
  626. GELOGD("var_reci_chn_0 is %f, size is %u.", DEFAULT_VAR_RECI_CHN, aipp_params_->var_reci_chn_0_size());
  627. CHECK_FALSE_EXEC(aipp_params_->var_reci_chn_1_size() > 0, aipp_params_->add_var_reci_chn_1(DEFAULT_VAR_RECI_CHN));
  628. GELOGD("var_reci_chn_1 is %f, size is %u.", DEFAULT_VAR_RECI_CHN, aipp_params_->var_reci_chn_1_size());
  629. CHECK_FALSE_EXEC(aipp_params_->var_reci_chn_2_size() > 0, aipp_params_->add_var_reci_chn_2(DEFAULT_VAR_RECI_CHN));
  630. GELOGD("var_reci_chn_2 is %f, size is %u.", DEFAULT_VAR_RECI_CHN, aipp_params_->var_reci_chn_2_size());
  631. CHECK_FALSE_EXEC(aipp_params_->var_reci_chn_3_size() > 0, aipp_params_->add_var_reci_chn_3(DEFAULT_VAR_RECI_CHN));
  632. GELOGD("var_reci_chn_3 is %f, size is %u.", DEFAULT_VAR_RECI_CHN, aipp_params_->var_reci_chn_3_size());
  633. }
  634. Status AippOp::GenerateOpDesc(OpDescPtr op_desc) {
  635. GE_CHECK_NOTNULL(op_desc);
  636. static std::atomic_long atomic_op_idx(0);
  637. auto op_idx = atomic_op_idx.fetch_add(1);
  638. op_desc->SetName(std::string("aipp_node").append(std::to_string(op_idx)));
  639. op_desc->SetType(AIPP);
  640. // Add two InputDesc, add the second after the first one is added successfully.
  641. if ((op_desc->AddInputDesc(GeTensorDesc()) != GRAPH_SUCCESS) ||
  642. (op_desc->AddInputDesc(GeTensorDesc()) != GRAPH_SUCCESS)) {
  643. REPORT_CALL_ERROR("E19999", "Add input desc into op:%s(%s) failed",
  644. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  645. GELOGE(FAILED, "[Add][InputDesc] into op:%s(%s) failed",
  646. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  647. return FAILED;
  648. }
  649. if (op_desc->AddOutputDesc(GeTensorDesc()) != GRAPH_SUCCESS) {
  650. REPORT_CALL_ERROR("E19999", "Add output desc into op:%s(%s) failed",
  651. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  652. GELOGE(FAILED, "[Add][OutputDesc] into op:%s(%s) failed",
  653. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  654. return FAILED;
  655. }
  656. GeAttrValue::NAMED_ATTRS aipp_attrs;
  657. ConvertParamToAttr(aipp_attrs);
  658. GE_IF_BOOL_EXEC(!AttrUtils::SetNamedAttrs(op_desc, ATTR_NAME_AIPP, aipp_attrs),
  659. REPORT_INNER_ERROR("E19999", "Set Attr:%s to op:%s(%s) failed", ATTR_NAME_AIPP.c_str(),
  660. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  661. GELOGE(FAILED, "[Set][Attr] %s to op:%s(%s) failed", ATTR_NAME_AIPP.c_str(),
  662. op_desc->GetName().c_str(), op_desc->GetType().c_str());
  663. return FAILED);
  664. return SUCCESS;
  665. }
  666. void AippOp::ConvertParamToAttr(GeAttrValue::NAMED_ATTRS &aipp_attrs) {
  667. GE_CHECK_NOTNULL_JUST_RETURN(aipp_params_);
  668. SAVE_AIPP_ATTR(aipp_mode, GeAttrValue::INT);
  669. SAVE_AIPP_ATTR(related_input_rank, GeAttrValue::INT);
  670. if (aipp_params_->aipp_mode() == domi::AippOpParams::static_) {
  671. SAVE_AIPP_ATTR(input_format, GeAttrValue::INT);
  672. SAVE_AIPP_ATTR(csc_switch, GeAttrValue::BOOL);
  673. SAVE_AIPP_ATTR(crop, GeAttrValue::BOOL);
  674. SAVE_AIPP_ATTR(resize, GeAttrValue::BOOL);
  675. SAVE_AIPP_ATTR(load_start_pos_w, GeAttrValue::INT);
  676. SAVE_AIPP_ATTR(load_start_pos_h, GeAttrValue::INT);
  677. SAVE_AIPP_ATTR(crop_size_w, GeAttrValue::INT);
  678. SAVE_AIPP_ATTR(crop_size_h, GeAttrValue::INT);
  679. SAVE_AIPP_ATTR(resize, GeAttrValue::BOOL);
  680. SAVE_AIPP_ATTR(resize_output_w, GeAttrValue::INT);
  681. SAVE_AIPP_ATTR(resize_output_h, GeAttrValue::INT);
  682. SAVE_AIPP_ATTR(padding, GeAttrValue::BOOL);
  683. SAVE_AIPP_ATTR(left_padding_size, GeAttrValue::INT);
  684. SAVE_AIPP_ATTR(right_padding_size, GeAttrValue::INT);
  685. SAVE_AIPP_ATTR(top_padding_size, GeAttrValue::INT);
  686. SAVE_AIPP_ATTR(bottom_padding_size, GeAttrValue::INT);
  687. SAVE_AIPP_ATTR(src_image_size_w, GeAttrValue::INT);
  688. SAVE_AIPP_ATTR(src_image_size_h, GeAttrValue::INT);
  689. SAVE_AIPP_ATTR(cpadding_value, GeAttrValue::FLOAT);
  690. SAVE_AIPP_ATTR(rbuv_swap_switch, GeAttrValue::BOOL);
  691. SAVE_AIPP_ATTR(ax_swap_switch, GeAttrValue::BOOL);
  692. SAVE_AIPP_ATTR(single_line_mode, GeAttrValue::BOOL);
  693. SAVE_AIPP_ATTR(mean_chn_0, GeAttrValue::INT);
  694. SAVE_AIPP_ATTR(mean_chn_1, GeAttrValue::INT);
  695. SAVE_AIPP_ATTR(mean_chn_2, GeAttrValue::INT);
  696. SAVE_AIPP_ATTR(mean_chn_3, GeAttrValue::INT);
  697. SAVE_AIPP_ATTR(min_chn_0, GeAttrValue::FLOAT);
  698. SAVE_AIPP_ATTR(min_chn_1, GeAttrValue::FLOAT);
  699. SAVE_AIPP_ATTR(min_chn_2, GeAttrValue::FLOAT);
  700. SAVE_AIPP_ATTR(min_chn_3, GeAttrValue::FLOAT);
  701. SAVE_AIPP_ATTR_LIST(var_reci_chn_0, GeAttrValue::FLOAT);
  702. SAVE_AIPP_ATTR_LIST(var_reci_chn_1, GeAttrValue::FLOAT);
  703. SAVE_AIPP_ATTR_LIST(var_reci_chn_2, GeAttrValue::FLOAT);
  704. SAVE_AIPP_ATTR_LIST(var_reci_chn_3, GeAttrValue::FLOAT);
  705. SAVE_AIPP_ATTR_LIST(matrix_r0c0, GeAttrValue::INT);
  706. SAVE_AIPP_ATTR_LIST(matrix_r0c1, GeAttrValue::INT);
  707. SAVE_AIPP_ATTR_LIST(matrix_r0c2, GeAttrValue::INT);
  708. SAVE_AIPP_ATTR_LIST(matrix_r1c0, GeAttrValue::INT);
  709. SAVE_AIPP_ATTR_LIST(matrix_r1c1, GeAttrValue::INT);
  710. SAVE_AIPP_ATTR_LIST(matrix_r1c2, GeAttrValue::INT);
  711. SAVE_AIPP_ATTR_LIST(matrix_r2c0, GeAttrValue::INT);
  712. SAVE_AIPP_ATTR_LIST(matrix_r2c1, GeAttrValue::INT);
  713. SAVE_AIPP_ATTR_LIST(matrix_r2c2, GeAttrValue::INT);
  714. SAVE_AIPP_ATTR_LIST(output_bias_0, GeAttrValue::INT);
  715. SAVE_AIPP_ATTR_LIST(output_bias_1, GeAttrValue::INT);
  716. SAVE_AIPP_ATTR_LIST(output_bias_2, GeAttrValue::INT);
  717. SAVE_AIPP_ATTR_LIST(input_bias_0, GeAttrValue::INT);
  718. SAVE_AIPP_ATTR_LIST(input_bias_1, GeAttrValue::INT);
  719. SAVE_AIPP_ATTR_LIST(input_bias_2, GeAttrValue::INT);
  720. } else {
  721. SAVE_AIPP_ATTR(max_src_image_size, GeAttrValue::INT);
  722. SAVE_AIPP_ATTR(support_rotation, GeAttrValue::BOOL);
  723. }
  724. }
  725. Status AippOp::CreateAippData(const NodePtr &aipp_node) {
  726. GELOGD("Enter add aipp data node process.");
  727. // get previous node, it should be DATA
  728. auto data_node = aipp_node->GetInDataNodes().at(kAippImageInputIndex);
  729. auto data_op_desc = data_node->GetOpDesc();
  730. GE_CHECK_NOTNULL(data_op_desc);
  731. auto ori_data_format = GetAndCheckFormat();
  732. if (ori_data_format != FORMAT_NCHW && ori_data_format != FORMAT_NHWC) {
  733. string format_str = TypeUtils::FormatToSerialString(ori_data_format);
  734. GELOGE(PARAM_INVALID, "[Check][Param] when dynamic aipp, input_format must be NCHW or NHWC, but [%s] format is %s",
  735. data_node->GetName().c_str(), format_str.c_str());
  736. string reason = "format must be NCHW or NHWC in dynamic aipp process";
  737. ErrorManager::GetInstance().ATCReportErrMessage("E19014", {"opname", "value", "reason"},
  738. {data_node->GetName(), "format " + format_str, reason});
  739. return PARAM_INVALID;
  740. }
  741. // dynamic aipp shape HWC is not fixed, need to be set -1
  742. int64_t data_shape_n = 0;
  743. // dynamic batch or HW, need acquire N from ATTR_MBATCH_ORIGIN_INPUT_DIMS
  744. if (data_op_desc->HasAttr(ATTR_MBATCH_ORIGIN_INPUT_DIMS)) {
  745. vector<int64_t> origin_input_dims;
  746. (void)AttrUtils::GetListInt(data_op_desc, ATTR_MBATCH_ORIGIN_INPUT_DIMS, origin_input_dims);
  747. if (!origin_input_dims.empty()) {
  748. data_shape_n = origin_input_dims[0];
  749. }
  750. } else {
  751. data_shape_n = data_op_desc->MutableInputDesc(0)->GetShape().GetDim(0);
  752. }
  753. vector<int64_t> dynamic_aipp_linked_data_shape{data_shape_n, kDynamicDim, kDynamicDim, kDynamicDim};
  754. (void)AttrUtils::SetListInt(data_op_desc, ATTR_DYNAMIC_AIPP_INPUT_DIMS, dynamic_aipp_linked_data_shape);
  755. int64_t batch_count = -1;
  756. if (GetDataDimN(data_node, ori_data_format, batch_count) != ge::SUCCESS) {
  757. string error_msg = "Get data_node dims and transfer to nchw_dims failed!";
  758. GE_ERRORLOG_AND_ERRORMSG(PARAM_INVALID, error_msg.c_str());
  759. return PARAM_INVALID;
  760. }
  761. if (batch_count <= 0) {
  762. string error_msg = "Batch count[" + std::to_string(batch_count) + "] is invalid, it must positive.";
  763. GE_ERRORLOG_AND_ERRORMSG(PARAM_INVALID, error_msg.c_str());
  764. return PARAM_INVALID;
  765. }
  766. int64_t max_dynamic_aipp_size = CalcMaxSize(batch_count);
  767. if (max_dynamic_aipp_size < 0) {
  768. string error_msg = "The dynamic aipp size is not positive";
  769. GE_ERRORLOG_AND_ERRORMSG(PARAM_INVALID, error_msg.c_str());
  770. return PARAM_INVALID;
  771. }
  772. GELOGI("Add aipp input data, batch count is %ld, max_dynamic_aipp_size is %ld", batch_count, max_dynamic_aipp_size);
  773. return AddNodeToGraph(aipp_node, max_dynamic_aipp_size);
  774. }
  775. Status AippOp::AddAttrToAippData(const OpDescPtr &aipp_data_op_desc) {
  776. // Add dynamic aipp config to aipp_data
  777. GeAttrValue::NAMED_ATTRS aipp_attr;
  778. ConvertParamToAttr(aipp_attr);
  779. (void)AttrUtils::SetNamedAttrs(aipp_data_op_desc, ATTR_NAME_AIPP, aipp_attr);
  780. (void)AttrUtils::SetStr(aipp_data_op_desc, ATTR_DATA_RELATED_AIPP_MODE, "dynamic_aipp_conf");
  781. // add node name attr to data linked aipp_data, it can be queried by acl.
  782. GE_CHECK_NOTNULL(data_node_linked_aipp);
  783. auto data_op_desc = data_node_linked_aipp->GetOpDesc();
  784. GE_CHECK_NOTNULL(data_op_desc);
  785. (void)AttrUtils::SetStr(data_op_desc, ATTR_DATA_AIPP_DATA_NAME_MAP, aipp_data_op_desc->GetName());
  786. (void)AttrUtils::SetStr(aipp_data_op_desc, ATTR_DATA_AIPP_DATA_NAME_MAP, data_op_desc->GetName());
  787. return SUCCESS;
  788. }
  789. Status AippOp::AddNodeToGraph(const NodePtr &aipp_node, int64_t max_dynamic_aipp_size) {
  790. std::vector<int64_t> input_shape_dim(1, max_dynamic_aipp_size);
  791. GeShape input_shape(input_shape_dim);
  792. // construct input tensor
  793. GeTensorDesc input_tensor(input_shape, FORMAT_ND, DT_UINT8);
  794. TensorUtils::SetReuseInput(input_tensor, false);
  795. TensorUtils::SetSize(input_tensor, max_dynamic_aipp_size);
  796. GE_CHECK_NOTNULL(aipp_node);
  797. const ComputeGraphPtr &graph = aipp_node->GetOwnerComputeGraph();
  798. string node_name;
  799. // First aippdata name should be definite.
  800. if (graph->FindFirstNodeMatchType(AIPPDATA) == nullptr) {
  801. GELOGI("Current graph has no aippdata node, so the name of it must be definite.");
  802. node_name = kDynamicAippData;
  803. } else {
  804. node_name = string(kDynamicAippData) + "_" + aipp_node->GetName();
  805. }
  806. GELOGI("Current add aippdata node name is %s", node_name.c_str());
  807. // new add aipp_data ops for dynamic aipp param input
  808. OpDescPtr op_desc_ptr_data = MakeShared<OpDesc>(node_name, AIPPDATA);
  809. GE_CHECK_NOTNULL(op_desc_ptr_data);
  810. if (AddAttrToAippData(op_desc_ptr_data) != SUCCESS) {
  811. return INTERNAL_ERROR;
  812. }
  813. auto stat1 = op_desc_ptr_data->AddInputDesc(input_tensor);
  814. GeShape output_shape(input_shape_dim);
  815. // construct output tensor
  816. GeTensorDesc output_tensor(output_shape, FORMAT_ND, DT_UINT8);
  817. TensorUtils::SetReuseInput(output_tensor, false);
  818. TensorUtils::SetSize(output_tensor, max_dynamic_aipp_size);
  819. auto stat2 = op_desc_ptr_data->AddOutputDesc(output_tensor);
  820. NodePtr aipp_data_node_ptr = graph->AddNode(op_desc_ptr_data);
  821. GE_CHECK_NOTNULL(aipp_data_node_ptr);
  822. // add node desc for aipp node
  823. auto stat3 = aipp_node->GetOpDesc()->UpdateInputDesc(kAippParamsInputIndex, output_tensor);
  824. if (stat1 != GRAPH_SUCCESS || stat2 != GRAPH_SUCCESS || stat3 != GRAPH_SUCCESS) {
  825. REPORT_CALL_ERROR("E19999", "Add and Update InputDesc to op:%s(%s) failed, index:%d",
  826. aipp_node->GetName().c_str(), aipp_node->GetType().c_str(), kAippParamsInputIndex);
  827. GELOGE(INTERNAL_ERROR, "[Update][InputDesc] to op:%s(%s) failed, index:%d",
  828. aipp_node->GetName().c_str(), aipp_node->GetType().c_str(), kAippParamsInputIndex);
  829. return INTERNAL_ERROR;
  830. }
  831. // aipp_node should have two input data but now tbe only one input
  832. if (GraphUtils::AddEdge(aipp_data_node_ptr->GetOutDataAnchor(kAippDataOutputIndex),
  833. aipp_node->GetInDataAnchor(kAippParamsInputIndex)) != GRAPH_SUCCESS) {
  834. REPORT_INNER_ERROR("E19999", "Add edge between op:%s(%s)(out_index:%u) and op:%s(%s)(in_index:%u) failed",
  835. aipp_data_node_ptr->GetName().c_str(), aipp_data_node_ptr->GetType().c_str(),
  836. kAippDataOutputIndex, aipp_node->GetName().c_str(), aipp_node->GetType().c_str(),
  837. kAippParamsInputIndex);
  838. GELOGE(INTERNAL_ERROR, "[Add][Edge] between op:%s(%s)(out_index:%u) and op:%s(%s)(in_index:%u) failed",
  839. aipp_data_node_ptr->GetName().c_str(), aipp_data_node_ptr->GetType().c_str(),
  840. kAippDataOutputIndex, aipp_node->GetName().c_str(), aipp_node->GetType().c_str(),
  841. kAippParamsInputIndex);
  842. return INTERNAL_ERROR;
  843. }
  844. return SUCCESS;
  845. }
  846. } // namespace ge

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