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.

tbe_utils.cc 8.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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/tbe/tbe_utils.h"
  17. #include <sys/types.h>
  18. #include <dirent.h>
  19. #include <vector>
  20. #include <string>
  21. #include <utility>
  22. #include <map>
  23. #include <functional>
  24. #include <iostream>
  25. #include <fstream>
  26. #include "runtime/kernel.h"
  27. #include "kernel/oplib/oplib.h"
  28. #include "utils/utils.h"
  29. #include "session/anf_runtime_algorithm.h"
  30. #include "common/utils.h"
  31. #include "device/kernel_info.h"
  32. #include "ir/dtype/type.h"
  33. #include "kernel/tbe/tbe_convert_utils.h"
  34. #include "securec/include/securec.h"
  35. #include "operator/ops.h"
  36. namespace mindspore {
  37. namespace kernel {
  38. namespace tbe {
  39. constexpr auto kCceKernelMeta = "./kernel_meta/";
  40. constexpr auto kJsonSuffix = ".json";
  41. constexpr auto kInfoSuffix = ".info";
  42. uintptr_t KernelManager::kernel_stub_gen_ = 0;
  43. std::unordered_map<string, KernelMetaPtr> KernelManager::info_table_ = {};
  44. void TbeUtils::SaveJsonInfo(const std::string &json_name, const std::string &info) {
  45. char real_path[PATH_MAX] = {0};
  46. std::string path = kCceKernelMeta + json_name + kInfoSuffix;
  47. if (path.size() > PATH_MAX) {
  48. MS_LOG(ERROR) << "file path: " << path << "is too long.";
  49. return;
  50. }
  51. std::ifstream fin(path);
  52. if (fin) {
  53. MS_LOG(INFO) << "json file exist, no need to create.";
  54. return;
  55. }
  56. std::ofstream file_write;
  57. file_write.open(path);
  58. if (!file_write.is_open()) {
  59. return;
  60. }
  61. file_write << info << std::endl;
  62. file_write.close();
  63. if (realpath(path.c_str(), real_path) == nullptr) {
  64. MS_LOG(INFO) << "dir: " << path << "does not exit.";
  65. return;
  66. }
  67. MS_LOG(INFO) << "real path is: " << real_path;
  68. if (chmod(real_path, S_IRUSR) == -1) {
  69. MS_LOG(INFO) << "modify file: " << real_path << "to read only fail.";
  70. }
  71. }
  72. void TbeUtils::LoadCache() {
  73. static bool has_load = false;
  74. if (!has_load) {
  75. KernelMeta *bin_map = KernelMeta::GetInstance();
  76. if (bin_map != nullptr && !bin_map->ReadIndex(kCceKernelMeta)) {
  77. MS_LOG(INFO) << "Cache initialize failed[" << kCceKernelMeta << "]";
  78. } else {
  79. MS_LOG(INFO) << "Cache initialize to " << kCceKernelMeta;
  80. }
  81. has_load = true;
  82. }
  83. }
  84. KernelPackPtr TbeUtils::SearchCache(const std::string &kernel_name, const std::string &processor) {
  85. // search cache.
  86. KernelMeta *bin_map = KernelMeta::GetInstance();
  87. if (bin_map == nullptr) {
  88. MS_LOG(INFO) << "kernel cache is invalid.";
  89. return nullptr;
  90. }
  91. return bin_map->GetKernelPack(kernel_name, processor);
  92. }
  93. KernelPackPtr TbeUtils::InsertCache(const std::string &kernel_name, const std::string &processor) {
  94. MS_LOG(INFO) << "kernel name: " << kernel_name << ", processr:" << processor;
  95. if (processor != kProcessorAiCore) {
  96. MS_LOG(EXCEPTION) << "process type should be aicore, actually is: " << processor;
  97. }
  98. return SearchCache(kernel_name, processor);
  99. }
  100. int KernelManager::BinaryRegister(const mindspore::kernel::FlexArray &kernel_buffer, void **module,
  101. const string &magic) {
  102. static std::map<string, uint32_t> magic_maps = {{"RT_DEV_BINARY_MAGIC_ELF", RT_DEV_BINARY_MAGIC_ELF},
  103. {"RT_DEV_BINARY_MAGIC_PLAIN", RT_DEV_BINARY_MAGIC_PLAIN},
  104. {"RT_DEV_BINARY_MAGIC_PLAIN_AICPU", RT_DEV_BINARY_MAGIC_PLAIN_AICPU},
  105. {"RT_DEV_BINARY_MAGIC_ELF_AICPU", RT_DEV_BINARY_MAGIC_ELF_AICPU}};
  106. // object for device register.
  107. rtDevBinary_t dev_bin;
  108. dev_bin.data = kernel_buffer.contents;
  109. auto iter = magic_maps.find(magic);
  110. if (iter == magic_maps.end()) {
  111. MS_LOG(INFO) << "Invalid magic number: " << magic;
  112. return -1;
  113. }
  114. dev_bin.magic = iter->second;
  115. dev_bin.length = kernel_buffer.len;
  116. dev_bin.version = 2;
  117. if (RT_ERROR_NONE != rtDevBinaryRegister(&dev_bin, module)) {
  118. MS_LOG(INFO) << "Call runtime rtDevBinaryRegister error.";
  119. return -1;
  120. }
  121. return 0;
  122. }
  123. uintptr_t KernelManager::GenFuncStub(const mindspore::kernel::KernelPack &kernel_pack, bool force_reload,
  124. uint32_t *block_dim) {
  125. auto kernel = kernel_pack.GetKernel();
  126. if (kernel == nullptr) {
  127. MS_LOG(EXCEPTION) << "Invalid kernel pack, json or kernel is nullptr.";
  128. }
  129. auto kernel_contents = kernel->contents;
  130. if (kernel_contents == nullptr) {
  131. MS_LOG(EXCEPTION) << "Invalid kernel context, json or kernel is nullptr.";
  132. }
  133. auto kernel_json_info = kernel_pack.kernel_json_info();
  134. *block_dim = kernel_json_info.block_dim;
  135. string func_name = kernel_json_info.kernel_name;
  136. string magic = kernel_json_info.magic;
  137. if (!force_reload) {
  138. // use the cached object.
  139. auto iter = info_table_.find(func_name);
  140. if (iter != info_table_.end()) {
  141. auto kernelmeta = iter->second;
  142. *block_dim = kernelmeta->block_dim_;
  143. return kernelmeta->func_stub_;
  144. }
  145. }
  146. void *module = nullptr;
  147. if (BinaryRegister((*kernel_pack.GetKernel()), &module, magic) != 0) {
  148. MS_LOG(INFO) << "Call runtime BinaryRegister error.";
  149. return 0;
  150. }
  151. // to diff different funcs.
  152. uintptr_t func_stub = ++kernel_stub_gen_;
  153. if (RT_ERROR_NONE !=
  154. rtFunctionRegister(module, reinterpret_cast<void *>(func_stub), func_name.c_str(), func_name.c_str(), 0)) {
  155. MS_LOG(INFO) << "Call runtime rtFunctionRegister error.";
  156. return 0;
  157. }
  158. // cache the registered kernelmeta.
  159. info_table_[func_name] = std::make_shared<KernelMetaInfo>(KernelMetaInfo{func_stub, *block_dim});
  160. return func_stub;
  161. }
  162. std::string KernelManager::GetStubFuncName(const KernelPackPtr &kernel_pack) {
  163. MS_EXCEPTION_IF_NULL(kernel_pack);
  164. auto kernel_json_info = kernel_pack->kernel_json_info();
  165. return kernel_json_info.kernel_name;
  166. }
  167. KernelMeta *KernelMeta::GetInstance() {
  168. static KernelMeta inst;
  169. return &inst;
  170. }
  171. bool KernelMeta::ReadIndex(const std::string &bin_dir) {
  172. DIR *dir = opendir(bin_dir.c_str());
  173. if (dir == nullptr) {
  174. auto ret = mkdir(bin_dir.c_str(), S_IRWXG | S_IRWXU);
  175. if (ret != 0) {
  176. MS_LOG(INFO) << "kernel dir: " << bin_dir << "not exist";
  177. return false;
  178. }
  179. dir = opendir(bin_dir.c_str());
  180. }
  181. struct dirent *entry;
  182. while ((entry = readdir(dir)) != nullptr) {
  183. string bin_dir_tmp = bin_dir;
  184. std::string cce_json = entry->d_name;
  185. if (cce_json.length() <= 5) {
  186. continue;
  187. }
  188. std::string suffix = cce_json.substr(cce_json.length() - 5);
  189. if (suffix != kJsonSuffix) {
  190. continue;
  191. }
  192. auto sp = cce_json.rfind('/');
  193. if (sp != std::string::npos) {
  194. continue;
  195. }
  196. sp = cce_json.rfind('.');
  197. if (sp == std::string::npos) {
  198. continue;
  199. }
  200. auto kernel_name = cce_json.substr(0, sp);
  201. (void)bin_dir_tmp.append("/");
  202. (void)bin_dir_tmp.append(cce_json);
  203. kernel_index_map_[kernel_name] = bin_dir_tmp;
  204. }
  205. (void)closedir(dir);
  206. MS_LOG(INFO) << "Cache kernel initialized, kernel size: " << kernel_index_map_.size();
  207. return true;
  208. }
  209. KernelPackPtr KernelMeta::GetKernelPack(const std::string &kernel_name, const std::string &processor) {
  210. KernelPackPtr ret = nullptr;
  211. // 1. pack has been created
  212. auto kernel_pack_iter = kernel_pack_map_.find(kernel_name);
  213. if (kernel_pack_iter != kernel_pack_map_.end()) {
  214. MS_LOG(INFO) << "kernel pack [" << kernel_name << "]has been created.";
  215. ret = kernel_pack_iter->second;
  216. } else {
  217. // 2. kernel file has been create, but pack does not been created.
  218. std::string cce_json = kCceKernelMeta;
  219. (void)cce_json.append(kernel_name).append(kJsonSuffix);
  220. ret = std::make_shared<KernelPack>();
  221. if (!ret->LoadKernelMeta(cce_json, processor)) {
  222. MS_LOG(INFO) << "Read cache json and bin file failed[" << cce_json << "]";
  223. return nullptr;
  224. }
  225. kernel_pack_map_[kernel_name] = ret;
  226. auto iter = kernel_index_map_.find(kernel_name);
  227. if (iter == kernel_index_map_.end()) {
  228. MS_LOG(INFO) << "kernel name [" << kernel_name << "] has been ceated first.";
  229. kernel_index_map_[kernel_name] = cce_json;
  230. }
  231. }
  232. return ret;
  233. }
  234. } // namespace tbe
  235. } // namespace kernel
  236. } // namespace mindspore