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.

kernel_pack.cc 7.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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 <fstream>
  17. #include "mindspore/ccsrc/kernel/kernel.h"
  18. #include "kernel/kernel.h"
  19. #include "kernel/akg/akg_kernel_build.h"
  20. #include "nlohmann/json.hpp"
  21. #include "securec/include/securec.h"
  22. #include "pipeline/parse/python_adapter.h"
  23. #include "utils/log_adapter.h"
  24. #include "utils/convert_utils.h"
  25. namespace mindspore {
  26. namespace kernel {
  27. constexpr auto kUtilsModule = "mindspore._extends.utils";
  28. constexpr auto kCalSha256Func = "cal_sha256";
  29. namespace {
  30. bool CheckHash(const std::string &json_file, const std::string &bin_file, const nlohmann::json &js) {
  31. if (js.find("sha256") == js.end()) {
  32. MS_LOG(ERROR) << "No sha256 found in " << json_file;
  33. return false;
  34. }
  35. std::string sha256_str = js["sha256"];
  36. py::object ret = parse::python_adapter::CallPyFn(kUtilsModule, kCalSha256Func, bin_file);
  37. std::string sha256_cal = py::cast<std::string>(ret);
  38. if (sha256_cal.empty()) {
  39. MS_LOG(ERROR) << "Cal sha256 of " << bin_file << " failed.";
  40. return false;
  41. }
  42. if (sha256_cal != sha256_str) {
  43. MS_LOG(ERROR) << "Cal sha256 of " << bin_file << " failed.";
  44. return false;
  45. }
  46. return true;
  47. }
  48. } // namespace
  49. const std::string KernelPack::Serialize() const {
  50. MS_EXCEPTION_IF_NULL(json_);
  51. MS_EXCEPTION_IF_NULL(kernel_);
  52. std::string buffer;
  53. (void)buffer.append((const char *)json_, json_->len + sizeof(json_->len));
  54. (void)buffer.append((const char *)kernel_, kernel_->len + sizeof(kernel_->len));
  55. return buffer;
  56. }
  57. bool KernelPack::ReadFromJsonFileHelper(std::ifstream &kernelbin) {
  58. size_t binsize = LongToSize(kernelbin.seekg(0, std::ios::end).tellg());
  59. // free old data
  60. if (kernel_ != nullptr) {
  61. delete[] kernel_;
  62. kernel_ = nullptr;
  63. }
  64. void *ptr = static_cast<void *>(new (std::nothrow) uint8_t[sizeof(KernelPack) + binsize]);
  65. if (ptr != nullptr) {
  66. kernel_ = static_cast<FlexArray *>(ptr);
  67. }
  68. if (kernel_ == nullptr) {
  69. MS_LOG(ERROR) << "memory malloc failed.";
  70. kernelbin.close();
  71. return false;
  72. }
  73. if (memset_s(kernel_, sizeof(KernelPack) + binsize, 0, sizeof(KernelPack) + binsize) != EOK) {
  74. MS_LOG(ERROR) << "memset kernel_ failed.";
  75. delete[] kernel_;
  76. kernel_ = nullptr;
  77. kernelbin.close();
  78. return false;
  79. }
  80. kernel_->len = binsize;
  81. MS_LOG(INFO) << "kernel len:" << kernel_->len;
  82. (void)kernelbin.seekg(0, std::ios::beg);
  83. (void)kernelbin.read(kernel_->contents, SizeToLong(kernel_->len));
  84. return true;
  85. }
  86. bool KernelPack::ReadFromJsonFile(const std::string &json_f, const std::string &processor) {
  87. if (json_f.length() <= strlen(kJsonSuffix)) {
  88. MS_LOG(ERROR) << "please check json path.";
  89. return false;
  90. }
  91. std::ifstream kerneljson(json_f);
  92. if (!kerneljson.is_open()) {
  93. MS_LOG(DEBUG) << "read json file error, please check kernelmeta.";
  94. return false;
  95. }
  96. nlohmann::json js;
  97. kerneljson >> js;
  98. size_t binsize = LongToSize(kerneljson.seekg(0, std::ios::end).tellg());
  99. void *ptr = static_cast<void *>(new (std::nothrow) uint8_t[sizeof(KernelPack) + binsize]);
  100. if (ptr != nullptr) {
  101. json_ = static_cast<FlexArray *>(ptr);
  102. }
  103. if (json_ == nullptr) {
  104. MS_LOG(ERROR) << "memory malloc failed.";
  105. kerneljson.close();
  106. return false;
  107. }
  108. json_->len = binsize;
  109. (void)kerneljson.seekg(0, std::ios::beg);
  110. (void)kerneljson.read(json_->contents, SizeToLong(json_->len));
  111. if (processor == kProcessorCuda) {
  112. std::string bin_f = json_f.substr(0, json_f.length() - 5) + ".ptx";
  113. std::ifstream kernelbin(bin_f);
  114. if (!kernelbin.is_open()) {
  115. MS_LOG(ERROR) << "read kernel ptx file error, please check kernelmeta.";
  116. kerneljson.close();
  117. return false;
  118. }
  119. if (ReadFromJsonFileHelper(kernelbin) == false) {
  120. delete[] json_;
  121. json_ = nullptr;
  122. kerneljson.close();
  123. return false;
  124. }
  125. kerneljson.close();
  126. if (!CheckHash(json_f, bin_f, js)) {
  127. return false;
  128. }
  129. return true;
  130. }
  131. std::string binfilesuffix = js["binFileSuffix"];
  132. std::string bin_f = json_f.substr(0, json_f.length() - 5) + binfilesuffix;
  133. if (binfilesuffix.compare(".so") == 0) {
  134. // change "xx/xx.so" -> "xx/libxx.so"
  135. auto sp = bin_f.rfind('/');
  136. if (sp == std::string::npos) {
  137. MS_LOG(ERROR) << "illegal bin file path " << bin_f;
  138. kerneljson.close();
  139. return false;
  140. }
  141. bin_f = bin_f.substr(0, sp + 1) + "lib" + bin_f.substr(sp + 1, bin_f.length() - sp - 1);
  142. }
  143. std::ifstream kernelbin(bin_f, std::ios::binary);
  144. if (!kernelbin.is_open()) {
  145. MS_LOG(ERROR) << "read kernel binary file error, please check kernelmeta.";
  146. kerneljson.close();
  147. delete[] json_;
  148. json_ = nullptr;
  149. return false;
  150. }
  151. MS_LOG(INFO) << "kernelbin_name:" << bin_f;
  152. if (ReadFromJsonFileHelper(kernelbin) == false) {
  153. delete[] json_;
  154. json_ = nullptr;
  155. kerneljson.close();
  156. return false;
  157. }
  158. kerneljson.close();
  159. if (!CheckHash(json_f, bin_f, js)) {
  160. return false;
  161. }
  162. return true;
  163. }
  164. void KernelPack::ParseKernelJson(const nlohmann::json &js) {
  165. kernel_json_info_.bin_file_name = js["binFileName"];
  166. kernel_json_info_.bin_file_suffix = js["binFileSuffix"];
  167. kernel_json_info_.block_dim = js["blockDim"];
  168. kernel_json_info_.kernel_name = js["kernelName"];
  169. kernel_json_info_.magic = js["magic"];
  170. if (js.find("parameters") != js.end()) {
  171. if (!js.at("parameters").is_array()) {
  172. MS_LOG(DEBUG) << "Format error!,parameters should be array.";
  173. }
  174. std::vector<size_t> sizes = js.at("parameters");
  175. for (auto size : sizes) {
  176. MS_LOG(INFO) << "parameter " << size;
  177. kernel_json_info_.parameters.push_back(size);
  178. }
  179. }
  180. if (js.find("workspace") != js.end()) {
  181. auto workspace = js.at("workspace");
  182. std::vector<size_t> sizes = workspace.at("size");
  183. for (auto size : sizes) {
  184. MS_LOG(INFO) << "workspace_size_list " << size;
  185. kernel_json_info_.workspaces.push_back(size);
  186. }
  187. }
  188. kernel_json_info_.sha256 = js["sha256"];
  189. }
  190. bool KernelPack::LoadKernelMeta(const std::string &json_f, const std::string &processor) {
  191. if (json_f.length() <= strlen(kJsonSuffix)) {
  192. MS_LOG(ERROR) << "please check json path.";
  193. return false;
  194. }
  195. std::ifstream kernel_json(json_f);
  196. if (!kernel_json.is_open()) {
  197. MS_LOG(DEBUG) << "read json file error, please check kernelmeta.";
  198. return false;
  199. }
  200. nlohmann::json js;
  201. kernel_json >> js;
  202. ParseKernelJson(js);
  203. kernel_json.close();
  204. std::string bin_f = json_f.substr(0, json_f.length() - 5) + kernel_json_info_.bin_file_suffix;
  205. if (kernel_json_info_.bin_file_suffix == ".so") {
  206. // change "xx/xx.so" -> "xx/libxx.so"
  207. auto sp = bin_f.rfind('/');
  208. if (sp == std::string::npos) {
  209. MS_LOG(ERROR) << "illegal bin file path " << bin_f;
  210. return false;
  211. }
  212. bin_f = bin_f.substr(0, sp + 1) + "lib" + bin_f.substr(sp + 1, bin_f.length() - sp - 1);
  213. }
  214. std::ifstream kernelbin(bin_f, std::ios::binary);
  215. if (!kernelbin.is_open()) {
  216. MS_LOG(ERROR) << "read kernel binary file error, please check kernelmeta.";
  217. return false;
  218. }
  219. MS_LOG(INFO) << "kernelbin_name:" << bin_f;
  220. if (!ReadFromJsonFileHelper(kernelbin)) {
  221. return false;
  222. }
  223. return CheckHash(json_f, bin_f, js);
  224. }
  225. KernelJsonInfo KernelPack::kernel_json_info() const { return kernel_json_info_; }
  226. } // namespace kernel
  227. } // namespace mindspore