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.

option_parser.cc 7.7 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 "core/util/option_parser.h"
  17. #include <vector>
  18. #include <string>
  19. #include <cstring>
  20. #include <iostream>
  21. #include <iomanip>
  22. #include "include/infer_log.h"
  23. namespace mindspore {
  24. namespace serving {
  25. bool StartWith(const std::string &str, const std::string &expected) {
  26. return expected.empty() ||
  27. (str.size() >= expected.size() && memcmp(str.data(), expected.data(), expected.size()) == 0);
  28. }
  29. bool RemovePrefix(std::string *const str, const std::string &prefix) {
  30. if (!StartWith(*str, prefix)) return false;
  31. str->replace(str->begin(), str->begin() + prefix.size(), "");
  32. return true;
  33. }
  34. bool Option::ParseInt32(std::string *const arg) {
  35. if (RemovePrefix(arg, "--") && RemovePrefix(arg, name_) && RemovePrefix(arg, "=")) {
  36. int32_t parsed_value;
  37. try {
  38. parsed_value = std::stoi(arg->data());
  39. } catch (std::invalid_argument) {
  40. std::cout << "Parse " << name_ << " Error for option " << *arg << std::endl;
  41. return false;
  42. }
  43. *int32_default_ = parsed_value;
  44. return true;
  45. }
  46. return false;
  47. }
  48. bool Option::ParseBool(std::string *const arg) {
  49. if (RemovePrefix(arg, "--") && RemovePrefix(arg, name_) && RemovePrefix(arg, "=")) {
  50. if (*arg == "true") {
  51. *bool_default_ = true;
  52. } else if (*arg == "false") {
  53. *bool_default_ = false;
  54. } else {
  55. std::cout << "Parse " << name_ << " Error for option " << *arg << std::endl;
  56. return false;
  57. }
  58. return true;
  59. }
  60. return false;
  61. }
  62. bool Option::ParseString(std::string *const arg) {
  63. if (RemovePrefix(arg, "--") && RemovePrefix(arg, name_) && RemovePrefix(arg, "=")) {
  64. *string_default_ = *arg;
  65. return true;
  66. }
  67. return false;
  68. }
  69. bool Option::ParseFloat(std::string *const arg) {
  70. if (RemovePrefix(arg, "--") && RemovePrefix(arg, name_) && RemovePrefix(arg, "=")) {
  71. float parsed_value;
  72. try {
  73. parsed_value = std::stof(arg->data());
  74. } catch (std::invalid_argument) {
  75. std::cout << "Parse " << name_ << " Error for option " << *arg << std::endl;
  76. return false;
  77. }
  78. *float_default_ = parsed_value;
  79. return true;
  80. }
  81. return false;
  82. }
  83. Option::Option(const std::string &name, int32_t *const default_point, const std::string &usage)
  84. : name_(name),
  85. type_(MS_TYPE_INT32),
  86. int32_default_(default_point),
  87. bool_default_(nullptr),
  88. string_default_(nullptr),
  89. float_default_(nullptr),
  90. usage_(usage) {}
  91. Option::Option(const std::string &name, bool *const default_point, const std::string &usage)
  92. : name_(name),
  93. type_(MS_TYPE_BOOL),
  94. int32_default_(nullptr),
  95. bool_default_(default_point),
  96. string_default_(nullptr),
  97. float_default_(nullptr),
  98. usage_(usage) {}
  99. Option::Option(const std::string &name, std::string *const default_point, const std::string &usage)
  100. : name_(name),
  101. type_(MS_TYPE_STRING),
  102. int32_default_(nullptr),
  103. bool_default_(nullptr),
  104. string_default_(default_point),
  105. float_default_(nullptr),
  106. usage_(usage) {}
  107. Option::Option(const std::string &name, float *const default_point, const std::string &usage)
  108. : name_(name),
  109. type_(MS_TYPE_FLOAT),
  110. int32_default_(nullptr),
  111. bool_default_(nullptr),
  112. string_default_(nullptr),
  113. float_default_(default_point),
  114. usage_(usage) {}
  115. bool Option::Parse(std::string *const arg) {
  116. bool result = false;
  117. switch (type_) {
  118. case MS_TYPE_BOOL:
  119. result = ParseBool(arg);
  120. break;
  121. case MS_TYPE_FLOAT:
  122. result = ParseFloat(arg);
  123. break;
  124. case MS_TYPE_INT32:
  125. result = ParseInt32(arg);
  126. break;
  127. case MS_TYPE_STRING:
  128. result = ParseString(arg);
  129. break;
  130. default:
  131. break;
  132. }
  133. return result;
  134. }
  135. std::shared_ptr<Options> Options::inst_ = nullptr;
  136. Options &Options::Instance() {
  137. static Options instance;
  138. return instance;
  139. }
  140. Options::Options() : args_(nullptr) { CreateOptions(); }
  141. void Options::CreateOptions() {
  142. args_ = std::make_shared<Arguments>();
  143. std::vector<Option> options = {
  144. Option("port", &args_->grpc_port,
  145. "[Optional] Port to listen on for gRPC API, default is 5500, range from 1 to 65535"),
  146. Option("rest_api_port", &args_->rest_api_port,
  147. "[Optional] Port to listen on for RESTful API, default is 5501, range from 1 to 65535"),
  148. Option("model_name", &args_->model_name, "[Required] model name "),
  149. Option("model_path", &args_->model_path, "[Required] the path of the model files"),
  150. Option("device_id", &args_->device_id, "[Optional] the device id, default is 0, range from 0 to 7"),
  151. };
  152. options_ = options;
  153. }
  154. bool Options::CheckOptions() {
  155. if (args_->model_name == "" || args_->model_path == "") {
  156. std::cout << "Serving Error: model_path and model_name should not be null" << std::endl;
  157. return false;
  158. }
  159. if (args_->device_type != "Ascend") {
  160. std::cout << "Serving Error: device_type only support Ascend right now" << std::endl;
  161. return false;
  162. }
  163. if (args_->device_id > 7) {
  164. std::cout << "Serving Error: the device_id should be in [0~7]" << std::endl;
  165. return false;
  166. }
  167. if (args_->grpc_port < 1 || args_->grpc_port > 65535) {
  168. std::cout << "Serving Error: the port should be in [1~65535]" << std::endl;
  169. return false;
  170. }
  171. if (args_->rest_api_port < 1 || args_->rest_api_port > 65535) {
  172. std::cout << "Serving Error: the rest_api_port should be in [1~65535]" << std::endl;
  173. return false;
  174. }
  175. if (args_->rest_api_port == args_->grpc_port) {
  176. std::cout << "Serving Error: the rest_api_port and grpc port should not be same" << std::endl;
  177. return false;
  178. }
  179. return true;
  180. }
  181. bool Options::ParseCommandLine(int argc, char **argv) {
  182. if (argc < 2 || (strcmp(argv[1], "--help") == 0)) {
  183. Usage();
  184. return false;
  185. }
  186. std::vector<std::string> unkown_options;
  187. for (int i = 1; i < argc; ++i) {
  188. bool found = false;
  189. for (auto &option : options_) {
  190. std::string arg = argv[i];
  191. if (option.Parse(&arg)) {
  192. found = true;
  193. break;
  194. }
  195. }
  196. if (found == false) {
  197. unkown_options.push_back(argv[i]);
  198. }
  199. }
  200. if (!unkown_options.empty()) {
  201. std::cout << "unkown options:" << std::endl;
  202. for (const auto &option : unkown_options) {
  203. std::cout << option << std::endl;
  204. }
  205. }
  206. bool valid = (unkown_options.empty() && CheckOptions());
  207. if (!valid) {
  208. Usage();
  209. }
  210. return valid;
  211. }
  212. void Options::Usage() {
  213. std::cout << "USAGE: mindspore-serving [options]" << std::endl;
  214. for (const auto &option : options_) {
  215. std::string type;
  216. switch (option.type_) {
  217. case Option::MS_TYPE_BOOL:
  218. type = "bool";
  219. break;
  220. case Option::MS_TYPE_FLOAT:
  221. type = "float";
  222. break;
  223. case Option::MS_TYPE_INT32:
  224. type = "int32";
  225. break;
  226. case Option::MS_TYPE_STRING:
  227. type = "string";
  228. break;
  229. default:
  230. break;
  231. }
  232. std::cout << "--" << std::setw(30) << std::left << option.name_ << std::setw(10) << std::left << type
  233. << option.usage_ << std::endl;
  234. }
  235. }
  236. } // namespace serving
  237. } // namespace mindspore