• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2019-2023 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 <map>
17 #include <fstream>
18 #include <thread>
19 #include <vector>
20 #include <algorithm>
21 #include "nlohmann/json.hpp"
22 #include "securec/include/securec.h"
23 #include "utils/log_adapter.h"
24 #include "include/common/utils/convert_utils.h"
25 #include "utils/system/sha256.h"
26 #include "kernel/common_utils.h"
27 #include "kernel/framework_utils.h"
28 #include "kernel/kash/kernel_pack.h"
29 
30 namespace mindspore {
31 namespace kernel {
32 constexpr size_t kWorkspaceSize = 32;
33 constexpr size_t kJsonSuffixLength = 5;
34 constexpr char kMagic[] = "magic";
35 constexpr char kBlockDim[] = "blockDim";
36 constexpr char kKernelName[] = "kernelName";
37 constexpr char kBinFileName[] = "binFileName";
38 constexpr char kBinFileSuffix[] = "binFileSuffix";
39 constexpr char kCoreType[] = "core_type";
40 constexpr char kTaskRation[] = "taskRation";
41 constexpr char kWorkspace[] = "workspace";
42 constexpr char kParameters[] = "parameters";
43 constexpr char kOpParaSize[] = "opParaSize";
44 constexpr char kSHA256[] = "sha256";
45 constexpr char kKBHit[] = "KBHit";
46 constexpr char kKernelList[] = "kernelList";
47 constexpr char kBatchBindOnly[] = "batchBindOnly";
48 constexpr char kArgsRemap[] = "args_remap";
49 constexpr char kSize[] = "size";
50 constexpr char kGlobalWorkspaceSpecWorkspace[] = "globalworkspace_spec_workspace";
51 namespace {
CheckHash(const std::string &,const std::string & bin_file,const nlohmann::json & js)52 bool CheckHash(const std::string & /* json_file */, const std::string &bin_file, const nlohmann::json &js) {
53   if (js.find(kSHA256) == js.end()) {
54     return false;
55   }
56   std::string sha256_cal = system::sha256::GetHashFromFile(bin_file);
57   std::string sha256_str = js[kSHA256];
58   if (sha256_cal.empty() || sha256_cal != sha256_str) {
59     MS_LOG(WARNING) << "Check sha256 for [" << bin_file << "] failed, it will try to rebuild the op.";
60     return false;
61   }
62   return true;
63 }
64 const int indent = 4;  // for dump json
65 constexpr uint32_t kInvalidTaskRatio = 0xFFFFFFFFU;
66 constexpr auto kTbeMixCubePrefix = "_mix_aic";
67 constexpr auto kTbeMixVectorPrefix = "_mix_aiv";
68 constexpr auto kCoreTypeMixAIV = "MIX_AIV";
69 constexpr auto kCoreTypeMixAIC = "MIX_AIC";
70 constexpr auto kFloatType = "float";
71 constexpr auto kInitValue = "init_value";
72 constexpr auto kModeInArgsFirstField = "_mode_in_args_first_field";
73 const std::vector<std::string> kBinaryMagicTypes = {
74   "RT_DEV_BINARY_MAGIC_PLAIN",     "RT_DEV_BINARY_MAGIC_PLAIN_AICPU", "RT_DEV_BINARY_MAGIC_PLAIN_AIVEC",
75   "RT_DEV_BINARY_MAGIC_ELF",       "RT_DEV_BINARY_MAGIC_ELF_AICPU",   "RT_DEV_BINARY_MAGIC_ELF_AIVEC",
76   "RT_DEV_BINARY_MAGIC_ELF_AICUBE"};
77 
78 template <typename T>
ParseJsonValue(const std::string & key,const nlohmann::json & json,T * res)79 bool ParseJsonValue(const std::string &key, const nlohmann::json &json, T *res) {
80   MS_EXCEPTION_IF_NULL(res);
81   auto obj_json = json.find(key);
82   if (obj_json != json.end()) {
83     try {
84       *res = obj_json.value();
85       return true;
86     } catch (std::exception &e) {
87       MS_LOG(DEBUG) << "Parse json value failed, detail: " << e.what();
88     }
89   } else {
90     MS_LOG(DEBUG) << "Can not find key [" << key << "] in json file, json info: " << json.dump(indent);
91   }
92   return false;
93 }
94 
LoadJsonFromFile(const std::string & json_file,nlohmann::json * js)95 bool LoadJsonFromFile(const std::string &json_file, nlohmann::json *js) {
96   std::ifstream json_fs(json_file);
97   if (!json_fs.is_open()) {
98     MS_LOG(INFO) << "Open json file: " << json_file << " error, please check kernel_meta.";
99     return false;
100   }
101   try {
102     json_fs >> *js;
103     json_fs.close();
104   } catch (std::exception &e) {
105     MS_LOG(WARNING) << "Parse json file error: " << json_file << ", sleep " << kRetryIntervalMilliSeconds
106                     << "ms and retry again. error ms: " << e.what();
107     json_fs.close();
108     std::this_thread::sleep_for(std::chrono::milliseconds(kRetryIntervalMilliSeconds));
109     std::ifstream retry_tmp(json_file);
110     if (!retry_tmp.is_open()) {
111       MS_LOG(INFO) << "Open json file: " << json_file << " error, please check kernel_meta.";
112       return false;
113     }
114     retry_tmp >> *js;
115     retry_tmp.close();
116   }
117   return true;
118 }
119 }  // namespace
120 
ReadFromJsonFileHelper(std::ifstream & kernel_bin)121 bool KernelPack::ReadFromJsonFileHelper(std::ifstream &kernel_bin) {
122   size_t bin_size = LongToSize(kernel_bin.seekg(0, std::ios::end).tellg());
123   // free old data
124   if (kernel_ != nullptr) {
125     delete[] kernel_;
126     kernel_ = nullptr;
127   }
128 
129   void *ptr = static_cast<void *>(new (std::nothrow) uint8_t[sizeof(KernelPack) + bin_size]);
130   if (ptr != nullptr) {
131     kernel_ = static_cast<FlexArray *>(ptr);
132   }
133   if (kernel_ == nullptr) {
134     MS_LOG(ERROR) << "Memory malloc failed.";
135     kernel_bin.close();
136     return false;
137   }
138   if (memset_s(kernel_, sizeof(KernelPack) + bin_size, 0, sizeof(KernelPack) + bin_size) != EOK) {
139     MS_LOG(ERROR) << "Memset kernel_ failed.";
140     delete[] kernel_;
141     kernel_ = nullptr;
142     kernel_bin.close();
143     return false;
144   }
145   kernel_->len = bin_size;
146   (void)kernel_bin.seekg(0, std::ios::beg);
147   (void)kernel_bin.read(kernel_->contents, SizeToLong(kernel_->len));
148   return true;
149 }
150 
ReadFromJsonFile(const std::string & json_f,const std::string & processor)151 bool KernelPack::ReadFromJsonFile(const std::string &json_f, const std::string &processor) {
152   if (json_f.length() <= strlen(kJsonSuffix)) {
153     MS_LOG(ERROR) << "Please check json path, file name: " << json_f;
154     return false;
155   }
156 
157   nlohmann::json js;
158   if (!LoadJsonFromFile(json_f, &js)) {
159     return false;
160   }
161 
162   std::ifstream kernel_json(json_f);
163   size_t bin_size = LongToSize(kernel_json.seekg(0, std::ios::end).tellg());
164   void *ptr = static_cast<void *>(new (std::nothrow) uint8_t[sizeof(KernelPack) + bin_size]);
165   if (ptr != nullptr) {
166     json_ = static_cast<FlexArray *>(ptr);
167   }
168   if (json_ == nullptr) {
169     MS_LOG(ERROR) << "memory malloc failed.";
170     kernel_json.close();
171     return false;
172   }
173   json_->len = bin_size;
174   (void)kernel_json.seekg(0, std::ios::beg);
175   (void)kernel_json.read(json_->contents, SizeToLong(json_->len));
176 
177   if (processor == kProcessorCpu) {
178     std::string bin_f = json_f.substr(0, json_f.length() - kJsonSuffixLength) + ".so";
179     if (!CheckHash(json_f, bin_f, js)) {
180       return false;
181     }
182     return true;
183   }
184 
185   if (processor == kProcessorCuda) {
186     std::string bin_f = json_f.substr(0, json_f.length() - kJsonSuffixLength) + ".ptx";
187     std::ifstream kernelbin(bin_f);
188     if (!kernelbin.is_open()) {
189       MS_LOG(ERROR) << "read kernel ptx file error, please check kernelmeta.";
190       kernel_json.close();
191       return false;
192     }
193 
194     if (!ReadFromJsonFileHelper(kernelbin)) {
195       delete[] json_;
196       json_ = nullptr;
197       kernel_json.close();
198       return false;
199     }
200     kernel_json.close();
201     if (!CheckHash(json_f, bin_f, js)) {
202       return false;
203     }
204 
205     // cuda json file may have workspace information
206     if (js.find(kWorkspace) != js.end()) {
207       auto workspace = js.at(kWorkspace);
208       std::vector<size_t> sizes = workspace.at(kSize);
209       for (auto size : sizes) {
210         kernel_json_info_.workspaces.push_back(size);
211       }
212     }
213 
214     return true;
215   }
216 
217   std::string binfile_suffix = js[kBinFileSuffix];
218   std::string bin_f = json_f.substr(0, json_f.length() - kJsonSuffixLength) + binfile_suffix;
219   if (binfile_suffix == ".so") {
220     // change "xx/xx.so" -> "xx/libxx.so"
221     auto sp = bin_f.rfind('/');
222     if (sp == std::string::npos) {
223       MS_LOG(ERROR) << "illegal bin file path " << bin_f;
224       kernel_json.close();
225       return false;
226     }
227     bin_f = bin_f.substr(0, sp + 1) + "lib" + bin_f.substr(sp + 1, bin_f.length() - sp - 1);
228   }
229 
230   std::ifstream kernelbin(bin_f, std::ios::binary);
231   if (!kernelbin.is_open()) {
232     MS_LOG(ERROR) << "read kernel binary file error, please check kernelmeta.";
233     kernel_json.close();
234     delete[] json_;
235     json_ = nullptr;
236     return false;
237   }
238 
239   MS_LOG(INFO) << "kernelbin_name:" << bin_f;
240   if (!ReadFromJsonFileHelper(kernelbin)) {
241     delete[] json_;
242     json_ = nullptr;
243     kernel_json.close();
244     return false;
245   }
246   kernel_json.close();
247 
248   if (!CheckHash(json_f, bin_f, js)) {
249     return false;
250   }
251 
252   return true;
253 }
254 
ParseKernelName(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)255 void KernelPack::ParseKernelName(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
256   MS_EXCEPTION_IF_NULL(kernel_json_info);
257   std::string name;
258   if (!ParseJsonValue(key, js, &name)) {
259     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
260   }
261 
262   kernel_json_info->kernel_name = name;
263 }
264 
ParseBinFileName(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)265 void KernelPack::ParseBinFileName(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
266   MS_EXCEPTION_IF_NULL(kernel_json_info);
267   std::string name;
268   if (!ParseJsonValue(key, js, &name)) {
269     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
270   }
271   kernel_json_info->bin_file_name = name;
272 }
273 
ParseBinFileSuffix(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)274 void KernelPack::ParseBinFileSuffix(const std::string &key, const nlohmann::json &js,
275                                     KernelJsonInfo *kernel_json_info) {
276   MS_EXCEPTION_IF_NULL(kernel_json_info);
277   std::string name;
278   if (!ParseJsonValue(key, js, &name)) {
279     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
280   }
281   kernel_json_info->bin_file_suffix = name;
282 }
283 
ParseMagic(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)284 void KernelPack::ParseMagic(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
285   MS_EXCEPTION_IF_NULL(kernel_json_info);
286   std::string magic;
287   if (!ParseJsonValue(key, js, &magic)) {
288     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
289   }
290   if (std::count(kBinaryMagicTypes.begin(), kBinaryMagicTypes.end(), magic) == 0) {
291     MS_LOG(ERROR) << "The value of magic [" << magic << "] is not one of BinaryMagicTypes:" << kBinaryMagicTypes;
292     return;
293   }
294   kernel_json_info->magic = magic;
295 }
296 
ParseBlockDim(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)297 void KernelPack::ParseBlockDim(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
298   MS_EXCEPTION_IF_NULL(kernel_json_info);
299   uint32_t block_dim = 0;
300   if (!ParseJsonValue(key, js, &block_dim)) {
301     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
302   }
303   kernel_json_info->block_dim = block_dim;
304 }
305 
ParseCoreType(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)306 void KernelPack::ParseCoreType(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
307   MS_EXCEPTION_IF_NULL(kernel_json_info);
308   std::string core_type;
309   if (!ParseJsonValue(key, js, &core_type)) {
310     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
311   }
312   kernel_json_info->core_type = core_type;
313 }
314 
ParseTaskRatio(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)315 void KernelPack::ParseTaskRatio(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
316   MS_EXCEPTION_IF_NULL(kernel_json_info);
317   uint32_t ratio = kInvalidTaskRatio;
318   if (!ParseJsonValue(key, js, &ratio)) {
319     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
320   }
321   if (ratio == kInvalidTaskRatio) {
322     MS_LOG(DEBUG) << "Task ratio empty, src json, " << js.dump(indent);
323   }
324   kernel_json_info->task_ration = ratio;
325 }
326 
ParseWorkSpace(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)327 void KernelPack::ParseWorkSpace(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
328   MS_EXCEPTION_IF_NULL(kernel_json_info);
329   if (js.find(key) == js.end()) {
330     return;
331   }
332   try {
333     auto workspace = js.at(key);
334     if (workspace.find("num") == workspace.end() || workspace.find(kSize) == workspace.end()) {
335       MS_LOG(WARNING) << "'num' and 'size' ars necessary in workspace, but not found. " << js.dump(indent);
336       return;
337     }
338     size_t num = workspace.at("num");
339     std::vector<int64_t> sizes = workspace.at(kSize);
340     if (num != sizes.size()) {
341       MS_LOG(WARNING) << "'num' and length of 'size' must be same. " << js.dump(indent);
342       return;
343     }
344     if (workspace.find(kType) != workspace.end()) {
345       std::vector<size_t> type = workspace.at(kType);
346       if (num != type.size()) {
347         MS_LOG(WARNING) << "'num' and length of 'type' must be same. " << js.dump(indent);
348         return;
349       }
350       for (size_t i = 0; i < type.size(); i++) {
351         (void)kernel_json_info->workspaces_type.emplace_back(type[i]);
352       }
353     }
354 
355     for (size_t i = 0; i < sizes.size(); i++) {
356       auto t = sizes[i] < 0 ? kWorkspaceSize : LongToSize(sizes[i]);
357       (void)kernel_json_info->workspaces.emplace_back(t);
358     }
359   } catch (std::exception &e) {
360     MS_LOG(ERROR) << "Parse json value failed, error info: " << e.what();
361   }
362 }
363 
ParseParameters(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)364 void KernelPack::ParseParameters(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
365   MS_EXCEPTION_IF_NULL(kernel_json_info);
366   if (js.find(key) == js.end()) {
367     return;
368   }
369   try {
370     nlohmann::json params = js.at(key);
371     constexpr int kDumpIndex = 4;
372     if (!params.is_array()) {
373       MS_LOG(INFO) << "Parameter should an array, " << params.dump(kDumpIndex);
374       return;
375     }
376     constexpr auto kIntType = "int";
377     for (auto item = params.begin(); item != params.end(); ++item) {
378       nlohmann::json obj = *item;
379       if (obj.is_null()) {
380         (void)kernel_json_info->parameters.emplace_back(0);
381         continue;
382       }
383       if (!obj.is_object()) {
384         auto in_param = params.get<std::vector<int64_t>>();
385         std::vector<size_t> tmp;
386         (void)std::transform(in_param.begin(), in_param.end(), std::back_inserter(tmp),
387                              [](int64_t v) { return LongToSize(v); });
388         kernel_json_info->parameters = tmp;
389         return;
390       }
391       (void)kernel_json_info->parameters.emplace_back(1);
392       auto dtype = obj.at(kDtype).get<std::string>();
393       (void)kernel_json_info->atomic_init_info.dtype_list.emplace_back(dtype);
394       if (dtype.find(kIntType) != std::string::npos) {
395         (void)kernel_json_info->atomic_init_info.init_value_int64_list.emplace_back(obj.at(kInitValue).get<int64_t>());
396       } else if (dtype.find(kFloatType) != std::string::npos) {
397         (void)kernel_json_info->atomic_init_info.init_value_float_list.emplace_back(obj.at(kInitValue).get<float>());
398       } else {
399         MS_LOG(INFO) << "Unsupported dtype: " << dtype;
400         return;
401       }
402     }
403   } catch (std::exception &e) {
404     MS_LOG(INFO) << "Parse json value failed, error info: " << e.what();
405   }
406 }
407 
ParseOpParaSize(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)408 void KernelPack::ParseOpParaSize(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
409   MS_EXCEPTION_IF_NULL(kernel_json_info);
410   kernel_json_info->op_para_size = (js.find(key) == js.end()) ? 0 : static_cast<uint32_t>(js.at(key));
411 }
412 
ParseSHA256(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)413 void KernelPack::ParseSHA256(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
414   MS_EXCEPTION_IF_NULL(kernel_json_info);
415   std::string sha;
416   if (!ParseJsonValue(key, js, &sha)) {
417     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
418   }
419   kernel_json_info->sha256 = sha;
420 }
421 
ParseKBHit(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)422 void KernelPack::ParseKBHit(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
423   MS_EXCEPTION_IF_NULL(kernel_json_info);
424   int32_t KBHit = 0;
425   if (!ParseJsonValue(key, js, &KBHit)) {
426     MS_LOG(DEBUG) << "Get value failed for key: " << key << ". Src json: " << js.dump(indent);
427   }
428   kernel_json_info->KBHit = KBHit;
429 }
430 
ParseModeInArgsFirstField(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)431 void KernelPack::ParseModeInArgsFirstField(const std::string &key, const nlohmann::json &js,
432                                            KernelJsonInfo *kernel_json_info) {
433   MS_EXCEPTION_IF_NULL(kernel_json_info);
434   kernel_json_info->mode_in_args_first_field = (js.find(key) == js.end()) ? 0 : static_cast<uint32_t>(js.at(key));
435 }
436 
ParseBatchBindOnly(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)437 void KernelPack::ParseBatchBindOnly(const std::string &key, const nlohmann::json &js,
438                                     KernelJsonInfo *kernel_json_info) {
439   MS_EXCEPTION_IF_NULL(kernel_json_info);
440   kernel_json_info->batch_bind_only = (js.find(key) == js.end()) ? 0 : static_cast<uint32_t>(js.at(key));
441 }
442 
ParseKernelList(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)443 void KernelPack::ParseKernelList(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
444   MS_EXCEPTION_IF_NULL(kernel_json_info);
445   kernel_json_info->has_kernel_list = (js.find(key) != js.end());
446 }
447 
ParseArgsRemap(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)448 void KernelPack::ParseArgsRemap(const std::string &key, const nlohmann::json &js, KernelJsonInfo *kernel_json_info) {
449   // Parse json["args_remap"], the value is a list of list, e.g. [[0, 1], [2]]
450   MS_EXCEPTION_IF_NULL(kernel_json_info);
451   if (js.find(key) != js.end()) {
452     try {
453       auto args_remap = js.at(key);
454       for (const auto &item : args_remap) {
455         std::vector<size_t> indices;
456         (void)std::copy(item.begin(), item.end(), std::back_inserter(indices));
457         kernel_json_info->args_remap.push_back(indices);
458       }
459     } catch (std::exception &e) {
460       MS_LOG(ERROR) << "Parse json['" << key << "'] failed, error info: " << e.what();
461     }
462   }
463 }
464 
ParseGlogbleWorkSpace(const std::string & key,const nlohmann::json & js,KernelJsonInfo * kernel_json_info)465 void KernelPack::ParseGlogbleWorkSpace(const std::string &key, const nlohmann::json &js,
466                                        KernelJsonInfo *kernel_json_info) {
467   MS_EXCEPTION_IF_NULL(kernel_json_info);
468   if (js.find(key) == js.end()) {
469     return;
470   }
471   try {
472     auto globalWorkspace = js.at(key);
473     if (globalWorkspace.find(kSize) != globalWorkspace.end()) {
474       kernel_json_info->global_workspace.size = globalWorkspace.at(kSize);
475       kernel_json_info->global_workspace.is_overflow = true;
476     }
477     if (globalWorkspace.find(kType) != globalWorkspace.end()) {
478       kernel_json_info->global_workspace.type = globalWorkspace.at(kType);
479       kernel_json_info->global_workspace.is_overflow = true;
480     }
481   } catch (std::exception &e) {
482     MS_LOG(ERROR) << "Parse json value failed, jsong is:" + js.dump() + ", error info: " << e.what();
483   }
484 }
485 
ParseKernelJson(const nlohmann::json & js)486 void KernelPack::ParseKernelJson(const nlohmann::json &js) {
487   using KernelJsonParser = std::function<void(const std::string &, const nlohmann::json &, KernelJsonInfo *)>;
488   const std::map<std::string, KernelJsonParser> kernel_json_map = {
489     {kMagic, ParseMagic},
490     {kBlockDim, ParseBlockDim},
491     {kKernelName, ParseKernelName},
492     {kBinFileName, ParseBinFileName},
493     {kBinFileSuffix, ParseBinFileSuffix},
494     {kCoreType, ParseCoreType},
495     {kTaskRation, ParseTaskRatio},
496     {kWorkspace, ParseWorkSpace},
497     {kParameters, ParseParameters},
498     {kOpParaSize, ParseOpParaSize},
499     {kSHA256, ParseSHA256},
500     {kKBHit, ParseKBHit},
501     {kKernelList, ParseKernelList},
502     {kModeInArgsFirstField, ParseModeInArgsFirstField},
503     {kBatchBindOnly, ParseBatchBindOnly},
504     {kArgsRemap, ParseArgsRemap},
505     {kGlobalWorkspaceSpecWorkspace, ParseGlogbleWorkSpace}};
506   auto iter = kernel_json_map.begin();
507   while (iter != kernel_json_map.end()) {
508     iter->second(iter->first, js, &kernel_json_info_);
509     iter++;
510   }
511 }
512 
LoadKernelMeta(const std::string & json_f)513 bool KernelPack::LoadKernelMeta(const std::string &json_f) {
514   if (json_f.length() <= strlen(kJsonSuffix)) {
515     MS_LOG(ERROR) << "please check json path.";
516     return false;
517   }
518   nlohmann::json js;
519   if (!LoadJsonFromFile(json_f, &js)) {
520     return false;
521   }
522   ParseKernelJson(js);
523 
524   std::string bin_f = json_f.substr(0, json_f.length() - kJsonSuffixLength) + kernel_json_info_.bin_file_suffix;
525   if (kernel_json_info_.bin_file_suffix == ".so") {
526     // change "xx/xx.so" -> "xx/libxx.so"
527     auto sp = bin_f.rfind('/');
528     if (sp == std::string::npos) {
529       MS_LOG(ERROR) << "illegal bin file path " << bin_f;
530       return false;
531     }
532     bin_f = bin_f.substr(0, sp + 1) + "lib" + bin_f.substr(sp + 1, bin_f.length() - sp - 1);
533   }
534 
535   std::ifstream kernelbin(bin_f, std::ios::binary);
536   if (!kernelbin.is_open()) {
537     MS_LOG(ERROR) << "read kernel binary file error, please check kernelmeta.";
538     return false;
539   }
540 
541   if (!ReadFromJsonFileHelper(kernelbin)) {
542     return false;
543   }
544 
545   return CheckHash(json_f, bin_f, js);
546 }
547 
kernel_json_info() const548 KernelJsonInfo KernelPack::kernel_json_info() const { return kernel_json_info_; }
549 }  // namespace kernel
550 }  // namespace mindspore
551