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_plugin_manager.cc 8.3 kB

5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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 "common/ge/tbe_plugin_manager.h"
  17. #include <dirent.h>
  18. #include <unistd.h>
  19. #include <algorithm>
  20. #include <cstring>
  21. #include <fstream>
  22. #include <iostream>
  23. #include <map>
  24. #include <memory>
  25. #include <string>
  26. #include "common/ge/ge_util.h"
  27. #include "framework/common/debug/log.h"
  28. #include "framework/common/debug/ge_log.h"
  29. #include "framework/common/util.h"
  30. #include "framework/common/ge_inner_error_codes.h"
  31. #include "framework/engine/dnnengine.h"
  32. #include "framework/omg/omg_inner_types.h"
  33. #include "external/ge/ge_api_types.h"
  34. #include "register/op_registry.h"
  35. #include "graph/opsproto_manager.h"
  36. #include "graph/utils/type_utils.h"
  37. namespace ge {
  38. std::map<string, string> TBEPluginManager::options_ = {};
  39. // Get Singleton Instance
  40. FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY TBEPluginManager &TBEPluginManager::Instance() {
  41. static TBEPluginManager instance_ptr_;
  42. return instance_ptr_;
  43. }
  44. Status TBEPluginManager::ClearHandles_() {
  45. Status ret = SUCCESS;
  46. for (const auto &handle : handles_vec_) {
  47. if (dlclose(handle) != 0) {
  48. ret = FAILED;
  49. GELOGW("Failed to close handle: %s", dlerror());
  50. }
  51. }
  52. handles_vec_.clear();
  53. return ret;
  54. }
  55. FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY Status TBEPluginManager::Finalize() {
  56. Status ret = ClearHandles_();
  57. return ret;
  58. }
  59. string TBEPluginManager::GetPath() {
  60. Dl_info dl_info;
  61. if (dladdr(reinterpret_cast<void *>(&TBEPluginManager::GetPath), &dl_info) == 0) {
  62. GELOGW("Failed to read so path!");
  63. return string();
  64. } else {
  65. string so_path = dl_info.dli_fname;
  66. char path[PATH_MAX] = {0};
  67. if (so_path.length() >= PATH_MAX) {
  68. GELOGW("File path is too long!");
  69. return string();
  70. }
  71. if (realpath(so_path.c_str(), path) == nullptr) {
  72. GELOGW("Failed to get realpath of %s", so_path.c_str());
  73. return string();
  74. }
  75. so_path = path;
  76. so_path = so_path.substr(0, so_path.rfind('/') + 1);
  77. return so_path;
  78. }
  79. }
  80. void TBEPluginManager::ProcessSoFullName(vector<string> &file_list, string &caffe_parser_path, string &full_name,
  81. const string &caffe_parser_so_suff, const string &aicpu_so_suff,
  82. const string &aicpu_host_so_suff) {
  83. if (full_name.size() >= caffe_parser_so_suff.size() &&
  84. full_name.compare(full_name.size() - caffe_parser_so_suff.size(), caffe_parser_so_suff.size(),
  85. caffe_parser_so_suff) == 0) {
  86. caffe_parser_path = full_name;
  87. } else {
  88. // Save parser so path into file_list vector
  89. file_list.push_back(full_name);
  90. }
  91. }
  92. void TBEPluginManager::FindParserSo(const string &path, vector<string> &file_list, string &caffe_parser_path) {
  93. // Path, change to absolute path
  94. string real_path = RealPath(path.c_str());
  95. // Plugin path does not exist
  96. if (real_path.empty()) {
  97. GELOGW("RealPath is empty.");
  98. return;
  99. }
  100. struct stat stat_buf;
  101. if ((stat(real_path.c_str(), &stat_buf) != 0) || (!S_ISDIR(stat_buf.st_mode))) {
  102. GELOGW("%s is not a dir.", real_path.c_str());
  103. return;
  104. }
  105. struct dirent *dent(0);
  106. DIR *dir = opendir(real_path.c_str());
  107. // Plugin path does not exist
  108. if (dir == nullptr) {
  109. GELOGW("Open directory %s failed.", real_path.c_str());
  110. return;
  111. }
  112. while ((dent = readdir(dir)) != nullptr) {
  113. if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue;
  114. string name = dent->d_name;
  115. string full_name = real_path + "/" + name;
  116. const string so_suff = ".so";
  117. const string caffe_parser_so_suff = "lib_caffe_parser.so";
  118. const string aicpu_so_suff = "_aicpu.so";
  119. const string aicpu_host_so_suff = "_online.so";
  120. if (name.size() >= so_suff.size() && name.compare(name.size() - so_suff.size(), so_suff.size(), so_suff) == 0) {
  121. ProcessSoFullName(file_list, caffe_parser_path, full_name, caffe_parser_so_suff, aicpu_so_suff,
  122. aicpu_host_so_suff);
  123. } else {
  124. FindParserSo(full_name, file_list, caffe_parser_path);
  125. }
  126. }
  127. closedir(dir);
  128. }
  129. void TBEPluginManager::GetPluginSoFileList(const string &path, vector<string> &file_list, string &caffe_parser_path) {
  130. // Support to split multiple so directories by ":"
  131. vector<string> v_path = StringUtils::Split(path, ':');
  132. for (size_t i = 0; i < v_path.size(); ++i) {
  133. FindParserSo(v_path[i], file_list, caffe_parser_path);
  134. GELOGI("CustomOpLib full name = %s", v_path[i].c_str());
  135. }
  136. }
  137. void TBEPluginManager::GetCustomOpPath(std::string &customop_path) {
  138. GELOGI("Enter get custom op path schedule");
  139. std::string fmk_type;
  140. domi::FrameworkType type = domi::TENSORFLOW;
  141. auto it = options_.find(FRAMEWORK_TYPE);
  142. if (it != options_.end()) {
  143. type = static_cast<domi::FrameworkType>(std::strtol(it->second.c_str(), nullptr, 10));
  144. }
  145. fmk_type = ge::TypeUtils::FmkTypeToSerialString(type);
  146. GELOGI("Framework type is %s.", fmk_type.c_str());
  147. const char *path_env = std::getenv("ASCEND_OPP_PATH");
  148. if (path_env != nullptr) {
  149. std::string path = path_env;
  150. customop_path = (path + "/framework/custom" + "/:") + (path + "/framework/built-in/" + fmk_type);
  151. GELOGI("Get custom so path from env : %s", path_env);
  152. return;
  153. }
  154. std::string path_base = GetPath();
  155. GELOGI("path_base is %s", path_base.c_str());
  156. path_base = path_base.substr(0, path_base.rfind('/'));
  157. path_base = path_base.substr(0, path_base.rfind('/') + 1);
  158. customop_path = (path_base + "ops/framework/custom" + "/:") + (path_base + "ops/framework/built-in/" + fmk_type);
  159. return;
  160. }
  161. void TBEPluginManager::LoadCustomOpLib() {
  162. LoadPluginSo(options_);
  163. std::vector<OpRegistrationData> registration_datas = domi::OpRegistry::Instance()->registrationDatas;
  164. GELOGI("The size of registration_datas is: %zu", registration_datas.size());
  165. for (OpRegistrationData reg_data : registration_datas) {
  166. GELOGD("Begin to register optype: %s, imply_type: %s", reg_data.GetOmOptype().c_str(),
  167. TypeUtils::ImplyTypeToSerialString(reg_data.GetImplyType()).c_str());
  168. domi::OpRegistry::Instance()->Register(reg_data);
  169. }
  170. }
  171. FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY
  172. void TBEPluginManager::LoadPluginSo(const std::map<string, string> &options) {
  173. vector<string> file_list;
  174. string caffe_parser_path;
  175. std::string plugin_path;
  176. options_ = options;
  177. GetCustomOpPath(plugin_path);
  178. // Whether there are files in the plugin so path
  179. GetPluginSoFileList(plugin_path, file_list, caffe_parser_path);
  180. // No file
  181. if (file_list.empty()) {
  182. // Print log
  183. GELOGW("Can not find any plugin file in plugin_path: %s", plugin_path.c_str());
  184. }
  185. GELOGW("The shared library will not be checked. Please ensure that the source of the shared library is trusted.");
  186. // Load other so files except lib_caffe_parser.so in the plugin so path
  187. for (auto elem : file_list) {
  188. StringUtils::Trim(elem);
  189. void *handle = dlopen(elem.c_str(), RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
  190. if (handle == nullptr) {
  191. GELOGW("dlopen failed, plugin name:%s. Message(%s).", elem.c_str(), dlerror());
  192. } else if (find(handles_vec_.begin(), handles_vec_.end(), handle) == handles_vec_.end()) {
  193. // Close dl when the program exist, not close here
  194. GELOGI("Plugin load %s success.", elem.c_str());
  195. handles_vec_.push_back(handle);
  196. } else {
  197. GELOGI("Plugin so has already been loaded, no need to load again.");
  198. }
  199. }
  200. }
  201. FMK_FUNC_HOST_VISIBILITY FMK_FUNC_DEV_VISIBILITY
  202. void TBEPluginManager::InitPreparation(const std::map<string, string> &options) {
  203. options_.insert(options.begin(), options.end());
  204. // Load TBE plugin
  205. TBEPluginManager::Instance().LoadCustomOpLib();
  206. }
  207. } // namespace ge

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