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.

new_op_test_utils.h 16 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  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. #ifndef OME_REBUILD_OME_OP_TEST_UTILS_H
  17. #define OME_REBUILD_OME_OP_TEST_UTILS_H
  18. #include <gtest/gtest.h>
  19. #include <memory>
  20. #include <utility>
  21. #include "common/fmk_types.h"
  22. #include "common/helper/model_helper.h"
  23. #include "common/op/attr_value_util.h"
  24. #include "common/properties_manager.h"
  25. #include "common/types.h"
  26. #include "executor/ge_executor.h"
  27. #include "graph/buffer.h"
  28. #include "graph/debug/ge_attr_define.h"
  29. #include "graph/ge_attr_value.h"
  30. #include "graph/model_serialize.h"
  31. #include "graph/utils/graph_utils.h"
  32. #include "graph/utils/op_desc_utils.h"
  33. #include "graph/utils/tensor_utils.h"
  34. #include "proto/ge_ir.pb.h"
  35. #define protected public
  36. #define private public
  37. #include "graph/compute_graph.h"
  38. #include "graph/debug/ge_attr_define.h"
  39. #include "graph/load/new_model_manager/davinci_model.h"
  40. #include "graph/node.h"
  41. #include "graph/op_desc.h"
  42. #include "graph/utils/attr_utils.h"
  43. #include "graph/utils/graph_utils.h"
  44. #include "graph/utils/op_desc_utils.h"
  45. #include "graph/utils/tensor_utils.h"
  46. #undef protected
  47. #undef private
  48. using namespace domi;
  49. using namespace ge;
  50. class GlobalModelData {
  51. public:
  52. GlobalModelData() {}
  53. ~GlobalModelData() {
  54. if (data_.model_data != nullptr) {
  55. delete[](uint8_t *) data_.model_data;
  56. data_.model_data = nullptr;
  57. }
  58. }
  59. ge::ModelData data_;
  60. };
  61. static GlobalModelData g_modelData;
  62. class OmeTestOpUtils {
  63. public:
  64. static void InitModel(std::shared_ptr<ge::DavinciModel> davinciModel) { InitModel(*davinciModel); }
  65. static ge::NodePtr GenNodeFromOpDesc(ge::OpDescPtr opDesc) {
  66. if (!opDesc) {
  67. return nullptr;
  68. }
  69. // return std::make_shared<ge::Node>(opDesc, nullptr);
  70. auto g = std::make_shared<ge::ComputeGraph>("g");
  71. return g->AddNode(std::move(opDesc));
  72. }
  73. static void AddInputOutputToTaskModel(std::shared_ptr<ge::Model> model,
  74. std::shared_ptr<domi::ModelTaskDef> modelTaskDef) {
  75. uint32_t stream_num111 = modelTaskDef->stream_num();
  76. uint32_t weights_num = modelTaskDef->weight_size();
  77. uint32_t mem_num = modelTaskDef->memory_size();
  78. int64_t memorySize = 0;
  79. int64_t weightSize = 0;
  80. (void)ge::AttrUtils::GetInt(model.get(), ATTR_MODEL_MEMORY_SIZE, memorySize);
  81. (void)ge::AttrUtils::GetInt(model.get(), ATTR_MODEL_WEIGHT_SIZE, weightSize);
  82. // Save memory_size/weight_size/stream_num/event_num to proto
  83. modelTaskDef->set_memory_size(memorySize);
  84. modelTaskDef->set_weight_size(weightSize);
  85. int64_t stream_num = 0;
  86. (void)ge::AttrUtils::GetInt(model.get(), ATTR_MODEL_STREAM_NUM, stream_num);
  87. modelTaskDef->set_stream_num(stream_num);
  88. ge::ComputeGraphPtr graph = ge::GraphUtils::GetComputeGraph(model->GetGraph());
  89. vector<ConstOpDescPtr> opDescPtrs;
  90. for (auto nodePtr : graph->GetAllNodes()) {
  91. if (nodePtr->GetType() == DATA_TYPE || nodePtr->GetType() == ANN_DATA_TYPE) {
  92. opDescPtrs.push_back(nodePtr->GetOpDesc());
  93. continue;
  94. }
  95. for (auto tensorDesc : nodePtr->GetOpDesc()->GetAllOutputsDescPtr()) {
  96. bool isOutput = false;
  97. ge::TensorUtils::GetOutputTensor(*tensorDesc, isOutput);
  98. if (isOutput) {
  99. // output Op and add to array
  100. opDescPtrs.push_back(nodePtr->GetOpDesc());
  101. break;
  102. }
  103. }
  104. }
  105. // save multi OpDescPtr to attr
  106. ge::ModelSerialize modelS;
  107. for (auto opDescPtr : opDescPtrs) {
  108. ge::Buffer buffer = modelS.SerializeOpDesc(opDescPtr);
  109. modelTaskDef->add_op(string(reinterpret_cast<const char *>(buffer.GetData()), buffer.GetSize()));
  110. }
  111. int64_t runMode = -1;
  112. for (auto nodePtr : graph->GetAllNodes()) {
  113. // TE CUSTOM op need to init
  114. if (ge::AttrUtils::GetInt(nodePtr->GetOpDesc(), ATTR_NAME_IMPLY_TYPE, runMode) &&
  115. runMode != (uint32_t)domi::ImplyType::BUILDIN && runMode != (uint32_t)domi::ImplyType::INVALID) {
  116. (*(modelTaskDef->mutable_attr()))["contain_custom"] = "1";
  117. break;
  118. }
  119. }
  120. }
  121. static void LoadStandardModelDataLocal(ge::ModelData &data) {
  122. static const std::string STANDARD_MODEL_DATA_PATH =
  123. "llt/framework/domi/ut/ome/test/data/standard_partition_model.txt";
  124. ge::proto::ModelDef modelDef;
  125. ReadProtoFromText(STANDARD_MODEL_DATA_PATH.c_str(), &modelDef);
  126. data.model_len = modelDef.ByteSizeLong();
  127. data.model_data = new uint8_t[data.model_len];
  128. modelDef.SerializePartialToArray(data.model_data, data.model_len);
  129. }
  130. static void InitModel(ge::DavinciModel &davinciModel) {
  131. ge::ModelData data;
  132. LoadStandardModelDataLocal(data);
  133. std::shared_ptr<ge::Model> model_ = std::make_shared<ge::Model>();
  134. ge::Model::Load((uint8_t *)data.model_data, data.model_len, *model_);
  135. GeModelPtr ge_model;
  136. ModelHelper::TransModelToGeModel(model_, ge_model);
  137. davinciModel.Assign(ge_model);
  138. if (data.model_data != nullptr) {
  139. delete[](uint8_t *) data.model_data;
  140. }
  141. }
  142. static void InitEmptyModel(ge::DavinciModel &davinciModel) {
  143. auto model = std::make_shared<ge::Model>();
  144. ge::AttrUtils::SetInt(model, ATTR_MODEL_MEMORY_SIZE, 81000000);
  145. ge::AttrUtils::SetInt(model, ATTR_MODEL_WEIGHT_SIZE, 4100000);
  146. ge::AttrUtils::SetInt(model, ATTR_MODEL_STREAM_NUM, 1);
  147. ge::AttrUtils::SetInt(model, ATTR_MODEL_EVENT_NUM, 1);
  148. ge::AttrUtils::SetInt(model, MODEL_ATTR_TASK_GEN_BASE_ADDR, 0x123);
  149. ge::AttrUtils::SetInt(model, MODEL_ATTR_TASK_GEN_WEIGHT_ADDR, 0x456);
  150. ge::AttrUtils::SetInt(model, ATTR_MODEL_BATCH_NUM, 1);
  151. // ge::AttrUtils::SetStr(model, ATTR_MODEL_TARGET_TYPE, "MINI"); // domi::MINI
  152. auto computeGraph = std::make_shared<ge::ComputeGraph>("graph");
  153. ge::GeAttrValue::BYTES buffer(4100000, 0);
  154. ge::AttrUtils::SetBytes(computeGraph, "weights_data", buffer);
  155. auto graph = ge::GraphUtils::CreateGraphFromComputeGraph(computeGraph);
  156. model->SetGraph(graph);
  157. GeModelPtr ge_model;
  158. ModelHelper::TransModelToGeModel(model, ge_model);
  159. davinciModel.Assign(ge_model);
  160. }
  161. static void InitModelWithoutMem(ge::DavinciModel &davinciModel) { InitModel(davinciModel); }
  162. static Status ModelLoadStub(const uint8_t *data, size_t len, ge::Model &model) {
  163. auto computeGraph = std::make_shared<ge::ComputeGraph>("graph");
  164. auto graph = ge::GraphUtils::CreateGraphFromComputeGraph(computeGraph);
  165. model.SetGraph(graph);
  166. return domi::SUCCESS;
  167. }
  168. static void InitDefaultTensorDesc(ge::GeTensorDesc &tensorDesc) {}
  169. static void AddInputDesc(ge::OpDescPtr opDesc, vector<int64_t> shape, ge::Format format, ge::DataType dataType,
  170. int64_t dataSize = 0) {
  171. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  172. InitDefaultTensorDesc(tensorDesc);
  173. ge::TensorUtils::SetSize(tensorDesc, dataSize);
  174. opDesc->AddInputDesc(tensorDesc);
  175. }
  176. static void AddOutputDesc(ge::OpDescPtr opDesc, vector<int64_t> shape, ge::Format format, ge::DataType dataType,
  177. int64_t dataSize = 0) {
  178. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  179. InitDefaultTensorDesc(tensorDesc);
  180. ge::TensorUtils::SetSize(tensorDesc, dataSize);
  181. opDesc->AddOutputDesc(tensorDesc);
  182. }
  183. static void AddWeight(ge::NodePtr nodePtr, uint8_t *data, size_t dataLen, vector<int64_t> shape = {},
  184. ge::Format format = ge::FORMAT_NCHW, ge::DataType dataType = ge::DT_FLOAT) {
  185. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  186. vector<ge::GeTensorPtr> weigths = ge::OpDescUtils::MutableWeights(nodePtr);
  187. weigths.push_back(std::make_shared<ge::GeTensor>(tensorDesc, data, dataLen));
  188. ge::OpDescUtils::SetWeights(nodePtr, weigths);
  189. }
  190. static ge::OpDescPtr CreateOpDesc() {
  191. auto opDesc = std::make_shared<ge::OpDesc>();
  192. return opDesc;
  193. }
  194. };
  195. class OmeTestOpDescBuilder {
  196. public:
  197. OmeTestOpDescBuilder(ge::OpDescPtr orgOpDesc = nullptr) : orgOpDesc_(orgOpDesc) {
  198. if (orgOpDesc_) {
  199. streamId_ = orgOpDesc_->GetStreamId();
  200. }
  201. }
  202. OmeTestOpDescBuilder &SetStreamId(int64_t streamId) {
  203. streamId_ = streamId;
  204. return *this;
  205. }
  206. OmeTestOpDescBuilder &SetWorkspace(vector<int64_t> workspace) {
  207. workspace_ = workspace;
  208. return *this;
  209. }
  210. OmeTestOpDescBuilder &SetWorkspaceBytes(vector<int64_t> workspaceBytes) {
  211. workspaceBytes_ = workspaceBytes;
  212. return *this;
  213. }
  214. OmeTestOpDescBuilder &SetType(const string &type) {
  215. type_ = type;
  216. return *this;
  217. }
  218. OmeTestOpDescBuilder &SetName(const string &name) {
  219. name_ = name;
  220. return *this;
  221. }
  222. OmeTestOpDescBuilder &SetInputs(vector<int64_t> inputs) {
  223. inputsDataOffeset_ = inputs;
  224. return *this;
  225. }
  226. OmeTestOpDescBuilder &AddInput(int64_t input) {
  227. inputsDataOffeset_.push_back(input);
  228. return *this;
  229. }
  230. OmeTestOpDescBuilder &SetOutputs(vector<int64_t> outputs) {
  231. outputsDataOffeset_ = outputs;
  232. return *this;
  233. }
  234. OmeTestOpDescBuilder &AddOutput(int64_t output) {
  235. outputsDataOffeset_.push_back(output);
  236. return *this;
  237. }
  238. OmeTestOpDescBuilder &SetEventId(int64_t eventId) {
  239. eventId_ = eventId;
  240. return *this;
  241. }
  242. OmeTestOpDescBuilder &Setscopeid(int64_t scopeid) {
  243. scopeid_ = scopeid;
  244. return *this;
  245. }
  246. ge::GeTensorDesc &AddInputDesc(vector<int64_t> shape, ge::Format format, ge::DataType dataType,
  247. int64_t dataSize = 0) {
  248. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  249. OmeTestOpUtils::InitDefaultTensorDesc(tensorDesc);
  250. ge::TensorUtils::SetSize(tensorDesc, dataSize);
  251. inputTensorDescs.push_back(tensorDesc);
  252. return inputTensorDescs.back();
  253. }
  254. ge::GeTensorDesc &AddInputDesc(vector<int64_t> shape, ge::Format format, ge::DataType dataType, int64_t realdimcnt,
  255. int64_t dataSize) {
  256. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  257. OmeTestOpUtils::InitDefaultTensorDesc(tensorDesc);
  258. ge::TensorUtils::SetSize(tensorDesc, dataSize);
  259. ge::TensorUtils::SetRealDimCnt(tensorDesc, realdimcnt);
  260. inputTensorDescs.push_back(tensorDesc);
  261. return inputTensorDescs.back();
  262. }
  263. ge::GeTensorDesc &AddOutputDesc(vector<int64_t> shape, ge::Format format, ge::DataType dataType,
  264. int64_t dataSize = 0) {
  265. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  266. OmeTestOpUtils::InitDefaultTensorDesc(tensorDesc);
  267. ge::TensorUtils::SetSize(tensorDesc, dataSize);
  268. outputTensorDescs.push_back(tensorDesc);
  269. return outputTensorDescs.back();
  270. }
  271. ge::GeTensorDesc &AddOutputDesc(vector<int64_t> shape, ge::Format format, ge::DataType dataType, int64_t realdimcnt,
  272. int64_t dataSize) {
  273. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  274. OmeTestOpUtils::InitDefaultTensorDesc(tensorDesc);
  275. ge::TensorUtils::SetSize(tensorDesc, dataSize);
  276. ge::TensorUtils::SetRealDimCnt(tensorDesc, realdimcnt);
  277. outputTensorDescs.push_back(tensorDesc);
  278. return outputTensorDescs.back();
  279. }
  280. ge::GeTensorPtr AddWeight(uint8_t *data, size_t dataLen, vector<int64_t> shape = {},
  281. ge::Format format = ge::FORMAT_NCHW, ge::DataType dataType = ge::DT_FLOAT) {
  282. ge::GeTensorDesc tensorDesc(ge::GeShape(shape), format, dataType);
  283. weights_.emplace_back(std::make_shared<ge::GeTensor>(tensorDesc, data, dataLen));
  284. return weights_.back();
  285. }
  286. ge::NodePtr Finish() {
  287. ge::OpDescPtr opDesc;
  288. if (orgOpDesc_) {
  289. opDesc = orgOpDesc_;
  290. } else {
  291. opDesc = OmeTestOpUtils::CreateOpDesc(); // std::make_shared<ge::OpDesc>(name_, type_);
  292. }
  293. if (!type_.empty()) {
  294. opDesc->SetType(type_);
  295. }
  296. if (!name_.empty()) {
  297. opDesc->SetName(name_);
  298. }
  299. opDesc->SetStreamId(streamId_);
  300. ge::AttrUtils::SetInt(opDesc, "id", 1);
  301. if (eventId_ != -1) {
  302. ge::AttrUtils::SetInt(opDesc, SEND_ATTR_EVENT_ID, eventId_);
  303. }
  304. if (scopeid_ != -1) {
  305. ge::AttrUtils::SetInt(opDesc, "fusion_scope", scopeid_);
  306. }
  307. // ge::AttrUtils::SetInt(opDesc, ATTR_NAME_STREAM_ID, streamId_);
  308. // if(!inputsDataOffeset_.empty())
  309. {
  310. vector<int64_t> inputs;
  311. inputs = opDesc->GetInputOffset();
  312. inputs.insert(inputs.end(), inputsDataOffeset_.begin(), inputsDataOffeset_.end());
  313. opDesc->SetInputOffset(inputs);
  314. }
  315. // if(!outputsDataOffeset_.empty())
  316. {
  317. vector<int64_t> outputs;
  318. outputs = opDesc->GetOutputOffset();
  319. outputs.insert(outputs.end(), outputsDataOffeset_.begin(), outputsDataOffeset_.end());
  320. opDesc->SetOutputOffset(outputs);
  321. }
  322. // if(!workspace_.empty())
  323. {
  324. vector<int64_t> workspace = opDesc->GetWorkspace();
  325. workspace.insert(workspace.end(), workspace_.begin(), workspace_.end());
  326. opDesc->SetWorkspace(workspace);
  327. }
  328. // if(!workspaceBytes_.empty())
  329. {
  330. vector<int64_t> workspaceBytes;
  331. workspaceBytes = opDesc->GetWorkspaceBytes();
  332. workspaceBytes.insert(workspaceBytes.end(), workspaceBytes_.begin(), workspaceBytes_.end());
  333. opDesc->SetWorkspaceBytes(workspaceBytes);
  334. }
  335. for (auto &tensorDesc : inputTensorDescs) {
  336. opDesc->AddInputDesc(tensorDesc);
  337. }
  338. for (auto &tensorDesc : outputTensorDescs) {
  339. opDesc->AddOutputDesc(tensorDesc);
  340. }
  341. static std::shared_ptr<ge::ComputeGraph> graph;
  342. // clear graph
  343. graph = std::make_shared<ge::ComputeGraph>("g");
  344. ge::NodePtr nodeOp = graph->AddNode(opDesc);
  345. // for(int i=0; i < inputTensorDescs.size(); i++)
  346. for (int i = 0; i < opDesc->GetInputsSize(); i++) {
  347. ge::OpDescPtr srcOpDesc = std::make_shared<ge::OpDesc>();
  348. ge::GeTensorDesc srcOutDesc;
  349. srcOpDesc->AddOutputDesc(srcOutDesc);
  350. ge::NodePtr srcNode = graph->AddNode(srcOpDesc);
  351. if (nullptr == srcNode) {
  352. DOMI_LOGE("Finish: nullptr == srcNode");
  353. }
  354. Status res = ge::GraphUtils::AddEdge(srcNode->GetOutDataAnchor(0), nodeOp->GetInDataAnchor(i));
  355. if (domi::SUCCESS != res) {
  356. DOMI_LOGE("Finish: GraphUtils::AddEdge failed");
  357. }
  358. // ge::NodePtr srcNode = node->GetOwnerComputeGraph()->AddNodeFront(srcOpDesc);
  359. // node->AddLinkFrom(srcNode);
  360. }
  361. {
  362. vector<ge::GeTensorPtr> weights;
  363. weights = ge::OpDescUtils::MutableWeights(nodeOp);
  364. weights.insert(weights.end(), weights_.begin(), weights_.end());
  365. ge::OpDescUtils::SetWeights(nodeOp, weights);
  366. }
  367. *this = OmeTestOpDescBuilder(opDesc); // clear up
  368. return nodeOp;
  369. }
  370. private:
  371. ge::OpDescPtr orgOpDesc_;
  372. int64_t streamId_ = 0;
  373. string type_;
  374. string name_;
  375. vector<int64_t> inputsDataOffeset_; // input
  376. vector<int64_t> outputsDataOffeset_; // output
  377. vector<ge::GeTensorDesc> inputTensorDescs;
  378. vector<ge::GeTensorDesc> outputTensorDescs;
  379. vector<int64_t> workspace_;
  380. vector<int64_t> workspaceBytes_;
  381. vector<ge::GeTensorPtr> weights_;
  382. int64_t eventId_ = -1;
  383. int64_t scopeid_ = -1;
  384. // std::shared_ptr<ge::ComputeGraph> graph_;
  385. };
  386. #endif // OME_REBUILD_OME_OP_TEST_UTILS_H

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

Contributors (1)