cnstream_config.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*************************************************************************
  2. * Copyright (C) [2019] by Cambricon, Inc. All rights reserved
  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. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  13. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  18. * THE SOFTWARE.
  19. *************************************************************************/
  20. #ifndef CNSTREAM_CONFIG_HPP_
  21. #define CNSTREAM_CONFIG_HPP_
  22. /**
  23. * @file cnstream_config.hpp
  24. *
  25. * This file contains a declaration of the CNModuleConfig class.
  26. */
  27. #include <list>
  28. #include <memory>
  29. #include <set>
  30. #include <string>
  31. #include <unordered_map>
  32. #include <utility>
  33. #include <vector>
  34. #include "cnstream_common.hpp"
  35. namespace cnstream {
  36. /*!
  37. * Defines an alias for std::unordered_map<std::string, std::string>.
  38. * ModuleParamSet now denotes an unordered map which contains the pairs of parameter name and parameter value.
  39. */
  40. using ModuleParamSet = std::unordered_map<std::string, std::string>;
  41. // Group:Framework Function
  42. /**
  43. * @brief Gets the complete path of a file.
  44. *
  45. * If the path you set is an absolute path, returns the absolute path.
  46. * If the path you set is a relative path, retuns the path that appends the relative path
  47. * to the specified JSON file path.
  48. *
  49. * @param[in] path The path relative to the JSON file or an absolute path.
  50. * @param[in] param_set The module parameters. The JSON file path is one of the parameters.
  51. *
  52. * @return Returns the complete path of a file.
  53. */
  54. std::string GetPathRelativeToTheJSONFile(const std::string &path, const ModuleParamSet &param_set);
  55. /**
  56. * @struct CNConfigBase
  57. *
  58. * @brief CNConfigBase is a base structure for configurations.
  59. */
  60. struct CNConfigBase {
  61. std::string config_root_dir = ""; ///< The directory where a configuration file is stored.
  62. /**
  63. * @brief Parses members from a JSON file.
  64. *
  65. * @param[in] jfname JSON configuration file path.
  66. *
  67. * @return Returns true if the JSON file has been parsed successfully. Otherwise, returns false.
  68. */
  69. bool ParseByJSONFile(const std::string &jfname);
  70. /**
  71. * @brief Parses members from JSON string.
  72. *
  73. * @param[in] jstr JSON string of a configuration.
  74. *
  75. * @return Returns true if the JSON string has been parsed successfully. Otherwise, returns false.
  76. */
  77. virtual bool ParseByJSONStr(const std::string &jstr) = 0;
  78. }; // struct CNConfigBase
  79. /**
  80. * @struct ProfilerConfig
  81. *
  82. * @brief ProfilerConfig is a structure for profiler configuration.
  83. *
  84. * The profiler configuration can be a JSON file.
  85. *
  86. * @code {.json}
  87. * {
  88. * "profiler_config" : {
  89. * "enable_profiling" : true,
  90. * "enable_tracing" : true
  91. * }
  92. * }
  93. * @endcode
  94. *
  95. * @note It will not take effect when the profiler configuration is in the subgraph configuration.
  96. **/
  97. struct ProfilerConfig : public CNConfigBase {
  98. bool enable_profiling = false; ///< Whether to enable profiling.
  99. bool enable_tracing = false; ///< Whether to enable tracing.
  100. size_t trace_event_capacity = 100000; ///< The maximum number of cached trace events.
  101. /**
  102. * @brief Parses members from JSON string.
  103. *
  104. * @param[in] jstr JSON configuration string.
  105. *
  106. * @return Returns true if the JSON string has been parsed successfully. Otherwise, returns false.
  107. */
  108. bool ParseByJSONStr(const std::string &jstr) override;
  109. }; // struct ProfilerConfig
  110. /**
  111. * @struct CNModuleConfig
  112. *
  113. * CNModuleConfig is a structure for module configuration.
  114. * The module configuration can be a JSON file.
  115. *
  116. * @code {.json}
  117. * {
  118. * "name": {
  119. * "parallelism": 3,
  120. * "max_input_queue_size": 20,
  121. * "class_name": "cnstream::Inferencer",
  122. * "next_modules": ["module_name/subgraph:subgraph_name",
  123. * "module_name/subgraph:subgraph_name", ...],
  124. * "custom_params" : {
  125. * "param_name" : "param_value",
  126. * "param_name" : "param_value",
  127. * ...
  128. * }
  129. * }
  130. * }
  131. * @endcode
  132. */
  133. struct CNModuleConfig : public CNConfigBase {
  134. std::string name; ///< The name of the module.
  135. std::unordered_map<std::string, std::string>
  136. parameters; ///< The key-value pairs. The pipeline passes this value to the CNModuleConfig::name module.
  137. int parallelism; ///< Module parallelism. It is equal to module thread number or the data queue of input data.
  138. int maxInputQueueSize; ///< The maximum size of the input data queues.
  139. std::string className; ///< The class name of the module.
  140. std::set<std::string> next; ///< The name of the downstream modules/subgraphs.
  141. /**
  142. * @brief Parses members except ``CNModuleConfig::name`` from the JSON file.
  143. *
  144. * @param[in] jstr JSON string of a configuration.
  145. *
  146. * @return Returns true if the JSON string has been parsed successfully. Otherwise, returns false.
  147. */
  148. bool ParseByJSONStr(const std::string &jstr) override;
  149. };
  150. /**
  151. * @struct CNSubgraphConfig
  152. *
  153. * @brief CNSubgraphConfig is a structure for subgraph configuration.
  154. *
  155. * The subgraph configuration can be a JSON file.
  156. *
  157. * @code {.json}
  158. * {
  159. * "subgraphs:name" : {
  160. * "config_path" : "/your/path/to/config_file.json",
  161. * "next_modules": ["module_name/subgraph:subgraph_name",
  162. * "module_name/subgraph:subgraph_name", ...]
  163. * }
  164. * }
  165. * @endcode
  166. */
  167. struct CNSubgraphConfig : public CNConfigBase {
  168. std::string name; ///< The name of the subgraph.
  169. std::string config_path; ///< The path of configuration file.
  170. std::set<std::string> next; ///< The name of the downstream modules/subgraphs.
  171. /**
  172. * @brief Parses members except ``CNSubgraphConfig::name`` from the JSON file.
  173. *
  174. * @param[in] jstr JSON string of a configuration.
  175. *
  176. * @return Returns true if the JSON string has been parsed successfully. Otherwise, returns false.
  177. */
  178. bool ParseByJSONStr(const std::string &jstr) override;
  179. };
  180. /**
  181. * @struct CNGraphConfig
  182. *
  183. * @brief CNGraphConfig is a structure for graph configuration.
  184. *
  185. * You can use ``CNGraphConfig`` to initialize a CNGraph instance.
  186. * The graph configuration can be a JSON file.
  187. *
  188. * @code {.json}
  189. * {
  190. * "profiler_config" : {
  191. * "enable_profiling" : true,
  192. * "enable_tracing" : true
  193. * },
  194. * "module1": {
  195. * "parallelism": 3,
  196. * "max_input_queue_size": 20,
  197. * "class_name": "cnstream::DataSource",
  198. * "next_modules": ["subgraph:subgraph1"],
  199. * "custom_params" : {
  200. * "param_name" : "param_value",
  201. * "param_name" : "param_value",
  202. * ...
  203. * }
  204. * },
  205. * "subgraph:subgraph1" : {
  206. * "config_path" : "/your/path/to/subgraph_config_file.json"
  207. * }
  208. * }
  209. * @endcode
  210. */
  211. struct CNGraphConfig : public CNConfigBase {
  212. std::string name = ""; ///< Graph name.
  213. ProfilerConfig profiler_config; ///< Configuration of profiler.
  214. std::vector<CNModuleConfig> module_configs; ///< Configurations of modules.
  215. std::vector<CNSubgraphConfig> subgraph_configs; ///< Configurations of subgraphs.
  216. /**
  217. * @brief Parses members except ``CNGraphConfig::name`` from the JSON file.
  218. *
  219. * @param[in] jstr: Json configuration string.
  220. *
  221. * @return Returns true if the JSON string has been parsed successfully. Otherwise, returns false.
  222. */
  223. bool ParseByJSONStr(const std::string &jstr) override;
  224. }; // struct GraphConfig
  225. /**
  226. * @class ParamRegister
  227. *
  228. * @brief ParamRegister is a class for module parameter registration.
  229. *
  230. * Each module registers its own parameters and descriptions.
  231. * This is used in CNStream Inspect tool to detect parameters of each module.
  232. *
  233. */
  234. class ParamRegister {
  235. private:
  236. std::vector<std::pair<std::string /*key*/, std::string /*desc*/>> module_params_;
  237. std::string module_desc_;
  238. public:
  239. /**
  240. * @brief Registers a paramter and its description.
  241. *
  242. * This is used in CNStream Inspect tool.
  243. *
  244. * @param[in] key The parameter name.
  245. * @param[in] desc The description of the paramter.
  246. *
  247. * @return Void.
  248. */
  249. void Register(const std::string &key, const std::string &desc) {
  250. module_params_.push_back(std::make_pair(key, desc));
  251. }
  252. /**
  253. * @brief Gets the registered paramters and the parameter descriptions.
  254. *
  255. * This is used in CNStream Inspect tool.
  256. *
  257. * @return Returns the registered paramters and the parameter descriptions.
  258. */
  259. std::vector<std::pair<std::string, std::string>> GetParams() { return module_params_; }
  260. /**
  261. * @brief Checks if the paramter is registered.
  262. *
  263. * This is used in CNStream Inspect tool.
  264. *
  265. * @param[in] key The parameter name.
  266. *
  267. * @return Returns true if the parameter has been registered. Otherwise, returns false.
  268. */
  269. bool IsRegisted(const std::string &key) const {
  270. if (strcmp(key.c_str(), CNS_JSON_DIR_PARAM_NAME) == 0) {
  271. return true;
  272. }
  273. for (auto &it : module_params_) {
  274. if (key == it.first) {
  275. return true;
  276. }
  277. }
  278. return false;
  279. }
  280. /**
  281. * @brief Sets the description of the module.
  282. *
  283. * This is used in CNStream Inspect tool.
  284. *
  285. * @param[in] desc The description of the module.
  286. *
  287. * @return Void.
  288. */
  289. void SetModuleDesc(const std::string &desc) { module_desc_ = desc; }
  290. /**
  291. * @brief Gets the description of the module.
  292. *
  293. * This is used in CNStream Inspect tool.
  294. *
  295. * @return Returns the description of the module.
  296. */
  297. std::string GetModuleDesc() { return module_desc_; }
  298. };
  299. /**
  300. * @class ParametersChecker
  301. *
  302. * @brief ParameterChecker is a class used to check module parameters.
  303. */
  304. class ParametersChecker {
  305. public:
  306. /**
  307. * @brief Checks if a path exists.
  308. *
  309. * @param[in] path The path relative to JSON file or an absolute path.
  310. * @param[in] paramSet The module parameters. The JSON file path is one of the parameters.
  311. *
  312. * @return Returns true if the path exists. Otherwise, returns false.
  313. */
  314. bool CheckPath(const std::string &path, const ModuleParamSet &paramSet) {
  315. std::string relative_path = GetPathRelativeToTheJSONFile(path, paramSet);
  316. if ((access(relative_path.c_str(), R_OK)) == -1) {
  317. return false;
  318. }
  319. return true;
  320. }
  321. /**
  322. * @brief Checks if the parameters are number, and the value is specified in the correct range.
  323. *
  324. * @param[in] check_list A list of parameter names.
  325. * @param[in] paramSet The module parameters.
  326. * @param[out] err_msg The error message.
  327. * @param[in] greater_than_zero If this parameter is set to ``true``, the parameter set should be
  328. * greater than or equal to zero. If this parameter is set to ``false``, the parameter set is less than zero.
  329. *
  330. * @return Returns true if the parameters are number and the value is in the correct range. Otherwise, returns false.
  331. */
  332. bool IsNum(const std::list<std::string> &check_list, const ModuleParamSet &paramSet, std::string &err_msg, // NOLINT
  333. bool greater_than_zero = false) {
  334. for (auto &it : check_list) {
  335. if (paramSet.find(it) != paramSet.end()) {
  336. std::stringstream sin(paramSet.find(it)->second);
  337. double d;
  338. char c;
  339. if (!(sin >> d)) {
  340. err_msg = "[" + it + "] : " + paramSet.find(it)->second + " is not a number.";
  341. return false;
  342. }
  343. if (sin >> c) {
  344. err_msg = "[" + it + "] : " + paramSet.find(it)->second + " is not a number.";
  345. return false;
  346. }
  347. if (greater_than_zero) {
  348. if (d < 0) {
  349. err_msg = "[" + it + "] : " + paramSet.find(it)->second + " must be greater than zero.";
  350. return false;
  351. }
  352. }
  353. }
  354. }
  355. return true;
  356. }
  357. }; // class ParametersChecker
  358. } // namespace cnstream
  359. #endif // CNSTREAM_CONFIG_HPP_