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.

akgkernelbuild.cc 19 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /**
  2. * Copyright 2019 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 "kernel/akg/akgkernelbuild.h"
  17. #include <Python.h>
  18. #include <sys/types.h>
  19. #include <signal.h>
  20. #include <unistd.h>
  21. #include <dirent.h>
  22. #include <cctype>
  23. #include <cstdint>
  24. #include <memory>
  25. #include <map>
  26. #include <utility>
  27. #include <algorithm>
  28. #include <functional>
  29. #include <sstream>
  30. #include <iterator>
  31. #include <numeric>
  32. #include <unordered_set>
  33. #include "common/utils.h"
  34. #include "utils/convert_utils.h"
  35. #include "utils/any.h"
  36. #include "utils/utils.h"
  37. #include "session/anf_runtime_algorithm.h"
  38. #include "kernel/akg/akg_kernel_attrs_process.h"
  39. namespace mindspore {
  40. namespace kernel {
  41. constexpr int ME_MAX_KERNEL_NAME_LENGTH = 200;
  42. constexpr int32_t ARGS_SIZE = 1;
  43. constexpr auto kCompileWithJsonFunc = "compilewithjson";
  44. // json key
  45. constexpr auto kInputDesc = "input_desc";
  46. constexpr auto kShape = "shape";
  47. constexpr auto kDataType = "data_type";
  48. constexpr auto kOutputDesc = "output_desc";
  49. constexpr auto kName = "name";
  50. constexpr auto kTensorName = "tensor_name";
  51. constexpr auto kValue = "value";
  52. constexpr auto KInpputNames = "input_names";
  53. constexpr auto KInput = "input";
  54. constexpr auto KDtype = "dtype";
  55. int AkgKernelBuild::op_cnt_ = 0;
  56. std::mutex AkgKernelBuild::op_cnt_mtx_;
  57. std::string PyObjectToStr(PyObject *const PyObj) {
  58. char *pChar = nullptr;
  59. std::string str_res;
  60. if (PyObj == nullptr) {
  61. MS_LOG(ERROR) << "Input parameter is nullptr.";
  62. return str_res;
  63. }
  64. PyObject *strArgs = PyObject_Str(PyObj);
  65. if (strArgs != nullptr) {
  66. (void)PyArg_Parse(strArgs, "s", &pChar);
  67. }
  68. if (pChar == nullptr) {
  69. MS_LOG(ERROR) << "pChar is nullptr.";
  70. return str_res;
  71. }
  72. str_res = pChar;
  73. return str_res;
  74. }
  75. std::string AkgKernelBuild::GetProcessor(const AnfNodePtr &anf_node) {
  76. MS_EXCEPTION_IF_NULL(anf_node);
  77. std::string device;
  78. switch (AnfAlgo::GetProcessor(anf_node)) {
  79. case Processor::AICORE:
  80. device = kProcessorAiCore;
  81. break;
  82. case Processor::AICPU:
  83. device = kProcessorAiCpu;
  84. break;
  85. case Processor::CUDA:
  86. device = kProcessorCuda;
  87. break;
  88. default:
  89. MS_LOG(ERROR) << "Unknown processor type.";
  90. break;
  91. }
  92. return device;
  93. }
  94. bool GetIOSize(const nlohmann::json &node_json, std::vector<size_t> *const input_size,
  95. std::vector<size_t> *const output_size) {
  96. if (input_size == nullptr || output_size == nullptr) {
  97. MS_LOG(ERROR) << "input size or output size is nullptr";
  98. return false;
  99. }
  100. input_size->clear();
  101. output_size->clear();
  102. for (size_t i = 0; i < node_json[kInputDesc].size(); i++) {
  103. for (size_t m = 0; m < node_json[kInputDesc][i].size(); m++) {
  104. std::string dtype = node_json[kInputDesc][i][m][kDataType];
  105. size_t nbyte = GetDtypeNbyte(dtype);
  106. size_t size_i = std::accumulate(node_json[kInputDesc][i][m][kShape].begin(),
  107. node_json[kInputDesc][i][m][kShape].end(), nbyte, std::multiplies<size_t>());
  108. input_size->push_back(size_i);
  109. }
  110. }
  111. for (size_t i = 0; i < node_json[kOutputDesc].size(); i++) {
  112. std::string dtype = node_json[kOutputDesc][i][kDataType];
  113. size_t nbyte = GetDtypeNbyte(dtype);
  114. size_t size_i = std::accumulate(node_json[kOutputDesc][i][kShape].begin(), node_json[kOutputDesc][i][kShape].end(),
  115. nbyte, std::multiplies<size_t>());
  116. output_size->push_back(size_i);
  117. }
  118. return true;
  119. }
  120. int AkgKernelBuild::GetOpCntInc() {
  121. op_cnt_mtx_.lock();
  122. int cnt = op_cnt_++;
  123. op_cnt_mtx_.unlock();
  124. return cnt;
  125. }
  126. bool AkgKernelBuild::CreateInputDescJson(const AnfNodePtr &anf_node, nlohmann::json *const inputs_json) {
  127. MS_EXCEPTION_IF_NULL(anf_node);
  128. MS_EXCEPTION_IF_NULL(inputs_json);
  129. // for dynamic input number, dyn_input_sizes has the info of dynamic input num for each input.
  130. std::string op_name = AnfAlgo::GetCNodeName(anf_node);
  131. auto op_info = mindspore::kernel::OpLib::FindOp(op_name, OpImplyType::kAKG);
  132. if (op_info == nullptr) {
  133. MS_LOG(ERROR) << "Apply kernel [" << op_name << "] op_info is nullptr";
  134. return false;
  135. }
  136. std::vector<std::shared_ptr<OpIOInfo>> inputs_ptr = op_info->inputs_ptr();
  137. if (inputs_ptr.empty()) {
  138. MS_LOG(INFO) << "Apply kernel [" << op_name << "] regist info has no input info";
  139. return true;
  140. }
  141. auto op_info_input_num = inputs_ptr.size();
  142. // for dynamic input number, dyn_input_sizes has the info of dynamic input num for each input.
  143. std::vector<int> dyn_input_sizes;
  144. auto primitive = AnfAlgo::GetCNodePrimitive(anf_node);
  145. MS_EXCEPTION_IF_NULL(primitive);
  146. if (primitive->GetAttr(kAttrDynInputSizes) != nullptr) {
  147. dyn_input_sizes = GetValue<const std::vector<int>>(primitive->GetAttr(kAttrDynInputSizes));
  148. }
  149. size_t real_input_index = 0;
  150. std::vector<nlohmann::json> input_list;
  151. for (size_t i = 0; i < op_info_input_num; i++) {
  152. size_t input_tensor_num;
  153. std::shared_ptr<OpIOInfo> input_ptr = inputs_ptr[i];
  154. std::string op_input_name;
  155. if (input_ptr == nullptr) {
  156. MS_LOG(ERROR) << "Apply kernel [" << op_name << "] regist input[" << i << "] is nullptr";
  157. return false;
  158. }
  159. op_input_name = input_ptr->name();
  160. if (dyn_input_sizes.empty()) {
  161. input_tensor_num = 1;
  162. } else {
  163. input_tensor_num = IntToSize(dyn_input_sizes[i]);
  164. }
  165. input_list.clear();
  166. for (size_t input_i = 0; input_i < input_tensor_num; input_i++) {
  167. // dtype : float16
  168. auto type_id = AnfAlgo::GetInputDeviceDataType(anf_node, real_input_index);
  169. TypePtr type_ptr = TypeIdToType(type_id);
  170. MS_EXCEPTION_IF_NULL(type_ptr);
  171. std::string dtype = type_ptr->ToString();
  172. dtype = Dtype2String(dtype);
  173. if (dtype.empty()) {
  174. MS_LOG(ERROR) << "Op [" << op_name << "] input [" << input_i << "] data type is null. ";
  175. return false;
  176. }
  177. nlohmann::json input_desc_json;
  178. input_desc_json[kDataType] = dtype;
  179. input_desc_json[kName] = op_input_name;
  180. input_desc_json[kTensorName] =
  181. op_input_name + "_" + std::to_string(real_input_index) + "_" + std::to_string(input_i);
  182. input_desc_json[kShape] = AnfAlgo::GetInputDeviceShape(anf_node, real_input_index);
  183. input_list.emplace_back(input_desc_json);
  184. }
  185. inputs_json->emplace_back(input_list);
  186. real_input_index++;
  187. }
  188. return true;
  189. }
  190. bool AkgKernelBuild::CreateOutputDescJson(const AnfNodePtr &anf_node, nlohmann::json *const outputs_json) {
  191. MS_EXCEPTION_IF_NULL(anf_node);
  192. MS_EXCEPTION_IF_NULL(outputs_json);
  193. size_t output_tensor_num = AnfAlgo::GetOutputTensorNum(anf_node);
  194. std::string op_name = AnfAlgo::GetCNodeName(anf_node);
  195. auto op_info_ptr = mindspore::kernel::OpLib::FindOp(op_name, OpImplyType::kAKG);
  196. auto outputs = op_info_ptr->outputs_ptr();
  197. for (size_t i = 0; i < output_tensor_num; i++) {
  198. nlohmann::json output_json;
  199. auto type_id = AnfAlgo::GetOutputDeviceDataType(anf_node, i);
  200. TypePtr type_ptr = TypeIdToType(type_id);
  201. MS_EXCEPTION_IF_NULL(type_ptr);
  202. std::string dtype = type_ptr->ToString();
  203. dtype = Dtype2String(dtype);
  204. if (dtype.empty()) {
  205. MS_LOG(ERROR) << "Op [" << op_name << "] output [" << i << "] data type is null. ";
  206. return false;
  207. }
  208. std::string output_name = outputs[i]->name();
  209. output_json[kDataType] = dtype;
  210. output_json[kName] = output_name;
  211. output_json[kTensorName] = output_name + "_" + std::to_string(i);
  212. output_json[kShape] = AnfAlgo::GetOutputDeviceShape(anf_node, i);
  213. outputs_json->push_back(output_json);
  214. }
  215. return true;
  216. }
  217. void GetJson(const AnfNodePtr &anf_node, const std::vector<int> &dyn_input_sizes,
  218. const std::shared_ptr<OpAttr> &op_attr, nlohmann::json *const attr_json, const ValuePtr &attr_value) {
  219. MS_EXCEPTION_IF_NULL(anf_node);
  220. MS_EXCEPTION_IF_NULL(op_attr);
  221. MS_EXCEPTION_IF_NULL(attr_json);
  222. std::string type = op_attr->type();
  223. if (type == "int") {
  224. (*attr_json)[kValue] = GetValue<int>(attr_value);
  225. } else if (type == "str") {
  226. (*attr_json)[kValue] = GetValue<std::string>(attr_value);
  227. } else if (type == "bool") {
  228. (*attr_json)[kValue] = GetValue<bool>(attr_value);
  229. } else if (type == "float") {
  230. (*attr_json)[kValue] = GetValue<float>(attr_value);
  231. } else if (type == "listInt") {
  232. (*attr_json)[kValue] = GetValue<std::vector<int>>(attr_value);
  233. } else if (type == "listStr") {
  234. std::vector<std::string> data_format;
  235. if (op_attr->name() == kArgDataformat) {
  236. size_t tensor_args_num = !dyn_input_sizes.empty() ? dyn_input_sizes.size() : AnfAlgo::GetInputTensorNum(anf_node);
  237. for (size_t format_i = 0; format_i < tensor_args_num; format_i++) {
  238. auto input_format = AnfAlgo::GetInputFormat(anf_node, format_i);
  239. data_format.push_back(input_format);
  240. }
  241. } else {
  242. data_format = GetValue<std::vector<std::string>>(attr_value);
  243. }
  244. (*attr_json)[kValue] = data_format;
  245. } else {
  246. MS_LOG(WARNING) << "attr type:" << type;
  247. }
  248. }
  249. bool AkgKernelBuild::CreateAttrDescJson(const AnfNodePtr &anf_node, const std::string &op_name,
  250. const std::shared_ptr<OpInfo> &op_info, nlohmann::json *const attrs_json) {
  251. MS_EXCEPTION_IF_NULL(anf_node);
  252. MS_EXCEPTION_IF_NULL(attrs_json);
  253. MS_EXCEPTION_IF_NULL(op_info);
  254. std::vector<std::shared_ptr<OpAttr>> attrs = op_info->attrs_ptr();
  255. if (attrs.empty()) {
  256. MS_LOG(INFO) << "Apply kernel [" << op_name << "] op info attrs is empty";
  257. return true;
  258. }
  259. std::vector<std::shared_ptr<OpIOInfo>> inputs = op_info->inputs_ptr();
  260. std::vector<int> dyn_input_sizes;
  261. auto primitive = AnfAlgo::GetCNodePrimitive(anf_node);
  262. MS_EXCEPTION_IF_NULL(primitive);
  263. if (primitive->GetAttr(kAttrDynInputSizes) != nullptr) {
  264. dyn_input_sizes = GetValue<const std::vector<int>>(primitive->GetAttr(kAttrDynInputSizes));
  265. }
  266. if (inputs.empty()) {
  267. MS_LOG(ERROR) << "Apply kernel [" << op_name << "] op info inputs is empty";
  268. return false;
  269. }
  270. // create input name list for atch "x_shape" in att with "x" in primitive.
  271. std::map<size_t, std::string> op_info_shape_name;
  272. for (size_t op_info_input_i = 0; op_info_input_i < inputs.size(); op_info_input_i++) {
  273. std::string input_name = inputs[op_info_input_i]->name();
  274. std::string x_shape_name = input_name + "_shape";
  275. (void)op_info_shape_name.insert(make_pair(op_info_input_i, x_shape_name));
  276. }
  277. for (const auto &op_attr : attrs) {
  278. nlohmann::json attr_json;
  279. ValuePtr attr_value = primitive->GetAttr(op_attr->name());
  280. if (attr_value == nullptr && op_attr->name() != kArgDataformat) {
  281. if (op_attr->param_type() == "required") {
  282. // match "x_shape" in att with "x" in primitive.
  283. std::string attr_name = op_attr->name();
  284. auto find_item = std::find_if(
  285. op_info_shape_name.begin(), op_info_shape_name.end(),
  286. [attr_name](const std::map<size_t, std::string>::value_type item) { return item.second == attr_name; });
  287. if (find_item != op_info_shape_name.end()) {
  288. if (!dyn_input_sizes.empty()) {
  289. if (find_item->first >= dyn_input_sizes.size() - 1) {
  290. MS_LOG(EXCEPTION) << "dyn_input_sizes list index:" << find_item->first
  291. << " is out of range:" << dyn_input_sizes.size() - 1 << ".";
  292. return false;
  293. }
  294. size_t tensor_idx = IntToSize(std::accumulate(&dyn_input_sizes[0], &dyn_input_sizes[find_item->first], 0));
  295. for (int input_i = 0; input_i < dyn_input_sizes[find_item->first]; input_i++) {
  296. attr_json[kValue] = AnfAlgo::GetPrevNodeOutputInferShape(anf_node, tensor_idx);
  297. attr_json[kName] = op_attr->name();
  298. attrs_json->push_back(attr_json);
  299. tensor_idx++;
  300. }
  301. } else {
  302. attr_json[kValue] = AnfAlgo::GetPrevNodeOutputInferShape(anf_node, find_item->first);
  303. attr_json[kName] = op_attr->name();
  304. attrs_json->push_back(attr_json);
  305. }
  306. } else {
  307. MS_LOG(ERROR) << "op [" << op_name << "] should have attr :" << op_attr->name();
  308. return false;
  309. }
  310. }
  311. continue;
  312. }
  313. GetJson(anf_node, dyn_input_sizes, op_attr, &attr_json, attr_value);
  314. attr_json[kName] = op_attr->name();
  315. attrs_json->push_back(attr_json);
  316. }
  317. return true;
  318. }
  319. bool AkgKernelBuild::GenerateSingleKernelJson(const AnfNodePtr &anf_node, const std::string &op_name,
  320. nlohmann::json *const node_json) {
  321. MS_EXCEPTION_IF_NULL(anf_node);
  322. MS_EXCEPTION_IF_NULL(node_json);
  323. int op_cnt = GetOpCntInc();
  324. auto op_info_ptr = mindspore::kernel::OpLib::FindOp(op_name, OpImplyType::kAKG);
  325. MS_EXCEPTION_IF_NULL(op_info_ptr);
  326. // get basic params from currentNodeOpDesc
  327. (*node_json)["platform"] = "AKG";
  328. (*node_json)[kName] = op_name;
  329. (*node_json)["fusion_type"] = AnfAlgo::GetFusionType(anf_node);
  330. (*node_json)["impl_path"] = op_info_ptr->impl_path();
  331. (*node_json)["process"] = AkgKernelBuild::GetProcessor(anf_node);
  332. auto primitive = AnfAlgo::GetCNodePrimitive(anf_node);
  333. MS_EXCEPTION_IF_NULL(primitive);
  334. ValuePtr input_names_v = primitive->GetAttr(KInpputNames);
  335. if (input_names_v == nullptr) {
  336. MS_LOG(ERROR) << "ApplyKernel has no input_names, op[" << op_name << "].";
  337. return false;
  338. }
  339. std::vector<std::string> prim_input_names = GetValue<const std::vector<std::string>>(input_names_v);
  340. std::string inputs_name;
  341. for (const auto &prim_input_name : prim_input_names) {
  342. (void)inputs_name.append("_input_").append(prim_input_name).append("_");
  343. }
  344. // input desc
  345. nlohmann::json inputs_json;
  346. if (!CreateInputDescJson(anf_node, &inputs_json)) {
  347. MS_LOG(ERROR) << "Create input desc json failed, op[" << op_name << "].";
  348. return false;
  349. }
  350. (*node_json)[kInputDesc] = inputs_json;
  351. MS_LOG(INFO) << "Akg create input desc json success.";
  352. std::string inputs_shape = "inputs_shape_";
  353. for (auto &i : inputs_json) {
  354. for (auto &m : i) {
  355. std::string data_type = m[kDataType];
  356. (void)inputs_shape.append("_").append(data_type).append("_");
  357. for (auto &j : m[kShape]) {
  358. size_t n = j;
  359. (void)inputs_shape.append(std::to_string(n)).append("_");
  360. }
  361. }
  362. }
  363. // output desc
  364. nlohmann::json outputs_json;
  365. if (!CreateOutputDescJson(anf_node, &outputs_json)) {
  366. MS_LOG(ERROR) << "Create output desc json failed, op[" << op_name << "].";
  367. return false;
  368. }
  369. (*node_json)[kOutputDesc] = outputs_json;
  370. MS_LOG(INFO) << "Akg create output desc json success.";
  371. std::string outputs_shape = "outputs_shape_";
  372. for (auto &i : outputs_json) {
  373. std::string data_type = i[kDataType];
  374. (void)outputs_shape.append("_").append(data_type).append("_");
  375. for (auto &j : i[kShape]) {
  376. size_t m = j;
  377. (void)outputs_shape.append(std::to_string(m)).append("_");
  378. }
  379. }
  380. // attribute desc
  381. nlohmann::json attrs_json;
  382. if (!CreateAttrDescJson(anf_node, op_name, op_info_ptr, &attrs_json)) {
  383. MS_LOG(ERROR) << "Create attr desc json failed, op[" << op_name << "].";
  384. return false;
  385. }
  386. (*node_json)["attr"] = attrs_json;
  387. std::string json_str = node_json->dump();
  388. size_t hash_id = std::hash<std::string>()(json_str);
  389. json_name_ = op_name + "_";
  390. (void)json_name_.append(std::to_string(hash_id));
  391. MS_LOG(INFO) << "full scope name is : " << anf_node->fullname_with_scope() << ", json info name is : " << json_name_;
  392. json_info_ = json_str;
  393. (*node_json)["id"] = op_cnt;
  394. (*node_json)["op"] = json_name_;
  395. MS_LOG(INFO) << "Akg create node desc json success.";
  396. return true;
  397. }
  398. KernelPackPtr AkgKernelBuild::OpBuild(const std::string &node_json, const AnfNodePtr &anf_node) {
  399. MS_EXCEPTION_IF_NULL(anf_node);
  400. auto processor = AkgKernelBuild::GetProcessor(anf_node);
  401. auto cached_kernel_pack = SearchCache(json_name_, processor);
  402. if (cached_kernel_pack != nullptr) {
  403. MS_LOG(INFO) << "Use cached kernel, json_name_[" << json_name_ << "], fullname_with_scope["
  404. << anf_node->fullname_with_scope() << "].";
  405. return cached_kernel_pack;
  406. }
  407. PyObject *pModule = nullptr;
  408. PyObject *pFunc = nullptr;
  409. PyObject *pArg = nullptr;
  410. PyObject *pRes = nullptr;
  411. pModule = PyImport_ImportModule(kAkgModule);
  412. if (pModule == nullptr) {
  413. MS_LOG(ERROR) << "Failed to import [" << kAkgModule << "].";
  414. return nullptr;
  415. }
  416. pFunc = PyObject_GetAttrString(pModule, kCompileWithJsonFunc);
  417. pArg = PyTuple_New(ARGS_SIZE);
  418. (void)PyTuple_SetItem(pArg, 0, Py_BuildValue("s", node_json.c_str()));
  419. (void)alarm(AUTODIFF_COMPILE_OVERTIME);
  420. pRes = PyEval_CallObject(pFunc, pArg);
  421. (void)alarm(0);
  422. if (pRes == nullptr) {
  423. MS_LOG(ERROR) << "No ret got, failed to call function [" << kCompileWithJsonFunc << "], args:\n("
  424. << PyObjectToStr(pArg) << ").";
  425. return nullptr;
  426. }
  427. if (PyObject_IsTrue(pRes) != 1) {
  428. MS_LOG(ERROR) << "Illegal ret, failed to call function [" << kCompileWithJsonFunc << "], args:\n("
  429. << PyObjectToStr(pArg) << ").";
  430. return nullptr;
  431. }
  432. auto new_kernel_pack = InsertCache(json_name_, processor);
  433. kernel::SaveJsonInfo(json_name_, json_info_);
  434. if (new_kernel_pack == nullptr) {
  435. MS_LOG(ERROR) << "Insert to cache failed, json_name_[" << json_name_ << "], fullname_with_scope["
  436. << anf_node->fullname_with_scope() << "].";
  437. return nullptr;
  438. }
  439. return new_kernel_pack;
  440. }
  441. KernelPackPtr AkgKernelBuild::BuildByJson(const AnfNodePtr &anf_node, std::vector<size_t> *const input_size,
  442. std::vector<size_t> *const output_size) {
  443. MS_EXCEPTION_IF_NULL(anf_node);
  444. std::string op_name = AnfAlgo::GetCNodeName(anf_node);
  445. auto it = kAkgKernelAttrsProcessMap.find(op_name);
  446. if (it != kAkgKernelAttrsProcessMap.end()) {
  447. it->second(anf_node);
  448. }
  449. MS_LOG(INFO) << "Akg start compile, op[" << op_name << "], device[" << AkgKernelBuild::GetProcessor(anf_node) << "]";
  450. nlohmann::json node_json;
  451. if (!GenerateSingleKernelJson(anf_node, op_name, &node_json)) {
  452. MS_LOG(ERROR) << "Op[" << op_name << "] create single kernel json failed.";
  453. }
  454. std::string json_str = node_json.dump();
  455. auto kernel_pack = OpBuild(json_str, anf_node);
  456. if (kernel_pack == nullptr) {
  457. MS_LOG(ERROR) << "Akg build failed op[" << op_name << "], json:" << json_str;
  458. return nullptr;
  459. }
  460. if (!GetIOSize(node_json, input_size, output_size)) {
  461. MS_LOG(ERROR) << "Cal mem size failed.";
  462. return nullptr;
  463. }
  464. MS_LOG(INFO) << "Akg compile success, op[" << op_name << "], device[" << AkgKernelBuild::GetProcessor(anf_node)
  465. << "]";
  466. return kernel_pack;
  467. }
  468. } // namespace kernel
  469. } // namespace mindspore