• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 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 
17 #include "transform/acl_ir/op_api_exec.h"
18 #include <dirent.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #include <iostream>
22 #include <vector>
23 #include <string>
24 
25 namespace mindspore::transform {
26 namespace {
27 using InitHugeMemThreadLocalCast = int (*)(void *, bool);
28 using UnInitHugeMemThreadLocalCast = void (*)(void *, bool);
29 using ReleaseHugeMemCast = void (*)(void *, bool);
30 }  // namespace
31 
32 static std::mutex init_mutex;
33 static bool aclnn_init = false;
34 std::vector<std::pair<void *, std::string>> opapi_lib_handle;
35 
GetInstance()36 OpApiDefaultResource &OpApiDefaultResource::GetInstance() {
37   static OpApiDefaultResource instance;
38   return instance;
39 }
40 
init_mem_func()41 InitHugeMemThreadLocal OpApiDefaultResource::init_mem_func() {
42   if (init_mem_func_ != nullptr) {
43     return init_mem_func_;
44   }
45   auto init_mem_func = GetOpApiFunc("InitHugeMemThreadLocal");
46   if (init_mem_func == nullptr) {
47     MS_LOG(EXCEPTION) << "InitHugeMemThreadLocal not in " << GetOpApiLibName() << ", please check!";
48   }
49   init_mem_func_ = reinterpret_cast<InitHugeMemThreadLocalCast>(init_mem_func);
50   return init_mem_func_;
51 }
52 
uninit_mem_func()53 UnInitHugeMemThreadLocal OpApiDefaultResource::uninit_mem_func() {
54   if (uninit_mem_func_ != nullptr) {
55     return uninit_mem_func_;
56   }
57   auto uninit_mem_func = GetOpApiFunc("UnInitHugeMemThreadLocal");
58   if (uninit_mem_func == nullptr) {
59     MS_LOG(EXCEPTION) << "UnInitHugeMemThreadLocal not in " << GetOpApiLibName() << ", please check!";
60   }
61   uninit_mem_func_ = reinterpret_cast<UnInitHugeMemThreadLocalCast>(uninit_mem_func);
62   return uninit_mem_func_;
63 }
64 
release_mem_func()65 ReleaseHugeMem OpApiDefaultResource::release_mem_func() {
66   if (release_mem_func_ != nullptr) {
67     return release_mem_func_;
68   }
69   auto release_mem_func = GetOpApiFunc("ReleaseHugeMem");
70   if (release_mem_func == nullptr) {
71     MS_LOG(EXCEPTION) << "ReleaseHugeMem not in " << GetOpApiLibName() << ", please check!";
72   }
73   release_mem_func_ = reinterpret_cast<ReleaseHugeMemCast>(release_mem_func);
74   return release_mem_func_;
75 }
76 
UpdateOutputShape(const aclTensor * tensor)77 ShapeVector UpdateOutputShape(const aclTensor *tensor) {
78   MS_EXCEPTION_IF_NULL(tensor);
79   static const auto op_api_func = GetOpApiFunc("aclGetViewShape");
80   if (op_api_func == nullptr) {
81     MS_LOG(EXCEPTION) << "aclGetViewShape not in " << GetOpApiLibName() << ", please check!";
82   }
83   using aclGetViewShapeFunc = int (*)(const aclTensor *tensor, int64_t **view_dims, uint64_t *view_dims_num);
84   auto aclGetViewShape = reinterpret_cast<aclGetViewShapeFunc>(op_api_func);
85   int64_t *view_dims = nullptr;
86   uint64_t view_dim_num = 0;
87   auto ret = aclGetViewShape(tensor, &view_dims, &view_dim_num);
88   if (ret != 0) {
89     MS_LOG(EXCEPTION) << "aclGetViewShape failed!";
90   }
91   ShapeVector output_shape(view_dims, view_dims + view_dim_num);
92   delete view_dims;
93   view_dims = nullptr;
94   return output_shape;
95 }
96 
ParseCustomPriority(std::string file_name)97 std::vector<std::string> ParseCustomPriority(std::string file_name) {
98   std::ifstream file(file_name);
99   std::string line;
100   std::vector<std::string> vendor_names;
101 
102   if (!file.is_open()) {
103     MS_LOG(INFO) << "Could not open the file " << file_name;
104     return vendor_names;
105   }
106 
107   while (std::getline(file, line)) {
108     if (line.empty() || line[0] == ';' || line[0] == '#') {
109       continue;
110     }
111     auto pos = line.find('=');
112     if (pos == std::string::npos) {
113       MS_LOG(ERROR) << "Can not parse file: " << file_name;
114       break;
115     }
116 
117     pos = pos + 1;
118     while (pos < line.size()) {
119       auto new_pos = line.find(',', pos);
120       if (new_pos == std::string::npos) {
121         (void)vendor_names.emplace_back(line.substr(pos));
122         break;
123       }
124       (void)vendor_names.emplace_back(line.substr(pos, new_pos - pos));
125       pos = new_pos + 1;
126     }
127     break;
128   }
129   return vendor_names;
130 }
131 
GetAscendDefaultCustomPath(std::vector<std::string> * cust_paths)132 void GetAscendDefaultCustomPath(std::vector<std::string> *cust_paths) {
133   MS_EXCEPTION_IF_NULL(cust_paths);
134   auto ascend_path = mindspore::transform::GetAscendPath();
135   std::string custom_path = ascend_path + "opp/vendors/";
136   DIR *dir = opendir(custom_path.c_str());
137   if (dir == nullptr) {
138     MS_LOG(INFO) << "There is no custom path [" << custom_path << "] in ascend path [" << ascend_path << "].";
139     return;
140   }
141   std::string config_file = custom_path + "config.ini";
142   auto custom_priority = ParseCustomPriority(config_file);
143 
144   for (auto &item_custom : custom_priority) {
145     std::string custom_opapi = custom_path + item_custom + GetCustOpApiLibName();
146     std::ifstream file(custom_opapi);
147     if (!file.good()) {
148       MS_LOG(WARNING) << "Checking whether the so exists or if permission to access it is available: " << custom_opapi;
149       continue;
150     }
151     cust_paths->emplace_back(custom_opapi);
152     MS_LOG(INFO) << "Add path [" << custom_opapi << " to custom opapi paths.";
153   }
154   closedir(dir);
155 }
156 
LoadOpApiLib()157 void LoadOpApiLib() {
158   auto cust_paths = common::GetEnv("ASCEND_CUSTOM_OPP_PATH");
159   std::vector<std::string> cust_path_vec;
160   if (!cust_paths.empty()) {
161     MS_LOG(DEBUG) << "ASCEND_CUSTOM_OPP_PATH: " << cust_paths;
162     std::regex re{":"};
163     std::vector<std::string> split_path_vec(std::sregex_token_iterator(cust_paths.begin(), cust_paths.end(), re, -1),
164                                             std::sregex_token_iterator());
165     for (const auto &cust_path : split_path_vec) {
166       if (cust_path.empty()) {
167         continue;
168       }
169       auto lib_path = cust_path + GetCustOpApiLibName();
170       auto ret = access(lib_path.c_str(), F_OK);
171       if (ret == 0) {
172         cust_path_vec.push_back(lib_path);
173       }
174     }
175   }
176 
177   GetAscendDefaultCustomPath(&cust_path_vec);
178 
179   for (const auto &cust_lib_path : cust_path_vec) {
180     auto cust_handler = GetOpApiLibHandler(cust_lib_path);
181     if (cust_handler != nullptr) {
182       MS_LOG(DEBUG) << "Load cust open api lib " << cust_lib_path << " success";
183       (void)opapi_lib_handle.emplace_back(std::make_pair(cust_handler, cust_lib_path));
184     }
185   }
186 
187   auto ascend_path = mindspore::transform::GetAscendPath();
188   const std::vector<std::string> depend_libs = {"libdummy_tls.so", "libnnopbase.so"};
189   for (const auto &dep_lib : depend_libs) {
190     (void)GetOpApiLibHandler(ascend_path + "lib64/" + dep_lib);
191   }
192 
193   auto lib_path = ascend_path + GetOpApiLibName();
194   auto handle = GetOpApiLibHandler(lib_path);
195   if (handle != nullptr) {
196     MS_LOG(DEBUG) << "Load open api lib " << lib_path << " success";
197     (void)opapi_lib_handle.emplace_back(std::make_pair(handle, lib_path));
198   }
199   MS_LOG(DEBUG) << "Load all open api lib success";
200 }
201 
AclnnInit()202 void AclnnInit() {
203   std::lock_guard<std::mutex> lock(init_mutex);
204   if (aclnn_init) {
205     return;
206   }
207   static const auto aclnn_init_func = GetOpApiFunc("aclnnInit");
208   if (aclnn_init_func == nullptr) {
209     MS_LOG(EXCEPTION) << "aclnnInit not in " << GetOpApiLibName() << ", please check!";
210   }
211   using aclnnInitFunc = int (*)(const char *);
212   auto aclnnInit = reinterpret_cast<aclnnInitFunc>(aclnn_init_func);
213 
214   auto ret = aclnnInit(nullptr);
215   if (ret != 0) {
216     MS_LOG(EXCEPTION) << "aclnnInit failed!";
217   }
218   aclnn_init = true;
219   MS_LOG(DEBUG) << "aclnn init success!";
220 }
221 
AclnnFinalize()222 void AclnnFinalize() {
223   if (!aclnn_init) {
224     return;
225   }
226   static const auto aclnn_finalize_func = GetOpApiFunc("aclnnFinalize");
227   if (aclnn_finalize_func == nullptr) {
228     MS_LOG(EXCEPTION) << "aclnnFinalize not in " << GetOpApiLibName() << ", please check!";
229   }
230   using aclnnFinalizeFunc = int (*)();
231   auto aclnnFinalize = reinterpret_cast<aclnnFinalizeFunc>(aclnn_finalize_func);
232 
233   auto ret = aclnnFinalize();
234   if (ret != 0) {
235     MS_LOG(EXCEPTION) << "aclnnFinalize failed!";
236   }
237   aclnn_init = false;
238   MS_LOG(DEBUG) << "aclnn finalize success!";
239 }
240 }  // namespace mindspore::transform
241